]> andersk Git - moira.git/blame - clients/moira/utils.c
second code style cleanup: void/void * usage, proper #includes. try to
[moira.git] / clients / moira / utils.c
CommitLineData
7ac48069 1/* $Id $
2 *
3 * This is the file utils.c for the Moira Client, which allows users
59ec8dae 4 * to quickly and easily maintain most parts of the Moira database.
0a2c64cb 5 * It Contains: Many useful utility functions.
5eaef520 6 *
08345b74 7 * Created: 4/25/88
8 * By: Chris D. Peterson
9 *
7ac48069 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>.
08345b74 13 */
14
7ac48069 15#include <mit-copyright.h>
8defc06b 16#include <moira.h>
17#include <moira_site.h>
0a2c64cb 18#include "defs.h"
19#include "f_defs.h"
08345b74 20#include "globals.h"
7ac48069 21
ccce9c6a 22#include <netinet/in.h>
7798ebc3 23#include <arpa/inet.h>
7ac48069 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>
ccce9c6a 31
7ac48069 32RCSID("$Header$");
08345b74 33
0a2c64cb 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
5eaef520 40static void AddQueue(struct qelem *elem, struct qelem *pred)
0a2c64cb 41{
5eaef520 42 if (!pred)
43 {
44 elem->q_forw = NULL;
45 elem->q_back = NULL;
46 return;
0a2c64cb 47 }
5eaef520 48 elem->q_back = pred;
49 elem->q_forw = pred->q_forw;
50 pred->q_forw = elem;
0a2c64cb 51}
52
53/* Function Name: RemoveQueue
54 * Description: removes an element from a queue.
55 * Arguments: elem.
56 * Returns: none.
57 */
58
5eaef520 59static void RemoveQueue(struct qelem *elem)
0a2c64cb 60{
5eaef520 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;
0a2c64cb 65}
66
70ea6aa8 67
5eaef520 68/* CopyInfo: allocates memory for a copy of a NULL terminated array of
70ea6aa8 69 * strings <and returns a pointer to the copy.
70 */
71
5eaef520 72char **CopyInfo(char **info)
70ea6aa8 73{
5eaef520 74 char **ret;
75 int i;
70ea6aa8 76
5eaef520 77 ret = malloc(sizeof(char *) * (CountArgs(info) + 1));
78 if (!ret)
79 return ret;
80 for (i = 0; info[i]; i++)
7ac48069 81 ret[i] = strdup(info[i]);
5eaef520 82 ret[i] = NULL;
83 return ret;
70ea6aa8 84}
85
86
08345b74 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
5eaef520 93void FreeInfo(char **info)
08345b74 94{
5eaef520 95 while (*info)
96 FreeAndClear(info++, TRUE);
08345b74 97}
98
461c03b6 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
5eaef520 106void FreeAndClear(char **pointer, Bool free_it)
461c03b6 107{
5eaef520 108 if (!*pointer)
109 return;
110 else if (free_it)
111 free(*pointer);
112 *pointer = NULL;
461c03b6 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 */
5eaef520 121
122struct qelem *QueueTop(struct qelem *elem)
461c03b6 123{
5eaef520 124 if (!elem) /* NULL returns NULL. */
125 return NULL;
126 while (elem->q_back)
127 elem = elem->q_back;
128 return elem;
461c03b6 129}
130
08345b74 131/* Function Name: FreeQueueElem
132 * Description: Frees one element of the queue.
133 * Arguments: elem - the elem to free.
134 * Returns: none
135 */
136
5eaef520 137static void FreeQueueElem(struct qelem *elem)
08345b74 138{
7ac48069 139 char **info = elem->q_data;
461c03b6 140
5eaef520 141 if (info)
142 {
143 FreeInfo(info); /* free info fields */
144 free(elem->q_data); /* free info array itself. */
08345b74 145 }
5eaef520 146 RemoveQueue(elem); /* remove this element from the queue */
147 free(elem); /* free its space. */
08345b74 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
5eaef520 156void FreeQueue(struct qelem *elem)
08345b74 157{
5eaef520 158 struct qelem *temp, *local = QueueTop(elem);
08345b74 159
5eaef520 160 while (local)
161 {
162 temp = local->q_forw;
163 FreeQueueElem(local);
164 local = temp;
08345b74 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
5eaef520 174int QueueCount(struct qelem *elem)
08345b74 175{
5eaef520 176 int count = 0;
177 elem = QueueTop(elem);
178 while (elem)
179 {
180 count++;
181 elem = elem->q_forw;
08345b74 182 }
5eaef520 183 return count;
08345b74 184}
185
0a2c64cb 186/* Function Name: StoreInfo
59ec8dae 187 * Description: Stores information from a moira query into a queue.
0a2c64cb 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.
8defc06b 195 * Returns: MR_CONT, or MR_ABORT if it has problems.
0a2c64cb 196 */
197
7ac48069 198int StoreInfo(int argc, char **argv, void *data)
08345b74 199{
5eaef520 200 char **info = malloc(MAX_ARGS_SIZE * sizeof(char *));
7ac48069 201 struct qelem **old_elem = data;
5eaef520 202 struct qelem *new_elem = malloc(sizeof(struct qelem));
203 int count;
08345b74 204
5eaef520 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;
402461ad 211 }
212
5eaef520 213 for (count = 0; count < argc; count++)
7ac48069 214 info[count] = strdup(argv[count]);
5eaef520 215 info[count] = NULL; /* NULL terminate this sucker. */
08345b74 216
7ac48069 217 new_elem->q_data = info;
5eaef520 218 AddQueue(new_elem, *old_elem);
08345b74 219
5eaef520 220 *old_elem = new_elem;
221 return MR_CONT;
08345b74 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
5eaef520 231int CountArgs(char **info)
08345b74 232{
5eaef520 233 int number = 0;
234
235 while (*info)
236 {
237 number++;
238 info++;
461c03b6 239 }
08345b74 240
5eaef520 241 return number;
242}
08345b74 243
08345b74 244/* Function Name: PromptWithDefault
5eaef520 245 * Description: allows a user to be prompted for input, and given a
08345b74 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.
1feef067 250 * Returns: zero on failure
08345b74 251 */
252
5eaef520 253int PromptWithDefault(char *prompt, char *buf, int buflen, char *def)
08345b74 254{
5eaef520 255 char tmp[BUFSIZ];
256 int ans;
08345b74 257
5eaef520 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;
1feef067 266 }
267
5eaef520 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;
08345b74 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
5eaef520 285Bool YesNoQuestion(char *prompt, int bool_def)
08345b74 286{
5eaef520 287 char ans[2];
08345b74 288
5eaef520 289 while (TRUE)
290 {
291 if (!PromptWithDefault(prompt, ans, 2, bool_def ? "y" : "n"))
292 return -1;
293 switch (ans[0])
294 {
08345b74 295 case 'n':
296 case 'N':
5eaef520 297 return FALSE;
08345b74 298 case 'y':
299 case 'Y':
5eaef520 300 return TRUE;
08345b74 301 default:
5eaef520 302 Put_message("Please answer 'y' or 'n'.");
303 break;
08345b74 304 }
305 }
306}
5eaef520 307
08345b74 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
5eaef520 318Bool YesNoQuitQuestion(char *prompt, int bool_def)
08345b74 319{
5eaef520 320 char ans[2];
08345b74 321
5eaef520 322 while (TRUE)
323 {
324 if (!PromptWithDefault(prompt, ans, 2, bool_def ? "y" : "n"))
325 return -1;
326 switch (ans[0])
327 {
08345b74 328 case 'n':
329 case 'N':
5eaef520 330 return FALSE;
08345b74 331 case 'y':
332 case 'Y':
5eaef520 333 return TRUE;
08345b74 334 case 'q':
335 case 'Q':
5eaef520 336 return -1;
08345b74 337 default:
5eaef520 338 Put_message("Please answer 'y', 'n' or 'q'.");
339 break;
08345b74 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
5eaef520 351Bool Confirm(char *prompt)
08345b74 352{
5eaef520 353 return !verbose || (YesNoQuestion(prompt, FALSE) == TRUE);
08345b74 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
5eaef520 362Bool ValidName(char *s)
08345b74 363{
5eaef520 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;
08345b74 373}
374
375/* Function Name: ToggleVerboseMode
376 * Description: This function toggles the verbose mode.
377 * Arguments: none
378 * Returns: DM_NORMAL.
379 */
380
7ac48069 381int ToggleVerboseMode(int argc, char **argv)
08345b74 382{
85ca828a 383 verbose = !verbose;
08345b74 384
461c03b6 385 if (verbose)
386 Put_message("Delete functions will first confirm\n");
387 else
388 Put_message("Delete functions will be silent\n");
5eaef520 389
390 return DM_NORMAL;
08345b74 391}
392
08345b74 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.
85ca828a 399 * NOTE: This screws up the numbers of the elements of the array in a
08345b74 400 * big way.
401 */
402
5eaef520 403void SlipInNewName(char **info, char *name)
08345b74 404{
44d12d58 405 int i;
08345b74 406
5eaef520 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. */
08345b74 411}
412
08345b74 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.
075fe5bb 419 * Returns: SUB_ERROR if break hit (^C).
08345b74 420 */
421
5eaef520 422int GetValueFromUser(char *prompt, char **pointer)
08345b74 423{
5eaef520 424 char buf[BUFSIZ];
08345b74 425
5eaef520 426 if (PromptWithDefault(prompt, buf, BUFSIZ, *pointer) == 0)
427 return SUB_ERROR;
075fe5bb 428
5eaef520 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 */
0a2c64cb 434
5eaef520 435 if (*pointer)
436 {
437 if (strcmp(buf, *pointer))
438 {
439 free(*pointer);
7ac48069 440 *pointer = strdup(buf);
ef889832 441 }
0a2c64cb 442 }
5eaef520 443 return SUB_NORMAL;
075fe5bb 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
5eaef520 455int GetYesNoValueFromUser(char *prompt, char **pointer)
075fe5bb 456{
5eaef520 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;
075fe5bb 464
5eaef520 465 sprintf(user_prompt, "%s (y/n)", prompt);
075fe5bb 466
5eaef520 467 switch (YesNoQuestion(user_prompt, default_val))
468 {
075fe5bb 469 case TRUE:
5eaef520 470 if (*pointer)
471 free(*pointer);
7ac48069 472 *pointer = strdup(DEFAULT_YES);
5eaef520 473 break;
075fe5bb 474 case FALSE:
5eaef520 475 if (*pointer)
476 free(*pointer);
7ac48069 477 *pointer = strdup(DEFAULT_NO);
5eaef520 478 break;
075fe5bb 479 case -1:
480 default:
5eaef520 481 return SUB_ERROR;
075fe5bb 482 }
5eaef520 483 return SUB_NORMAL;
075fe5bb 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
5eaef520 495static Bool GetFSVal(char *name, int mask, int current, int *new)
075fe5bb 496{
5eaef520 497 char temp_buf[BUFSIZ];
498 sprintf(temp_buf, "Is this a %s filsystem", name);
499 switch (YesNoQuestion(temp_buf, ((mask & current) == mask)))
500 {
075fe5bb 501 case TRUE:
5eaef520 502 *new |= mask;
503 break;
075fe5bb 504 case FALSE:
5eaef520 505 break; /* zero by default. */
075fe5bb 506 default:
5eaef520 507 return FALSE;
075fe5bb 508 }
5eaef520 509 return TRUE;
075fe5bb 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
5eaef520 518int 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;
1feef067 541 }
075fe5bb 542
5eaef520 543 FreeAndClear(current, TRUE);
544 sprintf(ret_value, "%d", new_val);
7ac48069 545 *current = strdup(ret_value);
5eaef520 546 return SUB_NORMAL;
08345b74 547}
548
3ceae461 549/* atot: convert ASCII integer unix time into human readable date string */
550
5eaef520 551char *atot(char *itime)
3ceae461 552{
5eaef520 553 time_t time;
7ac48069 554 char *ct;
3ceae461 555
5eaef520 556 time = (time_t) atoi(itime);
557 ct = ctime(&time);
558 ct[24] = 0;
559 return &ct[4];
3ceae461 560}
561
562
08345b74 563/* Function Name: Print
564 * Description: prints out all the arguments on a single line.
59ec8dae 565 * Arguments: argc, argv - the standard Moira arguments.
08345b74 566 * callback - the callback function - NOT USED.
8defc06b 567 * Returns: MR_CONT
08345b74 568 */
569
7ac48069 570int Print(int argc, char **argv, void *callback)
08345b74 571{
5eaef520 572 char buf[BUFSIZ];
44d12d58 573 int i;
08345b74 574
5eaef520 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);
08345b74 580
5eaef520 581 return MR_CONT;
08345b74 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.
5eaef520 588 * Arguments: argc, argc - normal arguments for mr_callback function.
08345b74 589 * callback - either a type of member or NULL.
8defc06b 590 * Returns: MR_CONT or MR_QUIT.
08345b74 591 */
592
7ac48069 593int PrintByType(int argc, char **argv, void *callback)
08345b74 594{
5eaef520 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;
08345b74 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
5eaef520 609int PrintHelp(char **message)
08345b74 610{
44d12d58 611 int i;
a9517c80 612
5eaef520 613 for (i = 0; i < CountArgs(message); i++)
614 Put_message(message[i]);
a9517c80 615
5eaef520 616 return DM_NORMAL;
08345b74 617}
618
402461ad 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
7ac48069 627void Loop(struct qelem *elem, void (*func)(char **))
402461ad 628{
5eaef520 629 while (elem)
630 {
7ac48069 631 (*func) (elem->q_data);
5eaef520 632 elem = elem->q_forw;
402461ad 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
7ac48069 663void QueryLoop(struct qelem *elem, char * (*print_func)(char **),
664 void (*op_func)(char **, Bool), char *query_string)
5eaef520 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 {
7ac48069 673 char **info = elem->q_data;
5eaef520 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 {
402461ad 683 case TRUE:
5eaef520 684 (*op_func) (info, one_item);
685 break;
402461ad 686 case FALSE:
5eaef520 687 break;
402461ad 688 default: /* Quit. */
5eaef520 689 Put_message("Aborting...");
690 return;
402461ad 691 }
692 }
5eaef520 693 elem = elem->q_forw;
402461ad 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
5eaef520 703char *NullPrint(char **info)
402461ad 704{
5eaef520 705 return info[NAME];
402461ad 706}
707
6769d5bc 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
5eaef520 715struct qelem *GetTypeValues(char *tname)
6769d5bc 716{
5eaef520 717 int stat;
7ac48069 718 char *argv[3], *p, **pp;
5eaef520 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;
6769d5bc 725
5eaef520 726 for (elem = cache; elem; elem = elem->q_forw)
727 {
7ac48069 728 ce = elem->q_data;
5eaef520 729 if (!strcmp(ce->cache_name, tname))
730 return ce->cache_data;
6769d5bc 731 }
732
5eaef520 733 argv[0] = tname;
734 argv[1] = "TYPE";
735 argv[2] = "*";
736 elem = NULL;
7ac48069 737 if ((stat = do_mr_query("get_alias", 3, argv, StoreInfo, &elem)))
5eaef520 738 {
739 com_err(program_name, stat, " in GetTypeValues");
740 return NULL;
6769d5bc 741 }
5eaef520 742 oelem = elem;
743 for (elem = QueueTop(elem); elem; elem = elem->q_forw)
744 {
7ac48069 745 pp = elem->q_data;
746 p = strdup(pp[2]);
5eaef520 747 FreeInfo(pp);
748 elem->q_data = p;
6769d5bc 749 }
5eaef520 750 elem = malloc(sizeof(struct qelem));
751 ce = malloc(sizeof(struct cache_elem));
7ac48069 752 ce->cache_name = strdup(tname);
5eaef520 753 ce->cache_data = QueueTop(oelem);
7ac48069 754 elem->q_data = ce;
5eaef520 755 AddQueue(elem, cache);
756 cache = QueueTop(elem);
757 return ce->cache_data;
6769d5bc 758}
759
760
761/* Function Name: GetTypeFromUser
762 * Description: gets a typed value from the user
763 * Arguments: prompt string, type name, buffer pointer
245b2337 764 * Returns: SUB_ERROR if ^C, SUB_NORMAL otherwise
6769d5bc 765 */
766
5eaef520 767int GetTypeFromUser(char *prompt, char *tname, char **pointer)
6769d5bc 768{
5eaef520 769 char def[BUFSIZ], buffer[BUFSIZ], *p, *argv[3];
770 struct qelem *elem;
771 int stat;
6769d5bc 772
5eaef520 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, ", ");
6769d5bc 781 }
5eaef520 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);
7ac48069 793 *pointer = strdup(def);
5eaef520 794 return GetTypeFromUser(prompt, tname, pointer);
6769d5bc 795 }
5eaef520 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;
1feef067 802 }
6769d5bc 803 }
5eaef520 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 {
d1641b6c 820 for (p = argv[2]; *p; p++)
5eaef520 821 {
822 if (islower(*p))
823 *p = toupper(*p);
824 }
825 }
7ac48069 826 if ((stat = do_mr_query("add_alias", 3, argv, NULL, NULL)))
5eaef520 827 com_err(program_name, stat, " in add_alias");
828 else
829 {
830 elem = malloc(sizeof(struct qelem));
7ac48069 831 elem->q_data = strdup(*pointer);
5eaef520 832 AddQueue(elem, GetTypeValues(tname));
833 Put_message("Done.");
6769d5bc 834 }
835 }
7ac48069 836 *pointer = strdup(def);
5eaef520 837 return GetTypeFromUser(prompt, tname, pointer);
6769d5bc 838}
839
840
ccce9c6a 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
5eaef520 848int 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));
7ac48069 855 value = strdup(inet_ntoa(addr));
5eaef520 856 ret = GetValueFromUser(prompt, &value);
857 if (ret == SUB_ERROR)
858 return SUB_ERROR;
859 addr.s_addr = inet_addr(value);
860 free(pointer);
7ac48069 861 sprintf(buf, "%ld", ntohl(addr.s_addr));
862 *pointer = strdup(buf);
5eaef520 863 return SUB_NORMAL;
864}
865
866
7ac48069 867int do_mr_query(char *name, int argc, char **argv,
868 int (*proc)(int, char **, void *), void *hint)
5eaef520 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;
198d5016 883 }
5eaef520 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;
198d5016 891 }
5eaef520 892 status = mr_query(name, argc, argv, proc, hint);
893 return status;
198d5016 894}
895
This page took 1.406034 seconds and 5 git commands to generate.