]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/cups-deviced.c
Update svn:keyword properties.
[thirdparty/cups.git] / scheduler / cups-deviced.c
index 3fb619e1eb2b469502ba502c01047c4a4993af30..0cd5b8ea8c4042065ae87a2c5c315a40cffb6871 100644 (file)
@@ -1,9 +1,9 @@
 /*
- * "$Id: cups-deviced.c 7624 2008-06-09 15:55:04Z mike $"
+ * "$Id$"
  *
- *   Device scanning mini-daemon for the Common UNIX Printing System (CUPS).
+ *   Device scanning mini-daemon for CUPS.
  *
- *   Copyright 2007-2008 by Apple Inc.
+ *   Copyright 2007-2011 by Apple Inc.
  *   Copyright 1997-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -17,7 +17,6 @@
  *   main()                 - Scan for devices and return an IPP response.
  *   add_device()           - Add a new device to the list.
  *   compare_devices()      - Compare device names to eliminate duplicates.
- *   create_strings_array() - Create a CUPS array of strings.
  *   get_current_time()     - Get the current time as a double value in seconds.
  *   get_device()           - Get a device from a backend.
  *   process_children()     - Process all dead children...
@@ -65,10 +64,8 @@ typedef struct
 typedef struct
 {
   char device_class[128],              /* Device class */
-       device_make_and_model[128],     /* Make and model, if known */
        device_info[128],               /* Device info/description */
-       device_uri[1024],               /* Device URI */
-       device_id[1024];                /* 1284 Device ID */
+       device_uri[1024];               /* Device URI */
 } cupsd_device_t;
 
 
@@ -92,7 +89,8 @@ static int            send_class,     /* Send device-class attribute? */
                        send_make_and_model,
                                        /* Send device-make-and-model attribute? */
                        send_uri,       /* Send device-uri attribute? */
-                       send_id;        /* Send device-id attribute? */
+                       send_id,        /* Send device-id attribute? */
+                       send_location;  /* Send device-location attribute? */
 static int             dead_children = 0;
                                        /* Dead children? */
 
@@ -105,10 +103,10 @@ static int                add_device(const char *device_class,
                                   const char *device_make_and_model,
                                   const char *device_info,
                                   const char *device_uri,
-                                  const char *device_id);
+                                  const char *device_id,
+                                  const char *device_location);
 static int             compare_devices(cupsd_device_t *p0,
                                        cupsd_device_t *p1);
-static cups_array_t    *create_strings_array(const char *s);
 static double          get_current_time(void);
 static int             get_device(cupsd_backend_t *backend);
 static void            process_children(void);
@@ -140,7 +138,8 @@ main(int  argc,                             /* I - Number of command-line args */
   int          num_options;            /* Number of options */
   cups_option_t        *options;               /* Options */
   cups_array_t *requested,             /* requested-attributes values */
-               *exclude;               /* exclude-schemes values */
+               *exclude,               /* exclude-schemes values */
+               *include;               /* include-schemes values */
 #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
   struct sigaction action;             /* Actions for POSIX signals */
 #endif /* HAVE_SIGACTION && !HAVE_SIGSET */
@@ -192,13 +191,18 @@ main(int  argc,                           /* I - Number of command-line args */
   }
 
   num_options = cupsParseOptions(argv[5], 0, &options);
-  requested   = create_strings_array(cupsGetOption("requested-attributes",
-                                                   num_options, options));
-  exclude     = create_strings_array(cupsGetOption("exclude-schemes",
-                                                   num_options, options));
+  requested   = cupsdCreateStringsArray(cupsGetOption("requested-attributes",
+                                                      num_options, options));
+  exclude     = cupsdCreateStringsArray(cupsGetOption("exclude-schemes",
+                                                      num_options, options));
+  include     = cupsdCreateStringsArray(cupsGetOption("include-schemes",
+                                                      num_options, options));
 
   if (!requested || cupsArrayFind(requested, "all") != NULL)
-    send_class = send_info = send_make_and_model = send_uri = send_id = 1;
+  {
+    send_class = send_info = send_make_and_model = send_uri = send_id =
+        send_location = 1;
+  }
   else
   {
     send_class          = cupsArrayFind(requested, "device-class") != NULL;
@@ -206,6 +210,7 @@ main(int  argc,                             /* I - Number of command-line args */
     send_make_and_model = cupsArrayFind(requested, "device-make-and-model") != NULL;
     send_uri            = cupsArrayFind(requested, "device-uri") != NULL;
     send_id             = cupsArrayFind(requested, "device-id") != NULL;
+    send_location       = cupsArrayFind(requested, "device-location") != NULL;
   }
 
  /*
@@ -263,7 +268,12 @@ main(int  argc,                            /* I - Number of command-line args */
         (dent->fileinfo.st_mode & (S_IRUSR | S_IXUSR)) != (S_IRUSR | S_IXUSR))
       continue;
 
-    if (cupsArrayFind(exclude, dent->filename))
+   /*
+    * Skip excluded or not included backends...
+    */
+
+    if (cupsArrayFind(exclude, dent->filename) ||
+        (include && !cupsArrayFind(include, dent->filename)))
       continue;
 
    /*
@@ -303,11 +313,22 @@ main(int  argc,                           /* I - Number of command-line args */
     {
       for (i = 0; i < num_backends; i ++)
         if (backend_fds[i].revents && backends[i].pipe)
-         if (get_device(backends + i))
+       {
+         cups_file_t *bpipe = backends[i].pipe;
+                                       /* Copy of pipe for backend... */
+
+         do
          {
-           backend_fds[i].fd     = 0;
-           backend_fds[i].events = 0;
+           if (get_device(backends + i))
+           {
+             backend_fds[i].fd     = 0;
+             backend_fds[i].events = 0;
+             break;
+           }
          }
+         while (bpipe->ptr &&
+                memchr(bpipe->ptr, '\n', bpipe->end - bpipe->ptr));
+        }
     }
 
    /*
@@ -345,7 +366,8 @@ add_device(
     const char *device_make_and_model, /* I - Device make and model */
     const char *device_info,           /* I - Device information */
     const char *device_uri,            /* I - Device URI */
-    const char *device_id)             /* I - 1284 device ID */
+    const char *device_id,             /* I - 1284 device ID */
+    const char *device_location)       /* I - Physical location */
 {
   cupsd_device_t       *device;        /* New device */
 
@@ -366,11 +388,8 @@ add_device(
   */
 
   strlcpy(device->device_class, device_class, sizeof(device->device_class));
-  strlcpy(device->device_make_and_model, device_make_and_model,
-          sizeof(device->device_make_and_model));
   strlcpy(device->device_info, device_info, sizeof(device->device_info));
   strlcpy(device->device_uri, device_uri, sizeof(device->device_uri));
-  strlcpy(device->device_id, device_id, sizeof(device->device_id));
 
  /*
   * Add the device to the array and return...
@@ -397,16 +416,20 @@ add_device(
       cupsdSendIPPGroup(IPP_TAG_PRINTER);
       if (send_class)
        cupsdSendIPPString(IPP_TAG_KEYWORD, "device-class",
-                          device->device_class);
+                          device_class);
       if (send_info)
-       cupsdSendIPPString(IPP_TAG_TEXT, "device-info", device->device_info);
+       cupsdSendIPPString(IPP_TAG_TEXT, "device-info", device_info);
       if (send_make_and_model)
        cupsdSendIPPString(IPP_TAG_TEXT, "device-make-and-model",
-                          device->device_make_and_model);
+                          device_make_and_model);
       if (send_uri)
-       cupsdSendIPPString(IPP_TAG_URI, "device-uri", device->device_uri);
+       cupsdSendIPPString(IPP_TAG_URI, "device-uri", device_uri);
       if (send_id)
-       cupsdSendIPPString(IPP_TAG_TEXT, "device-id", device->device_id);
+       cupsdSendIPPString(IPP_TAG_TEXT, "device-id",
+                          device_id ? device_id : "");
+      if (send_location)
+       cupsdSendIPPString(IPP_TAG_TEXT, "device-location",
+                          device_location ? device_location : "");
 
       fflush(stdout);
       fputs("DEBUG: Flushed attributes...\n", stderr);
@@ -434,53 +457,10 @@ compare_devices(cupsd_device_t *d0,       /* I - First device */
 
   if ((diff = cupsdCompareNames(d0->device_info, d1->device_info)) != 0)
     return (diff);
-  else if ((diff = strcasecmp(d0->device_class, d1->device_class)) != 0)
+  else if ((diff = _cups_strcasecmp(d0->device_class, d1->device_class)) != 0)
     return (diff);
   else
-    return (strcasecmp(d0->device_uri, d1->device_uri));
-}
-
-
-/*
- * 'create_strings_array()' - Create a CUPS array of strings.
- */
-
-static cups_array_t *                  /* O - CUPS array */
-create_strings_array(const char *s)    /* I - Comma-delimited strings */
-{
-  cups_array_t *a;                     /* CUPS array */
-  const char   *start,                 /* Start of string */
-               *end;                   /* End of string */
-  char         *ptr;                   /* New string */
-
-
-  if (!s)
-    return (NULL);
-
-  if ((a = cupsArrayNew((cups_array_func_t)strcmp, NULL)) != NULL)
-  {
-    for (start = end = s; *end; start = end + 1)
-    {
-     /*
-      * Find the end of the current delimited string...
-      */
-
-      if ((end = strchr(start, ',')) == NULL)
-        end = start + strlen(start);
-
-     /*
-      * Duplicate the string and add it to the array...
-      */
-
-      if ((ptr = calloc(1, end - start + 1)) == NULL)
-        break;
-
-      memcpy(ptr, start, end - start);
-      cupsArrayAdd(a, ptr);
-    }
-  }
-
-  return (a);
+    return (_cups_strcasecmp(d0->device_uri, d1->device_uri));
 }
 
 
@@ -508,11 +488,14 @@ static int                                /* O - 0 on success, -1 on error */
 get_device(cupsd_backend_t *backend)   /* I - Backend to read from */
 {
   char line[2048],                     /* Line from backend */
-       dclass[64],                     /* Device class */
-       uri[1024],                      /* Device URI */
-       info[128],                      /* Device info */
-       make_model[256],                /* Make and model */
-       device_id[1024];                /* 1284 device ID */
+       temp[2048],                     /* Copy of line */
+       *ptr,                           /* Pointer into line */
+       *dclass,                        /* Device class */
+       *uri,                           /* Device URI */
+       *make_model,                    /* Make and model */
+       *info,                          /* Device info */
+       *device_id,                     /* 1284 device ID */
+       *location;                      /* Physical location */
 
 
   if (cupsFileGets(backend->pipe, line, sizeof(line)))
@@ -520,35 +503,123 @@ get_device(cupsd_backend_t *backend)     /* I - Backend to read from */
    /*
     * Each line is of the form:
     *
-    *   class URI "make model" "name" ["1284 device ID"]
+    *   class URI "make model" "name" ["1284 device ID"] ["location"]
+    */
+
+    strlcpy(temp, line, sizeof(temp));
+
+   /*
+    * device-class
+    */
+
+    dclass = temp;
+
+    for (ptr = temp; *ptr; ptr ++)
+      if (isspace(*ptr & 255))
+        break;
+
+    while (isspace(*ptr & 255))
+      *ptr++ = '\0';
+
+   /*
+    * device-uri
+    */
+
+    if (!*ptr)
+      goto error;
+
+    for (uri = ptr; *ptr; ptr ++)
+      if (isspace(*ptr & 255))
+        break;
+
+    while (isspace(*ptr & 255))
+      *ptr++ = '\0';
+
+   /*
+    * device-make-and-model
     */
 
-    device_id[0] = '\0';
+    if (*ptr != '\"')
+      goto error;
 
-    if (sscanf(line,
-              "%63s%1023s%*[ \t]\"%255[^\"]\"%*[ \t]\"%127[^\"]\""
-              "%*[ \t]\"%1023[^\"]",
-              dclass, uri, make_model, info, device_id) < 4)
+    for (ptr ++, make_model = ptr; *ptr && *ptr != '\"'; ptr ++)
     {
-     /*
-      * Bad format; strip trailing newline and write an error message.
-      */
+      if (*ptr == '\\' && ptr[1])
+        _cups_strcpy(ptr, ptr + 1);
+    }
+
+    if (*ptr != '\"')
+      goto error;
+
+    for (*ptr++ = '\0'; isspace(*ptr & 255); *ptr++ = '\0');
+
+   /*
+    * device-info
+    */
 
-      if (line[strlen(line) - 1] == '\n')
-       line[strlen(line) - 1] = '\0';
+    if (*ptr != '\"')
+      goto error;
 
-      fprintf(stderr, "ERROR: [cups-deviced] Bad line from \"%s\": %s\n",
-             backend->name, line);
+    for (ptr ++, info = ptr; *ptr && *ptr != '\"'; ptr ++)
+    {
+      if (*ptr == '\\' && ptr[1])
+        _cups_strcpy(ptr, ptr + 1);
     }
-    else
+
+    if (*ptr != '\"')
+      goto error;
+
+    for (*ptr++ = '\0'; isspace(*ptr & 255); *ptr++ = '\0');
+
+   /*
+    * device-id
+    */
+
+    if (*ptr == '\"')
     {
+      for (ptr ++, device_id = ptr; *ptr && *ptr != '\"'; ptr ++)
+      {
+       if (*ptr == '\\' && ptr[1])
+         _cups_strcpy(ptr, ptr + 1);
+      }
+
+      if (*ptr != '\"')
+       goto error;
+
+      for (*ptr++ = '\0'; isspace(*ptr & 255); *ptr++ = '\0');
+
      /*
-      * Add the device to the array of available devices...
+      * device-location
       */
 
-      if (!add_device(dclass, make_model, info, uri, device_id))
-        fprintf(stderr, "DEBUG: [cups-deviced] Found device \"%s\"...\n", uri);
+      if (*ptr == '\"')
+      {
+       for (ptr ++, location = ptr; *ptr && *ptr != '\"'; ptr ++)
+       {
+         if (*ptr == '\\' && ptr[1])
+           _cups_strcpy(ptr, ptr + 1);
+       }
+
+       if (*ptr != '\"')
+         goto error;
+
+       *ptr = '\0';
+      }
+      else
+        location = NULL;
     }
+    else
+    {
+      device_id = NULL;
+      location  = NULL;
+    }
+
+   /*
+    * Add the device to the array of available devices...
+    */
+
+    if (!add_device(dclass, make_model, info, uri, device_id, location))
+      fprintf(stderr, "DEBUG: [cups-deviced] Found device \"%s\"...\n", uri);
 
     return (0);
   }
@@ -561,6 +632,19 @@ get_device(cupsd_backend_t *backend)       /* I - Backend to read from */
   backend->pipe = NULL;
 
   return (-1);
+
+ /*
+  * Bad format; strip trailing newline and write an error message.
+  */
+
+  error:
+
+  if (line[strlen(line) - 1] == '\n')
+    line[strlen(line) - 1] = '\0';
+
+  fprintf(stderr, "ERROR: [cups-deviced] Bad line from \"%s\": %s\n",
+         backend->name, line);
+  return (0);
 }
 
 
@@ -683,6 +767,10 @@ start_backend(const char *name,            /* I - Backend to run */
 
   snprintf(program, sizeof(program), "%s/backend/%s", server_bin, name);
 
+  if (_cupsFileCheck(program, _CUPS_FILE_CHECK_PROGRAM, !geteuid(),
+                     _cupsFileCheckFilter, NULL))
+    return (-1);
+
   backend = backends + num_backends;
 
   argv[0] = (char *)name;
@@ -718,5 +806,5 @@ start_backend(const char *name,             /* I - Backend to run */
 
 
 /*
- * End of "$Id: cups-deviced.c 7624 2008-06-09 15:55:04Z mike $".
+ * End of "$Id$".
  */