2 * Command line oriented Moira print queue tool.
4 * Code based on the blanche command line tool and the moira curses tool.
5 * Copyright (C) 2009 by the Massachusetts Institute of Technology.
6 * For copying and distribution information, please see the file
9 * Mark Manley, mmanley@MIT.EDU, 12/09
12 #include <mit-copyright.h>
14 #include <moira_site.h>
28 const char *deflogserver = "WSLOGGER.MIT.EDU";
30 /* legacy variables that we need to set regardless */
31 const char *quotaserver = "[NONE]";
32 const char *pageprice = "10";
34 /* argument parsing macro */
35 #define argis(a, b) (!strcmp(*arg + 1, a) || !strcmp(*arg + 1, b))
37 /* flags from command line */
38 int info_flag, verbose, noauth;
39 int create_flag, setmac, delete_flag, rename_flag, ka, banner, update_flag;
40 char *lpracl, *lpcacl;
41 char *contact, *newname, *printserver, *type, *hwtype, *mac, *hostname, *queuename;
42 char *duplexname, *logserver, *location, *realname;
44 char *queuename, *whoami, *testqueue;
46 void usage(char **argv);
47 int show_printer_info(char *queuename);
48 int save_printer_info(int argc, char **argv, void *hint);
49 int save_hwaddr(int argc, char **argv, void *hint);
50 void recursive_display_list_members(void);
51 char *get_username(void);
52 int wrap_mr_query(char *handle, int argc, char **argv,
53 int (*callback)(int, char **, void *), void *callarg);
54 void print_query(char *query_name, int argc, char **argv);
55 int CountArgs(char **info);
57 int main(int argc, char **argv)
64 struct member *memberstruct;
65 char *server = NULL, *p;
68 /* clear all flags & lists */
69 i = info_flag = verbose = noauth = 0;
70 setmac = ka = create_flag = delete_flag = update_flag = 0;
71 location = lpracl = lpcacl = NULL;
72 logserver = duplexname = realname = newname = printserver = type = hwtype = mac = hostname = NULL;
81 while (++arg - argv < argc)
85 if (argis("i", "info"))
87 else if (argis("C", "create"))
89 else if (argis("D", "delete"))
91 else if (argis("L", "location"))
93 if (arg - argv < argc - 1)
102 else if (argis("r", "remotename"))
104 if (arg - argv < argc - 1)
113 else if (argis("T", "type"))
115 if (arg - argv < argc - 1)
124 else if (argis("s", "printserver"))
126 if (arg - argv < argc - 1)
130 printserver = canonicalize_hostname(strdup(*arg));
135 else if (argis("M", "model"))
137 if (arg - argv < argc - 1)
146 else if (argis("K", "kerbauth"))
151 else if (argis("NK", "nokerbauth"))
156 else if (argis("H", "hostname"))
158 if (arg - argv < argc - 1)
162 hostname = canonicalize_hostname(strdup(*arg));
167 else if (argis("n", "noauth"))
169 else if (argis("v", "verbose"))
171 else if (argis("S", "server") || argis("db", "database"))
173 if (arg - argv < argc - 1)
181 else if (argis("c", "contact"))
183 if (arg - argv < argc - 1)
192 else if (argis("l", "lpcacl"))
194 if (arg - argv < argc - 1)
203 else if (argis("ac", "lpracl"))
205 if (arg - argv < argc - 1)
214 else if (argis("m", "mac"))
216 if (arg - argv < argc - 1)
225 else if (argis("b", "banner"))
230 else if (argis("nb", "nobanner"))
235 else if (argis("L", "logserver"))
237 if (arg - argv < argc - 1)
241 logserver = canonicalize_hostname(strdup(*arg));
246 else if (argis("R", "rename"))
248 if (arg - argv < argc - 1)
258 else if (argis("d", "duplex"))
260 if (arg - argv < argc - 1)
272 else if (queuename == NULL)
277 if (queuename == NULL)
281 if (!update_flag && !rename_flag && !delete_flag && !create_flag && !setmac)
285 status = mrcl_connect(server, "eunice", 10, !noauth);
286 if (status == MRCL_AUTH_ERROR)
288 com_err(whoami, 0, "Authentication error while working on queue %s",
290 com_err(whoami, 0, "Try the -noauth flag if you don't "
291 "need authentication.");
298 if (hostname == NULL || type == NULL || hwtype == NULL )
302 for (i = 0; i < PRN_END; i++)
305 /* check for name conflicts. */
306 if (create_flag || rename_flag)
312 testqueue = queuename;
314 status = wrap_mr_query("get_printer", 1, &testqueue, NULL, NULL);
315 if (status != MR_NO_MATCH)
317 fprintf(stderr, "ERROR: A queue by that name already exists.\n");
321 status = wrap_mr_query("get_printer_by_duplexname", 1, &testqueue, NULL, NULL);
322 if (status != MR_NO_MATCH)
324 fprintf(stderr, "ERROR: A duplex queue by that name already exists.\n");
329 status = wrap_mr_query("get_printer_by_duplexname", 1, &testqueue, NULL, NULL);
330 if (status != MR_NO_MATCH)
332 fprintf(stderr, "ERROR: A duplex queue by that name already exists.\n");
339 /* create if needed */
342 if (realname == NULL)
343 realname = queuename; /* Variable for aliases */
345 if (logserver == NULL)
346 logserver = (char *) canonicalize_hostname(strdup(deflogserver));
348 pargv[PRN_NAME] = queuename;
349 pargv[PRN_TYPE] = type;
350 pargv[PRN_HWTYPE] = hwtype;
352 pargv[PRN_DUPLEXNAME] = (duplexname != NULL) ? duplexname : "";
354 pargv[PRN_HOSTNAME] = hostname;
355 pargv[PRN_LOGHOST] = logserver;
357 pargv[PRN_RM] = (printserver != NULL) ? printserver : "[ANY]";
359 pargv[PRN_CONTACT] = (contact != NULL) ? contact : "";
361 pargv[PRN_LOCATION] = (location != NULL) ? location : "";
363 pargv[PRN_RP] = realname;
364 pargv[PRN_RQ] = (char *) quotaserver;
365 pargv[PRN_KA] = (ka == 1) ? "1" : "0";
366 pargv[PRN_PC] = (char *) pageprice;
370 status = wrap_mr_query("get_list_info", 1, &lpracl,
374 com_err(whoami, status, "while getting authentication list information");
377 pargv[PRN_AC] = lpracl;
380 pargv[PRN_AC] = "[none]";
384 status = wrap_mr_query("get_list_info", 1, &lpcacl,
388 com_err(whoami, status, "while getting authentication list information");
391 pargv[PRN_LPC_ACL] = lpcacl;
394 pargv[PRN_LPC_ACL] = "[none]";
396 pargv[PRN_BANNER] = (banner == 1) ? "1" : "0";
398 status = wrap_mr_query("add_printer", CountArgs(pargv), pargv, NULL, NULL);
402 com_err(whoami, status, "while creating print queue.");
406 printf ("%s: queue %s created.\n", whoami, queuename);
408 else if (update_flag)
411 status = wrap_mr_query("get_printer", 1, &queuename, save_printer_info, pargv);
414 com_err(whoami, status, "while getting printer information");
418 pargv[0] = queuename;
419 if (newname && rename_flag)
420 pargv[PRN_NAME + 1] = newname;
422 pargv[PRN_TYPE + 1] = type;
424 pargv[PRN_HWTYPE + 1] = hwtype;
426 if (duplexname != NULL)
427 pargv[PRN_DUPLEXNAME + 1] = duplexname;
429 if (hostname != NULL)
430 pargv[PRN_HOSTNAME + 1] = hostname;
432 if (logserver != NULL)
433 pargv[PRN_LOGHOST + 1] = logserver;
435 if (printserver != NULL)
436 pargv[PRN_RM + 1] = printserver;
438 if (realname != NULL)
439 pargv[PRN_RP + 1] = realname;
441 if (quotaserver != NULL && strcmp(quotaserver,"[NONE]"))
442 pargv[PRN_RQ + 1] = (char *) quotaserver;
445 pargv[PRN_KA + 1] = ka ? "1" : "0";
447 pargv[PRN_AC + 1] = lpracl;
449 pargv[PRN_LPC_ACL + 1] = lpcacl;
451 pargv[PRN_BANNER + 1] = banner ? "1" : "0";
452 if (location != NULL)
453 pargv[PRN_LOCATION + 1] = location;
455 pargv[PRN_CONTACT + 1] = contact;
457 pargv[PRN_MODBY + 1] = pargv[PRN_MODTIME + 1] = pargv[PRN_MODWITH + 1] = NULL;
459 status = wrap_mr_query("update_printer", CountArgs(pargv), pargv, NULL, NULL);
462 com_err(whoami, status, "while updating print queue.");
468 printf ("%s: queue %s renamed to %s.\n", whoami, queuename, newname);
470 printf ("%s: queue %s updated.\n", whoami, queuename);
474 /* display printer info if requested to */
476 show_printer_info(queuename);
480 status = wrap_mr_query("get_printer", 1, &queuename, save_printer_info, pargv);
483 com_err(whoami, status, "while getting printer information");
487 if (hostname == NULL)
488 uargv[0] = (char *) strdup (pargv[PRN_HOSTNAME + 1]);
490 uargv[0] = (char *) strdup (hostname);
491 uargv[1] = (char *) strdup (mac);
492 if ((status = wrap_mr_query("update_host_hwaddr", 2, uargv, NULL, NULL)))
493 com_err(whoami, status, "updating ethernet address.");
499 status = wrap_mr_query("delete_printer", 1, &queuename,
503 com_err(whoami, status, "while deleting printer");
507 printf ("%s: queue %s deleted.\n", whoami, queuename);
512 exit(success ? 0 : 1);
515 void usage(char **argv)
517 #define USAGE_OPTIONS_FORMAT " %-39s%s\n"
518 fprintf(stderr, "Usage: %s queue [options]\n", argv[0]);
519 fprintf(stderr, "Options are\n");
520 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-v | -verbose",
522 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-D | -delete",
523 "-R | -rename newname");
524 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-i | -info",
525 "-L | -location location");
526 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-H | -hostname host",
527 "-c | -contact contact");
528 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-r | -remotename name",
529 "-T | -type printer_type");
530 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-M | -model model",
531 "-s | -printserver print_server");
532 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-K | -kerbauth",
534 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-NK | -nokerbauth",
536 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-l | -lpcacl list",
537 "-ac | -lpracl contact");
538 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-d | -duplex name",
540 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-m | -mac hwaddr",
541 "-db | -database host[:port]");
545 int show_printer_info(char *queuename)
548 char *pargv[PRN_END];
549 int status, banner, i;
551 for (i = 0; i < PRN_END; i++)
554 memset (hwaddr,'\0',sizeof(hwaddr));
556 status = wrap_mr_query("get_printer", 1, &queuename, save_printer_info, pargv);
559 com_err(whoami, status, "while getting printer information");
563 status = wrap_mr_query("get_host_hwaddr", 1, &pargv[PRN_HOSTNAME + 1],
564 save_hwaddr, &hwaddr);
567 sprintf (hwaddr,"none");
569 banner = atoi(pargv[PRN_BANNER + 1]);
571 printf("Printer: %-18s Duplex queue: %-18s\n", pargv[PRN_NAME + 1],
572 *pargv[PRN_DUPLEXNAME + 1] ? pargv[PRN_DUPLEXNAME + 1] : "[none]");
573 printf("Type: %-10s Hardware type: %-10s Hardware address: %s\n",
574 pargv[PRN_TYPE + 1], pargv[PRN_HWTYPE + 1], hwaddr);
575 printf("Printer hostname: %s\n", pargv[PRN_HOSTNAME + 1]);
576 printf("Printer log host: %s\n", pargv[PRN_LOGHOST + 1]);
577 printf("Spool host: %s\n", pargv[PRN_RM + 1]);
578 printf("Remote Printer Name: %-10s Banner page: %s\n", pargv[PRN_RP + 1],
579 banner ? ( banner == PRN_BANNER_FIRST ? "Yes" : "Last" ) : "No");
580 printf("Authentication: %-3s Price/page: %-3s Quota Server: %s\n",
581 atoi(pargv[PRN_KA + 1]) ? "yes" : "no", pargv[PRN_PC + 1], pargv[PRN_RQ + 1]);
582 printf("Restrict list: %-23s LPC ACL: %-23s\n",
583 pargv[PRN_AC + 1], pargv[PRN_LPC_ACL + 1]);
584 printf("Location: %s\n", pargv[PRN_LOCATION + 1]);
585 printf("Contact: %s\n", pargv[PRN_CONTACT + 1]);
587 printf("Last mod by %s at %s with %s.\n", pargv[PRN_MODBY + 1], pargv[PRN_MODTIME + 1], pargv[PRN_MODWITH + 1]);
593 /* Copy retrieved information about a printer into a new argv */
595 int save_printer_info(int argc, char **argv, void *hint)
599 for (argc = 0; argc < PRN_END; argc++)
600 nargv[argc + 1] = strdup(argv[argc]);
604 int save_hwaddr(int argc, char **argv, void *hint)
611 int wrap_mr_query(char *handle, int argc, char **argv,
612 int (*callback)(int, char **, void *), void *callarg)
617 print_query(handle, argc, argv);
619 status = mr_query(handle, argc, argv, callback, callarg);
624 void print_query(char *query_name, int argc, char **argv)
628 printf("qy %s", query_name);
629 for(cnt=0; cnt<argc; cnt++)
630 printf(" <%s>", argv[cnt]);
634 char *get_username(void)
638 username = getenv("USER");
641 username = mrcl_krb_user();
644 com_err(whoami, 0, "Could not determine username");
651 /* Function Name: CountArgs
652 * Description: Retrieve the number of args in a null terminated
654 * Arguments: info - the argument list.
655 * Returns: number if args in the list.
658 int CountArgs(char **info)