3 * This is the file printer.c for the Moira Client, which allows users
4 * to quickly and easily maintain most parts of the Moira database.
5 * It Contains: Functions for handling the printers.
10 * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
11 * For copying and distribution information, please see the file
15 #include <mit-copyright.h>
17 #include <moira_site.h>
28 void RealDeletePrn(char **info, Bool one_item);
29 void ChangePrn(char **info, Bool one_item);
30 void ChangePrintSrvLoop(char **info, Bool one);
31 extern int GetAliasValue(int argc, char **argv, void *retval);
32 int StoreHWAddr(int argc, char **argv, void *retval);
34 static char *PrintPrintSrvInfo(char **info);
35 static char **SetPrintSrvDefaults(char **info, char *name);
36 static char **AskPrintSrvInfo(char **info);
45 #define DEFAULT_LOGHOST "WSLOGGER.MIT.EDU"
47 int StoreHWAddr(int argc, char **argv, void *retval)
54 /* Function Name: SetDefaults
55 * Description: sets the default values for filesystem additions.
56 * Arguments: info - an array of char pointers to recieve defaults.
57 * Returns: char ** (this array, now filled).
60 static char **SetDefaults(char **info, char *name)
62 info[PRN_NAME] = strdup(name);
63 info[PRN_TYPE] = strdup("PRIVATE");
64 info[PRN_HWTYPE] = strdup("HP");
65 info[PRN_DUPLEXNAME] = strdup("");
66 info[PRN_HOSTNAME] = strdup(name);
67 info[PRN_LOGHOST] = strdup(DEFAULT_LOGHOST);
68 info[PRN_RM] = strdup("[ANY]");
69 info[PRN_RP] = strdup(name);
70 info[PRN_RQ] = strdup("[NONE]");
71 info[PRN_KA] = strdup("1");
72 info[PRN_PC] = strdup("10");
73 info[PRN_AC] = strdup("[none]");
74 info[PRN_LPC_ACL] = strdup("[none]");
75 info[PRN_BANNER] = strdup("1");
76 info[PRN_LOCATION] = strdup("");
77 info[PRN_CONTACT] = strdup("");
78 info[PRN_MODTIME] = info[PRN_MODBY] = info[PRN_MODWITH] = NULL;
84 /* Function Name: GetPrnInfo
85 * Description: Stores the info in a queue.
86 * Arguments: name - name of the item to get information on.
87 * Returns: a pointer to the first element in the queue or null
88 * if printer not found.
91 static struct mqelem *GetPrnInfo(char *name, int how)
94 struct mqelem *elem = NULL;
99 stat = do_mr_query("get_printer", 1, &name, StoreInfo, &elem);
100 if (stat == MR_NO_MATCH)
102 stat = do_mr_query("get_printer_by_duplexname", 1, &name,
107 stat = do_mr_query("get_printer_by_ethernet", 1, &name,
111 name = canonicalize_hostname(strdup(name));
112 stat = do_mr_query("get_printer_by_hostname", 1, &name,
117 name = canonicalize_hostname(strdup(name));
118 stat = do_mr_query("get_printer_by_rm", 1, &name,
123 stat = do_mr_query("get_printer_by_location", 1, &name,
127 stat = do_mr_query("get_printer_by_contact", 1, &name,
134 com_err(program_name, stat, " in GetPrnInfo");
137 return QueueTop(elem);
140 /* Function Name: PrintPrnInfo
141 * Description: Yet another specialized print function.
142 * Arguments: info - all info about this Printer.
143 * Returns: printer name
146 static char *PrintPrnInfo(char **info)
148 char buf[BUFSIZ], *hwaddr;
149 int status, banner = atoi(info[PRN_BANNER]);
151 if (!info) /* If no informaion */
153 Put_message("PrintPrnInfo called with null info!");
157 sprintf(buf, "Printer: %-18s Duplex queue: %-18s", info[PRN_NAME],
158 *info[PRN_DUPLEXNAME] ? info[PRN_DUPLEXNAME] : "[none]");
160 sprintf(buf, "Type: %-10s Hardware type: %-10s Hardware address: ",
161 info[PRN_TYPE], info[PRN_HWTYPE]);
162 status = do_mr_query("get_host_hwaddr", 1, &info[PRN_HOSTNAME],
163 StoreHWAddr, &hwaddr);
164 if (status == MR_SUCCESS)
172 sprintf(buf, "Printer hostname: %s", info[PRN_HOSTNAME]);
174 sprintf(buf, "Printer log host: %s", info[PRN_LOGHOST]);
176 sprintf(buf, "Spool host: %s", info[PRN_RM]);
178 sprintf(buf, "Remote Printer Name: %-38s Banner page: %s", info[PRN_RP],
179 banner ? ( banner == PRN_BANNER_FIRST ? "Yes" : "Last" ) : "No");
181 sprintf(buf, "Authentication: %-3s Price/page: %-3s Quota Server: %s",
182 atoi(info[PRN_KA]) ? "yes" : "no", info[PRN_PC], info[PRN_RQ]);
184 sprintf(buf, "Restrict list: %-23s LPC ACL: %-23s",
185 info[PRN_AC], info[PRN_LPC_ACL]);
187 sprintf(buf, "Location: %s", info[PRN_LOCATION]);
189 sprintf(buf, "Contact: %s", info[PRN_CONTACT]);
191 sprintf(buf, MOD_FORMAT, info[PRN_MODBY], info[PRN_MODTIME],
195 return info[PRN_NAME];
198 /* Function Name: AskPrnInfo.
199 * Description: This function askes the user for information about a
200 * printer and saves it into a structure.
201 * Arguments: info - a pointer the the structure to put the
206 static char **AskPrnInfo(char **info)
208 char temp_buf[BUFSIZ];
209 char *args[3], *lpc_acl;
214 sprintf(temp_buf, "Printer entry for %s.", info[PRN_NAME]);
215 Put_message(temp_buf);
218 if (GetTypeFromUser("Type of Printer", "printertype", &info[PRN_TYPE]) ==
221 if (GetTypeFromUser("Hardware Type", "printerhwtype", &info[PRN_HWTYPE]) ==
224 if (GetValueFromUser("Duplex spool name", &info[PRN_DUPLEXNAME]) ==
227 if (GetValueFromUser("Printer hostname (or [none])", &info[PRN_HOSTNAME]) ==
230 info[PRN_HOSTNAME] = canonicalize_hostname(info[PRN_HOSTNAME]);
231 if (GetValueFromUser("Log host", &info[PRN_LOGHOST]) == SUB_ERROR)
233 info[PRN_LOGHOST] = canonicalize_hostname(info[PRN_LOGHOST]);
234 if (GetValueFromUser("Spool host (or [any])", &info[PRN_RM]) == SUB_ERROR)
236 info[PRN_RM] = canonicalize_hostname(info[PRN_RM]);
237 if (GetValueFromUser("Remote printer name", &info[PRN_RP]) == SUB_ERROR)
239 if (GetValueFromUser("Quota server", &info[PRN_RQ]) == SUB_ERROR)
241 info[PRN_RQ] = canonicalize_hostname(info[PRN_RQ]);
242 if (GetYesNoValueFromUser("Kerberos authenticated", &info[PRN_KA]) ==
245 if (GetValueFromUser("Price per page", &info[PRN_PC]) == SUB_ERROR)
247 if (GetValueFromUser("Restrict list", &info[PRN_AC]) == SUB_ERROR)
249 args[0] = info[PRN_TYPE];
252 status = do_mr_query("get_alias", 3, args, GetAliasValue, &lpc_acl);
253 if (status == MR_SUCCESS)
255 free(info[PRN_LPC_ACL]);
256 info[PRN_LPC_ACL] = lpc_acl;
258 if (GetValueFromUser("LPC ACL", &info[PRN_LPC_ACL]) == SUB_ERROR)
260 if (GetYesNoValueFromUser("Banner page", &info[PRN_BANNER]) == SUB_ERROR)
262 if (GetValueFromUser("Location", &info[PRN_LOCATION]) == SUB_ERROR)
264 if (GetValueFromUser("Contact", &info[PRN_CONTACT]) == SUB_ERROR)
267 FreeAndClear(&info[PRN_MODTIME], TRUE);
268 FreeAndClear(&info[PRN_MODBY], TRUE);
269 FreeAndClear(&info[PRN_MODWITH], TRUE);
274 /* ---------------- Printer Menu ------------------ */
276 /* Function Name: GetPrn
277 * Description: Get Printer information
278 * Arguments: argc, argv - name of printer in argv[1].
279 * Returns: DM_NORMAL.
282 int GetPrn(int argc, char **argv)
286 top = GetPrnInfo(argv[1], BY_NAME); /* get info. */
287 Loop(top, (void (*)(char **)) PrintPrnInfo);
288 FreeQueue(top); /* clean the queue. */
292 int GetPrnByEthernet(int argc, char **argv)
296 top = GetPrnInfo(argv[1], BY_ETHERNET); /* get info. */
297 Loop(top, (void (*)(char **)) PrintPrnInfo);
298 FreeQueue(top); /* clean the queue. */
302 int GetPrnByHostname(int argc, char **argv)
306 top = GetPrnInfo(argv[1], BY_HOSTNAME); /* get info. */
307 Loop(top, (void (*)(char **)) PrintPrnInfo);
308 FreeQueue(top); /* clean the queue. */
312 int GetPrnByRM(int argc, char **argv)
316 top = GetPrnInfo(argv[1], BY_RM); /* get info. */
317 Loop(top, (void (*)(char **)) PrintPrnInfo);
318 FreeQueue(top); /* clean the queue. */
322 int GetPrnByLocation(int argc, char **argv)
326 top = GetPrnInfo(argv[1], BY_LOCATION); /* get info. */
327 Loop(top, (void (*)(char **)) PrintPrnInfo);
328 FreeQueue(top); /* clean the queue. */
332 int GetPrnByContact(int argc, char **argv)
336 top = GetPrnInfo(argv[1], BY_CONTACT); /* get info. */
337 Loop(top, (void (*)(char **)) PrintPrnInfo);
338 FreeQueue(top); /* clean the queue. */
343 /* Function Name: RealDeletePrn
344 * Description: Does the real deletion work.
345 * Arguments: info - array of char *'s containing all useful info.
346 * one_item - a Boolean that is true if only one item
347 * in queue that dumped us here.
351 void RealDeletePrn(char **info, Bool one_item)
355 if ((stat = do_mr_query("delete_printer", 1, &info[PRN_NAME], NULL, NULL)))
356 com_err(program_name, stat, " printer not deleted.");
358 Put_message("Printer deleted.");
361 /* Function Name: DeletePrn
362 * Description: Delete a printer given its name.
363 * Arguments: argc, argv - argv[1] is the name of the printer.
367 int DeletePrn(int argc, char **argv)
369 struct mqelem *elem = GetPrnInfo(argv[1], BY_NAME);
370 QueryLoop(elem, PrintPrnInfo, RealDeletePrn, "Delete Printer");
376 /* Function Name: AddPrn
377 * Description: Add a printer
378 * Arguments: arc, argv - name of printer in argv[1].
379 * Returns: DM_NORMAL.
382 int AddPrn(int argc, char **argv)
384 char *info[MAX_ARGS_SIZE], **args;
387 if (!ValidName(argv[1]))
390 if (!(stat = do_mr_query("get_printer", 1, argv + 1, NULL, NULL)) ||
391 !(stat = do_mr_query("get_printer_by_duplexname", 1, argv + 1,
394 Put_message ("A Printer by that name already exists.");
397 else if (stat != MR_NO_MATCH)
399 com_err(program_name, stat, " in AddPrn");
403 args = AskPrnInfo(SetDefaults(info, argv[1]));
406 Put_message("Aborted.");
410 if ((stat = do_mr_query("add_printer", CountArgs(args), args, NULL, NULL)))
411 com_err(program_name, stat, " in AddPrn");
413 if (stat == MR_SUCCESS && strcasecmp(info[PRN_HOSTNAME], "[NONE]"))
414 UpdateHWAddr(2, &info[PRN_HOSTNAME - 1]);
421 /* Function Name: ChangePrn
422 * Description: Do the work of changing a Prn
423 * Arguments: argc, argv - printcap info
427 void ChangePrn(char **info, Bool one_item)
432 oldinfo = CopyInfo(info);
433 if (!AskPrnInfo(info))
435 if ((stat = do_mr_query("delete_printer", 1, &info[PRN_NAME], NULL, NULL)))
437 com_err(program_name, stat, " printer not updated.");
440 if ((stat = do_mr_query("add_printer", CountArgs(info), info, NULL, NULL)))
442 com_err(program_name, stat, " in ChngPrn");
443 if ((stat = do_mr_query("add_printer", CountArgs(oldinfo) - 3,
444 oldinfo, NULL, NULL)))
445 com_err(program_name, stat, " while attempting to put old info back");
452 /* Function Name: ChngPrn
453 * Description: Update the printcap information
454 * Arguments: argc, argv - name of printer in argv[1].
455 * Returns: DM_NORMAL.
458 int ChngPrn(int argc, char **argv)
460 struct mqelem *elem = GetPrnInfo(argv[1], BY_NAME);
461 QueryLoop(elem, NullPrint, ChangePrn, "Change the printer");
467 int UpdateHWAddr(int argc, char **argv)
470 char *name, *hwaddr, *s, *d, *uargv[2];
472 name = canonicalize_hostname(strdup(argv[1]));
473 stat = do_mr_query("get_host_hwaddr", 1, &name, StoreHWAddr, &hwaddr);
474 if (stat != MR_SUCCESS)
477 com_err(program_name, stat, " checking host ethernet address");
481 if (GetValueFromUser("Hardware ethernet address", &hwaddr) == SUB_ERROR)
497 if ((stat = do_mr_query("update_host_hwaddr", 2, uargv, NULL, NULL)))
498 com_err(program_name, stat, " updating ethernet address.");
506 int GetPrintSrv(int argc, char **argv)
509 struct mqelem *elem = NULL, *top;
512 name = canonicalize_hostname(strdup(argv[1]));
513 stat = do_mr_query("get_print_server", 1, &name, StoreInfo, &elem);
516 com_err(program_name, stat, " in GetPrintSrv");
520 top = QueueTop(elem);
521 Loop(top, (void (*)(char **)) PrintPrintSrvInfo);
522 FreeQueue(top); /* clean the queue. */
526 static char *PrintPrintSrvInfo(char **info)
531 if (!info) /* If no informaion */
533 Put_message("PrintPrintSrvInfo called with null info!");
537 sprintf(buf, "Hostname: %s", info[PRINTSERVER_HOST]);
539 sprintf(buf, "Kind: %-10s Printer Types: %s", info[PRINTSERVER_KIND],
540 info[PRINTSERVER_TYPES]);
542 if (!strcmp(info[PRINTSERVER_OWNER_TYPE], "NONE"))
543 sprintf(buf, "Owner: %-25s", info[PRINTSERVER_OWNER_TYPE]);
546 sprintf(buf, "Owner: %s %-*s", info[PRINTSERVER_OWNER_TYPE],
547 24 - strlen(info[PRINTSERVER_OWNER_TYPE]),
548 info[PRINTSERVER_OWNER_NAME]);
550 strcat(buf, "LPC ACL: ");
551 strcat(buf, info[PRINTSERVER_LPC_ACL]);
553 sprintf(buf, MOD_FORMAT, info[PRINTSERVER_MODBY], info[PRINTSERVER_MODTIME],
554 info[PRINTSERVER_MODWITH]);
557 return info[PRINTSERVER_HOST];
560 static char **SetPrintSrvDefaults(char **info, char *name)
562 info[PRINTSERVER_HOST] = strdup(name);
563 info[PRINTSERVER_KIND] = strdup("ATHENA");
564 info[PRINTSERVER_TYPES] = strdup("PRIVATE");
565 info[PRINTSERVER_OWNER_TYPE] = strdup("NONE");
566 info[PRINTSERVER_OWNER_NAME] = strdup("");
567 info[PRINTSERVER_LPC_ACL] = strdup("[none]");
568 info[PRINTSERVER_MODTIME] = info[PRINTSERVER_MODBY] =
569 info[PRINTSERVER_MODWITH] = NULL;
571 info[PRINTSERVER_END] = NULL;
575 static char **AskPrintSrvInfo(char **info)
578 char *args[3], *lpc_acl;
583 sprintf(buf, "Print Server entry for %s.", info[PRINTSERVER_HOST]);
587 if (GetTypeFromUser("Kind of LPD", "lpd_kind", &info[PRINTSERVER_KIND]) ==
590 if (GetValueFromUser("Printer types", &info[PRINTSERVER_TYPES]) == SUB_ERROR)
592 if (GetTypeFromUser("Owner type", "ace_type", &info[PRINTSERVER_OWNER_TYPE])
595 if (strcmp(info[PRINTSERVER_OWNER_TYPE], "NONE") &&
596 GetValueFromUser("Owner Name", &info[PRINTSERVER_OWNER_NAME]) ==
599 if (GetValueFromUser("LPC ACL", &info[PRINTSERVER_LPC_ACL]) == SUB_ERROR)
602 FreeAndClear(&info[PRINTSERVER_MODTIME], TRUE);
603 FreeAndClear(&info[PRINTSERVER_MODBY], TRUE);
604 FreeAndClear(&info[PRINTSERVER_MODWITH], TRUE);
609 int AddPrintSrv(int argc, char **argv)
611 char *info[MAX_ARGS_SIZE], **args, *name;
614 name = canonicalize_hostname(strdup(argv[1]));
616 if (!(stat = do_mr_query("get_print_server", 1, &name, NULL, NULL)))
618 Put_message ("A print server record for that host already exists.");
622 else if (stat != MR_NO_MATCH)
624 com_err(program_name, stat, " in AddPrintSrv");
629 args = AskPrintSrvInfo(SetPrintSrvDefaults(info, name));
633 Put_message("Aborted.");
637 if ((stat = do_mr_query("add_print_server", CountArgs(args),
639 com_err(program_name, stat, " in AddPrintSrv");
645 int ChangePrintSrv(int argc, char **argv)
648 struct mqelem *elem = NULL;
651 name = canonicalize_hostname(strdup(argv[1]));
652 if ((stat = do_mr_query("get_print_server", 1, &name, StoreInfo, &elem)))
655 com_err(program_name, stat, " in ChangePrintSrv");
660 QueryLoop(elem, NullPrint, ChangePrintSrvLoop, "Change the print server");
665 void ChangePrintSrvLoop(char **info, Bool one)
669 if (!AskPrintSrvInfo(info))
672 if ((stat = do_mr_query("update_print_server", CountArgs(info),
674 com_err(program_name, stat, " in ChangePrintSrv");
680 int DelPrintSrv(int argc, char **argv)
685 name = canonicalize_hostname(strdup(argv[1]));
687 if ((stat = do_mr_query("delete_print_server", 1, &name, NULL, NULL)))
688 com_err(program_name, stat, " while deleting print server");