xref: /illumos-gate/usr/src/cmd/hal/probing/printer/probe-printer.c (revision 42a7bded1b1244af097afdc88654381a3d3879f9)
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