]> andersk Git - moira.git/blob - clients/moira/printer.c
don't cast function pointers to (void *)
[moira.git] / clients / moira / printer.c
1 /* $Id$
2  *
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.
6  *
7  *      Created:        8/16/88
8  *      By:             Theodore Y. Ts'o
9  *
10  * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
11  * For copying and distribution information, please see the file
12  * <mit-copyright.h>.
13  */
14
15 #include <mit-copyright.h>
16 #include <moira.h>
17 #include <moira_site.h>
18 #include "defs.h"
19 #include "f_defs.h"
20 #include "globals.h"
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 RCSID("$Header$");
27
28 void RealDeletePrn(char **info, Bool one_item);
29 void ChangePrn(char **info, Bool one_item);
30 extern int GetAliasValue(int argc, char **argv, void *retval);
31 int StoreHWAddr(int argc, char **argv, void *retval);
32
33 #define BY_NAME 0
34 #define BY_ETHERNET 1
35 #define BY_HOSTNAME 2
36 #define BY_RM 3
37 #define BY_LOCATION 4
38 #define BY_CONTACT 5
39
40 #define DEFAULT_LOGHOST "WSLOGGER.MIT.EDU"
41
42 int StoreHWAddr(int argc, char **argv, void *retval)
43 {
44   char **p = retval;
45   *p = strdup(argv[0]);
46   return MR_CONT;
47 }
48
49 /*      Function Name: SetDefaults
50  *      Description: sets the default values for filesystem additions.
51  *      Arguments: info - an array of char pointers to recieve defaults.
52  *      Returns: char ** (this array, now filled).
53  */
54
55 static char **SetDefaults(char **info, char *name)
56 {
57   info[PRN_NAME] = strdup(name);
58   info[PRN_TYPE] = strdup("PRIVATE");
59   info[PRN_HWTYPE] = strdup("HP");
60   info[PRN_DUPLEXNAME] = strdup("");
61   info[PRN_HOSTNAME] = strdup(name);
62   info[PRN_LOGHOST] = strdup(DEFAULT_LOGHOST);
63   info[PRN_RM] = strdup("[ANY]");
64   info[PRN_RP] = strdup(name);
65   info[PRN_RQ] = strdup("[NONE]");
66   info[PRN_KA] = strdup("1");
67   info[PRN_PC] = strdup("10");
68   info[PRN_AC] = strdup("[none]");
69   info[PRN_LPC_ACL] = strdup("[none]");
70   info[PRN_BANNER] = strdup("1");
71   info[PRN_LOCATION] = strdup("");
72   info[PRN_CONTACT] = strdup("");
73   info[PRN_MODTIME] = info[PRN_MODBY] = info[PRN_MODWITH] = NULL;
74
75   info[PRN_END] = NULL;
76   return info;
77 }
78
79 /*      Function Name: GetPrnInfo
80  *      Description: Stores the info in a queue.
81  *      Arguments: name - name of the item to get information on.
82  *      Returns: a pointer to the first element in the queue or null
83  *              if printer not found.
84  */
85
86 static struct mqelem *GetPrnInfo(char *name, int how)
87 {
88   int stat;
89   struct mqelem *elem = NULL;
90
91   switch (how)
92     {
93     case BY_NAME:
94       stat = do_mr_query("get_printer", 1, &name, StoreInfo, &elem);
95       if (stat == MR_NO_MATCH)
96         {
97           stat = do_mr_query("get_printer_by_duplexname", 1, &name,
98                              StoreInfo, &elem);
99         }
100       break;
101     case BY_ETHERNET:
102       stat = do_mr_query("get_printer_by_ethernet", 1, &name,
103                          StoreInfo, &elem);
104       break;
105     case BY_HOSTNAME:
106       name = canonicalize_hostname(strdup(name));
107       stat = do_mr_query("get_printer_by_hostname", 1, &name,
108                          StoreInfo, &elem);
109       free(name);
110       break;
111     case BY_RM:
112       name = canonicalize_hostname(strdup(name));
113       stat = do_mr_query("get_printer_by_rm", 1, &name,
114                          StoreInfo, &elem);
115       free(name);
116       break;
117     case BY_LOCATION:
118       stat = do_mr_query("get_printer_by_location", 1, &name,
119                          StoreInfo, &elem);
120       break;
121     case BY_CONTACT:
122       stat = do_mr_query("get_printer_by_contact", 1, &name,
123                          StoreInfo, &elem);
124       break;
125     }
126
127   if (stat)
128     {
129       com_err(program_name, stat, " in GetPrnInfo");
130       return NULL;
131     }
132   return QueueTop(elem);
133 }
134
135 /*      Function Name: PrintPrnInfo
136  *      Description: Yet another specialized print function.
137  *      Arguments: info - all info about this Printer.
138  *      Returns: printer name
139  */
140
141 static char *PrintPrnInfo(char **info)
142 {
143   char buf[BUFSIZ], *hwaddr;
144   int status, banner = atoi(info[PRN_BANNER]);
145
146   if (!info)            /* If no informaion */
147     {
148       Put_message("PrintPrnInfo called with null info!");
149       return NULL;
150     }
151   Put_message("");
152   sprintf(buf, "Printer: %-18s Duplex queue: %-18s", info[PRN_NAME],
153           *info[PRN_DUPLEXNAME] ? info[PRN_DUPLEXNAME] : "[none]");
154   Put_message(buf);
155   sprintf(buf, "Type: %-10s Hardware type: %-10s Hardware address: ",
156           info[PRN_TYPE], info[PRN_HWTYPE]);
157   status = do_mr_query("get_host_hwaddr", 1, &info[PRN_HOSTNAME],
158                        StoreHWAddr, &hwaddr);
159   if (status == MR_SUCCESS)
160     {
161       strcat(buf, hwaddr);
162       free(hwaddr);
163     }
164   else
165     strcat(buf, "none");
166   Put_message(buf);
167   sprintf(buf, "Printer hostname: %s", info[PRN_HOSTNAME]);
168   Put_message(buf);
169   sprintf(buf, "Printer log host: %s", info[PRN_LOGHOST]);
170   Put_message(buf);
171   sprintf(buf, "Spool host: %s", info[PRN_RM]);
172   Put_message(buf);
173   sprintf(buf, "Remote Printer Name: %-38s Banner page: %s", info[PRN_RP],
174           banner ? ( banner == PRN_BANNER_FIRST ? "Yes" : "Last" ) : "No");
175   Put_message(buf);
176   sprintf(buf, "Authentication: %-3s Price/page: %-3s  Quota Server: %s",
177           atoi(info[PRN_KA]) ? "yes" : "no", info[PRN_PC], info[PRN_RQ]);
178   Put_message(buf);
179   sprintf(buf, "Restrict list: %-23s  LPC ACL: %-23s",
180           info[PRN_AC], info[PRN_LPC_ACL]);
181   Put_message(buf);
182   sprintf(buf, "Location: %s", info[PRN_LOCATION]);
183   Put_message(buf);
184   sprintf(buf, "Contact: %s", info[PRN_CONTACT]);
185   Put_message(buf);
186   sprintf(buf, MOD_FORMAT, info[PRN_MODBY], info[PRN_MODTIME],
187           info[PRN_MODWITH]);
188   Put_message(buf);
189
190   return info[PRN_NAME];
191 }
192
193 /*      Function Name: AskPrnInfo.
194  *      Description: This function askes the user for information about a
195  *                   printer and saves it into a structure.
196  *      Arguments: info - a pointer the the structure to put the
197  *                        info into.
198  *      Returns: none.
199  */
200
201 static char **AskPrnInfo(char **info)
202 {
203   char temp_buf[BUFSIZ];
204   char *args[3], *lpc_acl;
205   char *s, *d;
206   int status;
207
208   Put_message("");
209   sprintf(temp_buf, "Printer entry for %s.", info[PRN_NAME]);
210   Put_message(temp_buf);
211   Put_message("");
212
213   if (GetTypeFromUser("Type of Printer", "printertype", &info[PRN_TYPE]) ==
214       SUB_ERROR)
215     return NULL;
216   if (GetTypeFromUser("Hardware Type", "printerhwtype", &info[PRN_HWTYPE]) ==
217       SUB_ERROR)
218     return NULL;
219   if (GetValueFromUser("Duplex spool name", &info[PRN_DUPLEXNAME]) ==
220       SUB_ERROR)
221     return NULL;
222   if (GetValueFromUser("Printer hostname (or [none])", &info[PRN_HOSTNAME]) ==
223       SUB_ERROR)
224     return NULL;
225   info[PRN_HOSTNAME] = canonicalize_hostname(info[PRN_HOSTNAME]);
226   if (GetValueFromUser("Log host", &info[PRN_LOGHOST]) == SUB_ERROR)
227     return NULL;
228   info[PRN_LOGHOST] = canonicalize_hostname(info[PRN_LOGHOST]);
229   if (GetValueFromUser("Spool host (or [any])", &info[PRN_RM]) == SUB_ERROR)
230     return NULL;
231   info[PRN_RM] = canonicalize_hostname(info[PRN_RM]);
232   if (GetValueFromUser("Remote printer name", &info[PRN_RP]) == SUB_ERROR)
233     return NULL;
234   if (GetValueFromUser("Quota server", &info[PRN_RQ]) == SUB_ERROR)
235     return NULL;
236   info[PRN_RQ] = canonicalize_hostname(info[PRN_RQ]);
237   if (GetYesNoValueFromUser("Kerberos authenticated", &info[PRN_KA]) ==
238       SUB_ERROR)
239     return NULL;
240   if (GetValueFromUser("Price per page", &info[PRN_PC]) == SUB_ERROR)
241     return NULL;
242   if (GetValueFromUser("Restrict list", &info[PRN_AC]) == SUB_ERROR)
243     return NULL;
244   args[0] = info[PRN_TYPE];
245   args[1] = "LPC_ACL";
246   args[2] = "*";
247   status = do_mr_query("get_alias", 3, args, GetAliasValue, &lpc_acl);
248   if (status == MR_SUCCESS)
249     {
250       free(info[PRN_LPC_ACL]);
251       info[PRN_LPC_ACL] = lpc_acl;
252     }
253   if (GetValueFromUser("LPC ACL", &info[PRN_LPC_ACL]) == SUB_ERROR)
254     return NULL;
255   if (GetYesNoValueFromUser("Banner page", &info[PRN_BANNER]) == SUB_ERROR)
256     return NULL;
257   if (GetValueFromUser("Location", &info[PRN_LOCATION]) == SUB_ERROR)
258     return NULL;
259   if (GetValueFromUser("Contact", &info[PRN_CONTACT]) == SUB_ERROR)
260     return NULL;
261
262   FreeAndClear(&info[PRN_MODTIME], TRUE);
263   FreeAndClear(&info[PRN_MODBY], TRUE);
264   FreeAndClear(&info[PRN_MODWITH], TRUE);
265
266   return info;
267 }
268
269 /* ---------------- Printer Menu ------------------ */
270
271 /*      Function Name: GetPrn
272  *      Description: Get Printer information
273  *      Arguments: argc, argv - name of printer in argv[1].
274  *      Returns: DM_NORMAL.
275  */
276
277 int GetPrn(int argc, char **argv)
278 {
279   struct mqelem *top;
280
281   top = GetPrnInfo(argv[1], BY_NAME); /* get info. */
282   Loop(top, (void (*)(char **)) PrintPrnInfo);
283   FreeQueue(top);               /* clean the queue. */
284   return DM_NORMAL;
285 }
286
287 int GetPrnByEthernet(int argc, char **argv)
288 {
289   struct mqelem *top;
290
291   top = GetPrnInfo(argv[1], BY_ETHERNET); /* get info. */
292   Loop(top, (void (*)(char **)) PrintPrnInfo);
293   FreeQueue(top);               /* clean the queue. */
294   return DM_NORMAL;
295 }
296
297 int GetPrnByHostname(int argc, char **argv)
298 {
299   struct mqelem *top;
300
301   top = GetPrnInfo(argv[1], BY_HOSTNAME); /* get info. */
302   Loop(top, (void (*)(char **)) PrintPrnInfo);
303   FreeQueue(top);               /* clean the queue. */
304   return DM_NORMAL;
305 }
306
307 int GetPrnByRM(int argc, char **argv)
308 {
309   struct mqelem *top;
310
311   top = GetPrnInfo(argv[1], BY_RM); /* get info. */
312   Loop(top, (void (*)(char **)) PrintPrnInfo);
313   FreeQueue(top);               /* clean the queue. */
314   return DM_NORMAL;
315 }
316
317 int GetPrnByLocation(int argc, char **argv)
318 {
319   struct mqelem *top;
320
321   top = GetPrnInfo(argv[1], BY_LOCATION); /* get info. */
322   Loop(top, (void (*)(char **)) PrintPrnInfo);
323   FreeQueue(top);               /* clean the queue. */
324   return DM_NORMAL;
325 }
326
327 int GetPrnByContact(int argc, char **argv)
328 {
329   struct mqelem *top;
330
331   top = GetPrnInfo(argv[1], BY_CONTACT); /* get info. */
332   Loop(top, (void (*)(char **)) PrintPrnInfo);
333   FreeQueue(top);               /* clean the queue. */
334   return DM_NORMAL;
335 }
336
337
338 /*      Function Name: RealDeletePrn
339  *      Description: Does the real deletion work.
340  *      Arguments: info - array of char *'s containing all useful info.
341  *                 one_item - a Boolean that is true if only one item
342  *                              in queue that dumped us here.
343  *      Returns: none.
344  */
345
346 void RealDeletePrn(char **info, Bool one_item)
347 {
348   int stat;
349
350   if ((stat = do_mr_query("delete_printer", 1, &info[PRN_NAME], NULL, NULL)))
351     com_err(program_name, stat, " printer not deleted.");
352   else
353     Put_message("Printer deleted.");
354 }
355
356 /*      Function Name: DeletePrn
357  *      Description: Delete a printer given its name.
358  *      Arguments: argc, argv - argv[1] is the name of the printer.
359  *      Returns: none.
360  */
361
362 int DeletePrn(int argc, char **argv)
363 {
364   struct mqelem *elem = GetPrnInfo(argv[1], BY_NAME);
365   QueryLoop(elem, PrintPrnInfo, RealDeletePrn, "Delete Printer");
366
367   FreeQueue(elem);
368   return DM_NORMAL;
369 }
370
371 /*      Function Name: AddPrn
372  *      Description: Add a printer
373  *      Arguments: arc, argv - name of printer in argv[1].
374  *      Returns: DM_NORMAL.
375  */
376
377 int AddPrn(int argc, char **argv)
378 {
379   char *info[MAX_ARGS_SIZE], **args;
380   int stat;
381
382   if (!ValidName(argv[1]))
383     return DM_NORMAL;
384
385   if (!(stat = do_mr_query("get_printer", 1, argv + 1, NULL, NULL)) ||
386       !(stat = do_mr_query("get_printer_by_duplexname", 1, argv + 1,
387                            NULL, NULL)))
388     {
389       Put_message ("A Printer by that name already exists.");
390       return DM_NORMAL;
391     }
392   else if (stat != MR_NO_MATCH)
393     {
394       com_err(program_name, stat, " in AddPrn");
395       return DM_NORMAL;
396     }
397
398   args = AskPrnInfo(SetDefaults(info, argv[1]));
399   if (!args)
400     {
401       Put_message("Aborted.");
402       return DM_NORMAL;
403     }
404
405   if ((stat = do_mr_query("add_printer", CountArgs(args), args, NULL, NULL)))
406     com_err(program_name, stat, " in AddPrn");
407
408   if (stat == MR_SUCCESS && strcasecmp(info[PRN_HOSTNAME], "[NONE]"))
409     UpdateHWAddr(2, &info[PRN_HOSTNAME - 1]);
410
411   FreeInfo(info);
412   return DM_NORMAL;
413 }
414
415
416 /*      Function Name: ChangePrn
417  *      Description: Do the work of changing a Prn
418  *      Arguments: argc, argv - printcap info
419  *      Returns:
420  */
421
422 void ChangePrn(char **info, Bool one_item)
423 {
424   int stat;
425   char **oldinfo;
426
427   oldinfo = CopyInfo(info);
428   if (!AskPrnInfo(info))
429     return;
430   if ((stat = do_mr_query("delete_printer", 1, &info[PRN_NAME], NULL, NULL)))
431     {
432       com_err(program_name, stat, " printer not updated.");
433       return;
434     }
435   if ((stat = do_mr_query("add_printer", CountArgs(info), info, NULL, NULL)))
436     {
437       com_err(program_name, stat, " in ChngPrn");
438       if ((stat = do_mr_query("add_printer", CountArgs(oldinfo) - 3,
439                               oldinfo, NULL, NULL)))
440         com_err(program_name, stat, " while attempting to put old info back");
441     }
442   FreeInfo(oldinfo);
443   return;
444 }
445
446
447 /*      Function Name: ChngPrn
448  *      Description:   Update the printcap information
449  *      Arguments:     argc, argv - name of printer in argv[1].
450  *      Returns:       DM_NORMAL.
451  */
452
453 int ChngPrn(int argc, char **argv)
454 {
455   struct mqelem *elem = GetPrnInfo(argv[1], BY_NAME);
456   QueryLoop(elem, NullPrint, ChangePrn, "Change the printer");
457   FreeQueue(elem);
458   return DM_NORMAL;
459 }
460
461
462 int UpdateHWAddr(int argc, char **argv)
463 {
464   int stat;
465   char *name, *hwaddr, *s, *d, *uargv[2];
466
467   name = canonicalize_hostname(strdup(argv[1]));
468   stat = do_mr_query("get_host_hwaddr", 1, &name, StoreHWAddr, &hwaddr);
469   if (stat != MR_SUCCESS)
470     {
471       free(name);
472       com_err(program_name, stat, " checking host ethernet address");
473       return DM_NORMAL;
474     }
475
476   if (GetValueFromUser("Hardware ethernet address", &hwaddr) == SUB_ERROR)
477     {
478       free(name);
479       return DM_NORMAL;
480     }
481
482   s = d = hwaddr;
483   do
484     {
485       if (*s != ':')
486         *d++ = *s;
487     }
488   while (*s++);
489
490   uargv[0] = name;
491   uargv[1] = hwaddr;
492   if ((stat = do_mr_query("update_host_hwaddr", 2, uargv, NULL, NULL)))
493     com_err(program_name, stat, " updating ethernet address.");
494
495   free(name);
496   free(hwaddr);
497   return DM_NORMAL;
498 }
This page took 0.074963 seconds and 5 git commands to generate.