142a7bdedSjacobs /***************************************************************************
242a7bdedSjacobs *
342a7bdedSjacobs * probe-printer.c : Probe for prnio(7i) printer device information
442a7bdedSjacobs *
542a7bdedSjacobs * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
642a7bdedSjacobs * Use is subject to license terms.
742a7bdedSjacobs *
842a7bdedSjacobs * Licensed under the Academic Free License version 2.1
942a7bdedSjacobs *
1042a7bdedSjacobs **************************************************************************/
1142a7bdedSjacobs
1242a7bdedSjacobs #pragma ident "%Z%%M% %I% %E% SMI"
1342a7bdedSjacobs
1442a7bdedSjacobs #ifdef HAVE_CONFIG_H
1542a7bdedSjacobs #include <config.h>
1642a7bdedSjacobs #endif
1742a7bdedSjacobs
1842a7bdedSjacobs #include <errno.h>
1942a7bdedSjacobs #include <string.h>
2042a7bdedSjacobs #include <strings.h>
2142a7bdedSjacobs #include <ctype.h>
2242a7bdedSjacobs #include <stdlib.h>
2342a7bdedSjacobs #include <stdio.h>
24*4e9cfc9aSjacobs #include <sys/param.h>
25*4e9cfc9aSjacobs #include <sys/types.h>
26*4e9cfc9aSjacobs #include <dirent.h>
2742a7bdedSjacobs #include <sys/ioctl.h>
2842a7bdedSjacobs #include <sys/prnio.h>
2942a7bdedSjacobs #include <fcntl.h>
3042a7bdedSjacobs #include <unistd.h>
3142a7bdedSjacobs #include <ctype.h>
3242a7bdedSjacobs
3342a7bdedSjacobs #include <libhal.h>
3442a7bdedSjacobs #include <logger.h>
3542a7bdedSjacobs
36*4e9cfc9aSjacobs #include "printer.h"
3742a7bdedSjacobs
3842a7bdedSjacobs static int
prnio_printer_info(char * device_file,char ** manufacturer,char ** model,char ** description,char ** serial_number,char *** command_set)39*4e9cfc9aSjacobs prnio_printer_info(char *device_file, char **manufacturer, char **model,
40*4e9cfc9aSjacobs char **description, char **serial_number, char ***command_set)
4142a7bdedSjacobs {
4242a7bdedSjacobs struct prn_1284_device_id id;
4342a7bdedSjacobs char buf[BUFSIZ];
44*4e9cfc9aSjacobs int fd = -1, rc = -1;
4542a7bdedSjacobs
4642a7bdedSjacobs memset(&id, 0, sizeof (id));
4742a7bdedSjacobs memset(&buf, 0, sizeof (buf));
4842a7bdedSjacobs id.id_data = buf;
4942a7bdedSjacobs id.id_len = sizeof (buf);
5042a7bdedSjacobs
51*4e9cfc9aSjacobs if ((fd = open (device_file, O_RDONLY | O_NONBLOCK)) < 0) {
52*4e9cfc9aSjacobs goto prnio_out;
53*4e9cfc9aSjacobs }
54*4e9cfc9aSjacobs
5542a7bdedSjacobs if (ioctl(fd, PRNIOC_GET_1284_DEVID, &id) < 0) {
56*4e9cfc9aSjacobs goto prnio_out;
5742a7bdedSjacobs }
5842a7bdedSjacobs
5942a7bdedSjacobs HAL_DEBUG(("IEEE-1284 DeviceId = %s", buf));
6042a7bdedSjacobs
61*4e9cfc9aSjacobs rc = ieee1284_devid_to_printer_info(buf, manufacturer, model,
62*4e9cfc9aSjacobs description, NULL, serial_number, command_set);
6342a7bdedSjacobs
64*4e9cfc9aSjacobs prnio_out:
65*4e9cfc9aSjacobs if (fd != -1)
66*4e9cfc9aSjacobs close(fd);
67*4e9cfc9aSjacobs
68*4e9cfc9aSjacobs return (rc);
6942a7bdedSjacobs }
7042a7bdedSjacobs
71*4e9cfc9aSjacobs /*
72*4e9cfc9aSjacobs * It is assumed that all devices that support prnio(7i), also have a link
73*4e9cfc9aSjacobs * in /dev/printers.
74*4e9cfc9aSjacobs */
75*4e9cfc9aSjacobs static char *
prnio_device_name(void)76*4e9cfc9aSjacobs prnio_device_name(void)
77*4e9cfc9aSjacobs {
78*4e9cfc9aSjacobs char *result = NULL;
79*4e9cfc9aSjacobs char *devfs_path;
80*4e9cfc9aSjacobs DIR *dp;
8142a7bdedSjacobs
82*4e9cfc9aSjacobs if (((devfs_path = getenv("HAL_PROP_SOLARIS_DEVFS_PATH")) != NULL) &&
83*4e9cfc9aSjacobs ((dp = opendir("/dev/printers")) != NULL)) {
84*4e9cfc9aSjacobs struct dirent *ep;
8542a7bdedSjacobs
86*4e9cfc9aSjacobs while ((ep = readdir(dp)) != NULL) {
87*4e9cfc9aSjacobs char path[MAXPATHLEN], lpath[MAXPATHLEN];
8842a7bdedSjacobs
89*4e9cfc9aSjacobs snprintf(path, sizeof (path), "/dev/printers/%s",
90*4e9cfc9aSjacobs ep->d_name);
91*4e9cfc9aSjacobs memset(lpath, 0, sizeof (lpath));
92*4e9cfc9aSjacobs if ((readlink(path, lpath, sizeof (lpath)) > 0) &&
93*4e9cfc9aSjacobs (strstr(lpath, devfs_path) != NULL)) {
94*4e9cfc9aSjacobs result = strdup(path);
95*4e9cfc9aSjacobs break;
9642a7bdedSjacobs }
9742a7bdedSjacobs }
98*4e9cfc9aSjacobs closedir(dp);
99*4e9cfc9aSjacobs }
10042a7bdedSjacobs
101*4e9cfc9aSjacobs return (result);
10242a7bdedSjacobs }
10342a7bdedSjacobs
10442a7bdedSjacobs int
main(int argc,char * argv[])10542a7bdedSjacobs main(int argc, char *argv[])
10642a7bdedSjacobs {
10742a7bdedSjacobs int ret = 1;
10842a7bdedSjacobs char *udi;
10942a7bdedSjacobs char *device_file;
110*4e9cfc9aSjacobs char *manufacturer = NULL,
111*4e9cfc9aSjacobs *model = NULL,
112*4e9cfc9aSjacobs *serial_number = NULL,
113*4e9cfc9aSjacobs *description = NULL,
114*4e9cfc9aSjacobs **command_set = NULL;
11542a7bdedSjacobs DBusError error;
11642a7bdedSjacobs LibHalContext *ctx = NULL;
11742a7bdedSjacobs LibHalChangeSet *cs = NULL;
11842a7bdedSjacobs
11942a7bdedSjacobs if ((udi = getenv("UDI")) == NULL)
12042a7bdedSjacobs goto out;
12142a7bdedSjacobs if ((device_file = getenv("HAL_PROP_PRINTER_DEVICE")) == NULL)
122*4e9cfc9aSjacobs device_file = prnio_device_name();
123*4e9cfc9aSjacobs
124*4e9cfc9aSjacobs if (device_file == NULL)
12542a7bdedSjacobs goto out;
12642a7bdedSjacobs
12742a7bdedSjacobs setup_logger();
12842a7bdedSjacobs
12942a7bdedSjacobs dbus_error_init(&error);
13042a7bdedSjacobs if ((ctx = libhal_ctx_init_direct(&error)) == NULL)
13142a7bdedSjacobs goto out;
13242a7bdedSjacobs
13342a7bdedSjacobs if ((cs = libhal_device_new_changeset(udi)) == NULL) {
13442a7bdedSjacobs HAL_DEBUG(("Cannot allocate changeset"));
13542a7bdedSjacobs goto out;
13642a7bdedSjacobs }
13742a7bdedSjacobs
138*4e9cfc9aSjacobs /* Probe the printer for characteristics via prnio(7i) */
139*4e9cfc9aSjacobs ret = prnio_printer_info(device_file, &manufacturer, &model,
140*4e9cfc9aSjacobs &description, &serial_number, &command_set);
141*4e9cfc9aSjacobs if (ret < 0) {
142*4e9cfc9aSjacobs HAL_DEBUG(("Cannot get prnio data for %s: %s",
143*4e9cfc9aSjacobs device_file, strerror(errno)));
14442a7bdedSjacobs goto out;
14542a7bdedSjacobs }
14642a7bdedSjacobs
147*4e9cfc9aSjacobs /* Add printer characteristics to the HAL device tree */
148*4e9cfc9aSjacobs ret = add_printer_info(cs, udi, manufacturer, model, description,
149*4e9cfc9aSjacobs serial_number, command_set, device_file);
150*4e9cfc9aSjacobs if (ret < 0) {
151*4e9cfc9aSjacobs HAL_DEBUG(("Cannot add printer data for %s to %s: %s",
152*4e9cfc9aSjacobs device_file, udi, strerror(errno)));
15342a7bdedSjacobs goto out;
15442a7bdedSjacobs }
15542a7bdedSjacobs
15642a7bdedSjacobs libhal_device_commit_changeset(ctx, cs, &error);
15742a7bdedSjacobs
15842a7bdedSjacobs ret = 0;
15942a7bdedSjacobs
16042a7bdedSjacobs out:
16142a7bdedSjacobs if (cs != NULL) {
16242a7bdedSjacobs libhal_device_free_changeset(cs);
16342a7bdedSjacobs }
16442a7bdedSjacobs
16542a7bdedSjacobs if (ctx != NULL) {
16642a7bdedSjacobs if (dbus_error_is_set(&error)) {
16742a7bdedSjacobs dbus_error_free(&error);
16842a7bdedSjacobs }
16942a7bdedSjacobs libhal_ctx_shutdown(ctx, &error);
17042a7bdedSjacobs libhal_ctx_free(ctx);
17142a7bdedSjacobs }
17242a7bdedSjacobs
173*4e9cfc9aSjacobs return (ret);
17442a7bdedSjacobs }
175