]> andersk Git - moira.git/blob - clients/moira/lists.c
Fix typo.
[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 mqelem *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, int tags);
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
54 /*      Function Name: PrintListAce
55  *      Description: This function prints the list ace information.
56  *      Arguments: info - an info structure.
57  *      Returns: none.
58  */
59
60 static void PrintListAce(char **info)
61 {
62   char buf[BUFSIZ];
63
64   sprintf(buf, "Item: %-20s Name: %s", info[ACE_TYPE], info[ACE_NAME]);
65   Put_message(buf);
66 }
67
68 /*      Function Name: PrintListInfo
69  *      Description: This function Prints out the List info in a coherent form.
70  *      Arguments: info - the List info.
71  *      Returns: none.
72  */
73
74 static void PrintListInfo(char **info)
75 {
76   char buf[BUFSIZ];
77
78   Put_message(" ");
79   sprintf(buf, "%20sList: %s", "", info[L_NAME]);
80   Put_message(buf);
81   sprintf(buf, "Description: %s", info[L_DESC]);
82   Put_message(buf);
83   if (atoi(info[L_MAILLIST]))
84     Put_message("This list is a mailing list.");
85   else
86     Put_message("This list is NOT a mailing list.");
87   if (atoi(info[L_GROUP]))
88     {
89       sprintf(buf, "This list is a Group and its ID number is %s",
90               info[L_GID]);
91       Put_message(buf);
92     }
93   else
94     Put_message("This list is NOT a Group.");
95
96   if (!strcmp(info[L_ACE_TYPE], "NONE"))
97     Put_message("This list has no Administrator, how strange?!");
98   else
99     {
100       sprintf(buf, "The Administrator of this list is the %s: %s",
101               info[L_ACE_TYPE], info[L_ACE_NAME]);
102       Put_message(buf);
103     }
104
105   sprintf(buf, "This list is: %s, %s, and %s",
106           atoi(info[L_ACTIVE]) ? "active" : "inactive",
107           atoi(info[L_PUBLIC]) ? "public" : "private",
108           atoi(info[L_HIDDEN]) ? "hidden" : "visible");
109   Put_message(buf);
110   sprintf(buf, MOD_FORMAT, info[L_MODBY], info[L_MODTIME], info[L_MODWITH]);
111   Put_message(buf);
112 }
113
114 /*      Function Name: GetListInfo
115  *      Description: Stores all info about a group of lists in a queue.
116  *      Arguments: type - type of info to store.
117  *                 name - name of the info.
118  *      Returns: the first element in the queue.
119  */
120
121 struct mqelem *GetListInfo(int type, char *name1, char *name2)
122 {
123   char *args[2];
124   struct mqelem *elem = NULL;
125   int status;
126
127   switch (type)
128     {
129     case LIST:
130       args[0] = name1;
131       if ((status = do_mr_query("get_list_info", 1, args, StoreInfo, &elem)))
132         {
133           com_err(program_name, status, " in get_list_info");
134           return NULL;
135         }
136       break;
137     case MEMBERS:
138       args[0] = name1;
139       if ((status = do_mr_query("get_members_of_list", 1, args,
140                                 StoreInfo, &elem)))
141         {
142           com_err(program_name, status, " in get_members_of_list");
143           return NULL;
144         }
145       break;
146     case GLOM:
147       args[0] = name1;
148       args[1] = name2;
149       if ((status = do_mr_query("get_lists_of_member", 2, args,
150                                 StoreInfo, &elem)))
151         {
152           com_err(program_name, status, " in get_list_of_members");
153           return NULL;
154         }
155       break;
156     case ACE_USE:
157       args[0] = name1;
158       args[1] = name2;
159       if ((status = do_mr_query("get_ace_use", 2, args, StoreInfo, &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 = strdup(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 mqelem *top, *list;
258
259   top = list = GetListInfo(LIST, argv[1], NULL);
260   while (list)
261     {
262       PrintListInfo(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   int stat;
280   char **args;
281   struct mqelem *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, &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                           NULL, 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 mqelem *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] =     strdup(name);
349   info[L_ACTIVE] =   strdup(DEFAULT_ACTIVE);
350   info[L_PUBLIC] =   strdup(DEFAULT_PUBLIC);
351   info[L_HIDDEN] =   strdup(DEFAULT_HIDDEN);
352   info[L_MAILLIST] = strdup(DEFAULT_MAILLIST);
353   info[L_GROUP] =    strdup(DEFAULT_GROUP);
354   info[L_GID] =      strdup(DEFAULT_GID);
355   info[L_ACE_TYPE] = strdup(DEFAULT_ACE_TYPE);
356   info[L_ACE_NAME] = strdup(DEFAULT_ACE_NAME);
357   info[L_DESC] =     strdup(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 mqelem *elem = NULL;
373
374   if (!ValidName(argv[1]))
375     return DM_NORMAL;
376   status = do_mr_query("get_list_info", 1, argv + 1, NULL, 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, &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("Create 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                             NULL, 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(int argc, char **argv)
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   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                                 NULL, 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 = strdup(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  *                 tags - whether or not to display tags
518  *      Returns: none.
519  *      NOTE: if type is NULL, all lists members are listed.
520  */
521
522 void ListMembersByType(char *type, int tags)
523 {
524   char temp_buf[BUFSIZ];
525   int status;
526   char *args[10];
527
528   args[0] = current_list;
529   args[1] = NULL;
530
531   found_some = FALSE;
532   if ((status = do_mr_query(tags ? "get_tagged_members_of_list" :
533                             "get_members_of_list", CountArgs(args),
534                             args, PrintByType, type)))
535     com_err(program_name, status, " in ListMembersByType");
536   if (!found_some)
537     {
538       if (!type)
539         Put_message("List is empty (no members).");
540       else
541         {
542           sprintf(temp_buf, "No %s Members", type);
543           Put_message(temp_buf);
544         }
545     }
546 }
547
548 /*      Function Name: ListAllMembers
549  *      Description: lists all members of the current list.
550  *      Arguments:
551  *      Returns: DM_NORMAL
552  */
553
554 int ListAllMembers(int argc, char **argv)
555 {
556   ListMembersByType(NULL, 0);
557   return DM_NORMAL;
558 }
559
560 /*      Function Name: ListUserMembers
561  *      Description: This function lists all members of a list of type "USER".
562  *      Arguments: none
563  *      Returns: DM_NORMAL.
564  */
565
566 int ListUserMembers(int argc, char **argv)
567 {
568   ListMembersByType("USER", 0);
569   return DM_NORMAL;
570 }
571
572 /*      Function Name: ListListMembers
573  *      Description: This function lists all members of a list of type "LIST".
574  *      Arguments: none
575  *      Returns: DM_NORMAL.
576  */
577
578 int ListListMembers(int argc, char **argv)
579 {
580   ListMembersByType("LIST", 0);
581   return DM_NORMAL;
582 }
583
584 /*      Function Name: ListStringMembers
585  *      Description:This function lists all members of a list of type "STRING".
586  *      Arguments: none
587  *      Returns: DM_NORMAL.
588  */
589
590 int ListStringMembers(int argc, char **argv)
591 {
592   ListMembersByType("STRING", 0);
593   return DM_NORMAL;
594 }
595
596 /*      Function Name: GetMemberInfo
597  *      Description: This function gets the information needed to
598  *                   add or delete a user from a list.
599  *      Arguments: argc, argv - standard.
600  *                 action - name of the action to be performed either
601  *                          "add" or "delete".
602  *                 ret_argc, ret_argv - the returned value of argc and argv.
603  *      Returns: SUB_ERROR or SUB_NORMAL.
604  */
605
606 int GetMemberInfo(char *action, char **ret_argv)
607 {
608   char temp_buf[BUFSIZ];
609
610   ret_argv[LM_LIST] = strdup(current_list);
611
612   ret_argv[LM_TYPE] = strdup("user");
613   if (GetTypeFromUser("Type of member", "member", &ret_argv[LM_TYPE]) ==
614       SUB_ERROR)
615     return SUB_ERROR;
616
617   sprintf(temp_buf, "Name of %s to %s", ret_argv[LM_TYPE], action);
618   ret_argv[LM_MEMBER] = strdup(user);
619   if (GetValueFromUser(temp_buf, &ret_argv[LM_MEMBER]) == SUB_ERROR)
620     return SUB_ERROR;
621   ret_argv[LM_END] = NULL;              /* NULL terminate this list. */
622
623   if (strcasecmp(ret_argv[LM_TYPE], "string") &&
624       !ValidName(ret_argv[LM_MEMBER]))
625     {
626       FreeInfo(ret_argv);
627       return SUB_ERROR;
628     }
629   return SUB_NORMAL;
630 }
631
632 /*      Function Name: AddMember
633  *      Description: This function adds a member to a list.
634  *      Arguments: none.
635  *      Returns: DM_NORMAL.
636  */
637
638 int AddMember(int argc, char **argv)
639 {
640   char *args[10], temp_buf[BUFSIZ], *p;
641   int status;
642   struct mqelem *mailhubs, *elem;
643
644   if (GetMemberInfo("add", args) == SUB_ERROR)
645     return DM_NORMAL;
646
647   if (!strcmp(args[LM_TYPE], "STRING"))
648     {
649       if ((p = strchr(args[LM_MEMBER], '@')))
650         {
651           char *host = canonicalize_hostname(strdup(++p));
652           mailhubs = GetTypeValues("mailhub");
653           for (elem = mailhubs; elem; elem = elem->q_forw)
654             {
655               if (!strcasecmp(host, elem->q_data))
656                 {
657                   free(host);
658                   host = strdup(args[LM_MEMBER]);
659                   *(--p) = 0;
660                   sprintf(temp_buf, "String \"%s\" should be USER or LIST "
661                           "\"%s\" because it is a local name.", host,
662                           args[LM_MEMBER]);
663                   Put_message(temp_buf);
664                   free(args[LM_TYPE]);
665                   free(host);
666                   return DM_NORMAL;
667                 }
668             }
669           free(host);
670         }
671       else if (!strchr(args[LM_MEMBER], '!'))
672         {
673           Put_message("Member which is not a foreign mail address "
674                       "should not be type STRING.");
675           return DM_NORMAL;
676         }
677     }
678
679   if ((status = do_mr_query("add_member_to_list", CountArgs(args), args,
680                             NULL, NULL)) != MR_SUCCESS)
681     {
682       if (status == MR_EXISTS)
683         {
684           sprintf(temp_buf, "The %s %s is already a member of LIST %s.",
685                   args[LM_TYPE], args[LM_MEMBER], args[LM_LIST]);
686           Put_message(temp_buf);
687         }
688       else
689         com_err(program_name, status, " in AddMember");
690     }
691
692   FreeInfo(args);
693   return DM_NORMAL;
694 }
695
696 /*      Function Name: DeleteMember
697  *      Description: This function deletes a member from a list.
698  *      Arguments: none.
699  *      Returns: DM_NORMAL
700  */
701
702 int DeleteMember(int argc, char **argv)
703 {
704   char *args[10];
705   int status;
706
707   if (GetMemberInfo("delete", args) == SUB_ERROR)
708     return DM_NORMAL;
709
710   if (Confirm("Are you sure you want to delete this member?"))
711     {
712       if ((status = do_mr_query("delete_member_from_list", CountArgs(args),
713                                 args, NULL, NULL)))
714         com_err(program_name, status, " in DeleteMember");
715       else
716         Put_message("Deletion Completed.");
717     }
718   else
719     Put_message("Deletion has been Aborted.");
720
721   FreeInfo(args);
722   return DM_NORMAL;
723 }
724
725 /*      Function Name: TagMember
726  *      Description: Add a tag to a list member
727  *      Arguments:
728  *      Returns: DM_NORMAL
729  */
730
731 int TagMember(int argc, char **argv)
732 {
733   char *args[10];
734   int status;
735   char temp_buf[BUFSIZ];
736
737   if (GetMemberInfo("tag", args) == SUB_ERROR)
738     return DM_NORMAL;
739
740   args[LM_TAG] = strdup("");
741   if (GetValueFromUser("Tag" , &args[LM_TAG]) == SUB_ERROR)
742     {
743       Put_message("Aborted.");
744       return DM_NORMAL;
745     }
746   args[LM_TAG_END] = NULL;              /* NULL terminate this list. */
747
748   if ((status = do_mr_query("tag_member_of_list", CountArgs(args),
749                             args, NULL, NULL)))
750     com_err(program_name, status, " in TagMember");
751
752   FreeInfo(args);
753   return DM_NORMAL;
754 }
755
756 /*      Function Name: ListAllMembers
757  *      Description: lists all members of the current list.
758  *      Arguments:
759  *      Returns: DM_NORMAL
760  */
761
762 int ListMembersWithTags(int argc, char **argv)
763 {
764   ListMembersByType(NULL, 1);
765   return DM_NORMAL;
766 }
767
768 /*      Function Name: InterRemoveItemFromLists
769  *      Description: This function allows interactive removal of an item
770  *                   (user, string, list) for all list  that it is on.
771  *      Arguments: none.
772  *      Returns: DM_NORMAL.
773  *      NOTES: QueryLoop() does not work here because info does not have
774  *             enough information in it to delete the member from the list.
775  */
776
777 int InterRemoveItemFromLists(int argc, char **argv)
778 {
779   int status;
780   char *type, *name, *args[10], buf[BUFSIZ];
781   struct mqelem *top, *elem;
782
783   type = strdup("USER");
784   if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
785     return DM_NORMAL;
786
787   sprintf(buf, "Name of %s", type);
788   name = strdup(user);
789   if (GetValueFromUser(buf, &name) == SUB_ERROR)
790     return DM_NORMAL;
791
792   if (!ValidName(name))
793     return DM_NORMAL;
794
795   top = elem = GetListInfo(GLOM, type, name);
796
797   while (elem)
798     {
799       char line[BUFSIZ];
800       char **info = elem->q_data;
801       sprintf(line, "Delete %s %s from the list \"%s\" (y/n/q)? ", type,
802               name, info[GLOM_NAME]);
803       switch (YesNoQuitQuestion(line, FALSE))
804         {
805         case TRUE:
806           Put_message("deleting...");
807           args[DM_LIST] = info[GLOM_NAME];
808           args[DM_TYPE] = type;
809           args[DM_MEMBER] = name;
810           if ((status = do_mr_query("delete_member_from_list", 3, args,
811                                     NULL, NULL)))
812             {
813               /* should probabally check to delete list. */
814               com_err(program_name, status, " in delete_member");
815             }
816           break;
817         case FALSE:
818           break;
819         default:
820           Put_message("Aborting...");
821           FreeQueue(top);
822           return DM_NORMAL;
823         }
824       elem = elem->q_forw;
825     }
826   FreeQueue(top);
827   return DM_NORMAL;
828 }
829
830 /*-*-* LIST MENU *-*-*/
831
832 /*      Function Name: ListByMember
833  *      Description: This gets all lists that a given member is a member of.
834  *      Arguments: none.
835  *      Returns: DM_NORMAL.
836  */
837
838 int ListByMember(int argc, char **argv)
839 {
840   char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name, **info;
841   Bool maillist, group;
842   struct mqelem *top, *elem;
843
844   type = strdup("USER");
845   if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
846     return DM_NORMAL;
847
848   sprintf(buf, "Name of %s", type);
849   name = strdup(user);
850   if (GetValueFromUser(buf, &name) == SUB_ERROR)
851     return DM_NORMAL;
852
853   /* What we really want is a recursive search */
854   sprintf(temp_buf, "R%s", type);
855   free(type);
856   type = strdup(temp_buf);
857
858   if ((maillist = YesNoQuestion("Show Lists that are Maillists (y/n) ?",
859                                 TRUE)) == -1)
860     return DM_NORMAL;
861   if ((group = YesNoQuestion("Show Lists that are Groups (y/n) ?",
862                              TRUE)) == -1)
863     return DM_NORMAL;
864
865   elem = top = GetListInfo(GLOM, type, name);
866
867   while (elem)
868     {
869       info = elem->q_data;
870       if ((maillist == TRUE && !strcmp(info[GLOM_MAILLIST], "1")) ||
871           (group == TRUE && !strcmp(info[GLOM_GROUP], "1")))
872         Put_message(info[GLOM_NAME]);
873       elem = elem->q_forw;
874     }
875   FreeQueue(top);
876   return DM_NORMAL;
877 }
878
879 /*      Function Name: ListByAdministrator
880  *      Description: This function prints all lists which a given user or
881  *                   group administers.
882  *      Arguments: none.
883  *      Returns: DM_NORMAL.
884  */
885
886 int ListByAdministrator(int argc, char **argv)
887 {
888   char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name;
889   struct mqelem *top;
890
891   type = strdup("USER");
892   if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
893     return DM_NORMAL;
894
895   sprintf(buf, "Name of %s", type);
896   name = strdup(user);
897   if (GetValueFromUser(buf, &name) == SUB_ERROR)
898     return DM_NORMAL;
899
900   switch (YesNoQuestion("Do you want a recursive search (y/n)", FALSE))
901     {
902     case TRUE:
903       sprintf(temp_buf, "R%s", type);   /* "USER" to "RUSER" etc. */
904       free(type);
905       type = strdup(temp_buf);
906       break;
907     case FALSE:
908       break;
909     default:
910       return DM_NORMAL;
911     }
912
913   top = GetListInfo(ACE_USE, type, name);
914   Loop(top, PrintListAce);
915
916   FreeQueue(top);
917   return DM_NORMAL;
918 }
919
920 /*      Function Name: ListAllPublicMailLists
921  *      Description: This function lists all public mailing lists.
922  *      Arguments: none
923  *      Returns: DM_NORMAL.
924  */
925
926 int ListAllPublicMailLists(int argc, char **argv)
927 {
928   int status;
929   static char *args[] = {
930     "TRUE",                     /* active */
931     "TRUE",                     /* public */
932     "FALSE",                    /* hidden */
933     "TRUE",                     /* maillist */
934     "DONTCARE",                 /* group. */
935   };
936
937   if (YesNoQuestion("This query will take a while. Do you wish to continue?",
938                     TRUE) == TRUE)
939     {
940       if ((status = do_mr_query("qualified_get_lists", 5, args,
941                                 Print, NULL)) != MR_SUCCESS)
942         com_err(program_name, status, " in ListAllGroups");
943     }
944
945   return DM_NORMAL;
946 }
This page took 0.178847 seconds and 5 git commands to generate.