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