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