1 /*****************************************************************************\
3 hp-mkuri.c - make uri with multi-point transport driver (HPMUD)
5 (c) 2008-2009 Copyright Hewlett-Packard Development Company, LP
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11 of the Software, and to permit persons to whom the Software is furnished to do
12 so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be included in all
15 copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 \*****************************************************************************/
32 #include <sys/types.h>
39 #define _STRINGIZE(x) #x
40 #define STRINGIZE(x) _STRINGIZE(x)
41 //#define BUG(args...) fprintf(stderr, __FILE__ " " STRINGIZE(__LINE__) ": " args)
42 #define BUG(args...) syslog(LOG_ERR, __FILE__ " " STRINGIZE(__LINE__) ": " args)
45 static char homedir[255] = "";
49 fprintf(stdout, "HPLIP Make URI %s\n", VERSION);
50 fprintf(stdout, "(c) 2008 Copyright Hewlett-Packard Development Company, LP\n");
51 fprintf(stdout, "usage: hp-mkuri -i ip [-p port]\n");
52 fprintf(stdout, "usage: hp-mkuri -z hostname\n");
53 fprintf(stdout, "usage: hp-mkuri -b busnum -d devnum\n");
54 fprintf(stdout, "usage: hp-mkuri -s serialnum\n");
55 fprintf(stdout, "usage: hp-mkuri -l /dev/parportx\n");
56 fprintf(stdout, "usage: hp-mkuri -m hostname [-p port]\n");
57 fprintf(stdout, "usage: hp-mkuri -o (probe)\n");
58 fprintf(stdout, "usage: hp-mkuri -c [-n (no notifier)] (check support)\n");
59 fprintf(stdout, "\nSupport matrix:\n");
60 fprintf(stdout, "+--------------+---------+-----+-----------------+-----------------+\n");
61 fprintf(stdout, "| return value | printer | fax | plugin_required | plugin_optional |\n");
62 fprintf(stdout, "+--------------+---------+-----+-----------------+-----------------+\n");
63 fprintf(stdout, "| 0 | yes | | | |\n");
64 fprintf(stdout, "+--------------+---------+-----+-----------------+-----------------+\n");
65 fprintf(stdout, "| 1 | * | * | * | * |\n");
66 fprintf(stdout, "+--------------+---------+-----+-----------------+-----------------+\n");
67 fprintf(stdout, "| 2 | yes | | yes | |\n");
68 fprintf(stdout, "+--------------+---------+-----+-----------------+-----------------+\n");
69 fprintf(stdout, "| 3 | yes | | | yes |\n");
70 fprintf(stdout, "+--------------+---------+-----+-----------------+-----------------+\n");
71 fprintf(stdout, "| 4 | yes | yes | | |\n");
72 fprintf(stdout, "+--------------+---------+-----+-----------------+-----------------+\n");
73 fprintf(stdout, "| 5 | yes | yes | yes | |\n");
74 fprintf(stdout, "+--------------+---------+-----+-----------------+-----------------+\n");
75 fprintf(stdout, "| 6 | yes | yes | | yes |\n");
76 fprintf(stdout, "+--------------+---------+-----+-----------------+-----------------+\n");
77 fprintf(stdout, " * no support or error\n");
80 static int GetPair(char *buf, int buf_len, char *key, char *value, char **tail)
89 for (; buf[i] != '\n' && i < buf_len; i++); /* eat comment line */
91 i++; /* bump past '\n' */
95 while ((buf[i] != '=') && (i < buf_len) && (j < HPMUD_LINE_SIZE))
97 for (j--; key[j] == ' ' && j > 0; j--); /* eat white space before = */
101 for (i++; buf[i] == ' ' && i < buf_len; i++); /* eat white space after = */
104 while ((buf[i] != '\n') && (i < buf_len) && (j < HPMUD_LINE_SIZE))
105 value[j++] = buf[i++];
106 for (j--; value[j] == ' ' && j > 0; j--); /* eat white space before \n */
110 i++; /* bump past '\n' */
113 *tail = buf + i; /* tail points to next line */
118 static int ReadConfig()
120 char key[HPMUD_LINE_SIZE];
121 char value[HPMUD_LINE_SIZE];
130 if((inFile = fopen(CONFDIR "/hplip.conf", "r")) == NULL)
132 BUG("unable to open %s: %m\n", CONFDIR "/hplip.conf");
138 /* Read the config file */
139 while ((fgets(rcbuf, sizeof(rcbuf), inFile) != NULL))
143 strncpy(section, rcbuf, sizeof(section)); /* found new section */
147 GetPair(rcbuf, strlen(rcbuf), key, value, &tail);
149 if ((strncasecmp(section, "[dirs]", 6) == 0) && (strcasecmp(key, "home") == 0))
151 strncpy(homedir, value, sizeof(homedir));
165 static int generalize_model(const char *sz, char *buf, int bufSize)
170 for (i=0; pMd[i] == ' ' && i < bufSize; i++); /* eat leading white space */
172 for (j=0; (pMd[i] != 0) && (pMd[i] != ';') && (j < bufSize); i++)
174 if (pMd[i]==' ' || pMd[i]=='/')
176 /* Remove double spaces. */
179 buf[j++] = '_'; /* convert space to "_" */
185 buf[j++] = tolower(pMd[i]);
190 for (j--; buf[j] == '_' && j > 0; j--); /* eat trailing white space */
194 return j; /* length does not include zero termination */
197 static int set_x_environment(void)
201 struct dirent *entry;
202 char path[32], line[256], cookie[128], *p;
205 if ((dir = opendir("/proc"))==NULL)
207 BUG("unable to open /proc: %m\n");
211 while ((entry = readdir(dir)) != NULL)
213 if (!isdigit(*entry->d_name))
216 /* Get command line for this PID. */
217 snprintf(path, sizeof(path), "/proc/%s/cmdline", entry->d_name);
218 if ((file = fopen(path, "r")) == NULL)
220 for (i=0; ((c = getc(file)) != EOF) && (i < (sizeof(line)-1)); i++)
228 if ((p = strstr(line, "-auth ")))
230 /* Found X server. */
231 for (p+=6; (*p == ' ') && (*p != 0); p++); /* eat any white space before cookie */
232 for (i=0; (*(p+i) != ' ') && (*(p+i) != 0) && i < (sizeof(cookie)-1); i++)
235 setenv("XAUTHORITY", cookie, 1);
236 setenv("DISPLAY", ":0.0", 1);
239 } /* while ((entry = readdir(dir)) != NULL) */
247 } /* set_x_environment */
249 static int notify(const char *summary, const char *message, int ms_timeout)
251 void *handle=NULL, *n;
254 typedef void (*notify_init_t)(char *);
255 typedef void *(*notify_notification_new_t)(const char *, const char *, const char *, void *);
256 typedef void (*notify_notification_set_timeout_t)(void *, int);
257 typedef void (*notify_notification_show_t)(void *, char *);
259 notify_init_t n_init;
260 notify_notification_new_t n_new;
261 notify_notification_set_timeout_t n_timeout;
262 notify_notification_show_t n_show;
266 /* Bypass glib build dependencies by loading libnotify manually. */
268 if ((handle = dlopen("libnotify.so.1", RTLD_LAZY)) == NULL)
270 BUG("failed to open libnotify: %m\n");
274 if ((n_init = (notify_init_t)dlsym(handle, "notify_init")) == NULL)
276 BUG("failed to find notify_init: %m\n");
281 if ((n_new = (notify_notification_new_t)dlsym(handle, "notify_notification_new")) == NULL)
283 BUG("failed to find notify_notification_new: %m\n");
286 n = n_new(summary, message, NULL, NULL);
288 if ((n_timeout = (notify_notification_set_timeout_t)dlsym(handle, "notify_notification_set_timeout")) == NULL)
290 BUG("failed to find notify_notification_set_timeout: %m\n");
293 n_timeout(n, ms_timeout);
295 if ((n_show = (notify_notification_show_t)dlsym(handle, "notify_notification_show")) == NULL)
297 BUG("failed to find notify_notification_show: %m\n");
311 static int check_support(int send_notify)
315 int ret=1, plugin_installed=1;
320 int support, plugin, fax;
322 /* Get hp model from environment variables. */
323 if ((pm = getenv("hp_model")))
325 strncpy(model, pm, sizeof(model));
329 fprintf(stderr, "error no hp_model environment variable set\n");
330 BUG("error no hp_model environment variable set\n");
336 BUG("invalid parameter(s)\n");
341 generalize_model(model, m, sizeof(m));
342 snprintf(model, sizeof(model), "[%s]", m);
347 snprintf(datfile, sizeof(datfile), "%s/data/models/models.dat", homedir);
349 if (hpmud_get_key_value(datfile, model, "support-type", value, sizeof(value)) != HPMUD_R_OK)
351 support = strtol(value, NULL, 10);
352 if (hpmud_get_key_value(datfile, model, "plugin", value, sizeof(value)) != HPMUD_R_OK)
354 plugin = strtol(value, NULL, 10);
355 if (hpmud_get_key_value(datfile, model, "fax-type", value, sizeof(value)) != HPMUD_R_OK)
357 fax = strtol(value, NULL, 10);
359 /* See if device is supported by hplip. */
360 if (support == HPMUD_SUPPORT_TYPE_NONE)
362 BUG("%s is not supported by HPLIP %s\n", pm, VERSION);
366 if (stat("/etc/udev/rules.d/86-hpmud-hp_laserjet_1018.rules", &sb) == -1)
369 if (send_notify && !plugin_installed)
371 /* See if device requires a Plugin. */
374 case HPMUD_PLUGIN_TYPE_REQUIRED:
375 BUG("%s requires a proprietary plugin\n", pm);
376 notify(pm, "requires a proprietary plugin, run hp-setup", 30000);
378 case HPMUD_PLUGIN_TYPE_OPTIONAL:
379 BUG("%s has a optional proprietary plugin\n", pm);
380 notify(pm, "has a optional proprietary plugin, run hp-setup", 30000);
388 if (plugin == HPMUD_PLUGIN_TYPE_REQUIRED)
390 else if (plugin == HPMUD_PLUGIN_TYPE_OPTIONAL)
395 if (plugin == HPMUD_PLUGIN_TYPE_REQUIRED)
397 else if (plugin == HPMUD_PLUGIN_TYPE_OPTIONAL)
403 } /* check_support */
405 int main(int argc, char *argv[])
407 char ip[HPMUD_LINE_SIZE]; /* internet address */
408 char bn[HPMUD_LINE_SIZE]; /* usb bus number */
409 char dn[HPMUD_LINE_SIZE]; /* usb device number */
410 char sn[HPMUD_LINE_SIZE]; /* usb serial number */
411 char pp[HPMUD_LINE_SIZE]; /* parallel port device */
412 char uri[HPMUD_LINE_SIZE];
413 char host[HPMUD_LINE_SIZE];
414 int i, port=1, ret=1, probe=0, support=0, send_notify=1;
415 enum HPMUD_RESULT stat;
416 char buf[HPMUD_LINE_SIZE*64];
419 ip[0] = bn[0] = dn[0] = pp[0] = uri[0] = sn[0] = host[0] = 0;
420 while ((i = getopt(argc, argv, "vhocni:p:b:d:l:s:z:")) != -1)
425 strncpy(ip, optarg, sizeof(ip));
428 strncpy(host, optarg, sizeof(host));
431 port = strtol(optarg, NULL, 10);
434 strncpy(bn, optarg, sizeof(bn));
437 strncpy(dn, optarg, sizeof(dn));
440 strncpy(pp, optarg, sizeof(pp));
443 strncpy(sn, optarg, sizeof(sn));
462 fprintf(stderr, "unknown argument: %s\n", argv[1]);
469 if (ip[0]==0 && (!(bn[0] && dn[0])) && pp[0]==0 && probe==0 && sn[0]==0 && support==0 && host[0]==0)
471 fprintf(stderr, "invalid command parameter(s)\n");
478 hpmud_probe_devices(HPMUD_BUS_ALL, buf, sizeof(buf), &cnt, &bytes_read);
480 fprintf(stdout, "%s", buf);
483 #ifdef HAVE_LIBNETSNMP
486 stat = hpmud_make_net_uri(ip, port, uri, sizeof(uri), &bytes_read);
487 if (stat == HPMUD_R_OK)
489 fprintf(stdout, "%s\n", uri);
490 fprintf(stdout, "hpaio%s\n", &uri[2]);
495 stat = hpmud_make_mdns_uri(host, port, uri, sizeof(uri), &bytes_read);
496 if (stat == HPMUD_R_OK)
498 fprintf(stdout, "%s\n", uri);
499 fprintf(stdout, "hpaio%s\n", &uri[2]);
506 stat = hpmud_make_usb_uri(bn, dn, uri, sizeof(uri), &bytes_read);
507 if (stat == HPMUD_R_OK)
509 fprintf(stdout, "%s\n", uri);
510 fprintf(stdout, "hpaio%s\n", &uri[2]);
516 stat = hpmud_make_usb_serial_uri(sn, uri, sizeof(uri), &bytes_read);
517 if (stat == HPMUD_R_OK)
519 fprintf(stdout, "%s\n", uri);
520 fprintf(stdout, "hpaio%s\n", &uri[2]);
527 stat = hpmud_make_par_uri(pp, uri, sizeof(uri), &bytes_read);
528 if (stat == HPMUD_R_OK)
530 fprintf(stdout, "%s\n", uri);
531 fprintf(stdout, "hpaio%s\n", &uri[2]);
539 ret = check_support(send_notify);