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.
8 * By: Chris D. Peterson
10 * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
11 * For copying and distribution information, please see the file
15 #include <mit-copyright.h>
18 #include <moira_site.h>
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);
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_MAILMAN DEFAULT_NO
48 #define DEFAULT_MAILMAN_SERVER "[ANY]"
49 #define DEFAULT_ACE_TYPE "user"
50 #define DEFAULT_ACE_NAME (user)
51 #define DEFAULT_MEMACE_TYPE "NONE"
52 #define DEFAULT_MEMACE_NAME "NONE"
53 #define DEFAULT_DESCRIPTION DEFAULT_COMMENT
55 /* globals only for this file. */
57 static char current_list[BUFSIZ];
60 /* Function Name: PrintListAce
61 * Description: This function prints the list ace information.
62 * Arguments: info - an info structure.
66 static void PrintListAce(char **info)
70 sprintf(buf, "Item: %-20s Name: %s", info[ACE_TYPE], info[ACE_NAME]);
74 /* Function Name: PrintListInfo
75 * Description: This function Prints out the List info in a coherent form.
76 * Arguments: info - the List info.
80 static void PrintListInfo(char **info)
85 sprintf(buf, "%20sList: %s", "", info[L_NAME]);
87 sprintf(buf, "Description: %s", info[L_DESC]);
89 if (atoi(info[L_MAILLIST]))
90 Put_message("This list is a mailing list.");
92 Put_message("This list is NOT a mailing list.");
93 if (atoi(info[L_GROUP]))
95 sprintf(buf, "This list is a Group%s and its ID number is %s",
96 atoi(info[L_NFSGROUP]) ? " and an NFS Group," : "",
101 Put_message("This list is NOT a Group.");
103 if (atoi(info[L_MAILMAN]))
105 sprintf(buf, "This list is a Mailman list on server %s",
106 info[L_MAILMAN_SERVER]);
110 if (!strcmp(info[L_ACE_TYPE], "NONE"))
111 Put_message("This list has no Administrator, how strange?!");
114 sprintf(buf, "The Administrator of this list is the %s: %s",
115 info[L_ACE_TYPE], info[L_ACE_NAME]);
119 if (strcmp(info[L_MEMACE_TYPE], "NONE"))
121 sprintf(buf, "The Membership Administrator of this list is the %s: %s",
122 info[L_MEMACE_TYPE], info[L_MEMACE_NAME]);
126 sprintf(buf, "This list is: %s, %s, and %s",
127 atoi(info[L_ACTIVE]) ? "active" : "inactive",
128 atoi(info[L_PUBLIC]) ? "public" : "private",
129 atoi(info[L_HIDDEN]) ? "hidden" : "visible");
131 sprintf(buf, MOD_FORMAT, info[L_MODBY], info[L_MODTIME], info[L_MODWITH]);
135 /* Function Name: GetListInfo
136 * Description: Stores all info about a group of lists in a queue.
137 * Arguments: type - type of info to store.
138 * name - name of the info.
139 * Returns: the first element in the queue.
142 struct mqelem *GetListInfo(int type, char *name1, char *name2)
145 struct mqelem *elem = NULL;
152 if ((status = do_mr_query("get_list_info", 1, args, StoreInfo, &elem)))
154 com_err(program_name, status, " in get_list_info");
160 if ((status = do_mr_query("get_members_of_list", 1, args,
163 com_err(program_name, status, " in get_members_of_list");
170 if (!strcmp(name1, "MACHINE"))
171 args[1] = canonicalize_hostname(strdup(name2));
172 if ((status = do_mr_query("get_lists_of_member", 2, args,
175 com_err(program_name, status, " in get_list_of_members");
182 if ((status = do_mr_query("get_ace_use", 2, args, StoreInfo, &elem)))
184 com_err(program_name, status, " in get_ace_use");
189 return QueueTop(elem);
192 /* Function Name: AskListInfo.
193 * Description: This function askes the user for information about a
194 * machine and saves it into a structure.
195 * Arguments: info - a pointer the the structure to put the
197 * name - add a newname field? (T/F)
198 * Returns: SUB_ERROR or SUB_NORMAL.
201 char **AskListInfo(char **info, Bool name)
203 char temp_buf[BUFSIZ], *newname;
207 sprintf(temp_buf, "Setting information of list %s.", info[L_NAME]);
208 Put_message(temp_buf);
215 newname = strdup(info[L_NAME]);
216 if (GetValueFromUser("The new name for this list", &newname) ==
219 if (ValidName(newname))
223 if (GetYesNoValueFromUser("Is this an active list", &info[L_ACTIVE]) ==
226 if (GetYesNoValueFromUser("Is this a public list", &info[L_PUBLIC]) ==
229 if (GetYesNoValueFromUser("Is this a hidden list", &info[L_HIDDEN]) ==
232 if (GetYesNoValueFromUser("Is this a maillist", &info[L_MAILLIST]) ==
235 if (GetYesNoValueFromUser("Is this a group", &info[L_GROUP]) == SUB_ERROR)
237 if (atoi(info[L_GROUP]))
239 if (GetYesNoValueFromUser("Is this an NFS group", &info[L_NFSGROUP]) ==
242 if (GetValueFromUser("What is the GID for this group.", &info[L_GID]) ==
247 if (GetYesNoValueFromUser("Is this a Mailman list", &info[L_MAILMAN]) ==
250 if (atoi(info[L_MAILMAN]))
252 if (GetValueFromUser("Mailman server", &info[L_MAILMAN_SERVER]) ==
255 info[L_MAILMAN_SERVER] = canonicalize_hostname(info[L_MAILMAN_SERVER]);
257 /* Change default owner */
258 strcpy(info[L_ACE_TYPE], "LIST");
259 strcpy(info[L_ACE_NAME], "mailman");
263 if (GetTypeFromUser("What Type of Administrator", "ace_type",
264 &info[L_ACE_TYPE]) == SUB_ERROR)
266 if (strcasecmp(info[L_ACE_TYPE], "none"))
268 sprintf(temp_buf, "Which %s will be the administrator of this list: ",
270 if (GetValueFromUser(temp_buf, &info[L_ACE_NAME]) == SUB_ERROR)
275 Put_message("Setting the administrator of this list to 'NONE'");
276 Put_message("will make you unable to further modify the list.");
277 if (YesNoQuestion("Do you really want to do this?", FALSE) == TRUE)
280 } while (!strcasecmp(info[L_ACE_TYPE], "none"));
282 if (!strcasecmp(info[L_ACE_TYPE], "kerberos"))
286 status = mrcl_validate_kerberos_member(info[L_ACE_NAME], &canon);
287 if (mrcl_get_message())
288 Put_message(mrcl_get_message());
289 if (status == MRCL_REJECT)
291 free(info[L_ACE_NAME]);
292 info[L_ACE_NAME] = canon;
296 if (GetTypeFromUser("What Type of Membership Administrator", "ace_type",
297 &info[L_MEMACE_TYPE]) == SUB_ERROR)
299 if (strcasecmp(info[L_MEMACE_TYPE], "none"))
301 sprintf(temp_buf, "Which %s will be the membership administrator of this list: ",
302 info[L_MEMACE_TYPE]);
303 if (GetValueFromUser(temp_buf, &info[L_MEMACE_NAME]) == SUB_ERROR)
308 Put_message("Setting the Membership Administrator of a Mailman list to 'NONE'");
309 Put_message("means no one will receive the list administrator password.");
310 if (YesNoQuestion("Do you really want to do this?", FALSE) == TRUE)
313 } while ((!strcasecmp(info[L_MEMACE_TYPE], "none")) &&
314 atoi(info[L_MAILMAN]));
316 if (!strcasecmp(info[L_MEMACE_TYPE], "kerberos"))
320 status = mrcl_validate_kerberos_member(info[L_MEMACE_NAME], &canon);
321 if (mrcl_get_message())
322 Put_message(mrcl_get_message());
323 if (status == MRCL_REJECT)
325 free(info[L_MEMACE_NAME]);
326 info[L_MEMACE_NAME] = canon;
328 if (GetValueFromUser("Description: ", &info[L_DESC]) == SUB_ERROR)
331 FreeAndClear(&info[L_MODTIME], TRUE);
332 FreeAndClear(&info[L_MODBY], TRUE);
333 FreeAndClear(&info[L_MODWITH], TRUE);
335 * Slide the newname into the #2 slot, this screws up all future references
338 if (name) /* slide the newname into the #2 slot. */
339 SlipInNewName(info, newname);
344 /* -------------- List functions. -------------- */
346 /* Function Name: ShowListInfo.
347 * Description: shows info on a list.
348 * Arguments: argc, argv - name of list in argv[1].
349 * Returns: DM status code.
352 int ShowListInfo(int argc, char **argv)
354 struct mqelem *top, *list;
356 top = list = GetListInfo(LIST, argv[1], NULL);
359 PrintListInfo(list->q_data);
367 /* Function Name: RealUpdateList
368 * Description: performs the actual update of the list.
369 * Arguments: info - all information needed to update the list.
370 * junk - an UNUSED boolean.
374 static void RealUpdateList(char **info, Bool junk)
378 struct mqelem *elem = NULL;
380 if (!(args = AskListInfo(info, TRUE)))
382 Put_message("Aborted.");
387 * If the new list name is less than 8 characters, make sure it doesn't
388 * collide with a username.
390 if ((strlen(args[2]) <= 8) &&
391 do_mr_query("get_user_account_by_login", 1, args + 1,
392 StoreInfo, &elem) != MR_NO_MATCH)
396 sprintf(buf, "\nA user by the name `%s' already exists in the database.",
399 Loop(QueueTop(elem), FreeInfo);
401 if (YesNoQuestion("Do you still want to rename this list to that name",
404 Put_message("List ** NOT ** Updated.");
409 if ((stat = do_mr_query("update_list", CountArgs(args), args,
410 NULL, NULL)) != MR_SUCCESS)
412 com_err(program_name, stat, " in UpdateList.");
413 Put_message("List ** NOT ** Updated.");
416 Put_message("List successfully updated.");
419 /* Function Name: UpdateList
420 * Description: updates the information on a list.
421 * Arguments: argc, argv - name of list in argv[1].
422 * Returns: DM Status code.
425 int UpdateList(int argc, char **argv)
429 top = GetListInfo(LIST, argv[1], (char *) NULL);
430 QueryLoop(top, NullPrint, RealUpdateList, "Update the list");
436 /* Function Name: SetDefaults
437 * Description: sets defaults for AddList function
438 * Arguments: info - the array to add them to.
439 * name - name of the program to add.
440 * Returns: defaults - the default information.
443 static char **SetDefaults(char **info, char *name)
445 info[L_NAME] = strdup(name);
446 info[L_ACTIVE] = strdup(DEFAULT_ACTIVE);
447 info[L_PUBLIC] = strdup(DEFAULT_PUBLIC);
448 info[L_HIDDEN] = strdup(DEFAULT_HIDDEN);
449 info[L_MAILLIST] = strdup(DEFAULT_MAILLIST);
450 info[L_GROUP] = strdup(DEFAULT_GROUP);
451 info[L_GID] = strdup(DEFAULT_GID);
452 info[L_NFSGROUP] = strdup(DEFAULT_NFSGROUP);
453 info[L_MAILMAN] = strdup(DEFAULT_MAILMAN);
454 info[L_MAILMAN_SERVER] = strdup(DEFAULT_MAILMAN_SERVER);
455 info[L_ACE_TYPE] = strdup(DEFAULT_ACE_TYPE);
456 info[L_ACE_NAME] = strdup(DEFAULT_ACE_NAME);
457 info[L_MEMACE_TYPE] = strdup(DEFAULT_MEMACE_TYPE);
458 info[L_MEMACE_NAME] = strdup(DEFAULT_MEMACE_NAME);
459 info[L_DESC] = strdup(DEFAULT_DESCRIPTION);
460 info[L_MODTIME] = info[L_MODBY] = info[L_MODWITH] = info[L_END] = NULL;
464 /* Function Name: AddList
466 * Arguments: argc, argv - name of list in argv[1].
467 * Returns: SUB_ERROR if list not created.
470 int AddList(int argc, char **argv)
472 static char *info[MAX_ARGS_SIZE], **add_args;
473 int status, ret_code = SUB_NORMAL;
474 struct mqelem *elem = NULL;
476 if (!ValidName(argv[1]))
478 status = do_mr_query("get_list_info", 1, argv + 1, NULL, NULL);
479 if (status != MR_NO_MATCH)
481 if (status == MR_SUCCESS)
482 Put_message("This list already exists.");
484 com_err(program_name, status, " in AddList.");
488 if (status = mr_access("add_list", L_MODTIME, SetDefaults(info, argv[1])))
490 com_err(program_name, status, " in AddList.");
495 * If the listname is less than 8 characters, make sure it doesn't
496 * collide with a username.
498 if ((strlen(argv[1]) <= 8) &&
499 do_mr_query("get_user_account_by_login", 1, argv + 1,
500 StoreInfo, &elem) != MR_NO_MATCH)
504 sprintf(buf, "\nA user by the name `%s' already exists in the database.",
507 Loop(QueueTop(elem), FreeInfo);
509 if (YesNoQuestion("Create a list with the same name", FALSE) != TRUE)
513 if (!(add_args = AskListInfo(SetDefaults(info, argv[1]), FALSE)))
515 Put_message("Aborted.");
519 if ((status = do_mr_query("add_list", CountArgs(add_args), add_args,
520 NULL, NULL)) != MR_SUCCESS)
522 com_err(program_name, status, " in AddList.");
523 Put_message("List Not Created.");
524 ret_code = SUB_ERROR;
527 if (atoi(add_args[L_MAILMAN]))
529 char mailman_address[256], buf[1024];
531 status = do_mr_query("get_list_info", 1, add_args, StoreInfo, &elem);
533 com_err(program_name, status, "while retrieving list information.");
536 strcpy(mailman_address, add_args[0]);
537 strcat(mailman_address, "@");
538 strcat(mailman_address, ((char **)elem->q_data)[L_MAILMAN_SERVER]);
539 sprintf(buf, "Add STRING %s to LIST %s", mailman_address,
541 if (YesNoQuestion(buf, TRUE) == TRUE)
544 args[0] = add_args[0];
546 args[2] = mailman_address;
548 status = do_mr_query("add_member_to_list", CountArgs(args), args,
551 com_err(program_name, status, "while adding member to list.");
560 /* Function Name: Instructions
561 * Description: This func prints out instruction on manipulating lists.
563 * Returns: DM Status Code.
566 int ListHelp(int argc, char **argv)
568 static char *message[] = {
569 "Listmaint handles the creation, deletion, and updating of lists.",
570 "A list can be a mailing list, a group list, or both.",
571 "The concept behind lists is that a list has an owner",
572 "- administrator - and members.",
573 "The administrator of a list may be another list.",
574 "The members of a list can be users (login names), other lists,",
575 "or address strings.",
576 "You can use certain keys to do the following:",
577 " Refresh the screen - Type ctrl-L.",
578 " Escape from a function - Type ctrl-C.",
579 " Suspend the program (temporarily) - Type ctrl-Z.",
583 return PrintHelp(message);
586 /*-*-* LISTMAINT UPDATE MENU *-*-*/
588 /* Function Name: ListmaintMemberMenuEntry
589 * Description: entry routine into the listmaint member menu.
590 * Arguments: m - the member menu.
591 * argc, argv - name of the list in argv[1].
595 int ListmaintMemberMenuEntry(Menu *m, int argc, char **argv)
597 char temp_buf[BUFSIZ];
598 char *list_name = argv[1];
601 if (!ValidName(list_name))
606 if (AddList(argc, argv) == SUB_ERROR)
608 sprintf(temp_buf, "List '%s' created. Do you want to %s", list_name,
609 "change its membership (y/n)? ");
610 if (YesNoQuestion(temp_buf, TRUE) != TRUE)
614 /* All we want to know is if it exists. */
615 switch ((stat = do_mr_query("count_members_of_list", 1, argv + 1,
621 Put_message("This list does not exist.");
624 Put_message("You are not allowed to view this list.");
627 com_err(program_name, stat, " in get_list_info");
631 sprintf(temp_buf, "Change/Display membership of '%s'", list_name);
632 m->m_title = strdup(temp_buf);
633 strcpy(current_list, list_name);
637 /* Function Name: ListmaintMemberMenuExit
638 * Description: This is the function called when the member menu is
639 * exited, it frees the memory that is storing the name.
640 * Arguments: m - the menu
644 int ListmaintMemberMenuExit(Menu *m)
647 strcpy(current_list, "");
651 /* Function Name: ListMembersByType
652 * Description: This function lists the users of a list by type.
653 * Arguments: type - the type of the list "USER", "LIST", or "STRING".
654 * tags - whether or not to display tags
656 * NOTE: if type is NULL, all lists members are listed.
659 void ListMembersByType(char *type, int tags)
661 char temp_buf[BUFSIZ];
665 args[0] = current_list;
669 if ((status = do_mr_query(tags ? "get_tagged_members_of_list" :
670 "get_members_of_list", CountArgs(args),
671 args, PrintByType, type)))
672 com_err(program_name, status, " in ListMembersByType");
676 Put_message("List is empty (no members).");
679 sprintf(temp_buf, "No %s Members", type);
680 Put_message(temp_buf);
685 /* Function Name: ListAllMembers
686 * Description: lists all members of the current list.
691 int ListAllMembers(int argc, char **argv)
693 ListMembersByType(NULL, 0);
697 /* Function Name: ListUserMembers
698 * Description: This function lists all members of a list of type "USER".
700 * Returns: DM_NORMAL.
703 int ListUserMembers(int argc, char **argv)
705 ListMembersByType("USER", 0);
709 /* Function Name: ListListMembers
710 * Description: This function lists all members of a list of type "LIST".
712 * Returns: DM_NORMAL.
715 int ListListMembers(int argc, char **argv)
717 ListMembersByType("LIST", 0);
721 /* Function Name: ListStringMembers
722 * Description:This function lists all members of a list of type "STRING".
724 * Returns: DM_NORMAL.
727 int ListStringMembers(int argc, char **argv)
729 ListMembersByType("STRING", 0);
733 /* Function Name: GetMemberInfo
734 * Description: This function gets the information needed to
735 * add or delete a user from a list.
736 * Arguments: argc, argv - standard.
737 * action - name of the action to be performed either
739 * ret_argc, ret_argv - the returned value of argc and argv.
740 * Returns: SUB_ERROR or SUB_NORMAL.
743 int GetMemberInfo(char *action, char **ret_argv)
745 char temp_buf[BUFSIZ];
747 ret_argv[LM_LIST] = strdup(current_list);
749 ret_argv[LM_TYPE] = strdup("user");
750 if (GetTypeFromUser("Type of member", "member", &ret_argv[LM_TYPE]) ==
754 sprintf(temp_buf, "Name of %s to %s", ret_argv[LM_TYPE], action);
755 ret_argv[LM_MEMBER] = strdup(user);
756 if (GetValueFromUser(temp_buf, &ret_argv[LM_MEMBER]) == SUB_ERROR)
758 ret_argv[LM_END] = NULL; /* NULL terminate this list. */
760 if (strcasecmp(ret_argv[LM_TYPE], "string") &&
761 !ValidName(ret_argv[LM_MEMBER]))
769 /* Function Name: AddMember
770 * Description: This function adds a member to a list.
772 * Returns: DM_NORMAL.
775 int AddMember(int argc, char **argv)
777 char *args[10], temp_buf[BUFSIZ], *p;
779 struct mqelem *mailhubs, *elem;
781 if (GetMemberInfo("add", args) == SUB_ERROR)
784 if (!strcmp(args[LM_TYPE], "STRING"))
786 status = mrcl_validate_string_member(args[LM_MEMBER]);
787 if (status != MRCL_SUCCESS)
788 Put_message(mrcl_get_message());
789 if (status == MRCL_REJECT)
792 else if (!strcmp(args[LM_TYPE], "KERBEROS"))
796 status = mrcl_validate_kerberos_member(args[LM_MEMBER], &canon);
797 if (mrcl_get_message())
798 Put_message(mrcl_get_message());
799 if (status == MRCL_REJECT)
801 free(args[LM_MEMBER]);
802 args[LM_MEMBER] = canon;
804 else if (!strcmp(args[LM_TYPE], "MACHINE"))
807 canon = canonicalize_hostname(strdup(args[LM_MEMBER]));
808 free(args[LM_MEMBER]);
809 args[LM_MEMBER] = canon;
812 if ((status = do_mr_query("add_member_to_list", CountArgs(args), args,
813 NULL, NULL)) != MR_SUCCESS)
815 if (status == MR_EXISTS)
817 sprintf(temp_buf, "The %s %s is already a member of LIST %s.",
818 args[LM_TYPE], args[LM_MEMBER], args[LM_LIST]);
819 Put_message(temp_buf);
822 com_err(program_name, status, " in AddMember");
829 /* Function Name: DeleteMember
830 * Description: This function deletes a member from a list.
835 int DeleteMember(int argc, char **argv)
840 if (GetMemberInfo("delete", args) == SUB_ERROR)
843 if (Confirm("Are you sure you want to delete this member?"))
845 if ((status = do_mr_query("delete_member_from_list", CountArgs(args),
848 if ((status == MR_STRING || status == MR_NO_MATCH) &&
849 !strcmp(args[LM_TYPE], "KERBEROS"))
852 mrcl_validate_kerberos_member(args[LM_MEMBER], &canon);
853 if (mrcl_get_message())
855 free(args[LM_MEMBER]);
856 args[LM_MEMBER] = canon;
857 if (do_mr_query("delete_member_from_list", CountArgs(args),
858 args, NULL, NULL) == MR_SUCCESS)
860 Put_message(mrcl_get_message());
865 else if ((status == MR_MACHINE || status == MR_NO_MATCH) &&
866 !strcmp(args[LM_TYPE], "MACHINE"))
869 canon = canonicalize_hostname(args[LM_MEMBER]);
870 free(args[LM_MEMBER]);
871 args[LM_MEMBER] = canon;
872 if (do_mr_query("delete_member_from_list", CountArgs(args),
873 args, NULL, NULL) == MR_SUCCESS)
878 com_err(program_name, status, " in DeleteMember");
880 Put_message("Deletion Completed.");
883 Put_message("Deletion has been Aborted.");
889 /* Function Name: TagMember
890 * Description: Add a tag to a list member
895 int TagMember(int argc, char **argv)
900 if (GetMemberInfo("tag", args) == SUB_ERROR)
903 args[LM_TAG] = strdup("");
904 if (GetValueFromUser("Tag" , &args[LM_TAG]) == SUB_ERROR)
906 Put_message("Aborted.");
909 args[LM_TAG_END] = NULL; /* NULL terminate this list. */
911 if ((status = do_mr_query("tag_member_of_list", CountArgs(args),
913 com_err(program_name, status, " in TagMember");
919 /* Function Name: ListAllMembers
920 * Description: lists all members of the current list.
925 int ListMembersWithTags(int argc, char **argv)
927 ListMembersByType(NULL, 1);
931 /* Function Name: InterRemoveItemFromLists
932 * Description: This function allows interactive removal of an item
933 * (user, string, list) for all list that it is on.
935 * Returns: DM_NORMAL.
936 * NOTES: QueryLoop() does not work here because info does not have
937 * enough information in it to delete the member from the list.
940 int InterRemoveItemFromLists(int argc, char **argv)
943 char *type, *name, *args[10], buf[BUFSIZ];
944 struct mqelem *top, *elem;
946 type = strdup("USER");
947 if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
950 sprintf(buf, "Name of %s", type);
952 if (GetValueFromUser(buf, &name) == SUB_ERROR)
955 if (!ValidName(name))
958 top = elem = GetListInfo(GLOM, type, name);
963 char **info = elem->q_data;
964 sprintf(line, "Delete %s %s from the list \"%s\" (y/n/q)? ", type,
965 name, info[GLOM_NAME]);
966 switch (YesNoQuitQuestion(line, FALSE))
969 Put_message("deleting...");
970 args[DM_LIST] = info[GLOM_NAME];
971 args[DM_TYPE] = type;
972 args[DM_MEMBER] = name;
973 if (!strcmp("MACHINE", type))
974 args[DM_MEMBER] = canonicalize_hostname(strdup(name));
975 if ((status = do_mr_query("delete_member_from_list", 3, args,
978 /* should probabally check to delete list. */
979 com_err(program_name, status, " in delete_member");
985 Put_message("Aborting...");
995 /*-*-* LIST MENU *-*-*/
997 /* Function Name: ListByMember
998 * Description: This gets all lists that a given member is a member of.
1000 * Returns: DM_NORMAL.
1003 int ListByMember(int argc, char **argv)
1005 char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name, **info;
1006 Bool maillist, group, neither;
1007 struct mqelem *top, *elem;
1009 type = strdup("USER");
1010 if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
1013 sprintf(buf, "Name of %s", type);
1014 name = strdup(user);
1015 if (GetValueFromUser(buf, &name) == SUB_ERROR)
1018 switch (YesNoQuestion("Do you want a recursive search (y/n)", TRUE))
1021 sprintf(temp_buf, "R%s", type); /* "USER" to "RUSER" etc. */
1023 type = strdup(temp_buf);
1031 if ((maillist = YesNoQuestion("Show Lists that are Maillists (y/n) ?",
1034 if ((group = YesNoQuestion("Show Lists that are Groups (y/n) ?",
1038 if ((neither = YesNoQuestion("Show Lists that are neither Maillists nor Groups (y/n) ?",
1042 elem = top = GetListInfo(GLOM, type, name);
1046 info = elem->q_data;
1047 if ((maillist == TRUE && !strcmp(info[GLOM_MAILLIST], "1")) ||
1048 (group == TRUE && !strcmp(info[GLOM_GROUP], "1")))
1049 Put_message(info[GLOM_NAME]);
1050 if (neither == TRUE && !strcmp(info[GLOM_MAILLIST], "0") &&
1051 !strcmp(info[GLOM_GROUP], "0"))
1052 Put_message(info[GLOM_NAME]);
1053 elem = elem->q_forw;
1059 /* Function Name: ListByAdministrator
1060 * Description: This function prints all lists which a given user or
1061 * group administers.
1063 * Returns: DM_NORMAL.
1066 int ListByAdministrator(int argc, char **argv)
1068 char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name;
1071 type = strdup("USER");
1072 if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
1075 sprintf(buf, "Name of %s", type);
1076 name = strdup(user);
1077 if (GetValueFromUser(buf, &name) == SUB_ERROR)
1080 switch (YesNoQuestion("Do you want a recursive search (y/n)", FALSE))
1083 sprintf(temp_buf, "R%s", type); /* "USER" to "RUSER" etc. */
1085 type = strdup(temp_buf);
1093 top = GetListInfo(ACE_USE, type, name);
1094 Loop(top, PrintListAce);
1100 /* Function Name: ListAllPublicMailLists
1101 * Description: This function lists all public mailing lists.
1103 * Returns: DM_NORMAL.
1106 int ListAllPublicMailLists(int argc, char **argv)
1109 static char *args[] = {
1110 "TRUE", /* active */
1111 "TRUE", /* public */
1112 "FALSE", /* hidden */
1113 "TRUE", /* maillist */
1114 "DONTCARE", /* group. */
1117 if (YesNoQuestion("This query will take a while. Do you wish to continue?",
1120 if ((status = do_mr_query("qualified_get_lists", 5, args,
1121 Print, NULL)) != MR_SUCCESS)
1122 com_err(program_name, status, " in ListAllGroups");