1/*
2 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
3 * Use is subject to license terms.
4 *
5 * Licensed under the Academic Free License version 2.1
6 */
7
8#ifdef HAVE_CONFIG_H
9#include <config.h>
10#endif
11
12#include <errno.h>
13#include <strings.h>
14#include <ctype.h>
15#include <stdlib.h>
16#include <stdio.h>
17#include <unistd.h>
18#include <ctype.h>
19
20#include <libhal.h>
21#include <logger.h>
22
23#include "printer.h"
24
25static char *
26strip_ws(char *s)
27{
28	if (s != NULL) {
29		char *p;
30
31		/* skip the leading whitespace */
32		for (; ((*s != '\0') && (isspace(*s) != 0)); s++);
33
34		/* drop the trailing whitespace */
35		for (p = s + strlen(s) - 1; ((p > s) && (isspace(*p) != 0));
36		     p--);
37		*(++p) = '\0';
38	}
39
40	return (s);
41}
42
43int
44ieee1284_devid_to_printer_info(char *devid_string, char **manufacturer,
45		char **model, char **description, char **class,
46		char **serial_no, char ***command_set)
47{
48	char *iter = NULL;
49	char *s;
50
51	if (devid_string == NULL)
52		return (-1);
53
54	/* parse the 1284 device id string */
55	for (s = (char *)strtok_r(devid_string, ";\n", &iter); s != NULL;
56			s = (char *)strtok_r(NULL, ";\n", &iter)) {
57		char *t, *u, *iter2 = NULL;
58
59		if ((t = (char *)strtok_r(s, ":\n", &iter2)) == NULL)
60			continue;
61
62		if ((u = (char *)strtok_r(NULL, ":\n", &iter2)) == NULL)
63			continue;
64
65		if (((strcasecmp(t, "MFG") == 0) ||
66		     (strcasecmp(t, "MANUFACTURER") == 0)) &&
67		    (manufacturer != NULL))
68				*manufacturer = strdup(strip_ws(u));
69		else if (((strcasecmp(t, "MDL") == 0) ||
70			  (strcasecmp(t, "MODEL") == 0)) &&
71			 (model != NULL))
72				*model = strdup(strip_ws(u));
73		else if (((strcasecmp(t, "DES") == 0) ||
74			  (strcasecmp(t, "DESCRIPTION") == 0)) &&
75			 (description != NULL))
76				*description = strdup(strip_ws(u));
77		else if (((strcasecmp(t, "CLS") == 0) ||
78			  (strcasecmp(t, "CLASS") == 0)) &&
79			 (class != NULL))
80				*class = strdup(strip_ws(u));
81		else if (((strcasecmp(t, "SER") == 0) ||
82			  (strcasecmp(t, "SERNO") == 0)) &&
83			 (serial_no != NULL))
84				*serial_no = strdup(strip_ws(u));
85		else if (((strcasecmp(t, "CMD") == 0) ||
86			  (strcasecmp(t, "COMMAND SET") == 0)) &&
87			 (command_set != NULL)) {
88			/* this should be more dynamic, I got lazy */
89			char *v, *iter3 = NULL;
90			char *cmds[32];
91			int i = 0;
92
93			memset(&cmds, 0, sizeof (cmds));
94#define	NELEM(a)	(sizeof (a) / sizeof (*(a)))
95			for (v = strtok_r(u, ",\n", &iter3);
96			     ((v != NULL) && (i < NELEM(cmds)));
97			     v = strtok_r(NULL, ",\n", &iter3)) {
98				cmds[i++] = strdup(strip_ws(v));
99			}
100#undef NELEM
101			*command_set = calloc(++i, sizeof (char *));
102			for (i = 0; (cmds)[i] != NULL; i++)
103				(*command_set)[i] = cmds[i];
104		}
105	}
106
107	return (0);
108}
109
110
111int
112add_printer_info(LibHalChangeSet *cs, char *udi, char *manufacturer,
113		char *model, char *description, char *serial_number,
114		char **command_set, char *device)
115{
116#define	NP(x)   (x?x:"")
117	HAL_DEBUG(("udi: %s, snmp data: vendor=%s, product=%s, "
118		    "description=%s, serial=%s, device=%s\n",
119		    NP(udi), NP(manufacturer), NP(model), NP(description),
120		    NP(serial_number), NP(device)));
121#undef NP
122
123	if (model != NULL)
124		libhal_changeset_set_property_string(cs,
125					"info.product", model);
126	if (manufacturer != NULL)
127		libhal_changeset_set_property_string(cs,
128					"printer.vendor", manufacturer);
129	if (model != NULL)
130		libhal_changeset_set_property_string(cs,
131					"printer.product", model);
132	if (serial_number != NULL)
133		libhal_changeset_set_property_string(cs,
134					"printer.serial", serial_number);
135	if (description != NULL)
136		libhal_changeset_set_property_string(cs,
137					"printer.description", description);
138	if (command_set != NULL)
139		libhal_changeset_set_property_strlist(cs, "printer.commandset",
140					(const char **)command_set);
141	if (device != NULL)
142		libhal_changeset_set_property_string(cs,
143					"printer.device", device);
144
145	return (0);
146}
147