]> andersk Git - moira.git/blob - clients/moira/utils.c
second code style cleanup: void/void * usage, proper #includes. try to
[moira.git] / clients / moira / utils.c
1 /* $Id $
2  *
3  *      This is the file utils.c for the Moira Client, which allows users
4  *      to quickly and easily maintain most parts of the Moira database.
5  *      It Contains:  Many useful utility functions.
6  *
7  *      Created:        4/25/88
8  *      By:             Chris D. Peterson
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 <netinet/in.h>
23 #include <arpa/inet.h>
24 #include <netdb.h>              /* for gethostbyname. */
25
26 #include <ctype.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <time.h>
31
32 RCSID("$Header$");
33
34 /*      Function Name: AddQueue
35  *      Description: Adds an element to a queue
36  *      Arguments: elem, pred - element and its predecessor.
37  *      Returns: none.
38  */
39
40 static void AddQueue(struct qelem *elem, struct qelem *pred)
41 {
42   if (!pred)
43     {
44       elem->q_forw = NULL;
45       elem->q_back = NULL;
46       return;
47     }
48   elem->q_back = pred;
49   elem->q_forw = pred->q_forw;
50   pred->q_forw = elem;
51 }
52
53 /*      Function Name: RemoveQueue
54  *      Description: removes an element from a queue.
55  *      Arguments: elem.
56  *      Returns: none.
57  */
58
59 static void RemoveQueue(struct qelem *elem)
60 {
61   if (elem->q_forw)
62     elem->q_forw->q_back = elem->q_back;
63   if (elem->q_back)
64     elem->q_back->q_forw = elem->q_forw;
65 }
66
67
68 /* CopyInfo: allocates memory for a copy of a NULL terminated array of
69  * strings <and returns a pointer to the copy.
70  */
71
72 char **CopyInfo(char **info)
73 {
74   char **ret;
75   int i;
76
77   ret = malloc(sizeof(char *) * (CountArgs(info) + 1));
78   if (!ret)
79     return ret;
80   for (i = 0; info[i]; i++)
81     ret[i] = strdup(info[i]);
82   ret[i] = NULL;
83   return ret;
84 }
85
86
87 /*      Function Name: FreeInfo
88  *      Description: Frees all elements of a NULL terminated arrary of char*'s
89  *      Arguments: info - array who's elements we are to free.
90  *      Returns: none.
91  */
92
93 void FreeInfo(char **info)
94 {
95   while (*info)
96     FreeAndClear(info++, TRUE);
97 }
98
99 /*      Function Name: FreeAndClear        - I couldn't resist the name.
100  *      Description: Clears pointer and optionially frees it.
101  *      Arguments: pointer - pointer to work with.
102  *                 free_it - if TRUE then free pointer.
103  *      Returns: none.
104  */
105
106 void FreeAndClear(char **pointer, Bool free_it)
107 {
108   if (!*pointer)
109     return;
110   else if (free_it)
111     free(*pointer);
112   *pointer = NULL;
113 }
114
115 /*      Function Name: QueueTop
116  *      Description: returns a qelem pointer that points to the top of
117  *                   a queue.
118  *      Arguments: elem - any element of a queue.
119  *      Returns: top element of a queue.
120  */
121
122 struct qelem *QueueTop(struct qelem *elem)
123 {
124   if (!elem)            /* NULL returns NULL.  */
125     return NULL;
126   while (elem->q_back)
127     elem = elem->q_back;
128   return elem;
129 }
130
131 /*      Function Name: FreeQueueElem
132  *      Description: Frees one element of the queue.
133  *      Arguments: elem - the elem to free.
134  *      Returns: none
135  */
136
137 static void FreeQueueElem(struct qelem *elem)
138 {
139   char **info = elem->q_data;
140
141   if (info)
142     {
143       FreeInfo(info); /* free info fields */
144       free(elem->q_data);               /* free info array itself. */
145     }
146   RemoveQueue(elem);            /* remove this element from the queue */
147   free(elem);                   /* free its space. */
148 }
149
150 /*      Function Name: FreeQueue
151  *      Description: Cleans up the queue
152  *      Arguments: elem - any element of the queue.
153  *      Returns: none.
154  */
155
156 void FreeQueue(struct qelem *elem)
157 {
158   struct qelem *temp, *local = QueueTop(elem);
159
160   while (local)
161     {
162       temp = local->q_forw;
163       FreeQueueElem(local);
164       local = temp;
165     }
166 }
167
168 /*      Function Name: QueueCount
169  *      Description: Counts the number of elements in a queue
170  *      Arguments: elem - any element in the queue.
171  *      Returns: none.
172  */
173
174 int QueueCount(struct qelem *elem)
175 {
176   int count = 0;
177   elem = QueueTop(elem);
178   while (elem)
179     {
180       count++;
181       elem = elem->q_forw;
182     }
183   return count;
184 }
185
186 /*      Function Name: StoreInfo
187  *      Description: Stores information from a moira query into a queue.
188  *      Arguments: argc, argv, - information returned from the query returned
189  *                               in argv.
190  *                 data - the previous element on the queue, this data will be
191  *                        stored in a qelem struct immediatly after this elem.
192  *                        If NULL then a new queue will be created.  This value
193  *                        is updated to the current element at the end off the
194  *                        call.
195  *      Returns: MR_CONT, or MR_ABORT if it has problems.
196  */
197
198 int StoreInfo(int argc, char **argv, void *data)
199 {
200   char **info = malloc(MAX_ARGS_SIZE * sizeof(char *));
201   struct qelem **old_elem = data;
202   struct qelem *new_elem = malloc(sizeof(struct qelem));
203   int count;
204
205   if (!new_elem || !info)
206     {
207       Put_message("Could Not allocate more memory.");
208       FreeQueue(*old_elem);
209       *old_elem = NULL;
210       return MR_ABORT;
211     }
212
213   for (count = 0; count < argc; count++)
214     info[count] = strdup(argv[count]);
215   info[count] = NULL;           /* NULL terminate this sucker. */
216
217   new_elem->q_data = info;
218   AddQueue(new_elem, *old_elem);
219
220   *old_elem = new_elem;
221   return MR_CONT;
222 }
223
224 /*      Function Name: CountArgs
225  *      Description:  Retrieve the number of args in a null terminated
226  *                     arglist.
227  *      Arguments: info - the argument list.
228  *      Returns: number if args in the list.
229  */
230
231 int CountArgs(char **info)
232 {
233   int number = 0;
234
235   while (*info)
236     {
237       number++;
238       info++;
239     }
240
241   return number;
242 }
243
244 /*      Function Name: PromptWithDefault
245  *      Description: allows a user to be prompted for input, and given a
246  *                   default choice.
247  *      Arguments: prompt - the prompt string.
248  *                 buf, buflen - buffer to be returned and its MAX size?
249  *                 default value for the answer.
250  *      Returns: zero on failure
251  */
252
253 int PromptWithDefault(char *prompt, char *buf, int buflen, char *def)
254 {
255   char tmp[BUFSIZ];
256   int ans;
257
258   if (parsed_argc > 0)
259     {
260       parsed_argc--;
261       strncpy(buf, parsed_argv[0], buflen);
262       sprintf(tmp, "%s: %s", prompt, buf);
263       Put_message(tmp);
264       parsed_argv++;
265       return 1;
266     }
267
268   sprintf(tmp, "%s [%s]: ", prompt, def ? def : "");
269   ans = Prompt_input(tmp, buf, buflen);
270   if (IS_EMPTY(buf))
271     strcpy(buf, def);
272   else if (!strcmp(buf, "\"\""))
273     *buf = 0;
274   return ans;
275 }
276
277 /*      Function Name: YesNoQuestion
278  *      Description: This prompts the user for the answer to a yes-no or
279  *                   true-false question.
280  *      Arguments: prompt - the prompt for the user.
281  *                 bool_def - the default value either TRUE or FALSE.
282  *      Returns: TRUE or FALSE or -1 on error
283  */
284
285 Bool YesNoQuestion(char *prompt, int bool_def)
286 {
287   char ans[2];
288
289   while (TRUE)
290     {
291       if (!PromptWithDefault(prompt, ans, 2, bool_def ? "y" : "n"))
292         return -1;
293       switch (ans[0])
294         {
295         case 'n':
296         case 'N':
297           return FALSE;
298         case 'y':
299         case 'Y':
300           return TRUE;
301         default:
302           Put_message("Please answer 'y' or 'n'.");
303           break;
304         }
305     }
306 }
307
308 /*      Function Name: YesNoQuitQuestion
309  *      Description: This prompts the user for the answer to a yes-no or
310  *                   true-false question, with a quit option.
311  *      Arguments: prompt - the prompt for the user.
312  *                 bool_def - the default value either TRUE or FALSE.
313  *      Returns: TRUE or FALSE or -1 on error or QUIT
314  *      NOTE: It is not possible to have quit the default, but then I don't
315  *            seem to need this functionality.
316  */
317
318 Bool YesNoQuitQuestion(char *prompt, int bool_def)
319 {
320   char ans[2];
321
322   while (TRUE)
323     {
324       if (!PromptWithDefault(prompt, ans, 2, bool_def ? "y" : "n"))
325         return -1;
326       switch (ans[0])
327         {
328         case 'n':
329         case 'N':
330           return FALSE;
331         case 'y':
332         case 'Y':
333           return TRUE;
334         case 'q':
335         case 'Q':
336           return -1;
337         default:
338           Put_message("Please answer 'y', 'n' or 'q'.");
339           break;
340         }
341     }
342 }
343
344 /*      Function Name: Confirm
345  *      Description:   This function asks the user to confirm the action
346  *                     he is about to take, used for things like deleting.
347  *      Arguments: prompt - the prompt string.
348  *      Returns:   TRUE/FALSE - wether or not the confirmation occured.
349  */
350
351 Bool Confirm(char *prompt)
352 {
353   return !verbose || (YesNoQuestion(prompt, FALSE) == TRUE);
354 }
355
356 /*      Function Name: ValidName
357  *      Description: This function checks to see if we have a valid list name.
358  *      Arguments: s - the list name.
359  *      Returns: TRUE if Valid.
360  */
361
362 Bool ValidName(char *s)
363 {
364   if (IS_EMPTY(s))
365     Put_message("Please use a non-empty name.");
366   else if (strchr(s, ' '))
367     Put_message("You cannot use space (' ') in this name.");
368   else if (strchr(s, '*') || strchr(s, '?'))
369     Put_message("Wildcards not accepted here.");
370   else
371     return TRUE;
372   return FALSE;
373 }
374
375 /*      Function Name: ToggleVerboseMode
376  *      Description: This function toggles the verbose mode.
377  *      Arguments: none
378  *      Returns: DM_NORMAL.
379  */
380
381 int ToggleVerboseMode(int argc, char **argv)
382 {
383   verbose = !verbose;
384
385   if (verbose)
386     Put_message("Delete functions will first confirm\n");
387   else
388     Put_message("Delete functions will be silent\n");
389
390   return DM_NORMAL;
391 }
392
393 /*      Function Name: SlipInNewName
394  *      Description: Slips the new name into the number 2 slot of a list, and
395  *                   returns a pointer to the new list.
396  *      Arguments: info - list that needs this name slipped into it.
397  *                 name - the name to slip into the list.
398  *      Returns: a pointer to the new list.
399  *      NOTE:  This screws up the numbers of the elements of the array in a
400  *             big way.
401  */
402
403 void SlipInNewName(char **info, char *name)
404 {
405   int i;
406
407   /* This also pushes the NULL down. */
408   for (i = CountArgs(info); i > 0; i--)
409     info[i + 1] = info[i];
410   info[1] = name;       /* now slip in the name. */
411 }
412
413 /*      Function Name: GetValueFromUser
414  *      Description: This function gets a value from a user for the field
415  *                   specified.
416  *      Arguments: prompt - prompt for user.
417  *                 pointer - pointer to default value, will be returned
418  *                          as new value.
419  *      Returns: SUB_ERROR if break hit (^C).
420  */
421
422 int GetValueFromUser(char *prompt, char **pointer)
423 {
424   char buf[BUFSIZ];
425
426   if (PromptWithDefault(prompt, buf, BUFSIZ, *pointer) == 0)
427     return SUB_ERROR;
428
429   /*
430    * If these are the same then there is no need to allocate a new string.
431    *
432    * a difference that makes no difference, IS no difference.
433    */
434
435   if (*pointer)
436     {
437       if (strcmp(buf, *pointer))
438         {
439           free(*pointer);
440           *pointer = strdup(buf);
441         }
442     }
443   return SUB_NORMAL;
444 }
445
446 /*      Function Name: GetYesNoValueFromUser
447  *      Description: This function gets a value from a user for the field
448  *                   specified.
449  *      Arguments: prompt - prompt for user.
450  *                 pointer - pointer to default value, will be returned
451  *                          as new value.
452  *      Returns: SUB_ERROR if break hit (^C).
453  */
454
455 int GetYesNoValueFromUser(char *prompt, char **pointer)
456 {
457   char user_prompt[BUFSIZ];
458   Bool default_val;
459
460   if (!strcmp(*pointer, DEFAULT_YES))
461     default_val = TRUE;
462   else
463     default_val = FALSE;
464
465   sprintf(user_prompt, "%s (y/n)", prompt);
466
467   switch (YesNoQuestion(user_prompt, default_val))
468     {
469     case TRUE:
470       if (*pointer)
471         free(*pointer);
472       *pointer = strdup(DEFAULT_YES);
473       break;
474     case FALSE:
475       if (*pointer)
476         free(*pointer);
477       *pointer = strdup(DEFAULT_NO);
478       break;
479     case -1:
480     default:
481       return SUB_ERROR;
482     }
483   return SUB_NORMAL;
484 }
485
486 /*      Function Name: GetFSVal
487  *      Description: asks about a specific filesystem value.
488  *      Arguments: name - string for this type of filesystem.
489  *                 mask - mask for this type of filesystem.
490  *                 current - current filesystem state. (for defaults).
491  *                 new - new filesystem state.
492  *      Returns: TRUE if successful.
493  */
494
495 static Bool GetFSVal(char *name, int mask, int current, int *new)
496 {
497   char temp_buf[BUFSIZ];
498   sprintf(temp_buf, "Is this a %s filsystem", name);
499   switch (YesNoQuestion(temp_buf, ((mask & current) == mask)))
500     {
501     case TRUE:
502       *new |= mask;
503       break;
504     case FALSE:
505       break;                    /* zero by default. */
506     default:
507       return FALSE;
508     }
509   return TRUE;
510 }
511
512 /*      Function Name: GetFSTypes
513  *      Description: Allows user to specify filsystem types.
514  *      Arguments: current - current value of filsystem, freed here.
515  *      Returns: SUB_ERROR on ^C.
516  */
517
518 int GetFSTypes(char **current, int options)
519 {
520   int c_value, new_val = 0;     /* current value of filesys type (int). */
521   char ret_value[BUFSIZ];
522
523   if (!*current)
524     c_value = 0;
525   else
526     c_value = atoi(*current);
527
528   if (GetFSVal("student", MR_FS_STUDENT, c_value, &new_val) == FALSE)
529     return SUB_ERROR;
530   if (GetFSVal("faculty", MR_FS_FACULTY, c_value, &new_val) == FALSE)
531     return SUB_ERROR;
532   if (GetFSVal("staff", MR_FS_STAFF, c_value, &new_val) == FALSE)
533     return SUB_ERROR;
534   if (GetFSVal("miscellaneous", MR_FS_MISC, c_value, &new_val) == FALSE)
535     return SUB_ERROR;
536   if (options)
537     {
538       if (GetFSVal("Group Quotas", MR_FS_GROUPQUOTA, c_value, &new_val) ==
539           FALSE)
540         return SUB_ERROR;
541     }
542
543   FreeAndClear(current, TRUE);
544   sprintf(ret_value, "%d", new_val);
545   *current = strdup(ret_value);
546   return SUB_NORMAL;
547 }
548
549 /* atot: convert ASCII integer unix time into human readable date string */
550
551 char *atot(char *itime)
552 {
553   time_t time;
554   char *ct;
555
556   time = (time_t) atoi(itime);
557   ct = ctime(&time);
558   ct[24] = 0;
559   return &ct[4];
560 }
561
562
563 /*      Function Name: Print
564  *      Description: prints out all the arguments on a single line.
565  *      Arguments: argc, argv - the standard Moira arguments.
566  *                 callback - the callback function - NOT USED.
567  *      Returns: MR_CONT
568  */
569
570 int Print(int argc, char **argv, void *callback)
571 {
572   char buf[BUFSIZ];
573   int i;
574
575   found_some = TRUE;
576   strcpy(buf, argv[0]); /* no newline 'cause Put_message adds one */
577   for (i = 1; i < argc; i++)
578     sprintf(buf, "%s %s", buf, argv[i]);
579   Put_message(buf);
580
581   return MR_CONT;
582 }
583
584 /*      Function Name: PrintByType
585  *      Description: This function prints all members of the type specified
586  *                   by the callback arg, unless the callback is NULL, in which
587  *                   case it prints all members.
588  *      Arguments: argc, argc - normal arguments for mr_callback function.
589  *                 callback - either a type of member or NULL.
590  *      Returns: MR_CONT or MR_QUIT.
591  */
592
593 int PrintByType(int argc, char **argv, void *callback)
594 {
595   if (!callback)
596     return Print(argc, argv, callback);
597   if (!strcmp(argv[0], callback))
598     return Print(argc, argv, callback);
599   return MR_CONT;
600 }
601
602 /*      Function Name: PrintHelp
603  *      Description: Prints Help Information in a NULL terminated
604  *                   char **.
605  *      Arguments: message.
606  *      Returns: DM_NORMAL.
607  */
608
609 int PrintHelp(char **message)
610 {
611   int i;
612
613   for (i = 0; i < CountArgs(message); i++)
614     Put_message(message[i]);
615
616   return DM_NORMAL;
617 }
618
619 /*      Function Name: Loop
620  *      Description: This function goes through the entire queue, and
621  *                   and executes the given function on each element.
622  *      Arguments: elem - top element of the queue.
623  *                 func - the function to execute.
624  *      Returns: none.
625  */
626
627 void Loop(struct qelem *elem, void (*func)(char **))
628 {
629   while (elem)
630     {
631       (*func) (elem->q_data);
632       elem = elem->q_forw;
633     }
634 }
635
636
637 /*      Function Name: QueryLoop
638  *      Description: This functions loops through a queue containing
639  *                   information about some item that we want to perform
640  *                   an operation on, and then calls the correct routine
641  *                   perform that operation.
642  *      Arguments: top - top of the queue of information.
643  *                 print_func - print function.
644  *                 op_function - operation to be performed.
645  *                 query_string - string the prompts the user whether or not
646  *                                to perform this operation.
647  *      Returns: none.
648  *      NOTES:
649  *               print_opt - should expect one arguent, the info array
650  *                           of char *'s.
651  *                           is expected to return the name of the item.
652  *               op_func   - should expect two arguments.
653  *                           1) the info array of char *'s.
654  *                           2) a boolean the is true if there only
655  *                              one item in this queue, used for delete
656  *                              confirmation.
657  *               query_string - this should be of such a form that when the
658  *                              name of the object and '(y/n/q) ?' are appended
659  *                              then it should still make sense, an example is
660  *                              "Delete the list"
661  */
662
663 void QueryLoop(struct qelem *elem, char * (*print_func)(char **),
664                void (*op_func)(char **, Bool), char *query_string)
665 {
666   Bool one_item;
667   char temp_buf[BUFSIZ], *name;
668
669   elem = QueueTop(elem);
670   one_item = (QueueCount(elem) == 1);
671   while (elem)
672     {
673       char **info = elem->q_data;
674
675       if (one_item)
676         (*op_func) (info, one_item);
677       else
678         {
679           name = (*print_func) (info); /* call print function. */
680           sprintf(temp_buf, "%s %s (y/n/q)", query_string, name);
681           switch (YesNoQuitQuestion(temp_buf, FALSE))
682             {
683             case TRUE:
684               (*op_func) (info, one_item);
685               break;
686             case FALSE:
687               break;
688             default:            /* Quit. */
689               Put_message("Aborting...");
690               return;
691             }
692         }
693       elem = elem->q_forw;
694     }
695 }
696
697 /*      Function Name: NullPrint
698  *      Description: print function that returns nothing.
699  *      Arguments: info - a pointer to the info array - Not used.
700  *      Returns: none.
701  */
702
703 char *NullPrint(char **info)
704 {
705   return info[NAME];
706 }
707
708
709 /*      Function Name: GetTypeValues
710  *      Description: gets legal values for a typed object, keeping a cache
711  *      Arguments: type name
712  *      Returns: argv of values
713  */
714
715 struct qelem *GetTypeValues(char *tname)
716 {
717   int stat;
718   char *argv[3], *p, **pp;
719   struct qelem *elem, *oelem;
720   static struct qelem *cache = NULL;
721   struct cache_elem {
722     char *cache_name;
723     struct qelem *cache_data;
724   } *ce;
725
726   for (elem = cache; elem; elem = elem->q_forw)
727     {
728       ce = elem->q_data;
729       if (!strcmp(ce->cache_name, tname))
730         return ce->cache_data;
731     }
732
733   argv[0] = tname;
734   argv[1] = "TYPE";
735   argv[2] = "*";
736   elem = NULL;
737   if ((stat = do_mr_query("get_alias", 3, argv, StoreInfo, &elem)))
738     {
739       com_err(program_name, stat, " in GetTypeValues");
740       return NULL;
741     }
742   oelem = elem;
743   for (elem = QueueTop(elem); elem; elem = elem->q_forw)
744     {
745       pp = elem->q_data;
746       p = strdup(pp[2]);
747       FreeInfo(pp);
748       elem->q_data = p;
749     }
750   elem = malloc(sizeof(struct qelem));
751   ce = malloc(sizeof(struct cache_elem));
752   ce->cache_name = strdup(tname);
753   ce->cache_data = QueueTop(oelem);
754   elem->q_data = ce;
755   AddQueue(elem, cache);
756   cache = QueueTop(elem);
757   return ce->cache_data;
758 }
759
760
761 /*      Function Name: GetTypeFromUser
762  *      Description: gets a typed value from the user
763  *      Arguments: prompt string, type name, buffer pointer
764  *      Returns: SUB_ERROR if ^C, SUB_NORMAL otherwise
765  */
766
767 int GetTypeFromUser(char *prompt, char *tname, char **pointer)
768 {
769   char def[BUFSIZ], buffer[BUFSIZ], *p, *argv[3];
770   struct qelem *elem;
771   int stat;
772
773   strcpy(def, *pointer);
774   strcpy(buffer, prompt);
775   strcat(buffer, " (");
776   for (elem = GetTypeValues(tname); elem; elem = elem->q_forw)
777     {
778       strcat(buffer, elem->q_data);
779       if (elem->q_forw)
780         strcat(buffer, ", ");
781     }
782   strcat(buffer, ")");
783   if (strlen(buffer) > 64)
784     sprintf(buffer, "%s (? for help)", prompt);
785   if (GetValueFromUser(buffer, pointer) == SUB_ERROR)
786     return SUB_ERROR;
787   if (**pointer == '?')
788     {
789       sprintf(buffer, "Type %s is one of:", tname);
790       Put_message(buffer);
791       for (elem = GetTypeValues(tname); elem; elem = elem->q_forw)
792         Put_message(elem->q_data);
793       *pointer = strdup(def);
794       return GetTypeFromUser(prompt, tname, pointer);
795     }
796   for (elem = GetTypeValues(tname); elem; elem = elem->q_forw)
797     {
798       if (!strcasecmp(elem->q_data, *pointer))
799         {
800           strcpy(*pointer, elem->q_data);
801           return SUB_NORMAL;
802         }
803     }
804   sprintf(buffer, "\"%s\" is not a legal value for %s.  Use one of:",
805           *pointer, tname);
806   Put_message(buffer);
807   for (elem = GetTypeValues(tname); elem; elem = elem->q_forw)
808     Put_message(elem->q_data);
809   sprintf(buffer, "Are you sure you want \"%s\" to be a legal %s",
810           *pointer, tname);
811   if (YesNoQuestion("Do you want this to be a new legal value", 0) == TRUE &&
812       YesNoQuestion(buffer, 0) == TRUE)
813     {
814       argv[0] = tname;
815       argv[1] = "TYPE";
816       argv[2] = *pointer;
817       /* don't uppercase access flags.  Do uppercase everything else */
818       if (strncmp(tname, "fs_access", 9))
819         {
820           for (p = argv[2]; *p; p++)
821             {
822               if (islower(*p))
823                 *p = toupper(*p);
824             }
825         }
826       if ((stat = do_mr_query("add_alias", 3, argv, NULL, NULL)))
827         com_err(program_name, stat, " in add_alias");
828       else
829         {
830           elem = malloc(sizeof(struct qelem));
831           elem->q_data = strdup(*pointer);
832           AddQueue(elem, GetTypeValues(tname));
833           Put_message("Done.");
834         }
835     }
836   *pointer = strdup(def);
837   return GetTypeFromUser(prompt, tname, pointer);
838 }
839
840
841 /*      Function Name: GetAddressFromUser
842  *      Description: gets an IP address from the user
843  *      Arguments: prompt string, buffer pointer
844  *              buffer contains default value as long int
845  *      Returns: SUB_ERROR if ^C, SUB_NORMAL otherwise
846  */
847
848 int GetAddressFromUser(char *prompt, char **pointer)
849 {
850   char *value, buf[256];
851   struct in_addr addr;
852   int ret;
853
854   addr.s_addr = htonl(atoi(*pointer));
855   value = strdup(inet_ntoa(addr));
856   ret = GetValueFromUser(prompt, &value);
857   if (ret == SUB_ERROR)
858     return SUB_ERROR;
859   addr.s_addr = inet_addr(value);
860   free(pointer);
861   sprintf(buf, "%ld", ntohl(addr.s_addr));
862   *pointer = strdup(buf);
863   return SUB_NORMAL;
864 }
865
866
867 int do_mr_query(char *name, int argc, char **argv,
868                 int (*proc)(int, char **, void *), void *hint)
869 {
870   int status;
871   extern char *whoami, *moira_server;
872
873   refresh_screen();
874   status = mr_query(name, argc, argv, proc, hint);
875   if (status != MR_ABORTED && status != MR_NOT_CONNECTED)
876     return status;
877   status = mr_connect(moira_server);
878   if (status)
879     {
880       com_err(whoami, status, " while re-connecting to server %s",
881               moira_server);
882       return MR_ABORTED;
883     }
884   status = mr_auth(whoami);
885   if (status)
886     {
887       com_err(whoami, status, " while re-authenticating to server %s",
888               moira_server);
889       mr_disconnect();
890       return MR_ABORTED;
891     }
892   status = mr_query(name, argc, argv, proc, hint);
893   return status;
894 }
895
This page took 0.200566 seconds and 5 git commands to generate.