]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - backend/serial.c
Merge changes from CUPS 1.5svn-r8849.
[thirdparty/cups.git] / backend / serial.c
index 86410014901839f2919290edf04c84fb72699e68..a77b76cba6b1e37e0772264c930c947d8788d54a 100644 (file)
@@ -1,9 +1,9 @@
 /*
- * "$Id: serial.c 6911 2007-09-04 20:35:08Z mike $"
+ * "$Id: serial.c 7647 2008-06-16 17:39:40Z mike $"
  *
  *   Serial port backend for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2009 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -84,7 +84,7 @@
  */
 
 static void    list_devices(void);
-static void    side_cb(int print_fd, int device_fd, int use_bc);
+static int     side_cb(int print_fd, int device_fd, int use_bc);
 
 
 /*
@@ -109,7 +109,8 @@ main(int  argc,                             /* I - Number of command-line arguments (6 or 7) */
                sep;                    /* Option separator */
   int          port;                   /* Port number (not used) */
   int          copies;                 /* Number of copies to print */
-  int          print_fd,               /* Print file */
+  int          side_eof = 0,           /* Saw EOF on side-channel? */
+               print_fd,               /* Print file */
                device_fd;              /* Serial device */
   int          nfds;                   /* Maximum file descriptor value + 1 */
   fd_set       input,                  /* Input set for reading */
@@ -185,7 +186,9 @@ main(int  argc,                             /* I - Number of command-line arguments (6 or 7) */
 
     if ((print_fd = open(argv[6], O_RDONLY)) < 0)
     {
-      perror("ERROR: unable to open print file");
+      _cupsLangPrintf(stderr,
+                      _("ERROR: Unable to open print file \"%s\": %s\n"),
+                      argv[6], strerror(errno));
       return (CUPS_BACKEND_FAILED);
     }
 
@@ -375,7 +378,7 @@ main(int  argc,                             /* I - Number of command-line arguments (6 or 7) */
              break;
 #  endif /* B230400 */
           default :
-             _cupsLangPrintf(stderr, _("WARNING: Unsupported baud rate %s!\n"),
+             _cupsLangPrintf(stderr, _("WARNING: Unsupported baud rate %s\n"),
                              value);
              break;
        }
@@ -556,7 +559,8 @@ main(int  argc,                             /* I - Number of command-line arguments (6 or 7) */
       if (!print_bytes)
        FD_SET(print_fd, &input);
       FD_SET(device_fd, &input);
-      FD_SET(CUPS_SC_FD, &input);
+      if (!print_bytes && !side_eof)
+        FD_SET(CUPS_SC_FD, &input);
 
       FD_ZERO(&output);
       if (print_bytes)
@@ -570,7 +574,16 @@ main(int  argc,                            /* I - Number of command-line arguments (6 or 7) */
       */
 
       if (FD_ISSET(CUPS_SC_FD, &input))
-        side_cb(print_fd, device_fd, 1);
+      {
+       /*
+       * Do the side-channel request, then start back over in the select
+       * loop since it may have read from print_fd...
+       */
+
+        if (side_cb(print_fd, device_fd, 1))
+         side_eof = 1;
+       continue;
+      }
 
      /*
       * Check if we have back-channel data ready...
@@ -581,7 +594,7 @@ main(int  argc,                             /* I - Number of command-line arguments (6 or 7) */
        if ((bc_bytes = read(device_fd, bc_buffer, sizeof(bc_buffer))) > 0)
        {
          fprintf(stderr,
-                 "DEBUG: Received " CUPS_LLFMT " bytes of back-channel data!\n",
+                 "DEBUG: Received " CUPS_LLFMT " bytes of back-channel data\n",
                  CUPS_LLCAST bc_bytes);
           cupsBackChannelWrite(bc_buffer, bc_bytes, 1.0);
        }
@@ -601,7 +614,7 @@ main(int  argc,                             /* I - Number of command-line arguments (6 or 7) */
 
          if (errno != EAGAIN || errno != EINTR)
          {
-           perror("ERROR: Unable to read print data");
+           _cupsLangPrintError(_("ERROR: Unable to read print data"));
 
             tcsetattr(device_fd, TCSADRAIN, &origopts);
 
@@ -677,7 +690,7 @@ main(int  argc,                             /* I - Number of command-line arguments (6 or 7) */
 
          if (errno != EAGAIN && errno != EINTR && errno != ENOTTY)
          {
-           perror("ERROR: Unable to write print data");
+           _cupsLangPrintError(_("ERROR: Unable to write print data"));
 
             tcsetattr(device_fd, TCSADRAIN, &origopts);
 
@@ -723,16 +736,18 @@ main(int  argc,                           /* I - Number of command-line arguments (6 or 7) */
 static void
 list_devices(void)
 {
-#if defined(__hpux) || defined(__sgi) || defined(__sun) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
+#if defined(__hpux) || defined(__sgi) || defined(__sun) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
   static char  *funky_hex = "0123456789abcdefghijklmnopqrstuvwxyz";
                                        /* Funky hex numbering used for some *
                                         * devices                           */
-#endif /* __hpux || __sgi || __sun || __FreeBSD__ || __OpenBSD__ */
+#endif /* __hpux || __sgi || __sun || __FreeBSD__ || __OpenBSD__ || __FreeBSD_kernel__ */
+
 
 #ifdef __linux
   int                  i, j;           /* Looping vars */
   int                  fd;             /* File descriptor */
   char                 device[255];    /* Device filename */
+  char                 info[255];      /* Device info/description */
 #  ifdef TIOCGSERIAL
   struct serial_struct serinfo;        /* serial port info */
 #  endif /* TIOCGSERIAL */
@@ -767,32 +782,35 @@ list_devices(void)
 
       close(fd);
 
+      snprintf(info, sizeof(info),
+              _cupsLangString(cupsLangDefault(), _("Serial Port #%d")), i + 1);
+
 #  if defined(_ARCH_PPC) || defined(powerpc) || defined(__powerpc)
-      printf("serial serial:%s?baud=230400 \"Unknown\" \"Serial Port #%d\"\n",
-             device, i + 1);
+      printf("serial serial:%s?baud=230400 \"Unknown\" \"%s\"\n", device, info);
 #  else
-      printf("serial serial:%s?baud=115200 \"Unknown\" \"Serial Port #%d\"\n",
-             device, i + 1);
+      printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info);
 #  endif /* _ARCH_PPC || powerpc || __powerpc */
     }
   }
 
   for (i = 0; i < 16; i ++)
   {
+    snprintf(info, sizeof(info),
+            _cupsLangString(cupsLangDefault(), _("USB Serial Port #%d")),
+            i + 1);
+
     sprintf(device, "/dev/usb/ttyUSB%d", i);
     if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
     {
       close(fd);
-      printf("serial serial:%s?baud=230400 \"Unknown\" \"USB Serial Port #%d\"\n",
-             device, i + 1);
+      printf("serial serial:%s?baud=230400 \"Unknown\" \"%s\"\n", device, info);
     }
 
     sprintf(device, "/dev/ttyUSB%d", i);
     if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
     {
       close(fd);
-      printf("serial serial:%s?baud=230400 \"Unknown\" \"USB Serial Port #%d\"\n",
-             device, i + 1);
+      printf("serial serial:%s?baud=230400 \"Unknown\" \"%s\"\n", device, info);
     }
   }
 
@@ -804,9 +822,9 @@ list_devices(void)
       if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
       {
         close(fd);
+
         printf("serial serial:%s?baud=115200 \"Unknown\" "
-              "\"Equinox ESP %d Port #%d\"\n",
-               device, i, j + 1);
+              "\"Equinox ESP %d Port #%d\"\n", device, i, j + 1);
       }
     }
   }
@@ -909,8 +927,9 @@ list_devices(void)
        }
       }
 #elif defined(__sun)
-  int          i, j, n;        /* Looping vars */
-  char         device[255];    /* Device filename */
+  int          i, j, n;                /* Looping vars */
+  char         device[255];            /* Device filename */
+  char         info[255];              /* Device info/description */
 
 
  /*
@@ -920,14 +939,17 @@ list_devices(void)
   for (i = 0; i < 26; i ++)
   {
     sprintf(device, "/dev/cua/%c", 'a' + i);
-    if (access(device, 0) == 0)
+    if (!access(device, 0))
+    {
+      snprintf(info, sizeof(info),
+              _cupsLangString(cupsLangDefault(), _("Serial Port #%d")), i + 1);
+
 #  ifdef B115200
-      printf("serial serial:%s?baud=115200 \"Unknown\" \"Serial Port #%d\"\n",
-             device, i + 1);
+      printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info);
 #  else
-      printf("serial serial:%s?baud=38400 \"Unknown\" \"Serial Port #%d\"\n",
-             device, i + 1);
+      printf("serial serial:%s?baud=38400 \"Unknown\" \"%s\"\n", device, info);
 #  endif /* B115200 */
+    }
   }
 
  /*
@@ -1023,10 +1045,11 @@ list_devices(void)
       printf("serial serial:%s?baud=38400 \"Unknown\" \"Serial Port #%d\"\n",
              device, i + 1);
   }
-#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
-  int  i, j;           /* Looping vars */
-  int  fd;             /* File descriptor */
-  char device[255];    /* Device filename */
+#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
+  int  i, j;                           /* Looping vars */
+  int  fd;                             /* File descriptor */
+  char device[255];                    /* Device filename */
+  char info[255];                      /* Device info/description */
 
 
  /*
@@ -1039,8 +1062,11 @@ list_devices(void)
     if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
     {
       close(fd);
-      printf("serial serial:%s?baud=115200 \"Unknown\" \"Standard Serial Port #%d\"\n",
-             device, i + 1);
+
+      snprintf(info, sizeof(info),
+              _cupsLangString(cupsLangDefault(), _("Serial Port #%d")), i + 1);
+
+      printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info);
     }
   }
 
@@ -1114,9 +1140,10 @@ list_devices(void)
     }
   }
 #elif defined(__NetBSD__)
-  int  i, j;           /* Looping vars */
-  int  fd;             /* File descriptor */
-  char device[255];    /* Device filename */
+  int  i, j;                           /* Looping vars */
+  int  fd;                             /* File descriptor */
+  char device[255];                    /* Device filename */
+  char info[255];                      /* Device info/description */
 
 
  /*
@@ -1129,8 +1156,11 @@ list_devices(void)
     if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
     {
       close(fd);
-      printf("serial serial:%s?baud=115200 \"Unknown\" \"Serial Port #%d\"\n",
-             device, i + 1);
+
+      snprintf(info, sizeof(info),
+              _cupsLangString(cupsLangDefault(), _("Serial Port #%d")), i + 1);
+
+      printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info);
     }
   }
 
@@ -1183,38 +1213,51 @@ list_devices(void)
       {
        CFTypeRef       serialNameAsCFString;
        CFTypeRef       bsdPathAsCFString;
+       CFTypeRef       hiddenVal;
        char            serialName[128];
        char            bsdPath[1024];
        Boolean         result;
 
 
-       serialNameAsCFString =
-           IORegistryEntryCreateCFProperty(serialService,
-                                           CFSTR(kIOTTYDeviceKey),
-                                           kCFAllocatorDefault, 0);
-       if (serialNameAsCFString)
+       /* Check if hidden... */
+       hiddenVal = IORegistryEntrySearchCFProperty(serialService, 
+                                                   kIOServicePlane,
+                                                   CFSTR("HiddenPort"),
+                                                   kCFAllocatorDefault,
+                                                   kIORegistryIterateRecursively | 
+                                                   kIORegistryIterateParents);
+       if (hiddenVal)
+         CFRelease(hiddenVal); /* This interface should not be used */
+       else
        {
-         result = CFStringGetCString(serialNameAsCFString, serialName,
-                                     sizeof(serialName),
-                                     kCFStringEncodingASCII);
-         CFRelease(serialNameAsCFString);
-
-         if (result)
+         serialNameAsCFString =
+             IORegistryEntryCreateCFProperty(serialService,
+                                             CFSTR(kIOTTYDeviceKey),
+                                             kCFAllocatorDefault, 0);
+         if (serialNameAsCFString)
          {
-           bsdPathAsCFString =
-               IORegistryEntryCreateCFProperty(serialService,
-                                               CFSTR(kIOCalloutDeviceKey),
-                                               kCFAllocatorDefault, 0);
-           if (bsdPathAsCFString)
+           result = CFStringGetCString(serialNameAsCFString, serialName,
+                                       sizeof(serialName),
+                                       kCFStringEncodingASCII);
+           CFRelease(serialNameAsCFString);
+  
+           if (result)
            {
-             result = CFStringGetCString(bsdPathAsCFString, bsdPath,
-                                         sizeof(bsdPath),
-                                         kCFStringEncodingASCII);
-             CFRelease(bsdPathAsCFString);
-
-             if (result)
-               printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n",
-                      bsdPath, serialName);
+             bsdPathAsCFString =
+                 IORegistryEntryCreateCFProperty(serialService,
+                                                 CFSTR(kIOCalloutDeviceKey),
+                                                 kCFAllocatorDefault, 0);
+             if (bsdPathAsCFString)
+             {
+               result = CFStringGetCString(bsdPathAsCFString, bsdPath,
+                                           sizeof(bsdPath),
+                                           kCFStringEncodingASCII);
+               CFRelease(bsdPathAsCFString);
+  
+               if (result)
+                 printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n",
+                        bsdPath, serialName);
+             }
            }
          }
        }
@@ -1237,7 +1280,7 @@ list_devices(void)
  * 'side_cb()' - Handle side-channel requests...
  */
 
-static void
+static int                             /* O - 0 on success, -1 on error */
 side_cb(int print_fd,                  /* I - Print file */
         int device_fd,                 /* I - Device file */
        int use_bc)                     /* I - Using back-channel? */
@@ -1251,11 +1294,7 @@ side_cb(int print_fd,                    /* I - Print file */
   datalen = sizeof(data);
 
   if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0))
-  {
-    _cupsLangPuts(stderr,
-                  _("WARNING: Failed to read side-channel request!\n"));
-    return;
-  }
+    return (-1);
 
   switch (command)
   {
@@ -1271,6 +1310,7 @@ side_cb(int print_fd,                     /* I - Print file */
         break;
 
     case CUPS_SC_CMD_GET_BIDI :
+       status  = CUPS_SC_STATUS_OK;
         data[0] = use_bc;
         datalen = 1;
         break;
@@ -1281,10 +1321,10 @@ side_cb(int print_fd,                   /* I - Print file */
        break;
   }
 
-  cupsSideChannelWrite(command, status, data, datalen, 1.0);
+  return (cupsSideChannelWrite(command, status, data, datalen, 1.0));
 }
 
 
 /*
- * End of "$Id: serial.c 6911 2007-09-04 20:35:08Z mike $".
+ * End of "$Id: serial.c 7647 2008-06-16 17:39:40Z mike $".
  */