42a7bded1b1244af097afdc88654381a3d3879f9jacobs/***************************************************************************
42a7bded1b1244af097afdc88654381a3d3879f9jacobs *
42a7bded1b1244af097afdc88654381a3d3879f9jacobs * probe-printer.c : Probe for prnio(7i) printer device information
42a7bded1b1244af097afdc88654381a3d3879f9jacobs *
42a7bded1b1244af097afdc88654381a3d3879f9jacobs * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
42a7bded1b1244af097afdc88654381a3d3879f9jacobs * Use is subject to license terms.
42a7bded1b1244af097afdc88654381a3d3879f9jacobs *
42a7bded1b1244af097afdc88654381a3d3879f9jacobs * Licensed under the Academic Free License version 2.1
42a7bded1b1244af097afdc88654381a3d3879f9jacobs *
42a7bded1b1244af097afdc88654381a3d3879f9jacobs **************************************************************************/
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
42a7bded1b1244af097afdc88654381a3d3879f9jacobs#pragma ident "%Z%%M% %I% %E% SMI"
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
42a7bded1b1244af097afdc88654381a3d3879f9jacobs#ifdef HAVE_CONFIG_H
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <config.h>
42a7bded1b1244af097afdc88654381a3d3879f9jacobs#endif
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
42a7bded1b1244af097afdc88654381a3d3879f9jacobs#include <errno.h>
42a7bded1b1244af097afdc88654381a3d3879f9jacobs#include <string.h>
42a7bded1b1244af097afdc88654381a3d3879f9jacobs#include <strings.h>
42a7bded1b1244af097afdc88654381a3d3879f9jacobs#include <ctype.h>
42a7bded1b1244af097afdc88654381a3d3879f9jacobs#include <stdlib.h>
42a7bded1b1244af097afdc88654381a3d3879f9jacobs#include <stdio.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <sys/param.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <sys/types.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <dirent.h>
42a7bded1b1244af097afdc88654381a3d3879f9jacobs#include <sys/ioctl.h>
42a7bded1b1244af097afdc88654381a3d3879f9jacobs#include <sys/prnio.h>
42a7bded1b1244af097afdc88654381a3d3879f9jacobs#include <fcntl.h>
42a7bded1b1244af097afdc88654381a3d3879f9jacobs#include <unistd.h>
42a7bded1b1244af097afdc88654381a3d3879f9jacobs#include <ctype.h>
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
42a7bded1b1244af097afdc88654381a3d3879f9jacobs#include <libhal.h>
42a7bded1b1244af097afdc88654381a3d3879f9jacobs#include <logger.h>
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include "printer.h"
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
42a7bded1b1244af097afdc88654381a3d3879f9jacobsstatic int
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsprnio_printer_info(char *device_file, char **manufacturer, char **model,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char **description, char **serial_number, char ***command_set)
42a7bded1b1244af097afdc88654381a3d3879f9jacobs{
42a7bded1b1244af097afdc88654381a3d3879f9jacobs struct prn_1284_device_id id;
42a7bded1b1244af097afdc88654381a3d3879f9jacobs char buf[BUFSIZ];
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs int fd = -1, rc = -1;
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
42a7bded1b1244af097afdc88654381a3d3879f9jacobs memset(&id, 0, sizeof (id));
42a7bded1b1244af097afdc88654381a3d3879f9jacobs memset(&buf, 0, sizeof (buf));
42a7bded1b1244af097afdc88654381a3d3879f9jacobs id.id_data = buf;
42a7bded1b1244af097afdc88654381a3d3879f9jacobs id.id_len = sizeof (buf);
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if ((fd = open (device_file, O_RDONLY | O_NONBLOCK)) < 0) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs goto prnio_out;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
42a7bded1b1244af097afdc88654381a3d3879f9jacobs if (ioctl(fd, PRNIOC_GET_1284_DEVID, &id) < 0) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs goto prnio_out;
42a7bded1b1244af097afdc88654381a3d3879f9jacobs }
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_DEBUG(("IEEE-1284 DeviceId = %s", buf));
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs rc = ieee1284_devid_to_printer_info(buf, manufacturer, model,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs description, NULL, serial_number, command_set);
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsprnio_out:
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (fd != -1)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs close(fd);
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (rc);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs/*
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs * It is assumed that all devices that support prnio(7i), also have a link
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs * in /dev/printers.
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsstatic char *
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsprnio_device_name(void)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *result = NULL;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *devfs_path;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DIR *dp;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (((devfs_path = getenv("HAL_PROP_SOLARIS_DEVFS_PATH")) != NULL) &&
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs ((dp = opendir("/dev/printers")) != NULL)) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs struct dirent *ep;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs while ((ep = readdir(dp)) != NULL) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char path[MAXPATHLEN], lpath[MAXPATHLEN];
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs snprintf(path, sizeof (path), "/dev/printers/%s",
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs ep->d_name);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs memset(lpath, 0, sizeof (lpath));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if ((readlink(path, lpath, sizeof (lpath)) > 0) &&
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs (strstr(lpath, devfs_path) != NULL)) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs result = strdup(path);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs break;
42a7bded1b1244af097afdc88654381a3d3879f9jacobs }
42a7bded1b1244af097afdc88654381a3d3879f9jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs closedir(dp);
42a7bded1b1244af097afdc88654381a3d3879f9jacobs }
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (result);
42a7bded1b1244af097afdc88654381a3d3879f9jacobs}
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsint
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsmain(int argc, char *argv[])
42a7bded1b1244af097afdc88654381a3d3879f9jacobs{
42a7bded1b1244af097afdc88654381a3d3879f9jacobs int ret = 1;
42a7bded1b1244af097afdc88654381a3d3879f9jacobs char *udi;
42a7bded1b1244af097afdc88654381a3d3879f9jacobs char *device_file;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *manufacturer = NULL,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs *model = NULL,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs *serial_number = NULL,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs *description = NULL,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs **command_set = NULL;
42a7bded1b1244af097afdc88654381a3d3879f9jacobs DBusError error;
42a7bded1b1244af097afdc88654381a3d3879f9jacobs LibHalContext *ctx = NULL;
42a7bded1b1244af097afdc88654381a3d3879f9jacobs LibHalChangeSet *cs = NULL;
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if ((udi = getenv("UDI")) == NULL)
42a7bded1b1244af097afdc88654381a3d3879f9jacobs goto out;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if ((device_file = getenv("HAL_PROP_PRINTER_DEVICE")) == NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs device_file = prnio_device_name();
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (device_file == NULL)
42a7bded1b1244af097afdc88654381a3d3879f9jacobs goto out;
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs setup_logger();
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs dbus_error_init(&error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if ((ctx = libhal_ctx_init_direct(&error)) == NULL)
42a7bded1b1244af097afdc88654381a3d3879f9jacobs goto out;
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if ((cs = libhal_device_new_changeset(udi)) == NULL) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_DEBUG(("Cannot allocate changeset"));
42a7bded1b1244af097afdc88654381a3d3879f9jacobs goto out;
42a7bded1b1244af097afdc88654381a3d3879f9jacobs }
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs /* Probe the printer for characteristics via prnio(7i) */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs ret = prnio_printer_info(device_file, &manufacturer, &model,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs &description, &serial_number, &command_set);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (ret < 0) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_DEBUG(("Cannot get prnio data for %s: %s",
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs device_file, strerror(errno)));
42a7bded1b1244af097afdc88654381a3d3879f9jacobs goto out;
42a7bded1b1244af097afdc88654381a3d3879f9jacobs }
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs /* Add printer characteristics to the HAL device tree */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs ret = add_printer_info(cs, udi, manufacturer, model, description,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs serial_number, command_set, device_file);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (ret < 0) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_DEBUG(("Cannot add printer data for %s to %s: %s",
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs device_file, udi, strerror(errno)));
42a7bded1b1244af097afdc88654381a3d3879f9jacobs goto out;
42a7bded1b1244af097afdc88654381a3d3879f9jacobs }
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs libhal_device_commit_changeset(ctx, cs, &error);
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
42a7bded1b1244af097afdc88654381a3d3879f9jacobs ret = 0;
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
42a7bded1b1244af097afdc88654381a3d3879f9jacobsout:
42a7bded1b1244af097afdc88654381a3d3879f9jacobs if (cs != NULL) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs libhal_device_free_changeset(cs);
42a7bded1b1244af097afdc88654381a3d3879f9jacobs }
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
42a7bded1b1244af097afdc88654381a3d3879f9jacobs if (ctx != NULL) {
42a7bded1b1244af097afdc88654381a3d3879f9jacobs if (dbus_error_is_set(&error)) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs dbus_error_free(&error);
42a7bded1b1244af097afdc88654381a3d3879f9jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs libhal_ctx_shutdown(ctx, &error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs libhal_ctx_free(ctx);
42a7bded1b1244af097afdc88654381a3d3879f9jacobs }
42a7bded1b1244af097afdc88654381a3d3879f9jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (ret);
42a7bded1b1244af097afdc88654381a3d3879f9jacobs}