]> andersk Git - moira.git/blob - clients/moira/utils.c
This version while still untested compiles and links almost
[moira.git] / clients / moira / utils.c
1 #ifndef lint
2   static char rcsid_module_c[] = "$Header$";
3 #endif lint
4
5 /*      This is the file utils.c for allmaint, the SMS client that allows
6  *      a user to maintaint most important parts of the SMS database.
7  *      It Contains: Many utilities used by allmaint.
8  *      
9  *      Created:        4/25/88
10  *      By:             Chris D. Peterson
11  *
12  *      $Source$
13  *      $Author$
14  *      $Header$
15  *      
16  *      Copyright 1987, 1988 by the Massachusetts Institute of Technology.
17  *
18  *      For further information on copyright and distribution 
19  *      see the file mit-copyright.h
20  */
21
22
23 #include <stdio.h>
24 #include <strings.h>
25 #include <sms.h>
26 #include <menu.h>
27
28 #include "mit-copyright.h"
29 #include "allmaint.h"
30 #include "allmaint_funcs.h"
31 #include "globals.h"
32 #include "infodefs.h"
33
34 #include <netdb.h>              /* for gethostbyname. */
35 /* #include <ctype.h> */
36 /* #include <varargs.h> */
37 /* #include <sys/types.h> */
38
39 /*      Function Name: FreeInfo
40  *      Description: Frees all elements of a NULL terminated arrary of char*'s
41  *      Arguments: info - array who's elements we are to free.
42  *      Returns: none.
43  */
44
45 void
46 FreeInfo(info)
47 char ** info;
48 {
49     char *pointer = *info;
50     while (pointer != NULL) 
51         free(pointer++);
52 }
53
54 /*      Function Name: FreeAndClear        - I couldn't resist the name.
55  *      Description: Clears pointer and optionially frees it.
56  *      Arguments: pointer - pointer to work with.
57  *                 free_it - if TRUE then free pointer.
58  *      Returns: none.
59  */
60
61 void
62 FreeAndClear(pointer, free_it)
63 char ** pointer;
64 Bool free_it;
65 {
66     if (*pointer == NULL)
67         return;
68     else if (free_it)
69         free(*pointer);
70     *pointer = NULL;
71 }
72
73 /*      Function Name: QueueTop
74  *      Description: returns a qelem pointer that points to the top of
75  *                   a queue.
76  *      Arguments: elem - any element of a queue.
77  *      Returns: top element of a queue.
78  */
79     
80 struct qelem * 
81 QueueTop(elem)
82 struct qelem * elem;
83 {
84     if (elem == NULL)           /* NULL returns NULL.  */
85         return(NULL);
86     while (elem->q_back != NULL) 
87         elem = elem->q_back;
88     return(elem);
89 }
90
91 /*      Function Name: FreeQueueElem
92  *      Description: Frees one element of the queue.
93  *      Arguments: elem - the elem to free.
94  *      Returns: none
95  */
96
97 void
98 FreeQueueElem(elem)
99 struct qelem * elem;
100 {
101     char ** info = (char **) elem->q_data;
102
103     if (info != (char **) NULL) {
104         FreeInfo( info ); /* free info fields */
105         free(elem->q_data);             /* free info array itself. */
106     }
107     remque(elem);               /* remove this element from the queue */
108     free(elem);                 /* free its space. */
109 }
110
111 /*      Function Name: FreeQueue
112  *      Description: Cleans up the queue
113  *      Arguments: elem - any element of the queue.
114  *      Returns: none.
115  */
116
117 void
118 FreeQueue(elem)
119 struct qelem * elem;
120 {
121     struct qelem *temp, *local = QueueTop(elem); 
122
123     while(local != NULL) {
124         temp = local->q_forw;
125         FreeQueueElem(local);
126         local = temp;
127     }
128 }
129
130 /*      Function Name: QueueCount
131  *      Description: Counts the number of elements in a queue
132  *      Arguments: elem - any element in the queue.
133  *      Returns: none.
134  */
135
136 int
137 QueueCount(elem)
138 struct qelem * elem;
139 {
140     int count = 0;
141     elem = QueueTop(elem);
142     while (elem != NULL) {
143         count ++;
144         elem = elem->q_forw;
145     }
146     return(count);
147 }
148
149 /* ARGSUSED */
150 int
151 StoreInfo(argc, argv, data)
152 int argc;
153 char ** argv;
154 char * data;
155 {
156     char ** info = (char **) malloc( MAX_ARGS_SIZE * sizeof(char *) );
157     struct qelem ** old_elem = (struct qelem **) data;
158     struct qelem * new_elem = (struct qelem *) malloc (sizeof (struct qelem));
159     int count;
160
161     for (count = 0; count < argc; count++)
162         info[count] = Strsave(argv[count]);
163     info[count] = NULL;         /* NULL terminate this sucker. */
164
165     if (*old_elem == (struct qelem *) NULL) {    /* first elem. */
166         new_elem->q_data = (char *) info;
167         new_elem->q_forw = new_elem->q_back = (struct qelem *) NULL;
168     }
169     else {                      /* all other elements. */
170         new_elem->q_data = (char *) info;
171         insque(new_elem, *old_elem);
172     }
173
174     *old_elem = new_elem;
175     return(SMS_CONT);
176 }
177
178 /*      Function Name: CountArgs
179  *      Description:  Retrieve the number of args in a null terminated
180  *                     arglist.
181  *      Arguments: info - the argument list.
182  *      Returns: number if args in the list.
183  */
184
185 int
186 CountArgs(info)
187 char ** info;
188 {
189     int number = 0;
190     
191     while (*info != NULL) {
192         number++;
193         info++;
194     }
195
196     return(number);
197 }    
198
199 /*      Function Name: Scream
200  *      Description: Bitch Loudly and exit, it is intended as a callback
201  *                   function for queries that should never return a value.
202  *      Arguments: none
203  *      Returns: doesn't exit.
204  */
205
206 int
207 Scream()
208 {
209     com_err(program_name, 0,
210             "\nAn SMS update returned a value -- programmer botch\n");
211     sms_disconnect();
212     exit(1);
213 }
214
215 /*      Function Name: PromptWithDefault
216  *      Description: allows a user to be prompted for input, and given a 
217  *                   default choice.
218  *      Arguments: prompt - the prompt string.
219  *                 buf, buflen - buffer to be returned and its MAX size?
220  *                 default value for the answer.
221  *      Returns: the value returned by prompt_input.
222  */
223
224 int
225 PromptWithDefault(prompt, buf, buflen, def)
226 char *prompt, *buf;
227 int buflen;
228 char *def;
229 {
230     char tmp[BUFSIZ];
231     int ans;
232
233     (void) sprintf(tmp, "%s [%s]: ", prompt, def ? def : "");
234     ans = Prompt_input(tmp, buf, buflen);
235     if (IS_EMPTY(buf))
236         (void) strcpy(buf, def);
237     return(ans);
238 }
239
240 /*      Function Name: YesNoQuestion
241  *      Description: This prompts the user for the answer to a yes-no or
242  *                   true-false question.
243  *      Arguments: prompt - the prompt for the user.
244  *                 bool_def - the default value either TRUE or FALSE.
245  *      Returns: TRUE or FALSE or -1 on error
246  */
247
248 Bool
249 YesNoQuestion(prompt, bool_def)
250 char *prompt;
251 int bool_def;
252 {
253     char ans;
254
255     while (TRUE) {
256         if (!PromptWithDefault(prompt, &ans, 1, bool_def ? "y" : "n"))
257             return(-1);
258         switch (ans) {
259         case 'n':
260         case 'N':
261             return(FALSE);
262         case 'y':
263         case 'Y':
264             return(TRUE);
265         default:
266             Put_message("Please answer 'y' or 'n'.");
267             break;
268         }
269     }
270 }
271 /*      Function Name: YesNoQuitQuestion
272  *      Description: This prompts the user for the answer to a yes-no or
273  *                   true-false question, with a quit option.
274  *      Arguments: prompt - the prompt for the user.
275  *                 bool_def - the default value either TRUE or FALSE.
276  *      Returns: TRUE or FALSE or -1 on error or QUIT
277  *      NOTE: It is not possible to have quit the default, but then I don't
278  *            seem to need this functionality.
279  */
280
281 Bool
282 YesNoQuitQuestion(prompt, bool_def)
283 char *prompt;
284 int bool_def;
285 {
286     char ans;
287
288     while (TRUE) {
289         if (!PromptWithDefault(prompt, &ans, 1, bool_def ? "y" : "n"))
290             return(-1);
291         switch (ans) {
292         case 'n':
293         case 'N':
294             return(FALSE);
295         case 'y':
296         case 'Y':
297             return(TRUE);
298         case 'q':
299         case 'Q':
300             return(-1);
301         default:
302             Put_message("Please answer 'y', 'n' or 'q'.");
303             break;
304         }
305     }
306 }
307
308 /*      Function Name: Confirm
309  *      Description:   This function asks the user to confirm the action
310  *                     he is about to take, used for things like deleting.
311  *      Arguments: prompt - the prompt string.
312  *      Returns:   TRUE/FALSE - wether or not the confirmation occured.
313  */
314
315 int
316 Confirm(prompt)
317 char * prompt;
318 {
319   return( ~verbose || YesNoQuestion(prompt,FALSE) );
320 }
321
322 /*      Function Name: ValidName
323  *      Description: This function checks to see if we have a valid list name.
324  *      Arguments: s - the list name.
325  *      Returns: TRUE if Valid.
326  */
327
328 Bool
329 ValidName(s)
330     char *s;
331 {
332     if (IS_EMPTY(s))
333         Put_message("Please use a non-empty name.");
334     else if (index(s, ' '))
335         Put_message("You cannot use space (' ') in this name.");
336     else
337         return TRUE;
338     return FALSE;
339 }
340
341 /*      Function Name: ToggleVerboseMode
342  *      Description: This function toggles the verbose mode.
343  *      Arguments: none
344  *      Returns: DM_NORMAL.
345  */
346
347 int 
348 ToggleVerboseMode()
349 {
350
351   verbose = ~verbose;
352
353   if (verbose)
354     Put_message("Delete functions will first confirm\n");
355   else
356     Put_message("Delete functions will be silent\n");
357     
358   return(DM_NORMAL);
359 }
360
361 /*      Function Name: NullFunc
362  *      Description:  dummy callback routine 
363  *      Arguments: none
364  *      Returns: SMS_CONT
365  */
366
367 int
368 NullFunc()
369 {
370     return(SMS_CONT);
371 }
372
373 /*      Function Name: SlipInNewName
374  *      Description: Slips the new name into the number 2 slot of a list, and
375  *                   returns a pointer to the new list.
376  *      Arguments: info - list that needs this name slipped into it.
377  *                 name - the name to slip into the list.
378  *      Returns: a pointer to the new list.
379  *      NOTE:  This screws up the numbers if the elements of the array in a
380  *             big way.
381  */
382
383 SlipInNewName(info, name)
384 char ** info;
385 char * name;
386 {
387     register int i;
388
389     /* This also pushes the NULL down. */
390     for (i = CountArgs(info); i > 1; i--) { 
391         info[i+i] = info[i];
392     }
393     info[1] = Strsave(name);    /* now slip in the name. */
394 }
395
396 /*      Function Name: GetValueFromUser
397  *      Description: This function gets a value from a user for the field
398  *                   specified.
399  *      Arguments: prompt - prompt for user.
400  *                 pointer - pointer to default value, will be returned
401  *                          as new value.
402  *      Returns: none.
403  */
404
405 void
406 GetValueFromUser(prompt, pointer)
407 char * prompt, ** pointer;
408 {
409     char buf[BUFSIZ];
410
411     PromptWithDefault(prompt, buf, BUFSIZ, *pointer);
412     if ( pointer != NULL)
413         free(*pointer);
414     *pointer = Strsave(buf);
415 }
416
417 /*      Function Name: CanonicalizeHostname
418  *      Description: This function takes a machine name and canonicalize's it.
419  *      Arguments: machine - name of the machine to work on.
420  *      Returns: new name or NULL if nameserver returns error
421  */
422
423 char *
424 CanonicalizeHostname(machine)
425 char *machine;
426 {
427     struct hostent *hostinfo;
428
429     hostinfo = gethostbyname(machine);
430     if (hostinfo != (struct hostent *) NULL)
431         machine = hostinfo->h_name;
432     else                        
433 /*
434  *  gethostbyname failed.  This should be very rare, since we're
435  *  dealing with local hosts, so no fancy error recovery. 
436  */
437         machine = (char *) NULL;
438     return (machine);
439 }
440
441 /*      Function Name: Strsave
442  *      Description: save a string.
443  *      Arguments: string  - the string to save.
444  *      Returns: The malloced string, now safely saved, or NULL.
445  */
446
447 char *
448 Strsave(str)
449 char *str;
450 {
451     register char *newstr = malloc((unsigned) strlen(str) + 1);
452
453     if (newstr == (char *) NULL)
454         return ((char *) NULL);
455     else
456         return (strcpy(newstr, str));
457 }
458
459 /*      Function Name: EncryptMITID
460  *      Description: Encrypts an mit ID number. 
461  *      Arguments: sbuf - the buffer to return the encrypted number in.
462  *                 idnumber - the id number (string).
463  *                 first, last - name of the person.
464  *      Returns: none.
465  */
466
467 void
468 EncryptMITID(sbuf, idnumber, first, last)
469 char *sbuf, *idnumber, *first, *last;
470 {
471     char salt[3];
472     extern char *crypt();
473
474 #define _tolower(c) ((c)|0x60)
475
476     salt[0] = _tolower(last[0]);
477     salt[1] = _tolower(first[0]);
478     salt[2] = 0;
479
480     (void) strcpy(sbuf, crypt(&idnumber[2], salt));
481 }
482
483 /*      Function Name: RemoveHyphens
484  *      Description: Removes all hyphens from the string passed to it.
485  *      Arguments: str - the string to remove the hyphes from
486  *      Returns: none
487  */
488
489 void
490 RemoveHyphens(str)
491 char *str;
492 {
493     char *hyphen;
494
495     while ((hyphen = index(str, '-')) != NULL)
496         (void) strcpy(hyphen, hyphen + 1);
497 }
498
499 /*      Function Name: Print
500  *      Description: prints out all the arguments on a single line.
501  *      Arguments: argc, argv - the standard SMS arguments.
502  *                 callback - the callback function - NOT USED.
503  *      Returns: SMS_CONT
504  */
505
506 /* ARGSUSED */
507 int
508 Print(argc, argv, callback)
509 int argc;
510 char **argv, *callback;
511 {
512     char buf[BUFSIZ];
513     register int i;
514
515     found_some = TRUE;
516     (void) strcpy(buf,argv[0]); /* no newline 'cause Put_message adds one */
517     for (i = 1; i < argc; i++)
518         (void) sprintf(buf,"%s %s",buf,argv[i]);
519     (void) Put_message(buf);
520
521     return (SMS_CONT);
522 }
523
524 /*      Function Name: PrintByType
525  *      Description: This function prints all members of the type specified
526  *                   by the callback arg, unless the callback is NULL, in which
527  *                   case it prints all members.
528  *      Arguments: argc, argc - normal arguments for sms_callback function. 
529  *                 callback - either a type of member or NULL.
530  *      Returns: SMS_CONT or SMS_QUIT.
531  */
532
533 /*ARGSUSED*/
534 int
535 PrintByType(argc, argv, callback)
536 int argc;
537 char **argv, *callback;
538 {
539     if (callback == NULL)
540         return( Print(argc, argv, callback) );
541     if (strcmp(argv[0], callback) == 0) 
542         return( Print(1, argv + 1, callback) );
543     return(SMS_CONT);
544 }
545
546 /*      Function Name: PrintHelp
547  *      Description: Prints Help Information in a NULL terminated
548  *                   char **.
549  *      Arguments: message.
550  *      Returns: DM_NORMAL.
551  */
552
553 int
554 PrintHelp(message)
555 char ** message;
556 {
557     Print(CountArgs(message), message, (char *) NULL);
558     return(DM_NORMAL);
559 }
560
561 /*
562  * Local Variables:
563  * mode: c
564  * c-indent-level: 4
565  * c-continued-statement-offset: 4
566  * c-brace-offset: -4
567  * c-argdecl-indent: 4
568  * c-label-offset: -4
569  * End:
570  */
This page took 0.091561 seconds and 5 git commands to generate.