1 /*************************************************************************** 2 * 3 * probe-printer.c : Probe for prnio(4I) 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 #ifdef HAVE_CONFIG_H 13 #include <config.h> 14 #endif 15 16 #include <errno.h> 17 #include <string.h> 18 #include <strings.h> 19 #include <ctype.h> 20 #include <stdlib.h> 21 #include <stdio.h> 22 #include <sys/param.h> 23 #include <sys/types.h> 24 #include <dirent.h> 25 #include <sys/ioctl.h> 26 #include <sys/prnio.h> 27 #include <fcntl.h> 28 #include <unistd.h> 29 #include <ctype.h> 30 31 #include <libhal.h> 32 #include <logger.h> 33 34 #include "printer.h" 35 36 static int 37 prnio_printer_info(char *device_file, char **manufacturer, char **model, 38 char **description, char **serial_number, char ***command_set) 39 { 40 struct prn_1284_device_id id; 41 char buf[BUFSIZ]; 42 int fd = -1, rc = -1; 43 44 memset(&id, 0, sizeof (id)); 45 memset(&buf, 0, sizeof (buf)); 46 id.id_data = buf; 47 id.id_len = sizeof (buf); 48 49 if ((fd = open (device_file, O_RDONLY | O_NONBLOCK)) < 0) { 50 goto prnio_out; 51 } 52 53 if (ioctl(fd, PRNIOC_GET_1284_DEVID, &id) < 0) { 54 goto prnio_out; 55 } 56 57 HAL_DEBUG(("IEEE-1284 DeviceId = %s", buf)); 58 59 rc = ieee1284_devid_to_printer_info(buf, manufacturer, model, 60 description, NULL, serial_number, command_set); 61 62 prnio_out: 63 if (fd != -1) 64 close(fd); 65 66 return (rc); 67 } 68 69 /* 70 * It is assumed that all devices that support prnio(4I), also have a link 71 * in /dev/printers. 72 */ 73 static char * 74 prnio_device_name(void) 75 { 76 char *result = NULL; 77 char *devfs_path; 78 DIR *dp; 79 80 if (((devfs_path = getenv("HAL_PROP_SOLARIS_DEVFS_PATH")) != NULL) && 81 ((dp = opendir("/dev/printers")) != NULL)) { 82 struct dirent *ep; 83 84 while ((ep = readdir(dp)) != NULL) { 85 char path[MAXPATHLEN], lpath[MAXPATHLEN]; 86 87 snprintf(path, sizeof (path), "/dev/printers/%s", 88 ep->d_name); 89 memset(lpath, 0, sizeof (lpath)); 90 if ((readlink(path, lpath, sizeof (lpath)) > 0) && 91 (strstr(lpath, devfs_path) != NULL)) { 92 result = strdup(path); 93 break; 94 } 95 } 96 closedir(dp); 97 } 98 99 return (result); 100 } 101 102 int 103 main(int argc, char *argv[]) 104 { 105 int ret = 1; 106 char *udi; 107 char *device_file; 108 char *manufacturer = NULL, 109 *model = NULL, 110 *serial_number = NULL, 111 *description = NULL, 112 **command_set = NULL; 113 DBusError error; 114 LibHalContext *ctx = NULL; 115 LibHalChangeSet *cs = NULL; 116 117 if ((udi = getenv("UDI")) == NULL) 118 goto out; 119 if ((device_file = getenv("HAL_PROP_PRINTER_DEVICE")) == NULL) 120 device_file = prnio_device_name(); 121 122 if (device_file == NULL) 123 goto out; 124 125 setup_logger(); 126 127 dbus_error_init(&error); 128 if ((ctx = libhal_ctx_init_direct(&error)) == NULL) 129 goto out; 130 131 if ((cs = libhal_device_new_changeset(udi)) == NULL) { 132 HAL_DEBUG(("Cannot allocate changeset")); 133 goto out; 134 } 135 136 /* Probe the printer for characteristics via prnio(4I) */ 137 ret = prnio_printer_info(device_file, &manufacturer, &model, 138 &description, &serial_number, &command_set); 139 if (ret < 0) { 140 HAL_DEBUG(("Cannot get prnio data for %s: %s", 141 device_file, strerror(errno))); 142 goto out; 143 } 144 145 /* Add printer characteristics to the HAL device tree */ 146 ret = add_printer_info(cs, udi, manufacturer, model, description, 147 serial_number, command_set, device_file); 148 if (ret < 0) { 149 HAL_DEBUG(("Cannot add printer data for %s to %s: %s", 150 device_file, udi, strerror(errno))); 151 goto out; 152 } 153 154 libhal_device_commit_changeset(ctx, cs, &error); 155 156 ret = 0; 157 158 out: 159 if (cs != NULL) { 160 libhal_device_free_changeset(cs); 161 } 162 163 if (ctx != NULL) { 164 if (dbus_error_is_set(&error)) { 165 dbus_error_free(&error); 166 } 167 libhal_ctx_shutdown(ctx, &error); 168 libhal_ctx_free(ctx); 169 } 170 171 return (ret); 172 } 173