]> andersk Git - moira.git/blob - clients/moira/lists.c
1bd5f7f85f8e435a0d5426cfb367eb2da2d2d3d3
[moira.git] / clients / moira / lists.c
1 #if (!defined(lint) && !defined(SABER))
2   static char rcsid_module_c[] = "$Header$";
3 #endif
4
5 /*      This is the file lists.c for the MOIRA Client, which allows a nieve
6  *      user to quickly and easily maintain most parts of the MOIRA database.
7  *      It Contains: All list manipulation functions, except delete.
8  *
9  *      Created:        4/12/88
10  *      By:             Chris D. Peterson
11  *
12  *      $Source$
13  *      $Author$
14  *      $Header$
15  *
16  *      Copyright 1988 by the Massachusetts Institute of Technology.
17  *
18  *      For further information on copyright and distribution
19  *      see the file mit-copyright.h
20  */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <moira.h>
25 #include <moira_site.h>
26 #include <menu.h>
27
28 #include "mit-copyright.h"
29 #include "defs.h"
30 #include "f_defs.h"
31 #include "globals.h"
32
33 #define LIST    0
34 #define MEMBERS 1
35 #define GLOM    2
36 #define ACE_USE 3
37
38 #define DEFAULT_ACTIVE      DEFAULT_YES
39 #define DEFAULT_PUBLIC      DEFAULT_YES
40 #define DEFAULT_HIDDEN      DEFAULT_NO
41 #define DEFAULT_MAILLIST    DEFAULT_YES
42 #define DEFAULT_GROUP       DEFAULT_NO
43 #define DEFAULT_GID         UNIQUE_GID
44 #define DEFAULT_ACE_TYPE    "user"
45 #define DEFAULT_ACE_NAME    (user)
46 #define DEFAULT_DESCRIPTION DEFAULT_COMMENT
47
48 /* globals only for this file. */
49
50 static char current_list[BUFSIZ];
51
52 /*      Function Name: PrintListAce
53  *      Description: This function prints the list ace information.
54  *      Arguments: info - an info structure.
55  *      Returns: none.
56  */
57
58 static void PrintListAce(char **info)
59 {
60   char buf[BUFSIZ];
61
62   sprintf(buf, "Item: %-20s Name: %s", info[ACE_TYPE], info[ACE_NAME]);
63   Put_message(buf);
64 }
65
66 /*      Function Name: PrintListInfo
67  *      Description: This function Prints out the List info in a coherent form.
68  *      Arguments: info - the List info.
69  *      Returns: none.
70  */
71
72 static void PrintListInfo(char **info)
73 {
74   char buf[BUFSIZ];
75
76   Put_message(" ");
77   sprintf(buf, "%20sList: %s", "", info[L_NAME]);
78   Put_message(buf);
79   sprintf(buf, "Description: %s", info[L_DESC]);
80   Put_message(buf);
81   if (atoi(info[L_MAILLIST]))
82     Put_message("This list is a mailing list.");
83   else
84     Put_message("This list is NOT a mailing list.");
85   if (atoi(info[L_GROUP]))
86     {
87       sprintf(buf, "This list is a Group and its ID number is %s",
88               info[L_GID]);
89       Put_message(buf);
90     }
91   else
92     Put_message("This list is NOT a Group.");
93
94   if (!strcmp(info[L_ACE_TYPE], "NONE"))
95     Put_message("This list has no Administrator, how strange?!");
96   else
97     {
98       sprintf(buf, "The Administrator of this list is the %s: %s",
99               info[L_ACE_TYPE], info[L_ACE_NAME]);
100       Put_message(buf);
101     }
102
103   sprintf(buf, "This list is: %s, %s, and %s",
104           atoi(info[L_ACTIVE]) ? "active" : "inactive",
105           atoi(info[L_PUBLIC]) ? "public" : "private",
106           atoi(info[L_HIDDEN]) ? "hidden" : "visible");
107   Put_message(buf);
108   sprintf(buf, MOD_FORMAT, info[L_MODBY], info[L_MODTIME], info[L_MODWITH]);
109   Put_message(buf);
110 }
111
112 /*      Function Name: GetListInfo
113  *      Description: Stores all info about a group of lists in a queue.
114  *      Arguments: type - type of info to store.
115  *                 name - name of the info.
116  *      Returns: the first element in the queue.
117  */
118
119 struct qelem *GetListInfo(int type, char *name1, char *name2)
120 {
121   char *args[2];
122   struct qelem *elem = NULL;
123   register int status;
124
125   switch (type)
126     {
127     case LIST:
128       args[0] = name1;
129       if ((status = do_mr_query("get_list_info", 1, args,
130                                 StoreInfo, (char *) &elem)))
131         {
132           com_err(program_name, status, " in get_list_info");
133           return NULL;
134         }
135       break;
136     case MEMBERS:
137       args[0] = name1;
138       if ((status = do_mr_query("get_members_of_list", 1, args,
139                                 StoreInfo, (char *) &elem)))
140         {
141           com_err(program_name, status, " in get_members_of_list");
142           return NULL;
143         }
144       break;
145     case GLOM:
146       args[0] = name1;
147       args[1] = name2;
148       if ((status = do_mr_query("get_lists_of_member", 2, args,
149                                 StoreInfo, (char *) &elem)))
150         {
151           com_err(program_name, status, " in get_list_of_members");
152           return NULL;
153         }
154       break;
155     case ACE_USE:
156       args[0] = name1;
157       args[1] = name2;
158       if ((status = do_mr_query("get_ace_use", 2, args,
159                                 StoreInfo, (char *) &elem)))
160         {
161           com_err(program_name, status, " in get_ace_use");
162           return NULL;
163         }
164       break;
165     }
166   return QueueTop(elem);
167 }
168
169 /*      Function Name: AskListInfo.
170  *      Description: This function askes the user for information about a
171  *                   machine and saves it into a structure.
172  *      Arguments: info - a pointer the the structure to put the
173  *                             info into.
174  *                 name - add a newname field? (T/F)
175  *      Returns: SUB_ERROR or SUB_NORMAL.
176  */
177
178 char **AskListInfo(char **info, Bool name)
179 {
180   char temp_buf[BUFSIZ], *newname;
181
182   Put_message(" ");
183   sprintf(temp_buf, "Setting information of list %s.", info[L_NAME]);
184   Put_message(temp_buf);
185   Put_message(" ");
186
187   if (name)
188     {
189       while (1)
190         {
191           newname = Strsave(info[L_NAME]);
192           if (GetValueFromUser("The new name for this list", &newname) ==
193               SUB_ERROR)
194             return NULL;
195           if (ValidName(newname))
196             break;
197         }
198     }
199   if (GetYesNoValueFromUser("Is this an active list", &info[L_ACTIVE]) ==
200       SUB_ERROR)
201     return NULL;
202   if (GetYesNoValueFromUser("Is this a public list", &info[L_PUBLIC]) ==
203       SUB_ERROR)
204     return NULL;
205   if (GetYesNoValueFromUser("Is this a hidden list", &info[L_HIDDEN]) ==
206       SUB_ERROR)
207     return NULL;
208   if (GetYesNoValueFromUser("Is this a maillist", &info[L_MAILLIST]) ==
209       SUB_ERROR)
210     return NULL;
211   if (GetYesNoValueFromUser("Is this a group", &info[L_GROUP]) == SUB_ERROR)
212     return NULL;
213   if (atoi(info[L_GROUP]))
214     {
215       if (GetValueFromUser("What is the GID for this group.", &info[L_GID]) ==
216           SUB_ERROR)
217         return NULL;
218     }
219
220   if (GetTypeFromUser("What Type of Administrator", "ace_type",
221                       &info[L_ACE_TYPE]) == SUB_ERROR)
222     return NULL;
223   if (strcasecmp(info[L_ACE_TYPE], "NONE") &&
224       strcasecmp(info[L_ACE_TYPE], "none"))
225     {
226       sprintf(temp_buf, "Which %s will be the administrator of this list: ",
227               info[L_ACE_TYPE]);
228       if (GetValueFromUser(temp_buf, &info[L_ACE_NAME]) == SUB_ERROR)
229         return NULL;
230     }
231   if (GetValueFromUser("Description: ", &info[L_DESC]) == SUB_ERROR)
232     return NULL;
233
234   FreeAndClear(&info[L_MODTIME], TRUE);
235   FreeAndClear(&info[L_MODBY], TRUE);
236   FreeAndClear(&info[L_MODWITH], TRUE);
237   /*
238    * Slide the newname into the #2 slot, this screws up all future references
239    * to this list.
240    */
241   if (name)                     /* slide the newname into the #2 slot. */
242     SlipInNewName(info, newname);
243
244   return info;
245 }
246
247 /* -------------- List functions. -------------- */
248
249 /*      Function Name: ShowListInfo.
250  *      Description: shows info on a list.
251  *      Arguments: argc, argv - name of list in argv[1].
252  *      Returns: DM status code.
253  */
254
255 int ShowListInfo(int argc, char **argv)
256 {
257   struct qelem *top, *list;
258
259   top = list = GetListInfo(LIST, argv[1], NULL);
260   while (list)
261     {
262       PrintListInfo((char **) list->q_data);
263       list = list->q_forw;
264     }
265
266   FreeQueue(top);
267   return DM_NORMAL;
268 }
269
270 /*      Function Name: RealUpdateList
271  *      Description: performs the actual update of the list.
272  *      Arguments: info - all information needed to update the list.
273  *                 junk - an UNUSED boolean.
274  *      Returns: none.
275  */
276
277 static void RealUpdateList(char **info, Bool junk)
278 {
279   register int stat;
280   char **args;
281   struct qelem *elem = NULL;
282
283   if (!(args = AskListInfo(info, TRUE)))
284     {
285       Put_message("Aborted.");
286       return;
287     }
288
289   /*
290    * If the new list name is less than 8 characters, make sure it doesn't
291    * collide with a username.
292    */
293   if ((strlen(args[2]) <= 8) &&
294       do_mr_query("get_user_account_by_login", 1, args + 1,
295                   StoreInfo, (char *) &elem) != MR_NO_MATCH)
296     {
297       char buf[256];
298
299       sprintf(buf, "\nA user by the name `%s' already exists in the database.",
300               args[1]);
301       Put_message(buf);
302       Loop(QueueTop(elem), FreeInfo);
303       FreeQueue(elem);
304       if (YesNoQuestion("Do you still want to rename this list to that name",
305                         FALSE) != TRUE)
306         {
307           Put_message("List ** NOT ** Updated.");
308           return;
309         }
310     }
311
312   if ((stat = do_mr_query("update_list", CountArgs(args), args,
313                           Scream, (char *) NULL)) != MR_SUCCESS)
314     {
315       com_err(program_name, stat, " in UpdateList.");
316       Put_message("List ** NOT ** Updated.");
317     }
318   else
319     Put_message("List successfully updated.");
320 }
321
322 /*      Function Name: UpdateList
323  *      Description: updates the information on a list.
324  *      Arguments: argc, argv - name of list in argv[1].
325  *      Returns: DM Status code.
326  */
327
328 int UpdateList(int argc, char **argv)
329 {
330   struct qelem *top;
331
332   top = GetListInfo(LIST, argv[1], (char *) NULL);
333   QueryLoop(top, NullPrint, RealUpdateList, "Update the list");
334
335   FreeQueue(top);
336   return DM_NORMAL;
337 }
338
339 /*      Function Name: SetDefaults
340  *      Description: sets defaults for AddList function
341  *      Arguments: info - the array to add them to.
342  *                 name - name of the program to add.
343  *      Returns: defaults - the default information.
344  */
345
346 static char **SetDefaults(char **info, char *name)
347 {
348   info[L_NAME] =     Strsave(name);
349   info[L_ACTIVE] =   Strsave(DEFAULT_ACTIVE);
350   info[L_PUBLIC] =   Strsave(DEFAULT_PUBLIC);
351   info[L_HIDDEN] =   Strsave(DEFAULT_HIDDEN);
352   info[L_MAILLIST] = Strsave(DEFAULT_MAILLIST);
353   info[L_GROUP] =    Strsave(DEFAULT_GROUP);
354   info[L_GID] =      Strsave(DEFAULT_GID);
355   info[L_ACE_TYPE] = Strsave(DEFAULT_ACE_TYPE);
356   info[L_ACE_NAME] = Strsave(DEFAULT_ACE_NAME);
357   info[L_DESC] =     Strsave(DEFAULT_DESCRIPTION);
358   info[L_MODTIME] = info[L_MODBY] = info[L_MODWITH] = info[L_END] = NULL;
359   return info;
360 }
361
362 /*      Function Name: AddList
363  *      Description:
364  *      Arguments: argc, argv - name of list in argv[1].
365  *      Returns: SUB_ERROR if list not created.
366  */
367
368 int AddList(int argc, char **argv)
369 {
370   static char *info[MAX_ARGS_SIZE], **add_args;
371   int status, ret_code = SUB_NORMAL;
372   struct qelem *elem = NULL;
373
374   if (!ValidName(argv[1]))
375     return DM_NORMAL;
376   status = do_mr_query("get_list_info", 1, argv + 1, NullFunc, NULL);
377   if (status != MR_NO_MATCH)
378     {
379       if (status == MR_SUCCESS)
380         Put_message("This list already exists.");
381       else
382         com_err(program_name, status, " in AddList.");
383       return SUB_ERROR;
384     }
385
386   /*
387    * If the listname is less than 8 characters, make sure it doesn't
388    * collide with a username.
389    */
390   if ((strlen(argv[1]) <= 8) &&
391       do_mr_query("get_user_account_by_login", 1, argv + 1,
392                   StoreInfo, (char *) &elem) != MR_NO_MATCH)
393     {
394       char buf[256];
395
396       sprintf(buf, "\nA user by the name `%s' already exists in the database.",
397               argv[1]);
398       Put_message(buf);
399       Loop(QueueTop(elem), FreeInfo);
400       FreeQueue(elem);
401       if (YesNoQuestion("Crate a list with the same name", FALSE) != TRUE)
402         return SUB_ERROR;
403     }
404
405   if (!(add_args = AskListInfo(SetDefaults(info, argv[1]), FALSE)))
406     {
407       Put_message("Aborted.");
408       return SUB_ERROR;
409     }
410
411   if ((status = do_mr_query("add_list", CountArgs(add_args), add_args,
412                             Scream, (char *) NULL)) != MR_SUCCESS)
413     {
414       com_err(program_name, status, " in AddList.");
415       Put_message("List Not Created.");
416       ret_code = SUB_ERROR;
417     }
418
419   FreeInfo(info);
420   return ret_code;
421 }
422
423 /*      Function Name: Instructions
424  *      Description: This func prints out instruction on manipulating lists.
425  *      Arguments: none
426  *      Returns: DM Status Code.
427  */
428
429 int ListHelp(void)
430 {
431   static char *message[] = {
432     "Listmaint handles the creation, deletion, and updating of lists.",
433     "A list can be a mailing list, a group list, or both.",
434     "The concept behind lists is that a list has an owner",
435     "- administrator -  and members.",
436     "The administrator of a list may be another list.",
437     "The members of a list can be users (login names), other lists,",
438     "or address strings.",
439     "You can use certain keys to do the following:",
440     "    Refresh the screen - Type ctrl-L.",
441     "    Escape from a function - Type ctrl-C.",
442     "    Suspend the program (temporarily) - Type ctrl-Z.",
443     NULL,
444   };
445
446   return PrintHelp(message);
447 }
448
449 /*-*-* LISTMAINT UPDATE MENU *-*-*/
450
451 /*      Function Name: ListmaintMemberMenuEntry
452  *      Description: entry routine into the listmaint member menu.
453  *      Arguments: m - the member menu.
454  *                 argc, argv - name of the list in argv[1].
455  *      Returns: none.
456  */
457
458 int ListmaintMemberMenuEntry(Menu *m, int argc, char **argv)
459 {
460   char temp_buf[BUFSIZ];
461   char *list_name = argv[1];
462   register int stat;
463
464   if (!ValidName(list_name))
465     return DM_QUIT;
466
467   if (*argv[0] == 'a')
468     {   /* add_list */
469       if (AddList(argc, argv) == SUB_ERROR)
470         return DM_QUIT;
471       sprintf(temp_buf, "List '%s' created. Do you want to %s", list_name,
472               "change its membership (y/n)? ");
473       if (YesNoQuestion(temp_buf, TRUE) != TRUE)
474         return DM_QUIT;
475     }
476   else
477     /* All we want to know is if it exists. */
478     switch ((stat = do_mr_query("count_members_of_list", 1, argv + 1,
479                                 NullFunc, NULL)))
480       {
481       case MR_SUCCESS:
482         break;
483       case MR_LIST:
484         Put_message("This list does not exist.");
485         return DM_QUIT;
486       case MR_PERM:
487         Put_message("You are not allowed to view this list.");
488         break;
489       default:
490         com_err(program_name, stat, " in get_list_info");
491         return DM_QUIT;
492       }
493
494   sprintf(temp_buf, "Change/Display membership of '%s'", list_name);
495   m->m_title = Strsave(temp_buf);
496   strcpy(current_list, list_name);
497   return DM_NORMAL;
498 }
499
500 /*      Function Name: ListmaintMemberMenuExit
501  *      Description: This is the function called when the member menu is
502  *                   exited, it frees the memory that is storing the name.
503  *      Arguments: m - the menu
504  *      Returns: DM_NORMAL
505  */
506
507 int ListmaintMemberMenuExit(Menu *m)
508 {
509   free(m->m_title);
510   strcpy(current_list, "");
511   return DM_NORMAL;
512 }
513
514 /*      Function Name: ListMembersByType
515  *      Description: This function lists the users of a list by type.
516  *      Arguments: type - the type of the list "USER", "LIST", or "STRING".
517  *      Returns: none.
518  *      NOTE: if type is NULL, all lists members are listed.
519  */
520
521 int ListMembersByType(char *type)
522 {
523   char temp_buf[BUFSIZ];
524   register int status;
525   char *args[10];
526
527   args[0] = current_list;
528   args[1] = NULL;
529
530   found_some = FALSE;
531   if ((status = do_mr_query("get_members_of_list", CountArgs(args), args,
532                             PrintByType, type)))
533     {
534       com_err(program_name, status, " in ListMembersByType");
535       return DM_NORMAL;
536     }
537   if (!found_some)
538     {
539       if (!type)
540         Put_message("List is empty (no members).");
541       else
542         {
543           sprintf(temp_buf, "No %s Members", type);
544           Put_message(temp_buf);
545         }
546     }
547 }
548
549 /*      Function Name: ListAllMembers
550  *      Description: lists all members of the current list.
551  *      Arguments:
552  *      Returns: DM_NORMAL
553  */
554
555 int ListAllMembers(void)
556 {
557   ListMembersByType(NULL);
558   return DM_NORMAL;
559 }
560
561 /*      Function Name: ListUserMembers
562  *      Description: This function lists all members of a list of type "USER".
563  *      Arguments: none
564  *      Returns: DM_NORMAL.
565  */
566
567 int ListUserMembers(void)
568 {
569   ListMembersByType("USER");
570   return DM_NORMAL;
571 }
572
573 /*      Function Name: ListListMembers
574  *      Description: This function lists all members of a list of type "LIST".
575  *      Arguments: none
576  *      Returns: DM_NORMAL.
577  */
578
579 int ListListMembers(void)
580 {
581   ListMembersByType("LIST");
582   return DM_NORMAL;
583 }
584
585 /*      Function Name: ListStringMembers
586  *      Description:This function lists all members of a list of type "STRING".
587  *      Arguments: none
588  *      Returns: DM_NORMAL.
589  */
590
591 int ListStringMembers(void)
592 {
593   ListMembersByType("STRING");
594   return DM_NORMAL;
595 }
596
597 /*      Function Name: GetMemberInfo
598  *      Description: This function gets the information needed to
599  *                   add or delete a user from a list.
600  *      Arguments: argc, argv - standard.
601  *                 action - name of the action to be performed either
602  *                          "add" or "delete".
603  *                 ret_argc, ret_argv - the returned value of argc and argv.
604  *      Returns: SUB_ERROR or SUB_NORMAL.
605  */
606
607 int GetMemberInfo(char *action, char **ret_argv)
608 {
609   char temp_buf[BUFSIZ];
610
611   ret_argv[LM_LIST] = Strsave(current_list);
612
613   ret_argv[LM_TYPE] = Strsave("user");
614   if (GetTypeFromUser("Type of member", "member", &ret_argv[LM_TYPE]) ==
615       SUB_ERROR)
616     return SUB_ERROR;
617
618   sprintf(temp_buf, "Name of %s to %s", ret_argv[LM_TYPE], action);
619   ret_argv[LM_MEMBER] = Strsave(user);
620   if (GetValueFromUser(temp_buf, &ret_argv[LM_MEMBER]) == SUB_ERROR)
621     return SUB_ERROR;
622   ret_argv[LM_END] = NULL;              /* NULL terminate this list. */
623
624   if (strcasecmp(ret_argv[LM_TYPE], "string") &&
625       !ValidName(ret_argv[LM_MEMBER]))
626     {
627       FreeInfo(ret_argv);
628       return SUB_ERROR;
629     }
630   return SUB_NORMAL;
631 }
632
633 /*      Function Name: AddMember
634  *      Description: This function adds a member to a list.
635  *      Arguments: none.
636  *      Returns: DM_NORMAL.
637  */
638
639 int AddMember(void)
640 {
641   char *args[10], temp_buf[BUFSIZ], *p;
642   register int status;
643   struct qelem *mailhubs, *elem, *GetTypeValues();
644
645   if (GetMemberInfo("add", args) == SUB_ERROR)
646     return DM_NORMAL;
647
648   if (!strcmp(args[LM_TYPE], "STRING"))
649     {
650       if ((p = strchr(args[LM_MEMBER], '@')))
651         {
652           char *host = canonicalize_hostname(strsave(++p));
653           mailhubs = GetTypeValues("mailhub");
654           for (elem = mailhubs; elem; elem = elem->q_forw)
655             {
656               if (!strcasecmp(host, elem->q_data))
657                 {
658                   free(host);
659                   host = strsave(args[LM_MEMBER]);
660                   *(--p) = 0;
661                   sprintf(temp_buf, "String \"%s\" should be USER or LIST "
662                           "\"%s\" because it is a local name.", host,
663                           args[LM_MEMBER]);
664                   Put_message(temp_buf);
665                   free(args[LM_TYPE]);
666                   free(host);
667                   return DM_NORMAL;
668                 }
669             }
670           free(host);
671         }
672       else if (!strchr(args[LM_MEMBER], '!'))
673         {
674           Put_message("Member which is not a foreign mail address "
675                       "should not be type STRING.");
676           return DM_NORMAL;
677         }
678     }
679
680   if ((status = do_mr_query("add_member_to_list", CountArgs(args), args,
681                             Scream, NULL)) != MR_SUCCESS)
682     {
683       if (status == MR_EXISTS)
684         {
685           sprintf(temp_buf, "The %s %s is already a member of LIST %s.",
686                   args[LM_TYPE], args[LM_MEMBER], args[LM_LIST]);
687           Put_message(temp_buf);
688         }
689       else
690         com_err(program_name, status, " in AddMember");
691     }
692
693   FreeInfo(args);
694   return DM_NORMAL;
695 }
696
697 /*      Function Name: DeleteMember
698  *      Description: This function deletes a member from a list.
699  *      Arguments: none.
700  *      Returns: DM_NORMAL
701  */
702
703 int DeleteMember(void)
704 {
705   char *args[10];
706   register int status;
707
708   if (GetMemberInfo("delete", args) == SUB_ERROR)
709     return DM_NORMAL;
710
711   if (Confirm("Are you sure you want to delete this member?"))
712     {
713       if ((status = do_mr_query("delete_member_from_list", CountArgs(args),
714                                 args, Scream, NULL)))
715         com_err(program_name, status, " in DeleteMember");
716       else
717         Put_message("Deletion Completed.");
718     }
719   else
720     Put_message("Deletion has been Aborted.");
721
722   FreeInfo(args);
723   return DM_NORMAL;
724 }
725
726 /*      Function Name: InterRemoveItemFromLists
727  *      Description: This function allows interactive removal of an item
728  *                   (user, string, list) for all list  that it is on.
729  *      Arguments: none.
730  *      Returns: DM_NORMAL.
731  *      NOTES: QueryLoop() does not work here because info does not have
732  *             enough information in it to delete the member from the list.
733  */
734
735 int InterRemoveItemFromLists(void)
736 {
737   register int status;
738   char *type, *name, *args[10], buf[BUFSIZ];
739   struct qelem *top, *elem;
740
741   type = strsave("USER");
742   if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
743     return DM_NORMAL;
744
745   sprintf(buf, "Name of %s", type);
746   name = strsave(user);
747   if (GetValueFromUser(buf, &name) == SUB_ERROR)
748     return DM_NORMAL;
749
750   if (!ValidName(name))
751     return DM_NORMAL;
752
753   top = elem = GetListInfo(GLOM, type, name);
754
755   while (elem)
756     {
757       char line[BUFSIZ];
758       char **info = (char **) elem->q_data;
759       sprintf(line, "Delete %s %s from the list \"%s\" (y/n/q)? ", type,
760               name, info[GLOM_NAME]);
761       switch (YesNoQuitQuestion(line, FALSE))
762         {
763         case TRUE:
764           Put_message("deleting...");
765           args[DM_LIST] = info[GLOM_NAME];
766           args[DM_TYPE] = type;
767           args[DM_MEMBER] = name;
768           if ((status = do_mr_query("delete_member_from_list", 3, args,
769                                     Scream, (char *) NULL)))
770             {
771               /* should probabally check to delete list. */
772               com_err(program_name, status, " in delete_member");
773             }
774           break;
775         case FALSE:
776           break;
777         default:
778           Put_message("Aborting...");
779           FreeQueue(top);
780           return DM_NORMAL;
781         }
782       elem = elem->q_forw;
783     }
784   FreeQueue(top);
785   return DM_NORMAL;
786 }
787
788 /*-*-* LIST MENU *-*-*/
789
790 /*      Function Name: ListByMember
791  *      Description: This gets all lists that a given member is a member of.
792  *      Arguments: none.
793  *      Returns: DM_NORMAL.
794  */
795
796 int ListByMember(void)
797 {
798   char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name, **info;
799   Bool maillist, group;
800   struct qelem *top, *elem;
801
802   type = strsave("USER");
803   if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
804     return DM_NORMAL;
805
806   sprintf(buf, "Name of %s", type);
807   name = strsave(user);
808   if (GetValueFromUser(buf, &name) == SUB_ERROR)
809     return DM_NORMAL;
810
811   /* What we really want is a recursive search */
812   sprintf(temp_buf, "R%s", type);
813   free(type);
814   type = Strsave(temp_buf);
815
816   if ((maillist = YesNoQuestion("Show Lists that are Maillists (y/n) ?",
817                                 TRUE)) == -1)
818     return DM_NORMAL;
819   if ((group = YesNoQuestion("Show Lists that are Groups (y/n) ?",
820                              TRUE)) == -1)
821     return DM_NORMAL;
822
823   elem = top = GetListInfo(GLOM, type, name);
824
825   while (elem)
826     {
827       info = (char **) elem->q_data;
828       if ((maillist == TRUE && !strcmp(info[GLOM_MAILLIST], "1")) ||
829           (group == TRUE && !strcmp(info[GLOM_GROUP], "1")))
830         Put_message(info[GLOM_NAME]);
831       elem = elem->q_forw;
832     }
833   FreeQueue(top);
834   return DM_NORMAL;
835 }
836
837 /*      Function Name: ListByAdministrator
838  *      Description: This function prints all lists which a given user or
839  *                   group administers.
840  *      Arguments: none.
841  *      Returns: DM_NORMAL.
842  */
843
844 int ListByAdministrator(void)
845 {
846   char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name;
847   struct qelem *top;
848
849   type = strsave("USER");
850   if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
851     return DM_NORMAL;
852
853   sprintf(buf, "Name of %s", type);
854   name = strsave(user);
855   if (GetValueFromUser(buf, &name) == SUB_ERROR)
856     return DM_NORMAL;
857
858   switch (YesNoQuestion("Do you want a recursive search (y/n)", FALSE))
859     {
860     case TRUE:
861       sprintf(temp_buf, "R%s", type);   /* "USER" to "RUSER" etc. */
862       free(type);
863       type = Strsave(temp_buf);
864       break;
865     case FALSE:
866       break;
867     default:
868       return DM_NORMAL;
869     }
870
871   top = GetListInfo(ACE_USE, type, name);
872   Loop(top, PrintListAce);
873
874   FreeQueue(top);
875   return DM_NORMAL;
876 }
877
878 /*      Function Name: ListAllPublicMailLists
879  *      Description: This function lists all public mailing lists.
880  *      Arguments: none
881  *      Returns: DM_NORMAL.
882  */
883
884 int ListAllPublicMailLists(void)
885 {
886   register int status;
887   static char *args[] = {
888     "TRUE",                     /* active */
889     "TRUE",                     /* public */
890     "FALSE",                    /* hidden */
891     "TRUE",                     /* maillist */
892     "DONTCARE",                 /* group. */
893   };
894
895   if (YesNoQuestion("This query will take a while. Do you wish to continue?",
896                     TRUE) == TRUE)
897     {
898       if (status = do_mr_query("qualified_get_lists", 5, args,
899                                Print, NULL) != MR_SUCCESS)
900         com_err(program_name, status, " in ListAllGroups");
901     }
902
903   return DM_NORMAL;
904 }
This page took 0.098152 seconds and 3 git commands to generate.