1*42a7bdedSjacobs /*************************************************************************** 2*42a7bdedSjacobs * 3*42a7bdedSjacobs * probe-printer.c : Probe for prnio(7i) printer device information 4*42a7bdedSjacobs * 5*42a7bdedSjacobs * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 6*42a7bdedSjacobs * Use is subject to license terms. 7*42a7bdedSjacobs * 8*42a7bdedSjacobs * Licensed under the Academic Free License version 2.1 9*42a7bdedSjacobs * 10*42a7bdedSjacobs **************************************************************************/ 11*42a7bdedSjacobs 12*42a7bdedSjacobs #pragma ident "%Z%%M% %I% %E% SMI" 13*42a7bdedSjacobs 14*42a7bdedSjacobs #ifdef HAVE_CONFIG_H 15*42a7bdedSjacobs # include <config.h> 16*42a7bdedSjacobs #endif 17*42a7bdedSjacobs 18*42a7bdedSjacobs #include <errno.h> 19*42a7bdedSjacobs #include <string.h> 20*42a7bdedSjacobs #include <strings.h> 21*42a7bdedSjacobs #include <ctype.h> 22*42a7bdedSjacobs #include <stdlib.h> 23*42a7bdedSjacobs #include <stdio.h> 24*42a7bdedSjacobs #include <sys/ioctl.h> 25*42a7bdedSjacobs #include <sys/prnio.h> 26*42a7bdedSjacobs #include <fcntl.h> 27*42a7bdedSjacobs #include <unistd.h> 28*42a7bdedSjacobs #include <ctype.h> 29*42a7bdedSjacobs 30*42a7bdedSjacobs #include <libhal.h> 31*42a7bdedSjacobs #include <logger.h> 32*42a7bdedSjacobs 33*42a7bdedSjacobs #define NELEM(a) (sizeof (a) / sizeof (*(a))) 34*42a7bdedSjacobs 35*42a7bdedSjacobs static char * 36*42a7bdedSjacobs strip_ws(char *s) 37*42a7bdedSjacobs { 38*42a7bdedSjacobs if (s != NULL) { 39*42a7bdedSjacobs char *p; 40*42a7bdedSjacobs 41*42a7bdedSjacobs /* skip the leading whitespace */ 42*42a7bdedSjacobs for (; ((*s != NULL) && (isspace(*s) != 0)); s++) ; 43*42a7bdedSjacobs 44*42a7bdedSjacobs /* drop the trailing whitespace */ 45*42a7bdedSjacobs for (p = s + strlen(s) - 1; ((p > s) && (isspace(*p) != 0)); 46*42a7bdedSjacobs p--) ; 47*42a7bdedSjacobs *(++p) = '\0'; 48*42a7bdedSjacobs } 49*42a7bdedSjacobs 50*42a7bdedSjacobs return (s); 51*42a7bdedSjacobs } 52*42a7bdedSjacobs 53*42a7bdedSjacobs static int 54*42a7bdedSjacobs get_prnio_data(int fd, LibHalChangeSet *cs) 55*42a7bdedSjacobs { 56*42a7bdedSjacobs struct prn_1284_device_id id; 57*42a7bdedSjacobs char buf[BUFSIZ]; 58*42a7bdedSjacobs char *s, *iter = NULL; 59*42a7bdedSjacobs 60*42a7bdedSjacobs memset(&id, 0, sizeof (id)); 61*42a7bdedSjacobs memset(&buf, 0, sizeof (buf)); 62*42a7bdedSjacobs id.id_data = buf; 63*42a7bdedSjacobs id.id_len = sizeof (buf); 64*42a7bdedSjacobs 65*42a7bdedSjacobs if (ioctl(fd, PRNIOC_GET_1284_DEVID, &id) < 0) { 66*42a7bdedSjacobs return (-1); 67*42a7bdedSjacobs } 68*42a7bdedSjacobs 69*42a7bdedSjacobs HAL_DEBUG (("IEEE-1284 DeviceId = %s", buf)); 70*42a7bdedSjacobs 71*42a7bdedSjacobs for (s = strtok_r(buf, ";\n", &iter); s != NULL; 72*42a7bdedSjacobs s = strtok_r(NULL, ";\n", &iter)) { 73*42a7bdedSjacobs char *t, *u, *iter2 = NULL; 74*42a7bdedSjacobs 75*42a7bdedSjacobs if ((t = strtok_r(s, ":\n", &iter2)) == NULL) { 76*42a7bdedSjacobs continue; 77*42a7bdedSjacobs } 78*42a7bdedSjacobs 79*42a7bdedSjacobs if ((u = strtok_r(NULL, ":\n", &iter2)) == NULL) { 80*42a7bdedSjacobs continue; 81*42a7bdedSjacobs } 82*42a7bdedSjacobs 83*42a7bdedSjacobs if ((strcasecmp(t, "MFG") == 0) || 84*42a7bdedSjacobs (strcasecmp(t, "MANUFACTURER") == 0)) { 85*42a7bdedSjacobs libhal_changeset_set_property_string (cs, 86*42a7bdedSjacobs "printer.vendor", strip_ws(u)); 87*42a7bdedSjacobs } else if ((strcasecmp(t, "MDL") == 0) || 88*42a7bdedSjacobs (strcasecmp(t, "MODEL") == 0)) { 89*42a7bdedSjacobs libhal_changeset_set_property_string (cs, 90*42a7bdedSjacobs "printer.product", strip_ws(u)); 91*42a7bdedSjacobs } else if ((strcasecmp(t, "SN") == 0) || 92*42a7bdedSjacobs (strcasecmp(t, "SERN") == 0) || 93*42a7bdedSjacobs (strcasecmp(t, "SERIALNUMBER") == 0)) { 94*42a7bdedSjacobs libhal_changeset_set_property_string (cs, 95*42a7bdedSjacobs "printer.serial", strip_ws(u)); 96*42a7bdedSjacobs } else if ((strcasecmp(t, "DES") == 0) || 97*42a7bdedSjacobs (strcasecmp(t, "DESCRIPTION") == 0)) { 98*42a7bdedSjacobs libhal_changeset_set_property_string (cs, 99*42a7bdedSjacobs "printer.description", strip_ws(u)); 100*42a7bdedSjacobs } else if ((strcasecmp(t, "CMD") == 0) || 101*42a7bdedSjacobs (strcasecmp(t, "COMMAND SET") == 0) || 102*42a7bdedSjacobs (strcasecmp(t, "COMMANDSET") == 0)) { 103*42a7bdedSjacobs char *v, *iter3 = NULL; 104*42a7bdedSjacobs const char *cmds[32]; 105*42a7bdedSjacobs int i = 0; 106*42a7bdedSjacobs 107*42a7bdedSjacobs memset(&cmds, 0, sizeof (cmds)); 108*42a7bdedSjacobs for (v = strtok_r(u, ",\n", &iter3); 109*42a7bdedSjacobs ((v != NULL) && (i < NELEM(cmds))); 110*42a7bdedSjacobs v = strtok_r(NULL, ",\n", &iter3)) { 111*42a7bdedSjacobs cmds[i++] = strip_ws(v); 112*42a7bdedSjacobs } 113*42a7bdedSjacobs 114*42a7bdedSjacobs libhal_changeset_set_property_strlist(cs, 115*42a7bdedSjacobs "printer.commandset", cmds); 116*42a7bdedSjacobs } 117*42a7bdedSjacobs } 118*42a7bdedSjacobs 119*42a7bdedSjacobs return (0); 120*42a7bdedSjacobs } 121*42a7bdedSjacobs 122*42a7bdedSjacobs int 123*42a7bdedSjacobs main (int argc, char *argv[]) 124*42a7bdedSjacobs { 125*42a7bdedSjacobs int ret = 1; 126*42a7bdedSjacobs int fd = -1; 127*42a7bdedSjacobs char *udi; 128*42a7bdedSjacobs char *device_file; 129*42a7bdedSjacobs DBusError error; 130*42a7bdedSjacobs LibHalContext *ctx = NULL; 131*42a7bdedSjacobs LibHalChangeSet *cs = NULL; 132*42a7bdedSjacobs 133*42a7bdedSjacobs if ((udi = getenv ("UDI")) == NULL) 134*42a7bdedSjacobs goto out; 135*42a7bdedSjacobs if ((device_file = getenv ("HAL_PROP_PRINTER_DEVICE")) == NULL) 136*42a7bdedSjacobs goto out; 137*42a7bdedSjacobs 138*42a7bdedSjacobs setup_logger (); 139*42a7bdedSjacobs 140*42a7bdedSjacobs dbus_error_init (&error); 141*42a7bdedSjacobs if ((ctx = libhal_ctx_init_direct (&error)) == NULL) 142*42a7bdedSjacobs goto out; 143*42a7bdedSjacobs 144*42a7bdedSjacobs if ((cs = libhal_device_new_changeset (udi)) == NULL) { 145*42a7bdedSjacobs HAL_DEBUG (("Cannot allocate changeset")); 146*42a7bdedSjacobs goto out; 147*42a7bdedSjacobs } 148*42a7bdedSjacobs 149*42a7bdedSjacobs HAL_DEBUG (("Doing probe-printer for %s (udi=%s)", 150*42a7bdedSjacobs device_file, udi)); 151*42a7bdedSjacobs 152*42a7bdedSjacobs if ((fd = open (device_file, O_RDONLY | O_NONBLOCK)) < 0) { 153*42a7bdedSjacobs HAL_DEBUG (("Cannot open %s: %s", device_file, strerror (errno))); 154*42a7bdedSjacobs goto out; 155*42a7bdedSjacobs } 156*42a7bdedSjacobs 157*42a7bdedSjacobs if (get_prnio_data(fd, cs) < 0) { 158*42a7bdedSjacobs HAL_DEBUG (("Cannot get prnio data %s: %s", device_file, strerror (errno))); 159*42a7bdedSjacobs goto out; 160*42a7bdedSjacobs } 161*42a7bdedSjacobs 162*42a7bdedSjacobs libhal_device_commit_changeset (ctx, cs, &error); 163*42a7bdedSjacobs 164*42a7bdedSjacobs ret = 0; 165*42a7bdedSjacobs 166*42a7bdedSjacobs out: 167*42a7bdedSjacobs if (cs != NULL) { 168*42a7bdedSjacobs libhal_device_free_changeset (cs); 169*42a7bdedSjacobs } 170*42a7bdedSjacobs 171*42a7bdedSjacobs if (fd >= 0) { 172*42a7bdedSjacobs close (fd); 173*42a7bdedSjacobs } 174*42a7bdedSjacobs 175*42a7bdedSjacobs if (ctx != NULL) { 176*42a7bdedSjacobs if (dbus_error_is_set(&error)) { 177*42a7bdedSjacobs dbus_error_free (&error); 178*42a7bdedSjacobs } 179*42a7bdedSjacobs libhal_ctx_shutdown (ctx, &error); 180*42a7bdedSjacobs libhal_ctx_free (ctx); 181*42a7bdedSjacobs } 182*42a7bdedSjacobs 183*42a7bdedSjacobs return ret; 184*42a7bdedSjacobs } 185