/*
- * "$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
* 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...
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;
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? */
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);
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 */
}
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;
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;
}
/*
(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;
/*
{
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));
+ }
}
/*
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 */
- *temp; /* Found device */
+ cupsd_device_t *device; /* New 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...
*/
- if ((temp = cupsArrayFind(devices, device)) != NULL)
+ if (cupsArrayFind(devices, device))
{
/*
* Avoid duplicates!
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);
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));
}
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)))
/*
* 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);
}
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);
}
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;
/*
- * End of "$Id: cups-deviced.c 7624 2008-06-09 15:55:04Z mike $".
+ * End of "$Id$".
*/