]> andersk Git - moira.git/blame - clients/eunice/eunice.c
Command line printer manipulation client, and build goo.
[moira.git] / clients / eunice / eunice.c
CommitLineData
f72fe084 1/*
2 * Command line oriented Moira print queue tool.
3 *
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
7 * <mit-copyright.h>.
8 *
9 * Mark Manley, mmanley@MIT.EDU, 12/09
10 */
11
12#include <mit-copyright.h>
13#include <moira.h>
14#include <moira_site.h>
15#include <mrclient.h>
16
17#include <ctype.h>
18#include <errno.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22
23struct member {
24 int type;
25 char *name, *tag;
26};
27
28const char *deflogserver = "WSLOGGER.MIT.EDU";
29
30/* legacy variables that we need to set regardless */
31const char *quotaserver = "[NONE]";
32const char *pageprice = "10";
33
34/* argument parsing macro */
35#define argis(a, b) (!strcmp(*arg + 1, a) || !strcmp(*arg + 1, b))
36
37/* flags from command line */
38int info_flag, verbose, noauth;
39int create_flag, setmac, delete_flag, rename_flag, ka, banner, update_flag;
40char *lpracl, *lpcacl;
41char *contact, *newname, *printserver, *type, *hwtype, *mac, *hostname, *queuename;
42char *duplexname, *logserver, *location, *realname;
43
44char *queuename, *whoami, *testqueue;
45
46void usage(char **argv);
47int show_printer_info(char *queuename);
48int save_printer_info(int argc, char **argv, void *hint);
49int save_hwaddr(int argc, char **argv, void *hint);
50void recursive_display_list_members(void);
51char *get_username(void);
52int wrap_mr_query(char *handle, int argc, char **argv,
53 int (*callback)(int, char **, void *), void *callarg);
54void print_query(char *query_name, int argc, char **argv);
55int CountArgs(char **info);
56
57int main(int argc, char **argv)
58{
59 int status, success;
60 char **arg = argv;
61 char *uargv[2];
62 char *pargv[PRN_END];
63 char *membervec[4];
64 struct member *memberstruct;
65 char *server = NULL, *p;
66 int i;
67
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;
73
74
75 contact = NULL;
76 whoami = argv[0];
77
78 success = 1;
79
80 /* parse args */
81 while (++arg - argv < argc)
82 {
83 if (**arg == '-')
84 {
85 if (argis("i", "info"))
86 info_flag++;
87 else if (argis("C", "create"))
88 create_flag++;
89 else if (argis("D", "delete"))
90 delete_flag++;
91 else if (argis("L", "location"))
92 {
93 if (arg - argv < argc - 1)
94 {
95 ++arg;
96 update_flag++;
97 location = *arg;
98 }
99 else
100 usage(argv);
101 }
102 else if (argis("r", "remotename"))
103 {
104 if (arg - argv < argc - 1)
105 {
106 ++arg;
107 update_flag++;
108 realname = *arg;
109 }
110 else
111 usage(argv);
112 }
113 else if (argis("T", "type"))
114 {
115 if (arg - argv < argc - 1)
116 {
117 ++arg;
118 update_flag++;
119 type = *arg;
120 }
121 else
122 usage(argv);
123 }
124 else if (argis("s", "printserver"))
125 {
126 if (arg - argv < argc - 1)
127 {
128 ++arg;
129 update_flag++;
130 printserver = canonicalize_hostname(strdup(*arg));
131 }
132 else
133 usage(argv);
134 }
135 else if (argis("M", "model"))
136 {
137 if (arg - argv < argc - 1)
138 {
139 ++arg;
140 update_flag++;
141 hwtype = *arg;
142 }
143 else
144 usage(argv);
145 }
146 else if (argis("K", "kerbauth"))
147 {
148 ka++;
149 update_flag++;
150 }
151 else if (argis("NK", "nokerbauth"))
152 {
153 ka = 0;
154 update_flag++;
155 }
156 else if (argis("H", "hostname"))
157 {
158 if (arg - argv < argc - 1)
159 {
160 ++arg;
161 update_flag++;
162 hostname = canonicalize_hostname(strdup(*arg));
163 }
164 else
165 usage(argv);
166 }
167 else if (argis("n", "noauth"))
168 noauth++;
169 else if (argis("v", "verbose"))
170 verbose++;
171 else if (argis("S", "server") || argis("db", "database"))
172 {
173 if (arg - argv < argc - 1)
174 {
175 ++arg;
176 server = *arg;
177 }
178 else
179 usage(argv);
180 }
181 else if (argis("c", "contact"))
182 {
183 if (arg - argv < argc - 1)
184 {
185 ++arg;
186 contact = *arg;
187 update_flag++;
188 }
189 else
190 usage(argv);
191 }
192 else if (argis("l", "lpcacl"))
193 {
194 if (arg - argv < argc - 1)
195 {
196 ++arg;
197 lpcacl = *arg;
198 update_flag++;
199 }
200 else
201 usage(argv);
202 }
203 else if (argis("ac", "lpracl"))
204 {
205 if (arg - argv < argc - 1)
206 {
207 ++arg;
208 lpracl = *arg;
209 update_flag++;
210 }
211 else
212 usage(argv);
213 }
214 else if (argis("m", "mac"))
215 {
216 if (arg - argv < argc - 1)
217 {
218 ++arg;
219 setmac++;
220 mac = *arg;
221 }
222 else
223 usage(argv);
224 }
225 else if (argis("b", "banner"))
226 {
227 update_flag++;
228 banner = 1;
229 }
230 else if (argis("nb", "nobanner"))
231 {
232 update_flag++;
233 banner = 0;
234 }
235 else if (argis("L", "logserver"))
236 {
237 if (arg - argv < argc - 1)
238 {
239 ++arg;
240 update_flag++;
241 logserver = canonicalize_hostname(strdup(*arg));
242 }
243 else
244 usage(argv);
245 }
246 else if (argis("R", "rename"))
247 {
248 if (arg - argv < argc - 1)
249 {
250 rename_flag++;
251 update_flag++;
252 ++arg;
253 newname = *arg;
254 }
255 else
256 usage(argv);
257 }
258 else if (argis("d", "duplex"))
259 {
260 if (arg - argv < argc - 1)
261 {
262 ++arg;
263 update_flag++;
264 duplexname = *arg;
265 }
266 else
267 usage(argv);
268 }
269 else
270 usage(argv);
271 }
272 else if (queuename == NULL)
273 queuename = *arg;
274 else
275 usage(argv);
276 }
277 if (queuename == NULL)
278 usage(argv);
279
280
281 if (!update_flag && !rename_flag && !delete_flag && !create_flag && !setmac)
282 info_flag++;
283
284 /* fire up Moira */
285 status = mrcl_connect(server, "eunice", 10, !noauth);
286 if (status == MRCL_AUTH_ERROR)
287 {
288 com_err(whoami, 0, "Authentication error while working on queue %s",
289 queuename);
290 com_err(whoami, 0, "Try the -noauth flag if you don't "
291 "need authentication.");
292 }
293 if (status)
294 exit(2);
295
296 if (create_flag)
297 {
298 if (hostname == NULL || type == NULL || hwtype == NULL )
299 usage(argv);
300 }
301
302 for (i = 0; i < PRN_END; i++)
303 pargv[i] = NULL;
304
305 /* check for name conflicts. */
306 if (create_flag || rename_flag)
307 {
308
309 if (rename_flag)
310 testqueue = newname;
311 else
312 testqueue = queuename;
313
314 status = wrap_mr_query("get_printer", 1, &testqueue, NULL, NULL);
315 if (status != MR_NO_MATCH)
316 {
317 fprintf(stderr, "ERROR: A queue by that name already exists.\n");
318 exit(1);
319 }
320
321 status = wrap_mr_query("get_printer_by_duplexname", 1, &testqueue, NULL, NULL);
322 if (status != MR_NO_MATCH)
323 {
324 fprintf(stderr, "ERROR: A duplex queue by that name already exists.\n");
325 exit(1);
326 }
327
328 if (duplexname) {
329 status = wrap_mr_query("get_printer_by_duplexname", 1, &testqueue, NULL, NULL);
330 if (status != MR_NO_MATCH)
331 {
332 fprintf(stderr, "ERROR: A duplex queue by that name already exists.\n");
333 exit(1);
334 }
335 }
336
337 }
338
339 /* create if needed */
340 if (create_flag)
341 {
342 if (realname == NULL)
343 realname = queuename; /* Variable for aliases */
344
345 if (logserver == NULL)
346 logserver = (char *) canonicalize_hostname(strdup(deflogserver));
347
348 pargv[PRN_NAME] = queuename;
349 pargv[PRN_TYPE] = type;
350 pargv[PRN_HWTYPE] = hwtype;
351
352 pargv[PRN_DUPLEXNAME] = (duplexname != NULL) ? duplexname : "";
353
354 pargv[PRN_HOSTNAME] = hostname;
355 pargv[PRN_LOGHOST] = logserver;
356
357 pargv[PRN_RM] = (printserver != NULL) ? printserver : "[ANY]";
358
359 pargv[PRN_CONTACT] = (contact != NULL) ? contact : "";
360
361 pargv[PRN_LOCATION] = (location != NULL) ? location : "";
362
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;
367
368 if (lpracl != NULL)
369 {
370 status = wrap_mr_query("get_list_info", 1, &lpracl,
371 NULL, NULL);
372 if (status)
373 {
374 com_err(whoami, status, "while getting authentication list information");
375 exit(1);
376 }
377 pargv[PRN_AC] = lpracl;
378 }
379 else
380 pargv[PRN_AC] = "[none]";
381
382 if (lpcacl != NULL)
383 {
384 status = wrap_mr_query("get_list_info", 1, &lpcacl,
385 NULL, NULL);
386 if (status)
387 {
388 com_err(whoami, status, "while getting authentication list information");
389 exit(1);
390 }
391 pargv[PRN_LPC_ACL] = lpcacl;
392 }
393 else
394 pargv[PRN_LPC_ACL] = "[none]";
395
396 pargv[PRN_BANNER] = (banner == 1) ? "1" : "0";
397
398 status = wrap_mr_query("add_printer", CountArgs(pargv), pargv, NULL, NULL);
399
400 if (status)
401 {
402 com_err(whoami, status, "while creating print queue.");
403 exit(1);
404 }
405 else
406 printf ("%s: queue %s created.\n", whoami, queuename);
407 }
408 else if (update_flag)
409 {
410
411 status = wrap_mr_query("get_printer", 1, &queuename, save_printer_info, pargv);
412 if (status)
413 {
414 com_err(whoami, status, "while getting printer information");
415 exit(1);
416 }
417
418 pargv[0] = queuename;
419 if (newname && rename_flag)
420 pargv[PRN_NAME + 1] = newname;
421 if (type != NULL)
422 pargv[PRN_TYPE + 1] = type;
423 if (hwtype != NULL)
424 pargv[PRN_HWTYPE + 1] = hwtype;
425
426 if (duplexname != NULL)
427 pargv[PRN_DUPLEXNAME + 1] = duplexname;
428
429 if (hostname != NULL)
430 pargv[PRN_HOSTNAME + 1] = hostname;
431
432 if (logserver != NULL)
433 pargv[PRN_LOGHOST + 1] = logserver;
434
435 if (printserver != NULL)
436 pargv[PRN_RM + 1] = printserver;
437
438 if (realname != NULL)
439 pargv[PRN_RP + 1] = realname;
440
441 if (quotaserver != NULL && strcmp(quotaserver,"[NONE]"))
442 pargv[PRN_RQ + 1] = (char *) quotaserver;
443
444 if (ka != -1)
445 pargv[PRN_KA + 1] = ka ? "1" : "0";
446 if (lpracl != NULL)
447 pargv[PRN_AC + 1] = lpracl;
448 if (lpcacl != NULL)
449 pargv[PRN_LPC_ACL + 1] = lpcacl;
450 if (banner != -1)
451 pargv[PRN_BANNER + 1] = banner ? "1" : "0";
452 if (location != NULL)
453 pargv[PRN_LOCATION + 1] = location;
454 if (contact != NULL)
455 pargv[PRN_CONTACT + 1] = contact;
456
457 pargv[PRN_MODBY + 1] = pargv[PRN_MODTIME + 1] = pargv[PRN_MODWITH + 1] = NULL;
458
459 status = wrap_mr_query("update_printer", CountArgs(pargv), pargv, NULL, NULL);
460 if (status)
461 {
462 com_err(whoami, status, "while updating print queue.");
463 exit(1);
464 }
465 else
466 {
467 if (rename_flag)
468 printf ("%s: queue %s renamed to %s.\n", whoami, queuename, newname);
469 else
470 printf ("%s: queue %s updated.\n", whoami, queuename);
471 }
472 }
473
474 /* display printer info if requested to */
475 if (info_flag)
476 show_printer_info(queuename);
477
478 if (setmac)
479 {
480 status = wrap_mr_query("get_printer", 1, &queuename, save_printer_info, pargv);
481 if (status)
482 {
483 com_err(whoami, status, "while getting printer information");
484 exit(1);
485 }
486
487 if (hostname == NULL)
488 uargv[0] = (char *) strdup (pargv[PRN_HOSTNAME + 1]);
489 else
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.");
494 }
495
496
497 if (delete_flag)
498 {
499 status = wrap_mr_query("delete_printer", 1, &queuename,
500 NULL, NULL);
501 if (status)
502 {
503 com_err(whoami, status, "while deleting printer");
504 exit(1);
505 }
506 else
507 printf ("%s: queue %s deleted.\n", whoami, queuename);
508 }
509
510 /* We're done! */
511 mr_disconnect();
512 exit(success ? 0 : 1);
513}
514
515void usage(char **argv)
516{
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",
521 "-C | -create");
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",
533 "-b | -banner");
534 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-NK | -nokerbauth",
535 "-nb | -nobanner");
536 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-l | -lpcacl list",
537 "-ac | -lpracl contact");
538 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-d | -duplex name",
539 "-n | -noauth");
540 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-m | -mac hwaddr",
541 "-db | -database host[:port]");
542 exit(1);
543}
544
545int show_printer_info(char *queuename)
546{
547 char hwaddr[20];
548 char *pargv[PRN_END];
549 int status, banner, i;
550
551 for (i = 0; i < PRN_END; i++)
552 pargv[i] = NULL;
553
554 memset (hwaddr,'\0',sizeof(hwaddr));
555
556 status = wrap_mr_query("get_printer", 1, &queuename, save_printer_info, pargv);
557 if (status)
558 {
559 com_err(whoami, status, "while getting printer information");
560 exit (1);
561 }
562
563 status = wrap_mr_query("get_host_hwaddr", 1, &pargv[PRN_HOSTNAME + 1],
564 save_hwaddr, &hwaddr);
565
566 if (status)
567 sprintf (hwaddr,"none");
568
569 banner = atoi(pargv[PRN_BANNER + 1]);
570
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]);
586 printf("\n");
587 printf("Last mod by %s at %s with %s.\n", pargv[PRN_MODBY + 1], pargv[PRN_MODTIME + 1], pargv[PRN_MODWITH + 1]);
588
589 return MR_CONT;
590}
591
592
593/* Copy retrieved information about a printer into a new argv */
594
595int save_printer_info(int argc, char **argv, void *hint)
596{
597 char **nargv = hint;
598
599 for (argc = 0; argc < PRN_END; argc++)
600 nargv[argc + 1] = strdup(argv[argc]);
601 return MR_CONT;
602}
603
604int save_hwaddr(int argc, char **argv, void *hint)
605{
606 char *p = hint;
607 strcpy(p,argv[0]);
608 return MR_CONT;
609}
610
611int wrap_mr_query(char *handle, int argc, char **argv,
612 int (*callback)(int, char **, void *), void *callarg)
613{
614 int status = 0;
615
616 if (verbose)
617 print_query(handle, argc, argv);
618
619 status = mr_query(handle, argc, argv, callback, callarg);
620
621 return (status);
622}
623
624void print_query(char *query_name, int argc, char **argv)
625{
626 int cnt;
627
628 printf("qy %s", query_name);
629 for(cnt=0; cnt<argc; cnt++)
630 printf(" <%s>", argv[cnt]);
631 printf("\n");
632}
633
634char *get_username(void)
635{
636 char *username;
637
638 username = getenv("USER");
639 if (!username)
640 {
641 username = mrcl_krb_user();
642 if (!username)
643 {
644 com_err(whoami, 0, "Could not determine username");
645 exit(1);
646 }
647 }
648 return username;
649}
650
651/* Function Name: CountArgs
652 * Description: Retrieve the number of args in a null terminated
653 * arglist.
654 * Arguments: info - the argument list.
655 * Returns: number if args in the list.
656 */
657
658int CountArgs(char **info)
659{
660 int number = 0;
661
662 while (*info)
663 {
664 number++;
665 info++;
666 }
667
668 return number;
669}
This page took 0.169764 seconds and 5 git commands to generate.