#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "parport.h"
#include "ppdev.h"


static int get_deviceid (char *buffer, int lenght, int fd)
{
   ssize_t len = 0;

   if (read (fd, buffer, 2) < 2)
   {
      return 1;
   }
   len = ((unsigned char)buffer[0] << 8) + (unsigned char)buffer[1];
   if ( len > lenght )
      len = lenght - 3 ;
   len = read(fd, buffer+2, len);
   buffer[len+2] = '\0';
   return 0;
}


#define IOCNR_GET_DEVICE_ID	1
#define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len)	/* get device_id string */

int main(int argc, char **argv)
{
   int fd;
   unsigned char argp[1024];
   int length;
   char *dev;
   int compat = IEEE1284_MODE_COMPAT;
   int mode   = IEEE1284_MODE_NIBBLE;

   if ( argc == 2 )
   {
      if ( strstr(argv[1], "usb") )
      {
         /* call for usb devices */
         if ( (fd = open(argv[1], O_RDONLY)) > -1 )
         {
            if (ioctl (fd, LPIOC_GET_DEVICE_ID(sizeof(argp)-1), argp) > -1 )
            {
               length = (argp[0] << 8) + argp[1];
               if ( length > sizeof(argp)-1 )
                  length = sizeof(argp)-1;
               argp[length] = '\0';
               printf("%s\n",argp+2);
               exit(0);
            }
	    else
	    {
	       fprintf(stderr,"ioctl: %s\n",strerror(errno));
	    }
         }
	 else
	 {
	    fprintf(stderr,"open: %s\n",strerror(errno));
	 }
      }
      else
      {
         /* call for parport devices */
         /* replace /dev/lp# with /dev/parport# */
         if ( strlen(argv[1]) < 7 )
            exit(1);
         length = 20 + strlen(  argv[1] + 7 );
         dev = (char*)calloc( length,1);
         sprintf(dev, "/dev/parports/%s",&argv[1][7]);
         if ( access(dev, R_OK|W_OK) == -1 )
         {
            sprintf(dev, "/dev/parport%s",&argv[1][7]);
            if ( access(dev, R_OK|W_OK) == -1 )
            {
               exit(1);
            }
         }
         fd = open (dev, O_RDWR);
         if (fd == -1)
         {
            exit(1);
         }

         if (ioctl (fd, PPSETMODE, &mode))
         {
            exit(2);
         }

         if (ioctl (fd, PPCLAIM))
         {
            exit(3);
         }

         if (ioctl (fd, PPNEGOT, &compat))
         {
            exit(4);
         }

         mode |= IEEE1284_DEVICEID;
         if (ioctl (fd, PPNEGOT, &mode))
         {
            exit(5);
         }
         if ( get_deviceid((char*)argp, sizeof(argp)-1,fd) == 0 )
            printf("%s\n",argp+2);
	   
         ioctl (fd, PPNEGOT, &compat);
         ioctl (fd, PPRELEASE);
         close (fd);
         exit(0);
      }
   }

   exit(1);
   return 0;
}
