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