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