X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/blobdiff_plain/461c03b66c69c28fc6233126c21acecc1f2bc2d7..17bbb3bc324b5546a23c357435817bf93d248025:/clients/moira/lists.c diff --git a/clients/moira/lists.c b/clients/moira/lists.c index 732ff53f..337c22fb 100644 --- a/clients/moira/lists.c +++ b/clients/moira/lists.c @@ -1,43 +1,69 @@ -#ifndef lint - static char rcsid_module_c[] = "$Header$"; -#endif lint - -/* This is the file lists.c for allmaint, the SMS client that allows - * a user to maintaint most important parts of the SMS database. - * It Contains: - * - * Borrowed from listmaint code: 4/12/88 - * By: Chris D. Peterson +/* $Id$ * - * $Source$ - * $Author$ - * $Header$ - * - * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * This is the file lists.c for the Moira Client, which allows users + * to quickly and easily maintain most parts of the Moira database. + * It Contains: All list manipulation functions, except delete. * - * For further information on copyright and distribution - * see the file mit-copyright.h + * Created: 4/12/88 + * By: Chris D. Peterson + * + * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * . */ +#include +#include +#include +#include "defs.h" +#include "f_defs.h" +#include "globals.h" + #include -#include -#include -#include +#include +#include -#include "mit-copyright.h" -#include "allmaint.h" -#include "allmaint_funcs.h" -#include "globals.h" -#include "infodefs.h" +RCSID("$Header$"); + +struct mqelem *GetListInfo(int type, char *name1, char *name2); +char **AskListInfo(char **info, Bool name); +int AddList(int argc, char **argv); +void ListMembersByType(char *type, int tags); +int GetMemberInfo(char *action, char **ret_argv); #define LIST 0 #define MEMBERS 1 #define GLOM 2 -#define ACL_USE 3 +#define ACE_USE 3 + +#define DEFAULT_ACTIVE DEFAULT_YES +#define DEFAULT_PUBLIC DEFAULT_YES +#define DEFAULT_HIDDEN DEFAULT_NO +#define DEFAULT_MAILLIST DEFAULT_YES +#define DEFAULT_GROUP DEFAULT_NO +#define DEFAULT_GID UNIQUE_GID +#define DEFAULT_ACE_TYPE "user" +#define DEFAULT_ACE_NAME (user) +#define DEFAULT_DESCRIPTION DEFAULT_COMMENT /* globals only for this file. */ -static char * current_list; +static char current_list[BUFSIZ]; + + +/* Function Name: PrintListAce + * Description: This function prints the list ace information. + * Arguments: info - an info structure. + * Returns: none. + */ + +static void PrintListAce(char **info) +{ + char buf[BUFSIZ]; + + sprintf(buf, "Item: %-20s Name: %s", info[ACE_TYPE], info[ACE_NAME]); + Put_message(buf); +} /* Function Name: PrintListInfo * Description: This function Prints out the List info in a coherent form. @@ -45,44 +71,44 @@ static char * current_list; * Returns: none. */ -void -PrintListInfo(info) -char ** info; +static void PrintListInfo(char **info) { - char buf[BUFSIZ]; - - (void) sprintf(buf, "List: %s",info[L_NAME]); - (void) Put_message(buf); - (void) sprintf(buf, "\nDescription: %s", info[L_DESC]); - (void) Put_message(buf); - if ( atoi(info[L_MAILLIST])) - Put_message("This list is a mailing list."); - else - Put_message("This list is NOT a mailing list."); - if ( atoi(info[L_GROUP]) ) { - (void) sprintf(buf,"This list is Group and its ID number is %s", - info[L_GID]); - Put_message(buf); + char buf[BUFSIZ]; + + Put_message(" "); + sprintf(buf, "%20sList: %s", "", info[L_NAME]); + Put_message(buf); + sprintf(buf, "Description: %s", info[L_DESC]); + Put_message(buf); + if (atoi(info[L_MAILLIST])) + Put_message("This list is a mailing list."); + else + Put_message("This list is NOT a mailing list."); + if (atoi(info[L_GROUP])) + { + sprintf(buf, "This list is a Group and its ID number is %s", + info[L_GID]); + Put_message(buf); } - else - Put_message("This is NOT a Group."); - - if (strcmp(info[L_ACL_TYPE],"NONE") == 0) - Put_message("This list has no Administrator, how strange?!"); - else { - sprintf(buf, "The List Administrator of this list is the %s: %s", - info[L_ACL_TYPE], info[L_ACL_NAME]); - Put_message(buf); + else + Put_message("This list is NOT a Group."); + + if (!strcmp(info[L_ACE_TYPE], "NONE")) + Put_message("This list has no Administrator, how strange?!"); + else + { + sprintf(buf, "The Administrator of this list is the %s: %s", + info[L_ACE_TYPE], info[L_ACE_NAME]); + Put_message(buf); } - (void) sprintf(buf, "This list is: %s, %s, and %s", - info[L_ACTIVE] ? "active" : "inactive", - info[L_PUBLIC] ? "public" : "private", - info[L_HIDDEN] ? "hidden" : "visible"); - (void) Put_message(buf); - (void) sprintf(buf, "Last modification at %s, by %s using the program %s", - info[L_MODTIME], info[L_MODBY], info[L_MODWITH]); - (void) Put_message(buf); + sprintf(buf, "This list is: %s, %s, and %s", + atoi(info[L_ACTIVE]) ? "active" : "inactive", + atoi(info[L_PUBLIC]) ? "public" : "private", + atoi(info[L_HIDDEN]) ? "hidden" : "visible"); + Put_message(buf); + sprintf(buf, MOD_FORMAT, info[L_MODBY], info[L_MODTIME], info[L_MODWITH]); + Put_message(buf); } /* Function Name: GetListInfo @@ -92,57 +118,56 @@ char ** info; * Returns: the first element in the queue. */ -/* ARGSUSED */ -struct qelem * -GetListInfo(type, name1, name2) -int type; -char * name1, *name2; +struct mqelem *GetListInfo(int type, char *name1, char *name2) { - char *args[2]; - struct qelem * elem = NULL; - register int status; + char *args[2]; + struct mqelem *elem = NULL; + int status; - switch(type) { + switch (type) + { case LIST: - args[0] = name1; - if ( (status = sms_query("get_list_info", 1, args, - StoreInfo, (char *) &elem)) != 0) { - com_err(program_name, status, " in get_nfs_quotas_by_user"); - return (NULL); + args[0] = name1; + if ((status = do_mr_query("get_list_info", 1, args, StoreInfo, &elem))) + { + com_err(program_name, status, " in get_list_info"); + return NULL; } - break; + break; case MEMBERS: - args[0] = name1; - if ( (status = sms_query("get_members_of_list", 1, args, - StoreInfo, (char *) &elem)) != 0) { - com_err(program_name, status, " in get_nfs_quotas_by_user"); - return (NULL); + args[0] = name1; + if ((status = do_mr_query("get_members_of_list", 1, args, + StoreInfo, &elem))) + { + com_err(program_name, status, " in get_members_of_list"); + return NULL; } - break; + break; case GLOM: - args[0] = name1; - args[1] = name2; - if ( (status = sms_query("get_list_of_member", 2, args, - StoreInfo, (char *) &elem)) != 0) { - com_err(program_name, status, " in get_nfs_quotas_by_user"); - return (NULL); + args[0] = name1; + args[1] = name2; + if ((status = do_mr_query("get_lists_of_member", 2, args, + StoreInfo, &elem))) + { + com_err(program_name, status, " in get_list_of_members"); + return NULL; } - break; - case ACL_USE: - args[0] = name1; - args[1] = name2; - if ( (status = sms_query("get_acl_use", 2, args, - StoreInfo, (char *) &elem)) != 0) { - com_err(program_name, status, " in get_nfs_quotas_by_user"); - return (NULL); + break; + case ACE_USE: + args[0] = name1; + args[1] = name2; + if ((status = do_mr_query("get_ace_use", 2, args, StoreInfo, &elem))) + { + com_err(program_name, status, " in get_ace_use"); + return NULL; } - break; + break; } - return( QueueTop(elem) ); -} + return QueueTop(elem); +} /* Function Name: AskListInfo. - * Description: This function askes the user for information about a + * Description: This function askes the user for information about a * machine and saves it into a structure. * Arguments: info - a pointer the the structure to put the * info into. @@ -150,53 +175,73 @@ char * name1, *name2; * Returns: SUB_ERROR or SUB_NORMAL. */ -char ** -AskListInfo(info, name) -char ** info; -Bool name; +char **AskListInfo(char **info, Bool name) { - char temp_buf[BUFSIZ], *newname; - - sprintf(temp_buf,"\nChanging Attributes of list %s.\n",info[L_NAME]); - Put_message(temp_buf); - - if (name) { - newname = Strsave(info[L_NAME]); - GetValueFromUser("The new name for this list.", &newname); + char temp_buf[BUFSIZ], *newname; + + Put_message(" "); + sprintf(temp_buf, "Setting information of list %s.", info[L_NAME]); + Put_message(temp_buf); + Put_message(" "); + + if (name) + { + while (1) + { + newname = strdup(info[L_NAME]); + if (GetValueFromUser("The new name for this list", &newname) == + SUB_ERROR) + return NULL; + if (ValidName(newname)) + break; + } } - GetValueFromUser("Is this list active (1/0): ", &info[L_ACTIVE]); - GetValueFromUser("Is this list public (1/0): ", &info[L_PUBLIC]); - GetValueFromUser("Is this list hidden (1/0): ", &info[L_HIDDEN]); - GetValueFromUser("Is this a maillist (1/0): ", &info[L_MAILLIST]); - GetValueFromUser("is this a group (1/0): ", &info[L_GROUP]); - if (atoi(info[L_GROUP])) { - sprintf(temp_buf, "What is the Gid for this group, %s", - "'#' gets unique gid:"); - GetValueFromUser(temp_buf, &info[L_GID]); + if (GetYesNoValueFromUser("Is this an active list", &info[L_ACTIVE]) == + SUB_ERROR) + return NULL; + if (GetYesNoValueFromUser("Is this a public list", &info[L_PUBLIC]) == + SUB_ERROR) + return NULL; + if (GetYesNoValueFromUser("Is this a hidden list", &info[L_HIDDEN]) == + SUB_ERROR) + return NULL; + if (GetYesNoValueFromUser("Is this a maillist", &info[L_MAILLIST]) == + SUB_ERROR) + return NULL; + if (GetYesNoValueFromUser("Is this a group", &info[L_GROUP]) == SUB_ERROR) + return NULL; + if (atoi(info[L_GROUP])) + { + if (GetValueFromUser("What is the GID for this group.", &info[L_GID]) == + SUB_ERROR) + return NULL; } - GetValueFromUser("What Type of Administrator (none, user, list): ", - &info[L_ACL_TYPE]); - if ( (strcmp(info[L_ACL_TYPE], "USER") == 0) || - (strcmp(info[L_ACL_TYPE], "user") == 0) ) - GetValueFromUser("Who will be the administrator of this list: ", - &info[L_ACL_NAME]); - if ( (strcmp(info[L_ACL_TYPE], "LIST") == 0) || - (strcmp(info[L_ACL_TYPE], "list") == 0) ) - GetValueFromUser("Which group will be the administrator of this list: ", - &info[L_ACL_NAME]); - GetValueFromUser("Description: ", &info[L_DESC]); - - FreeAndClear(&info[L_MODTIME], TRUE); - FreeAndClear(&info[L_MODBY], TRUE); - FreeAndClear(&info[L_MODWITH], TRUE); -/* - * Slide the newname into the #2 slot, this screws up all future references - * to this list. - */ - if (name) /* slide the newname into the #2 slot. */ - SlipInNewName(info, newname); - return(info); + if (GetTypeFromUser("What Type of Administrator", "ace_type", + &info[L_ACE_TYPE]) == SUB_ERROR) + return NULL; + if (strcasecmp(info[L_ACE_TYPE], "NONE") && + strcasecmp(info[L_ACE_TYPE], "none")) + { + sprintf(temp_buf, "Which %s will be the administrator of this list: ", + info[L_ACE_TYPE]); + if (GetValueFromUser(temp_buf, &info[L_ACE_NAME]) == SUB_ERROR) + return NULL; + } + if (GetValueFromUser("Description: ", &info[L_DESC]) == SUB_ERROR) + return NULL; + + FreeAndClear(&info[L_MODTIME], TRUE); + FreeAndClear(&info[L_MODBY], TRUE); + FreeAndClear(&info[L_MODWITH], TRUE); + /* + * Slide the newname into the #2 slot, this screws up all future references + * to this list. + */ + if (name) /* slide the newname into the #2 slot. */ + SlipInNewName(info, newname); + + return info; } /* -------------- List functions. -------------- */ @@ -207,92 +252,172 @@ Bool name; * Returns: DM status code. */ -int -ShowListInfo(argc, argv) -int argc; -char **argv; +int ShowListInfo(int argc, char **argv) { - struct qelem *top, *list; + struct mqelem *top, *list; - top = list = GetListInfo(LIST, argv[1], (char *) NULL); - while (list != NULL) { - PrintListInfo( (char **) list->q_data); - list = list->q_forw; + top = list = GetListInfo(LIST, argv[1], NULL); + while (list) + { + PrintListInfo(list->q_data); + list = list->q_forw; } - - FreeQueue(top); - return(DM_NORMAL); + + FreeQueue(top); + return DM_NORMAL; +} + +/* Function Name: RealUpdateList + * Description: performs the actual update of the list. + * Arguments: info - all information needed to update the list. + * junk - an UNUSED boolean. + * Returns: none. + */ + +static void RealUpdateList(char **info, Bool junk) +{ + int stat; + char **args; + struct mqelem *elem = NULL; + + if (!(args = AskListInfo(info, TRUE))) + { + Put_message("Aborted."); + return; + } + + /* + * If the new list name is less than 8 characters, make sure it doesn't + * collide with a username. + */ + if ((strlen(args[2]) <= 8) && + do_mr_query("get_user_account_by_login", 1, args + 1, + StoreInfo, &elem) != MR_NO_MATCH) + { + char buf[256]; + + sprintf(buf, "\nA user by the name `%s' already exists in the database.", + args[1]); + Put_message(buf); + Loop(QueueTop(elem), FreeInfo); + FreeQueue(elem); + if (YesNoQuestion("Do you still want to rename this list to that name", + FALSE) != TRUE) + { + Put_message("List ** NOT ** Updated."); + return; + } + } + + if ((stat = do_mr_query("update_list", CountArgs(args), args, + NULL, NULL)) != MR_SUCCESS) + { + com_err(program_name, stat, " in UpdateList."); + Put_message("List ** NOT ** Updated."); + } + else + Put_message("List successfully updated."); } /* Function Name: UpdateList - * Description: + * Description: updates the information on a list. * Arguments: argc, argv - name of list in argv[1]. * Returns: DM Status code. */ -int -UpdateList(argc, argv) -int argc; -char **argv; +int UpdateList(int argc, char **argv) { - char **info, **up_args; - struct qelem *top, *list; - int status; - - list = top = GetListInfo(LIST, argv[1], (char *) NULL); - - while (list != NULL) { - info = (char **) list->q_data; - up_args = AskListInfo(info, TRUE); - if ( (status = sms_query("update_list", CountArgs(up_args), up_args, - Scream, (char *) NULL)) != 0) { - com_err(program_name, status, " in UpdateList."); - Put_message("List Not Updated."); - list = list->q_forw; - } - } + struct mqelem *top; - FreeQueue(top); - return(DM_NORMAL); + top = GetListInfo(LIST, argv[1], (char *) NULL); + QueryLoop(top, NullPrint, RealUpdateList, "Update the list"); + + FreeQueue(top); + return DM_NORMAL; +} + +/* Function Name: SetDefaults + * Description: sets defaults for AddList function + * Arguments: info - the array to add them to. + * name - name of the program to add. + * Returns: defaults - the default information. + */ + +static char **SetDefaults(char **info, char *name) +{ + info[L_NAME] = strdup(name); + info[L_ACTIVE] = strdup(DEFAULT_ACTIVE); + info[L_PUBLIC] = strdup(DEFAULT_PUBLIC); + info[L_HIDDEN] = strdup(DEFAULT_HIDDEN); + info[L_MAILLIST] = strdup(DEFAULT_MAILLIST); + info[L_GROUP] = strdup(DEFAULT_GROUP); + info[L_GID] = strdup(DEFAULT_GID); + info[L_ACE_TYPE] = strdup(DEFAULT_ACE_TYPE); + info[L_ACE_NAME] = strdup(DEFAULT_ACE_NAME); + info[L_DESC] = strdup(DEFAULT_DESCRIPTION); + info[L_MODTIME] = info[L_MODBY] = info[L_MODWITH] = info[L_END] = NULL; + return info; } /* Function Name: AddList - * Description: + * Description: * Arguments: argc, argv - name of list in argv[1]. - * Returns: DM Status code. + * Returns: SUB_ERROR if list not created. */ -int -AddList(argc, argv) -int argc; -char **argv; +int AddList(int argc, char **argv) { - static char *info[MAX_ARGS_SIZE], **add_args; - int status; - - if (!ValidName(argv[1])) /* Check if list name is valid. */ - return(DM_QUIT); - - status = sms_query("get_list_info", 1, argv + 1, NullFunc, - (char *) NULL); - if (status != SMS_NO_MATCH) { - if (status == 0) - Put_message("This list already exists."); - else - com_err(program_name, status, " in AddList."); - return(DM_QUIT); + static char *info[MAX_ARGS_SIZE], **add_args; + int status, ret_code = SUB_NORMAL; + struct mqelem *elem = NULL; + + if (!ValidName(argv[1])) + return DM_NORMAL; + status = do_mr_query("get_list_info", 1, argv + 1, NULL, NULL); + if (status != MR_NO_MATCH) + { + if (status == MR_SUCCESS) + Put_message("This list already exists."); + else + com_err(program_name, status, " in AddList."); + return SUB_ERROR; + } + + /* + * If the listname is less than 8 characters, make sure it doesn't + * collide with a username. + */ + if ((strlen(argv[1]) <= 8) && + do_mr_query("get_user_account_by_login", 1, argv + 1, + StoreInfo, &elem) != MR_NO_MATCH) + { + char buf[256]; + + sprintf(buf, "\nA user by the name `%s' already exists in the database.", + argv[1]); + Put_message(buf); + Loop(QueueTop(elem), FreeInfo); + FreeQueue(elem); + if (YesNoQuestion("Create a list with the same name", FALSE) != TRUE) + return SUB_ERROR; } - add_args = AskListInfo(info, FALSE); + if (!(add_args = AskListInfo(SetDefaults(info, argv[1]), FALSE))) + { + Put_message("Aborted."); + return SUB_ERROR; + } - if ( (status = sms_query("add_list", CountArgs(add_args), add_args, - Scream, (char *) NULL)) != 0) { - com_err(program_name, status, " in AddList."); - Put_message("List Not Created."); + if ((status = do_mr_query("add_list", CountArgs(add_args), add_args, + NULL, NULL)) != MR_SUCCESS) + { + com_err(program_name, status, " in AddList."); + Put_message("List Not Created."); + ret_code = SUB_ERROR; } - FreeInfo(info); - return(DM_NORMAL); + FreeInfo(info); + return ret_code; } /* Function Name: Instructions @@ -301,25 +426,24 @@ char **argv; * Returns: DM Status Code. */ -int -ListHelp() +int ListHelp(int argc, char **argv) { - static char * message[] = { - "Listmaint handles the creation, deletion, and updating of lists.\n", - "A list can be a mailing list, a group list, or both.\n", - "The concept behind lists is that a list has an owner", - "- administrator - and members.\n", - "The administrator of a list may be another list.\n", - "The members of a list can be users (login names), other lists,", - "or address strings.\n", - "You can use certain keys to do the following:", - " Refresh the screen - Type ctrl-L.\n", - " Escape from a function - Type ctrl-C.\n", - " Suspend the program (temporarily) - Type ctrl-Z.\n", - NULL, - }; - - return(PrintHelp(message)); + static char *message[] = { + "Listmaint handles the creation, deletion, and updating of lists.", + "A list can be a mailing list, a group list, or both.", + "The concept behind lists is that a list has an owner", + "- administrator - and members.", + "The administrator of a list may be another list.", + "The members of a list can be users (login names), other lists,", + "or address strings.", + "You can use certain keys to do the following:", + " Refresh the screen - Type ctrl-L.", + " Escape from a function - Type ctrl-C.", + " Suspend the program (temporarily) - Type ctrl-Z.", + NULL, + }; + + return PrintHelp(message); } /*-*-* LISTMAINT UPDATE MENU *-*-*/ @@ -331,95 +455,106 @@ ListHelp() * Returns: none. */ -/* ARGSUSED */ -int -ListmaintMemberMenuEntry(m, argc, argv) -Menu *m; -int argc; -char **argv; +int ListmaintMemberMenuEntry(Menu *m, int argc, char **argv) { - char temp_buf[BUFSIZ]; - char *list_name = argv[1]; - - if (*argv[0] == 'a') { /* add_list */ - /* actually, AddList no longer returns DM_QUIT. - * Maybe later, when com_err no longer blows out there. - */ - if (AddList(argc, argv) == DM_QUIT) - return(DM_QUIT); - (void) sprintf(temp_buf, "List '%s' created. Do you want to %s", - list_name, "change its membership?"); - if (YesNoQuestion(temp_buf, TRUE) != TRUE ) - return(DM_QUIT); - } - else if (!ValidName(list_name)) { - (void) sprintf(temp_buf, "Bad list: '%s'", list_name); - Put_message(temp_buf); - return(DM_QUIT); + char temp_buf[BUFSIZ]; + char *list_name = argv[1]; + int stat; + + if (!ValidName(list_name)) + return DM_QUIT; + + if (*argv[0] == 'a') + { /* add_list */ + if (AddList(argc, argv) == SUB_ERROR) + return DM_QUIT; + sprintf(temp_buf, "List '%s' created. Do you want to %s", list_name, + "change its membership (y/n)? "); + if (YesNoQuestion(temp_buf, TRUE) != TRUE) + return DM_QUIT; } - - (void) sprintf(temp_buf, - "Change/Display membership of '%s'", list_name); - m->m_title = Strsave(temp_buf); - strcpy(current_list, list_name); - return(DM_NORMAL); + else + /* All we want to know is if it exists. */ + switch ((stat = do_mr_query("count_members_of_list", 1, argv + 1, + NULL, NULL))) + { + case MR_SUCCESS: + break; + case MR_LIST: + Put_message("This list does not exist."); + return DM_QUIT; + case MR_PERM: + Put_message("You are not allowed to view this list."); + break; + default: + com_err(program_name, stat, " in get_list_info"); + return DM_QUIT; + } + + sprintf(temp_buf, "Change/Display membership of '%s'", list_name); + m->m_title = strdup(temp_buf); + strcpy(current_list, list_name); + return DM_NORMAL; } /* Function Name: ListmaintMemberMenuExit * Description: This is the function called when the member menu is * exited, it frees the memory that is storing the name. * Arguments: m - the menu - * Returns: DM_NORMAL + * Returns: DM_NORMAL */ -int -ListmaintMemberMenuExit(m) -Menu *m; +int ListmaintMemberMenuExit(Menu *m) { - free(m->m_title); - strcpy(current_list, ""); - return(DM_NORMAL); + free(m->m_title); + strcpy(current_list, ""); + return DM_NORMAL; } /* Function Name: ListMembersByType * Description: This function lists the users of a list by type. * Arguments: type - the type of the list "USER", "LIST", or "STRING". + * tags - whether or not to display tags * Returns: none. * NOTE: if type is NULL, all lists members are listed. */ -void -ListMembersByType(type) -char * type; +void ListMembersByType(char *type, int tags) { - char temp_buf[BUFSIZ]; - register int status; - - found_some = FALSE; - if ( (status = sms_query("get_members_of_list", 1, ¤t_list, - PrintByType, type)) != 0) - com_err(program_name, status, " in ListMembersByType\n"); - if (!found_some) { - if (type == NULL) - Put_message("List is empty (no members)."); - else { - sprintf(temp_buf,"No %s Members",type); - Put_message(temp_buf); + char temp_buf[BUFSIZ]; + int status; + char *args[10]; + + args[0] = current_list; + args[1] = NULL; + + found_some = FALSE; + if ((status = do_mr_query(tags ? "get_tagged_members_of_list" : + "get_members_of_list", CountArgs(args), + args, PrintByType, type))) + com_err(program_name, status, " in ListMembersByType"); + if (!found_some) + { + if (!type) + Put_message("List is empty (no members)."); + else + { + sprintf(temp_buf, "No %s Members", type); + Put_message(temp_buf); } } } /* Function Name: ListAllMembers * Description: lists all members of the current list. - * Arguments: + * Arguments: * Returns: DM_NORMAL */ -int -ListAllMembers() +int ListAllMembers(int argc, char **argv) { - ListMembersByType(NULL); - return (DM_NORMAL); + ListMembersByType(NULL, 0); + return DM_NORMAL; } /* Function Name: ListUserMembers @@ -428,10 +563,10 @@ ListAllMembers() * Returns: DM_NORMAL. */ -ListUserMembers() +int ListUserMembers(int argc, char **argv) { - ListMembersByType("USER"); - return(DM_NORMAL); + ListMembersByType("USER", 0); + return DM_NORMAL; } /* Function Name: ListListMembers @@ -440,10 +575,10 @@ ListUserMembers() * Returns: DM_NORMAL. */ -ListListMembers() +int ListListMembers(int argc, char **argv) { - ListMembersByType("LIST"); - return(DM_NORMAL); + ListMembersByType("LIST", 0); + return DM_NORMAL; } /* Function Name: ListStringMembers @@ -452,10 +587,10 @@ ListListMembers() * Returns: DM_NORMAL. */ -ListStringMembers() +int ListStringMembers(int argc, char **argv) { - ListMembersByType("STRING"); - return(DM_NORMAL); + ListMembersByType("STRING", 0); + return DM_NORMAL; } /* Function Name: GetMemberInfo @@ -468,33 +603,30 @@ ListStringMembers() * Returns: SUB_ERROR or SUB_NORMAL. */ -int -GetMemberInfo(action, ret_argv) -char *action, **ret_argv; +int GetMemberInfo(char *action, char **ret_argv) { - char temp_buf[BUFSIZ], ret_buf[BUFSIZ]; - register int status; - - ret_argv[LM_LIST] = Strsave(current_list); - ret_argv[LM_MEMBER] = "nobody"; - - PromptWithDefault("Type of member (USER, LIST, or STRING)", - ret_buf, BUFSIZ, "USER"); - ret_argv[LM_TYPE]= Strsave(ret_buf); - - status = sms_access("add_member_to_list", 3, ret_argv); - if (status == SMS_TYPE) { - Put_message("\"type\" must be one of 'STRING', 'LIST', or 'USER'."); - return(SUB_ERROR); - } else if (status) { - com_err(program_name, status, NULL); + char temp_buf[BUFSIZ]; + + ret_argv[LM_LIST] = strdup(current_list); + + ret_argv[LM_TYPE] = strdup("user"); + if (GetTypeFromUser("Type of member", "member", &ret_argv[LM_TYPE]) == + SUB_ERROR) + return SUB_ERROR; + + sprintf(temp_buf, "Name of %s to %s", ret_argv[LM_TYPE], action); + ret_argv[LM_MEMBER] = strdup(user); + if (GetValueFromUser(temp_buf, &ret_argv[LM_MEMBER]) == SUB_ERROR) + return SUB_ERROR; + ret_argv[LM_END] = NULL; /* NULL terminate this list. */ + + if (strcasecmp(ret_argv[LM_TYPE], "string") && + !ValidName(ret_argv[LM_MEMBER])) + { + FreeInfo(ret_argv); + return SUB_ERROR; } - - sprintf(temp_buf,"Name of member to %s", action); - PromptWithDefault(temp_buf, ret_buf, BUFSIZ, user); - ret_argv[LM_MEMBER] = Strsave(ret_buf); - ret_argv[LM_END] = NULL; /* null terminat this list. */ - return(SUB_NORMAL); + return SUB_NORMAL; } /* Function Name: AddMember @@ -503,21 +635,62 @@ char *action, **ret_argv; * Returns: DM_NORMAL. */ -int -AddMember() +int AddMember(int argc, char **argv) { - char *args[10]; - register int status; - - if( GetMemberInfo("add", args) == SUB_ERROR ) - return(DM_NORMAL); + char *args[10], temp_buf[BUFSIZ], *p; + int status; + struct mqelem *mailhubs, *elem; + + if (GetMemberInfo("add", args) == SUB_ERROR) + return DM_NORMAL; + + if (!strcmp(args[LM_TYPE], "STRING")) + { + if ((p = strchr(args[LM_MEMBER], '@'))) + { + char *host = canonicalize_hostname(strdup(++p)); + mailhubs = GetTypeValues("mailhub"); + for (elem = mailhubs; elem; elem = elem->q_forw) + { + if (!strcasecmp(host, elem->q_data)) + { + free(host); + host = strdup(args[LM_MEMBER]); + *(--p) = 0; + sprintf(temp_buf, "String \"%s\" should be USER or LIST " + "\"%s\" because it is a local name.", host, + args[LM_MEMBER]); + Put_message(temp_buf); + free(args[LM_TYPE]); + free(host); + return DM_NORMAL; + } + } + free(host); + } + else if (!strchr(args[LM_MEMBER], '!')) + { + Put_message("Member which is not a foreign mail address " + "should not be type STRING."); + return DM_NORMAL; + } + } - if (status = sms_query("add_member_to_list", CountArgs(args), args, - Scream, NULL) != 0) - com_err(program_name, status, " in AddMember\n"); + if ((status = do_mr_query("add_member_to_list", CountArgs(args), args, + NULL, NULL)) != MR_SUCCESS) + { + if (status == MR_EXISTS) + { + sprintf(temp_buf, "The %s %s is already a member of LIST %s.", + args[LM_TYPE], args[LM_MEMBER], args[LM_LIST]); + Put_message(temp_buf); + } + else + com_err(program_name, status, " in AddMember"); + } - FreeInfo(args); - return (DM_NORMAL); + FreeInfo(args); + return DM_NORMAL; } /* Function Name: DeleteMember @@ -526,78 +699,132 @@ AddMember() * Returns: DM_NORMAL */ -int -DeleteMember() +int DeleteMember(int argc, char **argv) { - char *args[10]; - register int status; - - if( GetMemberInfo("delete", args) == SUB_ERROR ) - return(DM_NORMAL); - - if (Confirm("Are you sure you want to delete this member?") ) { - if (status = sms_query("delete_member_from_list", CountArgs(args), - args, Scream, NULL)) - com_err(program_name, status, " in DeleteMember\n"); - else - Put_message("Deletion Completed."); + char *args[10]; + int status; + + if (GetMemberInfo("delete", args) == SUB_ERROR) + return DM_NORMAL; + + if (Confirm("Are you sure you want to delete this member?")) + { + if ((status = do_mr_query("delete_member_from_list", CountArgs(args), + args, NULL, NULL))) + com_err(program_name, status, " in DeleteMember"); + else + Put_message("Deletion Completed."); } - else - Put_message("Deletion has been Aborted."); + else + Put_message("Deletion has been Aborted."); - FreeInfo(args); - return(DM_NORMAL); + FreeInfo(args); + return DM_NORMAL; } +/* Function Name: TagMember + * Description: Add a tag to a list member + * Arguments: + * Returns: DM_NORMAL + */ + +int TagMember(int argc, char **argv) +{ + char *args[10]; + int status; + char temp_buf[BUFSIZ]; + + if (GetMemberInfo("tag", args) == SUB_ERROR) + return DM_NORMAL; + + args[LM_TAG] = strdup(""); + if (GetValueFromUser("Tag" , &args[LM_TAG]) == SUB_ERROR) + { + Put_message("Aborted."); + return DM_NORMAL; + } + args[LM_TAG_END] = NULL; /* NULL terminate this list. */ + + if ((status = do_mr_query("tag_member_of_list", CountArgs(args), + args, NULL, NULL))) + com_err(program_name, status, " in TagMember"); + + FreeInfo(args); + return DM_NORMAL; +} + +/* Function Name: ListAllMembers + * Description: lists all members of the current list. + * Arguments: + * Returns: DM_NORMAL + */ + +int ListMembersWithTags(int argc, char **argv) +{ + ListMembersByType(NULL, 1); + return DM_NORMAL; +} /* Function Name: InterRemoveItemFromLists * Description: This function allows interactive removal of an item * (user, string, list) for all list that it is on. * Arguments: none. * Returns: DM_NORMAL. + * NOTES: QueryLoop() does not work here because info does not have + * enough information in it to delete the member from the list. */ -int -InterRemoveItemFromLists() +int InterRemoveItemFromLists(int argc, char **argv) { - register int status; - char type[BUFSIZ], name[BUFSIZ], *args[10]; - struct qelem *top, *elem; - - if ( !(PromptWithDefault("Type of member (user, list, string)? ", type, - BUFSIZ, "user")) ) - return(DM_NORMAL); - - if ( !(PromptWithDefault("Name of member? ", name, BUFSIZ, user)) ) { - return(DM_NORMAL); - } - - top = elem = GetListInfo(GLOM, type, name); - - while(elem != NULL) { - char line[BUFSIZ], buf[BUFSIZ]; - char ** info = (char **) elem->q_data; - sprintf(line, "Delete %s from the list \"%s\" [Y/N/Q]? ", name, - info[0]); - PromptWithDefault(line, buf, BUFSIZ, "N" ); - if (buf[0] == 'y' || buf[0] == 'Y') { - Put_message("deleting..."); - args[DM_LIST] = info[GLOM_NAME]; - args[DM_TYPE] = type; - args[DM_MEMBER] = name; - if ( (status = sms_query("delete_member_from_list", 3, args, - Scream, (char *) NULL)) != 0) - /* should check to delete list. */ - com_err(program_name, status, " in delete_member"); - } - else if (buf[0] == 'q' || buf[0] == 'Q') { - Put_message("Quitting."); - break; + int status; + char *type, *name, *args[10], buf[BUFSIZ]; + struct mqelem *top, *elem; + + type = strdup("USER"); + if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR) + return DM_NORMAL; + + sprintf(buf, "Name of %s", type); + name = strdup(user); + if (GetValueFromUser(buf, &name) == SUB_ERROR) + return DM_NORMAL; + + if (!ValidName(name)) + return DM_NORMAL; + + top = elem = GetListInfo(GLOM, type, name); + + while (elem) + { + char line[BUFSIZ]; + char **info = elem->q_data; + sprintf(line, "Delete %s %s from the list \"%s\" (y/n/q)? ", type, + name, info[GLOM_NAME]); + switch (YesNoQuitQuestion(line, FALSE)) + { + case TRUE: + Put_message("deleting..."); + args[DM_LIST] = info[GLOM_NAME]; + args[DM_TYPE] = type; + args[DM_MEMBER] = name; + if ((status = do_mr_query("delete_member_from_list", 3, args, + NULL, NULL))) + { + /* should probabally check to delete list. */ + com_err(program_name, status, " in delete_member"); + } + break; + case FALSE: + break; + default: + Put_message("Aborting..."); + FreeQueue(top); + return DM_NORMAL; } - elem = elem->q_forw; + elem = elem->q_forw; } - FreeQueue(top); - return(DM_NORMAL); + FreeQueue(top); + return DM_NORMAL; } /*-*-* LIST MENU *-*-*/ @@ -608,41 +835,45 @@ InterRemoveItemFromLists() * Returns: DM_NORMAL. */ -int -ListByMember() +int ListByMember(int argc, char **argv) { - char buf[BUFSIZ], *type, *name, **info; - Bool maillist, group; - struct qelem *top, *elem; - - if ( !(PromptWithDefault("Type of member (user, list, string)? ", buf, - BUFSIZ, "user")) ) - return(DM_NORMAL); - - sprintf(buf, "R%s", buf); /* What we really want is a recursive search */ - type = Strsave(buf); - - if ( !(PromptWithDefault("Name of member? ", buf, BUFSIZ, user)) ) { - free(type); - return(DM_NORMAL); + char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name, **info; + Bool maillist, group; + struct mqelem *top, *elem; + + type = strdup("USER"); + if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR) + return DM_NORMAL; + + sprintf(buf, "Name of %s", type); + name = strdup(user); + if (GetValueFromUser(buf, &name) == SUB_ERROR) + return DM_NORMAL; + + /* What we really want is a recursive search */ + sprintf(temp_buf, "R%s", type); + free(type); + type = strdup(temp_buf); + + if ((maillist = YesNoQuestion("Show Lists that are Maillists (y/n) ?", + TRUE)) == -1) + return DM_NORMAL; + if ((group = YesNoQuestion("Show Lists that are Groups (y/n) ?", + TRUE)) == -1) + return DM_NORMAL; + + elem = top = GetListInfo(GLOM, type, name); + + while (elem) + { + info = elem->q_data; + if ((maillist == TRUE && !strcmp(info[GLOM_MAILLIST], "1")) || + (group == TRUE && !strcmp(info[GLOM_GROUP], "1"))) + Put_message(info[GLOM_NAME]); + elem = elem->q_forw; } - name = Strsave(buf); - - maillist = YesNoQuestion("Show only Lists that are Maillists (y/n) ?", - TRUE); - group = YesNoQuestion("Show only Lists that are Groups (y/n) ?", TRUE); - - elem = top = GetListInfo(GLOM, type, name); - - while (elem != NULL) { - info = (char**) elem->q_data; - if (maillist != TRUE || !strcmp(info[GLOM_MAILLIST], "1")) - if (group != TRUE || !strcmp(info[GLOM_GROUP], "1")) - Put_message(info[GLOM_NAME]); - elem = elem->q_forw; - } - FreeQueue(top); - return (DM_NORMAL); + FreeQueue(top); + return DM_NORMAL; } /* Function Name: ListByAdministrator @@ -652,86 +883,38 @@ ListByMember() * Returns: DM_NORMAL. */ -int -ListByAdministrator() +int ListByAdministrator(int argc, char **argv) { - char buf[BUFSIZ], *type, *name; - struct qelem *top, *elem; - - if ( !(PromptWithDefault("Type of member (user, list, string)? ", buf, - BUFSIZ, "user")) ) - return(DM_NORMAL); - - if ( YesNoQuestion("Do you want a recursive search?",TRUE) == 1 ) - sprintf(buf,"R%s",buf); /* "USER" to "RUSER" etc. */ - type = Strsave(buf); - - if ( !(PromptWithDefault("Name of member? ", buf, BUFSIZ, user)) ) { - free(type); - return(DM_NORMAL); - } - name = Strsave(buf); - - top = elem = GetListInfo(ACL_USE, type, name); - while (elem != NULL) { - char ** info = (char **) elem->q_data; - sprintf(buf, "Type: %s,\tName: %s", info[0], info[1]); - Put_message(buf); - elem = elem->q_forw; + char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name; + struct mqelem *top; + + type = strdup("USER"); + if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR) + return DM_NORMAL; + + sprintf(buf, "Name of %s", type); + name = strdup(user); + if (GetValueFromUser(buf, &name) == SUB_ERROR) + return DM_NORMAL; + + switch (YesNoQuestion("Do you want a recursive search (y/n)", FALSE)) + { + case TRUE: + sprintf(temp_buf, "R%s", type); /* "USER" to "RUSER" etc. */ + free(type); + type = strdup(temp_buf); + break; + case FALSE: + break; + default: + return DM_NORMAL; } - FreeQueue(top); - return (DM_NORMAL); -} -/* Function Name: ListAllGroups - * Description: This function lists all visable groups. - * Arguments: none. - * Returns: DM_NORMAL. - */ + top = GetListInfo(ACE_USE, type, name); + Loop(top, PrintListAce); -ListAllGroups() -{ - register int status; - static char * args[] = { - "TRUE", /* active */ - "DONTCARE", /* public */ - "FALSE", /* hidden */ - "DONTCARE", /* maillist */ - "TRUE", /* group. */ - }; - - if (YesNoQuestion("This query will take a while, Do you wish to continue?", - TRUE) == TRUE ) - if (status = sms_query("qualified_get_lists", 5, args, - Print, (char *) NULL) != 0) - com_err(program_name, status, " in ListAllGroups\n"); - return (DM_NORMAL); -} - -/* Function Name: ListAllMailLists - * Description: This function lists all visable maillists. - * Arguments: none - * Returns: DM_NORMAL. - */ - -ListAllMailLists() -{ - register int status; - static char * args[] = { - "TRUE", /* active */ - "DONTCARE", /* public */ - "FALSE", /* hidden */ - "TRUE", /* maillist */ - "DONTCARE", /* group. */ - }; - - if (YesNoQuestion("This query will take a while. Do you wish to continue?", - TRUE) == TRUE ) - if (status = sms_query("qualified_get_lists", 5, args, - Print, (char *) NULL) != 0) - com_err(program_name, status, " in ListAllGroups\n"); - - return (DM_NORMAL); + FreeQueue(top); + return DM_NORMAL; } /* Function Name: ListAllPublicMailLists @@ -740,33 +923,24 @@ ListAllMailLists() * Returns: DM_NORMAL. */ -ListAllPublicMailLists() +int ListAllPublicMailLists(int argc, char **argv) { - register int status; - static char * args[] = { - "TRUE", /* active */ - "TRUE", /* public */ - "FALSE", /* hidden */ - "TRUE", /* maillist */ - "DONTCARE", /* group. */ - }; - - if (YesNoQuestion("This query will take a while. Do you wish to continue?", - TRUE) == TRUE ) - if (status = sms_query("qualified_get_lists", 5, args, - Print, (char *) NULL) != 0) - com_err(program_name, status, " in ListAllGroups\n"); - - return (DM_NORMAL); -} + int status; + static char *args[] = { + "TRUE", /* active */ + "TRUE", /* public */ + "FALSE", /* hidden */ + "TRUE", /* maillist */ + "DONTCARE", /* group. */ + }; + + if (YesNoQuestion("This query will take a while. Do you wish to continue?", + TRUE) == TRUE) + { + if ((status = do_mr_query("qualified_get_lists", 5, args, + Print, NULL)) != MR_SUCCESS) + com_err(program_name, status, " in ListAllGroups"); + } -/* - * Local Variables: - * mode: c - * c-indent-level: 4 - * c-continued-statement-offset: 4 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * End: - */ + return DM_NORMAL; +}