]> andersk Git - moira.git/blob - clients/eunice/eunice.c
Command line printer manipulation client, and build goo.
[moira.git] / clients / eunice / eunice.c
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
23 struct member {
24   int type;
25   char *name, *tag;
26 };
27
28 const char *deflogserver = "WSLOGGER.MIT.EDU";
29
30 /* legacy variables that we need to set regardless */
31 const char *quotaserver = "[NONE]";
32 const 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 */
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;
43
44 char *queuename, *whoami, *testqueue;
45
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);
56
57 int 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
515 void 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
545 int 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
595 int 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
604 int save_hwaddr(int argc, char **argv, void *hint)
605 {
606   char *p = hint;
607   strcpy(p,argv[0]);
608   return MR_CONT;
609 }
610
611 int 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
624 void 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
634 char *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
658 int 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.131523 seconds and 5 git commands to generate.