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