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