]> andersk Git - moira.git/blob - clients/mmoira/form_setup.c
deal with AFS filesystem defaults
[moira.git] / clients / mmoira / form_setup.c
1 /* $Header$
2  */
3
4 #include <stdio.h>
5 #include <ctype.h>
6 #include <moira.h>
7 #include <moira_site.h>
8 #include <Xm/Xm.h>
9 #include "mmoira.h"
10
11
12 extern char *user, *program_name;
13 extern EntryForm *MoiraForms[];
14 EntryForm *GetAndClearForm();
15
16 char *user_states[] = { "0 - Registerable",
17                           "1 - Active",
18                           "2 - Half Registered",
19                           "3 - Deleted",
20                           "4 - Not registerable",
21                           "5 - Enrolled/Registerable",
22                           "6 - Enrolled/Not Registerable",
23                           "7 - Half Enrolled",
24                           NULL};
25 char *nfs_states[] = { "0 - Not Allocated",
26                          "1 - Student",
27                           "2 - Faculty",
28                           "4 - Staff",
29                           "8 - Miscellaneous",
30                           NULL};
31
32
33 static FixNameCase(form, field)
34 EntryForm *form;
35 int field;
36 {
37     char fixname[128], buf[256];
38
39     strcpy(fixname, stringval(form, field));
40     FixCase(fixname);
41     sprintf(buf, "You entered a name which does not follow the capitalization conventions.\nCorrect it to \"%s\"?", fixname);
42     if (strcmp(fixname, stringval(form, field)) &&
43         AskQuestion(buf, "fixcase"))
44       StoreField(form, field, fixname);
45 }
46
47
48 get_members(argc, argv, sq)
49 int argc;
50 char **argv;
51 struct save_queue *sq;
52 {
53     char buf[256];
54
55     sprintf(buf, "%s (%s)", argv[0], argv[1]);
56     sq_save_data(sq, strsave(buf));
57     return(MR_CONT);
58 }
59
60
61 /* Deal with AFS cell names */
62
63 char *canonicalize_cell(c)
64 char *c;
65 {
66     struct stat stbuf;
67     char path[512];
68     int count;
69
70     c = strtrim(c);
71     sprintf(path, "/afs/%s", c);
72     if (lstat(path, &stbuf) || !stbuf.st_mode&S_IFLNK)
73       return(c);
74     count = readlink(path, path, sizeof(path));
75     if (count < 1) return(c);
76     path[count] = 0;
77     free(c);
78     return(strsave(path));
79 }
80
81
82 int GetAliasValue(argc, argv, retval)
83 int argc;
84 char **argv;
85 char **retval;
86 {
87     *retval = strsave(argv[2]);
88     return(MR_CONT);
89 }
90
91
92
93 MoiraValueChanged(f, prompt)
94 EntryForm *f;
95 UserPrompt *prompt;
96 {
97     char buf[1024];
98     char *argv[5], *p;
99     int i, size, field;
100     struct save_queue *sq, *s;
101 #define maybechange(f, n, v)    {if (f->inputlines[n]->insensitive != v) { f->inputlines[n]->insensitive=v; f->inputlines[n]->changed = True; }}
102
103     for (field = 0; f->inputlines[field]; field++)
104       if (prompt == f->inputlines[field]) break;
105
106     switch (f->menu->operation) {
107     case MM_ADD_LIST:
108     case MM_MOD_LIST:
109         maybechange(f, L_GID, !boolval(f, L_GROUP));
110         if (!strcmp(stringval(f, L_ACE_TYPE), "NONE"))
111           maybechange(f, L_ACE_NAME, True)
112         else
113           maybechange(f, L_ACE_NAME, False)
114         break;
115     case MM_ADD_FILSYS:
116     case MM_MOD_FILSYS:
117         if (field == FS_TYPE &&
118             (!strcmp(stringval(f, FS_TYPE), "FSGROUP") ||
119              !strcmp(stringval(f, FS_TYPE), "MUL") ||
120              !strcmp(stringval(f, FS_TYPE), "ERR"))) {
121             maybechange(f, FS_MACHINE, True);
122             maybechange(f, FS_PACK, True);
123             maybechange(f, FS_M_POINT, True);
124             maybechange(f, FS_ACCESS, True);
125             maybechange(f, FS_CREATE, True);
126         } else if (field == FS_TYPE &&
127                    (!strcmp(stringval(f, FS_TYPE), "NFS") ||    
128                     !strcmp(stringval(f, FS_TYPE), "AFS") ||
129                     !strcmp(stringval(f, FS_TYPE), "RVD"))) {
130             maybechange(f, FS_MACHINE, False);
131             maybechange(f, FS_PACK, False);
132             maybechange(f, FS_M_POINT, False);
133             maybechange(f, FS_ACCESS, False);
134             maybechange(f, FS_CREATE, False);
135         }
136         if (field == FS_NAME && !strcmp(stringval(f, FS_M_POINT), "/mit/")) {
137             sprintf(buf, "/mit/%s", stringval(f, FS_NAME));
138             StoreField(f, FS_M_POINT, buf);
139         }
140         if (field == FS_MACHINE && !strcmp(stringval(f, FS_TYPE), "AFS")) {
141             p = strsave(stringval(f, FS_MACHINE));
142             p = canonicalize_cell(p);
143             lowercase(p);
144             StoreField(f, FS_MACHINE, p);
145             free(p);
146         }
147         if (field == FS_MACHINE && (!strcmp(stringval(f, FS_TYPE), "NFS") ||
148                                     !strcmp(stringval(f, FS_TYPE), "RVD"))) {
149             StoreHost(f, FS_MACHINE, &p);
150         }
151         if (!strcmp(stringval(f, FS_TYPE), "AFS") &&
152             *stringval(f, FS_NAME) &&
153             *stringval(f, FS_MACHINE) &&
154             *stringval(f, FS_L_TYPE)) {
155             char *path;
156             int depth;
157
158             sprintf(buf, "%s:%s", stringval(f, FS_MACHINE),
159                     stringval(f, FS_L_TYPE));
160             argv[0] = buf;
161             argv[1] = "AFSPATH";
162             argv[2] = "*";
163             path = "???";
164             i = MoiraQuery("get_alias", 3, argv, GetAliasValue, &path);
165             if (i == MR_SUCCESS) {
166                 p = index(path, ':');
167                 if (p) {
168                     *p = 0;
169                     depth = atoi(++p);
170                 } else depth = 0;
171                 sprintf(buf, "/afs/%s/%s", stringval(f, FS_MACHINE), path);
172                 if (depth >= 0) {
173                     for (p=stringval(f, FS_NAME);
174                          *p && (p - stringval(f, FS_NAME)) < depth;
175                          p++) {
176                         if (islower(*p)) {
177                             strcat(buf, "/x");
178                             buf[strlen(buf)-1] = *p;
179                         } else {
180                             sprintf(buf, "/afs/%s/%s/other",
181                                     stringval(f, FS_MACHINE), path);
182                             break;
183                         }
184                     }
185                 } else if (depth = -1) {
186                     if (isdigit(stringval(f, FS_NAME)[0])) {
187                         strcat(buf, "/");
188                         depth = strlen(buf);
189                         for (p = stringval(f, FS_NAME);
190                              *p && isdigit(*p);
191                              p++) {
192                             buf[depth++] = *p;
193                             buf[depth] = 0;
194                         }
195                     } else
196                       strcat(buf, "/other");
197                 } else {
198                     /* no default */
199                 }
200                 strcat(buf, "/");
201                 strcat(buf, stringval(f, FS_NAME));
202                 free(path);
203             } else {
204                 p = strsave(stringval(f, FS_L_TYPE));
205                 sprintf(buf, "/afs/%s/%s/%s", stringval(f, FS_MACHINE),
206                         lowercase(p), stringval(f, FS_NAME));
207                 free(p);
208             }
209             StoreField(f, FS_PACK, buf);
210         }
211         break;
212     case MM_SET_POBOX:
213         if (!strcmp(stringval(f, PO_TYPE), "POP")) {
214             maybechange(f, 2, True);
215             maybechange(f, 3, False);
216         } else if (!strcmp(stringval(f, PO_TYPE), "SMTP")) {
217             maybechange(f, 2, False);
218             maybechange(f, 3, True);
219         } else if (!strcmp(stringval(f, PO_TYPE), "NONE")) {
220             maybechange(f, 2, True);
221             maybechange(f, 3, True);
222         }
223         break;
224     case MM_ADD_QUOTA:
225     case MM_MOD_QUOTA:
226         if (!strcmp(stringval(f, Q_TYPE), "ANY"))
227           maybechange(f, Q_NAME, True)
228         else
229           maybechange(f, Q_NAME, False)
230         break;
231     case MM_ADD_ZEPHYR:
232     case MM_MOD_ZEPHYR:
233         if (!strcmp(stringval(f, ZA_XMT_TYPE), "NONE"))
234           maybechange(f, ZA_XMT_ID, True)
235         else
236           maybechange(f, ZA_XMT_ID, False)
237         if (!strcmp(stringval(f, ZA_SUB_TYPE), "NONE"))
238           maybechange(f, ZA_SUB_ID, True)
239         else
240           maybechange(f, ZA_SUB_ID, False)
241         if (!strcmp(stringval(f, ZA_IWS_TYPE), "NONE"))
242           maybechange(f, ZA_IWS_ID, True)
243         else
244           maybechange(f, ZA_IWS_ID, False)
245         if (!strcmp(stringval(f, ZA_IUI_TYPE), "NONE"))
246           maybechange(f, ZA_IUI_ID, True)
247         else
248           maybechange(f, ZA_IUI_ID, False)
249         break;
250     case MM_ADD_USER:
251         FixNameCase(f, U_LAST);
252         FixNameCase(f, U_FIRST);
253         FixNameCase(f, U_MIDDLE);
254         break;
255     case MM_SHOW_USER:
256         FixNameCase(f, 1);
257         FixNameCase(f, 2);
258         break;
259     case MM_ADD_FSGROUP:
260         argv[0] = stringval(f, 0);
261         sq = sq_create();
262         i = MoiraQuery("get_fsgroup_members", 1, argv, get_members, (char *)sq);
263         if (i) {
264             com_err(program_name, i, " retrieving filesystem group members");
265             break;
266         }
267         size = 1;
268         for (s = sq->q_next; s->q_next != sq; s = s->q_next)
269           size++;
270         if (f->inputlines[2]->keywords)
271           free(f->inputlines[2]->keywords);
272         f->inputlines[2]->keywords = (char **)malloc(sizeof(char *)*(size+2));
273         if (f->inputlines[2]->keywords == NULL) {
274             display_error("Out of memory while fetching members");
275             return;
276         }
277         f->inputlines[2]->keywords[0] = "[First]";
278         for (i = 0; i < size; i++)
279           sq_get_data(sq, &f->inputlines[2]->keywords[i+1]);
280         f->inputlines[2]->keywords[i+1] = NULL;
281         f->inputlines[2]->changed = 1;
282         sq_destroy(sq);
283         RemakeRadioField(f, 2);
284         break;
285     case MM_DEL_FSGROUP:
286         argv[0] = stringval(f, 0);
287         sq = sq_create();
288         i = MoiraQuery("get_fsgroup_members", 1, argv, get_members, (char *)sq);
289         if (i) {
290             com_err(program_name, i, " retrieving filesystem group members");
291             break;
292         }
293         size = 1;
294         for (s = sq->q_next; s->q_next != sq; s = s->q_next)
295           size++;
296         if (f->inputlines[1]->keywords)
297           free(f->inputlines[1]->keywords);
298         f->inputlines[1]->keywords = (char **)malloc(sizeof(char *)*(size+1));
299         if (f->inputlines[1]->keywords == NULL) {
300             display_error("Out of memory while fetching members");
301             return;
302         }
303         for (i = 0; i < size; i++)
304           sq_get_data(sq, &f->inputlines[1]->keywords[i]);
305         f->inputlines[1]->keywords[i] = NULL;
306         f->inputlines[1]->changed = 1;
307         sq_destroy(sq);
308         RemakeRadioField(f, 1);
309         break;
310     case MM_MOV_FSGROUP:
311         argv[0] = stringval(f, 0);
312         sq = sq_create();
313         i = MoiraQuery("get_fsgroup_members", 1, argv, get_members, (char *)sq);
314         if (i) {
315             com_err(program_name, i, " retrieving filesystem group members");
316             break;
317         }
318         size = 1;
319         for (s = sq->q_next; s->q_next != sq; s = s->q_next)
320           size++;
321         if (f->inputlines[1]->keywords)
322           free(f->inputlines[1]->keywords);
323         f->inputlines[1]->keywords = (char **)malloc(sizeof(char *)*(size+1));
324         if (f->inputlines[1]->keywords == NULL) {
325             display_error("Out of memory while fetching members");
326             return;
327         }
328         if (f->inputlines[2]->keywords)
329           free(f->inputlines[2]->keywords);
330         f->inputlines[2]->keywords = (char **)malloc(sizeof(char *)*(size+2));
331         if (f->inputlines[2]->keywords == NULL) {
332             display_error("Out of memory while fetching members");
333             return;
334         }
335         f->inputlines[2]->keywords[0] = "[First]";
336         for (i = 0; i < size; i++) {
337             sq_get_data(sq, &f->inputlines[1]->keywords[i]);
338             f->inputlines[2]->keywords[i+1] = f->inputlines[1]->keywords[i];
339         }
340         f->inputlines[1]->keywords[i] = NULL;
341         f->inputlines[2]->keywords[i+1] = NULL;
342         f->inputlines[1]->changed = 1;
343         f->inputlines[2]->changed = 1;
344         sq_destroy(sq);
345         RemakeRadioField(f, 1);
346         RemakeRadioField(f, 2);
347         break;
348     default:
349         return;
350     }
351     UpdateForm(f);
352 }
353
354
355 /* Called when a menu item is selected. */
356
357 MoiraMenuRequest(menu)
358 MenuItem        *menu;
359 {
360     EntryForm *f;
361
362     f = GetAndClearForm(menu->form);
363     if (f == NULL) {
364         if (!strcmp(menu->form, "0"))
365           MoiraMenuComplete(menu);
366         else
367           display_error("Sorry, unable to process that request (no form registered).");
368         return;
369     }
370
371     switch (menu->operation) {
372     case MM_SHOW_USER:
373         GetKeywords(f, 4, "class");
374         f->inputlines[1]->valuechanged = MoiraValueChanged;
375         f->inputlines[2]->valuechanged = MoiraValueChanged;
376         break;
377     case MM_ADD_USER:
378         StoreField(f, U_NAME, UNIQUE_LOGIN);
379         StoreField(f, U_UID, UNIQUE_UID);
380         StoreField(f, U_SHELL, "/bin/csh");
381         StoreField(f, U_STATE, user_states[US_NO_LOGIN_YET]);
382         f->inputlines[U_STATE]->keywords = user_states;
383         f->inputlines[U_LAST]->valuechanged = MoiraValueChanged;
384         f->inputlines[U_FIRST]->valuechanged = MoiraValueChanged;
385         f->inputlines[U_MIDDLE]->valuechanged = MoiraValueChanged;
386         GetKeywords(f, U_CLASS, "class");
387         break;
388     case MM_SET_POBOX:
389         GetKeywords(f, 1, "pobox");
390         GetKeywords(f, 3, "poserver");
391         f->inputlines[PO_TYPE]->valuechanged = MoiraValueChanged;
392         break;
393     case MM_ADD_FILSYS:
394         StoreField(f, FS_TYPE, "AFS");
395         StoreField(f, FS_M_POINT, "/mit/");
396         StoreField(f, FS_MACHINE, "athena.mit.edu");
397         StoreField(f, FS_ACCESS, "w");
398         StoreField(f, FS_OWNER, user);
399         StoreField(f, FS_OWNERS, user);
400         boolval(f, FS_CREATE) = TRUE;
401         GetKeywords(f, FS_TYPE, "filesys");
402         GetKeywords(f, FS_ACCESS, "fs_access_AFS");
403         GetKeywords(f, FS_L_TYPE, "lockertype");
404         f->inputlines[FS_TYPE]->valuechanged = MoiraValueChanged;
405         f->inputlines[FS_L_TYPE]->valuechanged = MoiraValueChanged;
406         f->inputlines[FS_NAME]->valuechanged = MoiraValueChanged;
407         f->inputlines[FS_MACHINE]->valuechanged = MoiraValueChanged;
408         break;
409     case MM_ADD_FSGROUP:
410         if (f->inputlines[2]->keywords)
411           free(f->inputlines[2]->keywords);
412         f->inputlines[2]->keywords = (char **)malloc(sizeof(char*)*2);
413         f->inputlines[2]->keywords[0] = "[First]";
414         f->inputlines[2]->keywords[1] = NULL;
415         f->inputlines[0]->valuechanged = MoiraValueChanged;
416         break;
417     case MM_DEL_FSGROUP:
418         if (f->inputlines[1]->keywords)
419           free(f->inputlines[1]->keywords);
420         f->inputlines[1]->keywords = (char **)malloc(sizeof(char*)*2);
421         f->inputlines[1]->keywords[0] = "[Placeholder]";
422         f->inputlines[1]->keywords[1] = NULL;
423         f->inputlines[0]->valuechanged = MoiraValueChanged;
424         break;
425     case MM_MOV_FSGROUP:
426         if (f->inputlines[1]->keywords)
427           free(f->inputlines[1]->keywords);
428         f->inputlines[1]->keywords = (char **)malloc(sizeof(char*)*2);
429         f->inputlines[1]->keywords[0] = "[Placeholder]";
430         f->inputlines[1]->keywords[1] = NULL;
431         if (f->inputlines[2]->keywords)
432           free(f->inputlines[2]->keywords);
433         f->inputlines[2]->keywords = (char **)malloc(sizeof(char*)*2);
434         f->inputlines[2]->keywords[0] = "[First]";
435         f->inputlines[2]->keywords[1] = NULL;
436         f->inputlines[0]->valuechanged = MoiraValueChanged;
437         break;
438     case MM_ADD_NFS:
439         StoreField(f, 1, "/u1/lockers");
440         StoreField(f, 2, "/dev/");
441         StoreField(f, 5, "0");
442         StoreField(f, 6, "0");
443         StoreField(f, 3, nfs_states[1]);
444         f->inputlines[3]->keywords = nfs_states;
445         break;
446     case MM_ADD_QUOTA:
447     case MM_DEL_QUOTA:
448     case MM_MOD_QUOTA:
449         GetKeywords(f, 1, "quota_type");
450         f->inputlines[Q_TYPE]->valuechanged = MoiraValueChanged;
451         break;
452     case MM_SHOW_ACE_USE:
453         StoreField(f, 0, "USER");
454         GetKeywords(f, 0, "ace_type");
455         break;
456     case MM_ADD_LIST:
457         boolval(f, L_ACTIVE) = TRUE;
458         boolval(f, L_MAILLIST) = TRUE;
459         StoreField(f, L_GID, UNIQUE_GID);
460         StoreField(f, L_ACE_TYPE, "USER");
461         GetKeywords(f, L_ACE_TYPE, "ace_type");
462         f->inputlines[L_GID]->insensitive = True;
463         f->inputlines[L_GROUP]->valuechanged = MoiraValueChanged;
464         f->inputlines[L_ACE_TYPE]->valuechanged = MoiraValueChanged;
465         break;
466     case MM_SHOW_MEMBERS:
467         GetKeywords(f, 1, "member");
468         break;
469     case MM_ADD_MEMBER:
470     case MM_DEL_MEMBER:
471         GetKeywords(f, 1, "member");
472         break;
473     case MM_DEL_ALL_MEMBER:
474         boolval(f, 2) = TRUE;
475         GetKeywords(f, 0, "member");
476         break;
477     case MM_ADD_MACH:
478         GetKeywords(f, 1, "mac_type");
479         break;
480     case MM_ADD_PCAP:
481         StoreField(f, PCAP_SPOOL_DIR, "/usr/spool/printer/");
482         boolval(f, PCAP_AUTH) = TRUE;
483         StoreField(f, PCAP_PRICE, "10");
484         break;
485     case MM_ADD_SERVICE:
486         StoreField(f, SVC_INTERVAL, "1430");
487         StoreField(f, SVC_TARGET, "/tmp/");
488         StoreField(f, SVC_SCRIPT, "/moira/bin/");
489         StoreField(f, 4, "UNIQUE");
490         StoreField(f, 6, "NONE");
491         GetKeywords(f, 4, "service");
492         GetKeywords(f, 6, "ace_type");
493         break;
494     case MM_SHOW_ALIAS:
495         StoreField(f, 2, "*");
496         GetKeywords(f, 1, "alias");
497         break;
498     case MM_ADD_ZEPHYR:
499         GetKeywords(f, 1, "ace_type");
500         GetKeywords(f, 3, "ace_type");
501         GetKeywords(f, 5, "ace_type");
502         GetKeywords(f, 7, "ace_type");
503         f->inputlines[ZA_XMT_TYPE]->valuechanged = MoiraValueChanged;
504         f->inputlines[ZA_SUB_TYPE]->valuechanged = MoiraValueChanged;
505         f->inputlines[ZA_IWS_TYPE]->valuechanged = MoiraValueChanged;
506         f->inputlines[ZA_IUI_TYPE]->valuechanged = MoiraValueChanged;
507         break;
508     }
509
510     f->menu = menu;
511     DisplayForm(f);
512 }
513
514
515 /* Find a form by name.  Returns a pointer to the form or NULL on error. */
516
517 EntryForm *GetForm(name)
518 char *name;
519 {
520     EntryForm **fp;
521
522     for (fp = MoiraForms; *fp; fp++)
523       if (!strcmp((*fp)->formname, name))
524         break;
525     return(*fp);
526 }
527
528
529 /* Find a form by name and clear all of its fields.  Returns a pointer
530  * to the form or NULL on error.
531  */
532
533 EntryForm *GetAndClearForm(name)
534 char *name;
535 {
536     EntryForm **fp;
537     UserPrompt *p, **pp;
538     static BottomButton **buttons = NULL;
539     int MoiraFormComplete(), MoiraFormApply();
540     int button_callback(), help_form_callback();
541
542     for (fp = MoiraForms; *fp; fp++)
543       if (!strcmp((*fp)->formname, name))
544         break;
545     if (*fp == (EntryForm *)NULL)
546       return(NULL);
547
548     for (pp = (*fp)->inputlines; p = *pp; pp++) {
549         switch (p->type) {
550         case FT_STRING:
551         case FT_KEYWORD:
552             if (p->returnvalue.stringvalue)
553               free(p->returnvalue.stringvalue);
554             p->returnvalue.stringvalue = (char *)malloc(MAXFIELDSIZE);
555             if (p->returnvalue.stringvalue == NULL) {
556                 fprintf(stderr, "Moira: out of memory\n");
557                 return(NULL);
558             }
559             *(p->returnvalue.stringvalue) = '\0';
560             break;
561         case FT_BOOLEAN:
562             p->returnvalue.booleanvalue = False;
563             break;
564         case FT_NUMBER:
565             p->returnvalue.integervalue = 0;
566             break;
567         }
568     }
569     if (buttons == NULL) {
570         buttons = (BottomButton **)malloc(5 * sizeof(BottomButton *));
571         buttons[0] = (BottomButton *)malloc(sizeof(BottomButton));
572         buttons[0]->label = "OK";
573         buttons[0]->returnfunction = MoiraFormComplete;
574         buttons[1] = (BottomButton *)malloc(sizeof(BottomButton));
575         buttons[1]->label = "Apply";
576         buttons[1]->returnfunction = MoiraFormApply;
577         buttons[2] = (BottomButton *)malloc(sizeof(BottomButton));
578         buttons[2]->label = "Cancel";
579         buttons[2]->returnfunction = button_callback;
580         buttons[3] = (BottomButton *)malloc(sizeof(BottomButton));
581         buttons[3]->label = "Help";
582         buttons[3]->returnfunction = help_form_callback;
583         buttons[4] = NULL;
584     }
585     (*fp)->buttons = buttons;
586     return(*fp);
587 }
588
589
590 /* Store a string into a given field in a form. */
591
592 StoreField(form, field, value)
593 EntryForm *form;
594 int field;
595 char *value;
596 {
597     strncpy(form->inputlines[field]->returnvalue.stringvalue,
598             value, MAXFIELDSIZE);
599 }
600
601
602 char *StringValue(form, field)
603 EntryForm *form;
604 int field;
605 {
606     switch (form->inputlines[field]->type) {
607     case FT_STRING:
608     case FT_KEYWORD:
609         return(stringval(form, field));
610     case FT_BOOLEAN:
611         return(boolval(form, field) ? "1" : "0");
612     }
613 }
614
615
616 StoreHost(form, field, dest)
617 EntryForm *form;
618 int field;
619 char **dest;
620 {
621     char *s;
622
623     s = strsave(stringval(form, field));
624     s = canonicalize_hostname(s);
625     StoreField(form, field, s);
626     form->inputlines[field]->changed = True;
627     UpdateForm(form);
628     free(s);
629     *dest = stringval(form, field);
630 }
631
632
633 /* Helper routine for GetKeywords() */
634
635 static get_alias(argc, argv, sq)
636 int argc;
637 char **argv;
638 struct save_queue *sq;
639 {
640     sq_save_data(sq, strsave(argv[2]));
641 #ifdef DEBUG
642     printf("found keyword %s\n", argv[2]);
643 #endif    
644     return(MR_CONT);
645 }
646
647 static get_sloc(argc, argv, sq)
648 int argc;
649 char **argv;
650 struct save_queue *sq;
651 {
652     sq_save_data(sq, strsave(argv[1]));
653 #ifdef DEBUG
654     printf("found sloc %s\n", argv[1]);
655 #endif    
656     return(MR_CONT);
657 }
658
659
660 /* Retrieve possible keyword values from Moira and store them in the specified
661  * field of the form.  Returns 0 if successful, -1 if not.
662  */
663
664 static struct save_queue *cache = NULL;
665 struct cache_elem { char *name; char **values; };
666
667 int GetKeywords(form, field, name)
668 EntryForm *form;
669 int field;
670 char *name;
671 {
672     struct save_queue *sq, *s;
673     struct cache_elem *ce;
674     int i, size, stat;
675     char *argv[4];
676
677     /* init cache */
678     if (cache == NULL)
679       cache = sq_create();
680     cache->q_lastget = NULL;
681
682     if (!strcmp(name, "fsgroup")) {
683         form->inputlines[field]->keywords = NULL;
684     }
685
686     /* look through cache */
687     while (sq_get_data(cache, &ce))
688       if (!strcmp(ce->name, name)) {
689           form->inputlines[field]->keywords = ce->values;
690           return(0);
691       }
692
693     /* not in cache, do query */
694     sq = sq_create();
695     if (!strcmp(name, "poserver")) {
696         argv[0] = "POP";
697         stat = MoiraQuery("get_server_locations", 1, argv, get_sloc,
698                           (char *)sq);
699         if (stat) {
700             com_err(program_name, stat, "retrieving service locations");
701             return(-1);
702         }
703     } else {
704         argv[0] = name;
705         argv[1] = "TYPE";
706         argv[2] = "*";
707         stat = MoiraQuery("get_alias", 3, argv, get_alias, (char *)sq);
708         if (stat) {
709             com_err(program_name, stat, "retrieving keyword values");
710             return(-1);
711         }
712     }
713
714     size = 1;
715     for (s = sq->q_next; s->q_next != sq; s = s->q_next)
716       size++;
717 #ifdef DEBUG
718     printf("Found %d keywords of type %s\n", size, name);
719 #endif
720
721     /* transform query data into proper malloc'ed structure */
722     ce = (struct cache_elem *) malloc(sizeof(struct cache_elem));
723     if (ce == NULL) {
724         display_error("Out of memory while fetching keywords");
725         return(-1);
726     }
727     ce->name = name;
728     ce->values = (char **) malloc(sizeof(char *) * (size + 1));
729     if (ce->values == NULL) {
730         display_error("Out of memory while fetching keywords");
731         return(-1);
732     }
733     for (i = 0; i < size; i++)
734       sq_get_data(sq, &(ce->values[i]));
735     ce->values[i] = NULL;
736     sq_destroy(sq);
737
738     /* put it in the cache */
739     sq_save_data(cache, ce);
740
741     /* and return answer */
742     form->inputlines[field]->keywords = ce->values;
743     return(0);
744 }
745
746 CacheNewValue(form, field, name, value)
747 EntryForm *form;
748 int field;
749 char *name;
750 char *value;
751 {
752     struct save_queue *sq;
753     struct cache_elem *ce;
754     int size;
755
756     /* init cache */
757     if (cache == NULL)
758       cache = sq_create();
759     cache->q_lastget = NULL;
760
761     /* find entry in cache */
762     while (sq_get_data(cache, &ce))
763       if (!strcmp(ce->name, name))
764         break;
765
766     /* get its size */
767     for (size = 0; ce->values[size]; size++);
768
769     /* add new keyword */
770     ce->values = (char **)realloc(ce->values, sizeof(char *) * (size + 2));
771     ce->values[size] = strsave(value);
772     ce->values[size + 1] = NULL;
773
774 #ifdef DEBUG    
775     printf("CacheNewValue(%x, %d, %s, %s)\n", form, field, name, value);
776     printf("  form is %x (%s)\n", form, form->formname);
777     printf("  field is %d (%s)\n", field, form->inputlines[field]->prompt);
778     printf("  keywords: ");
779     for (size = 0; ce->values[size]; size++) printf("%s ", ce->values[size]);
780     printf("\n");
781 #endif /* DEBUG */
782
783     /* new update form */
784     form->inputlines[field]->keywords = ce->values;
785     RemakeRadioField(form, field);
786 }
This page took 0.09177 seconds and 5 git commands to generate.