X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/blobdiff_plain/08345b744443a0a78d0311294c17158345a73036..9e2516d6d1802890f163cd811348d4e4091a2173:/clients/moira/attach.c diff --git a/clients/moira/attach.c b/clients/moira/attach.c index 0947fd06..a3b850a4 100644 --- a/clients/moira/attach.c +++ b/clients/moira/attach.c @@ -1,57 +1,84 @@ -#ifndef lint +#if (!defined(lint) && !defined(SABER)) static char rcsid_module_c[] = "$Header$"; -#endif lint +#endif -/* This is the file attach.c for allmaint, the SMS client that allows - * a user to maintaint most important parts of the SMS database. +/* This is the file attach.c for the SMS Client, which allows a nieve + * user to quickly and easily maintain most parts of the SMS database. * It Contains: Functions for maintaining data used by Hesiod * to map courses/projects/users to their file systems, * and maintain filesys info. * * Created: 5/4/88 * By: Chris D. Peterson - * Based Upon: attach.c 87/07/24 marcus * * $Source$ * $Author$ * $Header$ * - * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * Copyright 1988 by the Massachusetts Institute of Technology. * * For further information on copyright and distribution * see the file mit-copyright.h */ -#include "mit-copyright.h" -#include "allmaint.h" -#include "globals.h" -#include "infodefs.h" - #include #include #include +#include #include +#include "mit-copyright.h" +#include "defs.h" +#include "f_defs.h" +#include "globals.h" + #define FS_ALIAS_TYPE "FILESYS" -#define FS_NAME 0 -#define FS_TYPE 1 -#define FS_MACHINE 2 -#define FS_PACK 3 -#define FS_M_POINT 4 -#define FS_ACCESS 5 -#define FS_COMMENTS 6 -#define FS_OWNER 7 -#define FS_OWNERS 8 -#define FS_CREATE 9 -#define FS_L_TYPE 10 -#define FS_MODTIME 11 -#define FS_MODBY 12 -#define FS_MODWITH 13 - -#define FS_LABEL 14 -/* FS_MACHINE already defined, this is okay, as there is no overlap. */ -#define FS_GROUP 15 +#define LABEL 0 +#define MACHINE 1 +#define GROUP 2 +#define ALIAS 3 + +#define NO_MACHINE ("\\[NONE\\]") /* C will remove one of the /'s here, + * and the other quotes the [ for + * ingres' regexp facility. */ + +#define DEFAULT_TYPE ("NFS") +#define DEFAULT_MACHINE DEFAULT_NONE +#define DEFAULT_PACK DEFAULT_NONE +#define DEFAULT_M_POINT DEFAULT_NONE +#define DEFAULT_ACCESS ("w") +#define DEFAULT_COMMENTS DEFAULT_COMMENT +#define DEFAULT_OWNER (user) +#define DEFAULT_OWNERS (user) +#define DEFAULT_CREATE DEFAULT_YES +#define DEFAULT_L_TYPE ("PROJECT") + +/* Function Name: SetDefaults + * Description: sets the default values for filesystem additions. + * Arguments: info - an array of char pointers to recieve defaults. + * Returns: char ** (this array, now filled). + */ + +static char ** +SetDefaults(info, name) +char ** info; +char * name; +{ + info[FS_NAME] = Strsave(name); + info[FS_TYPE] = Strsave(DEFAULT_TYPE); + info[FS_MACHINE] = Strsave(DEFAULT_MACHINE); + info[FS_PACK] = Strsave(DEFAULT_PACK); + info[FS_M_POINT] = Strsave(DEFAULT_M_POINT); + info[FS_ACCESS] = Strsave(DEFAULT_ACCESS); + info[FS_COMMENTS] = Strsave(DEFAULT_COMMENTS); + info[FS_OWNER] = Strsave(DEFAULT_OWNER); + info[FS_OWNERS] = Strsave(DEFAULT_OWNERS); + info[FS_CREATE] = Strsave(DEFAULT_CREATE); + info[FS_L_TYPE] = Strsave(DEFAULT_L_TYPE); + info[FS_MODTIME] = info[FS_MODBY] = info[FS_MODWITH] = info[FS_END] = NULL; + return(info); +} /* Function Name: GetFSInfo * Description: Stores the info in a queue. @@ -60,42 +87,44 @@ * Returns: a pointer to the first element in the queue. */ -struct qelem * +static struct qelem * GetFSInfo(type, name) int type; char *name; { int stat; struct qelem * elem = NULL; - char * args[2]; + char * args[5]; switch (type) { - case FS_LABEL: - if ( (stat = sms_query("get_filesys_by_label", 1, &name, - StoreInfo, &elem)) != 0) { - com_err(whoami, stat, NULL); + case LABEL: + if ( (stat = do_sms_query("get_filesys_by_label", 1, &name, + StoreInfo, (char *)&elem)) != 0) { + com_err(program_name, stat, NULL); return(NULL); } break; - case FS_MACHINE: - if ( (stat = sms_query("get_filesys_by_label", 1, &name, - StoreInfo, &elem)) != 0) { - com_err(whoami, stat, NULL); + case MACHINE: + if ( (stat = do_sms_query("get_filesys_by_machine", 1, &name, + StoreInfo, (char *)&elem)) != 0) { + com_err(program_name, stat, NULL); return(NULL); } break; - case FS_GROUP: - if ( (stat = sms_query("get_filesys_by_label", 1, &name, - StoreInfo, &elem)) != 0) { - com_err(whoami, stat, NULL); + case GROUP: + if ( (stat = do_sms_query("get_filesys_by_group", 1, &name, + StoreInfo, (char *)&elem)) != 0) { + com_err(program_name, stat, NULL); return(NULL); } break; - case FS_ALIAS: - args[0] = name; - args[1] = FS_ALIAS_TYPE; - if ( (stat = sms_query("get_alias", 2, args, StoreInfo, &elem)) != 0) { - com_err(whoami, stat, " in get_alias."); + case ALIAS: + args[ALIAS_NAME] = name; + args[ALIAS_TYPE] = FS_ALIAS_TYPE; + args[ALIAS_TRANS] = "*"; + if ( (stat = do_sms_query("get_alias", 3, args, StoreInfo, + (char *) &elem)) != 0) { + com_err(program_name, stat, " in get_alias."); return(NULL); } } @@ -103,58 +132,97 @@ char *name; return(QueueTop(elem)); } -/* Function Name: PrintFSInfo - * Description: Prints the filesystem information. - * Arguments: info - a pointer to the filesystem information. - * Returns: none. +/* Function Name: PrintFSAlias + * Description: Prints a filesystem alias + * Arguments: info - an array contains the strings of info. + * Returns: the name of the filesys - used be QueryLoop(). */ -PrintFSInfo(info); +static char * +PrintFSAlias(info) +char ** info; +{ + char buf[BUFSIZ]; + + sprintf(buf,"Alias: %-25s Filesystem: %s",info[ALIAS_NAME], + info[ALIAS_TRANS]); + Put_message(buf); + return(info[ALIAS_NAME]); +} + +static int fsgCount = 1; + +static char * +PrintFSGMembers(info) char ** info; { char print_buf[BUFSIZ]; - sprintf(print_buf,"Information about filesystem: %s", info[FS_NAME]); - Put_message(print_buf); - sprintf(print_buf,"Type: %s\t\tMachine: %s\t\tPackname: %s",info[FS_TYPE], - info[FS_MACHINE], info[FS_PACK]); - Put_message(print_buf); - sprintf(print_buf,"Mountpoint %s\t\t Default Access: %s",info[FS_M_POINT], - info[FS_ACCESS]); - Put_message(print_buf); - sprintf(print_buf,"Comments; %s",info[FS_COMMENTS]); - Put_message(print_buf); - sprintf(print_buf, "User Ownership: %s,\t\tGroup Ownership:\t\t%s", - info[FS_OWNER], info[FS_OWNERS]); - Put_message(print_buf); - sprintf(print_buf, "Auto Create %s\t\tLocker Type: %s",info[FS_CREATE], - info[FS_L_TYPE]); - Put_message(print_buf); - sprintf(print_buf, "Last Modified at %s, by %s with %s",info[FS_MODTIME], - info[FS_MODBY], info[FS_MODWITH]); + + sprintf(print_buf, " %d. Filesystem: %-32s (sort key: %s)", fsgCount++, info[0], info[1]); Put_message(print_buf); + return(info[0]); } -/* Function Name: PrintAllFSInfo - * Description: Prints all infomation about a filesystem, stored in - * a queue. - * Arguments: elem - a pointer to the first elem in the queue. + +/* Function Name: PrintFSInfo + * Description: Prints the filesystem information. + * Arguments: info - a pointer to the filesystem information. * Returns: none. */ -void -PrintAllFSInfo(elem) -struct qelem * elem; +static char * +PrintFSInfo(info) +char ** info; { -/* - * Not nescessary, but makes it clear that we are not changing this value. - */ - struct qelem * local = elem; - - while(local != NULL) { - char ** info = (char **) local->q_date; - PrintFSInfo(info); - local = local->next; + char print_buf[BUFSIZ]; + + FORMFEED; + sprintf(print_buf,"%20s Filesystem Group: %s", + " ",info[FS_NAME]); + Put_message(print_buf); + + if (!strcmp(info[FS_TYPE], "FSGROUP")) { + int stat; + struct qelem *elem = NULL; + + sprintf(print_buf,"Comments; %s",info[FS_COMMENTS]); + Put_message(print_buf); + sprintf(print_buf, MOD_FORMAT, info[FS_MODBY], info[FS_MODTIME], + info[FS_MODWITH]); + Put_message(print_buf); + Put_message("Containing the filesystems (in order):"); + if ((stat = do_sms_query("get_fsgroup_members", 1, &info[FS_NAME], + StoreInfo, (char *)&elem)) != 0) { + if (stat == SMS_NO_MATCH) + Put_message(" [no members]"); + else + com_err(program_name, stat, NULL); + } else { + fsgCount = 1; + Loop(QueueTop(elem), (void *) PrintFSGMembers); + FreeQueue(elem); + } + } else { + sprintf(print_buf,"Type: %-40s Machine: %-15s", + info[FS_TYPE], info[FS_MACHINE]); + Put_message(print_buf); + sprintf(print_buf,"Default Access: %-2s Packname: %-17s Mountpoint %s ", + info[FS_ACCESS], info[FS_PACK], info[FS_M_POINT]); + Put_message(print_buf); + sprintf(print_buf,"Comments; %s",info[FS_COMMENTS]); + Put_message(print_buf); + sprintf(print_buf, "User Ownership: %-30s Group Ownership: %s", + info[FS_OWNER], info[FS_OWNERS]); + Put_message(print_buf); + sprintf(print_buf, "Auto Create: %-34s Locker Type: %s", + atoi(info[FS_CREATE]) ? "ON" : "OFF", + info[FS_L_TYPE]); + Put_message(print_buf); + sprintf(print_buf, MOD_FORMAT, info[FS_MODBY], info[FS_MODTIME], + info[FS_MODWITH]); + Put_message(print_buf); } + return(info[FS_NAME]); } /* Function Name: AskFSInfo. @@ -166,35 +234,50 @@ struct qelem * elem; * Returns: none. */ -void -AskFSInfo(info, flags); +static char ** +AskFSInfo(info, name) char ** info; Bool name; { - char * temp_buf, *newname; - char *ret_args[100]; - int counter; + char temp_buf[BUFSIZ], *newname; + int fsgroup = 0; - sprintf(temp_buf,"\nChanging Attributes of user %s.\n",info[NAME]); + Put_message(""); + sprintf(temp_buf, "Changing Attributes of filesystem %s.", + info[FS_NAME]); Put_message(temp_buf); + Put_message(""); if (name) { newname = Strsave(info[FS_NAME]); - GetValueFromUser("The new login name for this filesystem.", + GetValueFromUser("The new name for this filesystem", &newname); } - GetValueFromUser("Filesystem's Type:", &info[FS_TYPE]); - GetValueFromUser("Filesystem's Machine:", &info[FS_MACHINE]); - GetValueFromUser("Filesystem's Pack Name:", &info[FS_PACK]); - GetValueFromUser("Filesystem's Mount Point:", &info[FS_M_POINT]); - GetValueFromUser("Filesystem's Default Access:", &info[FS_ACCESS]); - GetValueFromUser("Commants about this Filesystem:", &info[FS_COMMENTS]); - GetValueFromUser("Filesystem's owner (user):", &info[FS_OWNER]); - GetValueFromUser("Filesystem's owners (group):", &info[FS_OWNERS]); - GetValueFromUser("Automatically create this filsystem (0/1):", - &info[FS_COMMENTS]); - GetValueFromUser("Filesystem's lockertype:", &info[FS_L_TYPE]); + GetTypeFromUser("Filesystem's Type", "filesys", &info[FS_TYPE]); + if (!strcmp(info[FS_TYPE], "FSGROUP") || !strcmp(info[FS_TYPE], "fsgroup")) + fsgroup++; + if (fsgroup) { + free(info[FS_MACHINE]); + info[FS_MACHINE] = Strsave(NO_MACHINE); + } else { + GetValueFromUser("Filesystem's Machine", &info[FS_MACHINE]); + strcpy(temp_buf, CanonicalizeHostname(info[FS_MACHINE])); + free(info[FS_MACHINE]); + info[FS_MACHINE] = Strsave(temp_buf); + } + if (!fsgroup) { + GetValueFromUser("Filesystem's Pack Name", &info[FS_PACK]); + GetValueFromUser("Filesystem's Mount Point", &info[FS_M_POINT]); + GetValueFromUser("Filesystem's Default Access", &info[FS_ACCESS]); + } + GetValueFromUser("Comments about this Filesystem", &info[FS_COMMENTS]); + GetValueFromUser("Filesystem's owner (user)", &info[FS_OWNER]); + GetValueFromUser("Filesystem's owners (group)", &info[FS_OWNERS]); + if (!fsgroup) + GetYesNoValueFromUser("Automatically create this filesystem", + &info[FS_CREATE]); + GetTypeFromUser("Filesystem's lockertype", "lockertype", &info[FS_L_TYPE]); FreeAndClear(&info[FS_MODTIME], TRUE); FreeAndClear(&info[FS_MODBY], TRUE); @@ -220,14 +303,47 @@ GetFS(argc, argv) int argc; char **argv; { - struct qelem *elem; + struct qelem *top; - elem = GetFSInfo(); /* get info. */ - PrintAllFSInfo(elem); /* print it all. */ - FreeQueue(elem); /* clean the queue. */ + top = GetFSInfo(LABEL, argv[1]); /* get info. */ + Loop(top, (void *) PrintFSInfo); + FreeQueue(top); /* clean the queue. */ return (DM_NORMAL); } +/* Function Name: RealDeleteFS + * Description: Does the real deletion work. + * Arguments: info - array of char *'s containing all useful info. + * one_item - a Boolean that is true if only one item + * in queue that dumped us here. + * Returns: none. + */ + +void +RealDeleteFS(info, one_item) +char ** info; +Bool one_item; +{ + int stat; + char temp_buf[BUFSIZ]; + +/* + * Deletetions are performed if the user hits 'y' on a list of multiple + * filesystem, or if the user confirms on a unique alias. + */ + sprintf(temp_buf, "Are you sure that you want to delete filesystem %s", + info[FS_NAME]); + if(!one_item || Confirm(temp_buf)) { + if ( (stat = do_sms_query("delete_filesys", 1, + &info[FS_NAME], Scream, NULL)) != 0) + com_err(program_name, stat, " filesystem not deleted."); + else + Put_message("Filesystem deleted."); + } + else + Put_message("Filesystem not deleted."); +} + /* Function Name: DeleteFS * Description: Delete a filesystem give its name. * Arguments: argc, argv - argv[1] is the name of the filesystem. @@ -241,62 +357,51 @@ DeleteFS(argc, argv) int argc; char **argv; { - int stat, answer, delete, number; - struct qelem *elem, *temp_elem; - - if ( (temp_elem = elem = GetFSInfo(FS_LABEL, argv[1], - (char *) NULL) ) == NULL ) /* get info. */ - return(DM_NORMAL); -/* - * 1) If there is no (zero) match then we exit immediately. - * 2) If there is exactly 1 element then we ask for confirmation only if in - * verbose mode, via the Confirm function. - * 3) If there is more than 1 filesystem to be deleted then we ask - * about each one, and delete on yes only, and about if the user hits - * quit. + struct qelem *elem = GetFSInfo(LABEL, argv[1]); + QueryLoop(elem, PrintFSInfo, RealDeleteFS, "Delete the Filesystem"); + + FreeQueue(elem); + return (DM_NORMAL); +} + +/* Function Name: RealChangeFS + * Description: performs the actual change to the filesys. + * Arguments: info - the information + * junk - an unused boolean. + * Returns: none. */ - number = QueueCount(elem); - while (temp_elem != NULL) { - char **info = (char **) temp_elem->q_data; - - if (number != 1) { - PrintFSInfo(info); - - answer = YesNoQuitQuestion("\nDelete this filesys?", FALSE); - switch(answer) { - case TRUE: - delete = TRUE; - break; - case FALSE: - delete = FALSE; - break; - default: /* Quit. */ - Put_message("Aborting Delete Operation."); - FreeQueue(elem); - return(DM_NORMAL); + +/* ARGSUSED. */ +static void +RealChangeFS(info, junk) +char ** info; +Bool junk; +{ + int stat; + char ** args = AskFSInfo(info, TRUE); + extern Menu nfsphys_menu; + + stat = do_sms_query("update_filesys", CountArgs(args), args, + NullFunc, NULL); + switch (stat) { + case SMS_NFS: + Put_message("That NFS filesystem is not exported."); + if (YesNoQuestion("Fix this now (Y/N)")) { + Do_menu(&nfsphys_menu, 0, NULL); + if (YesNoQuestion("Retry filesystem update now (Y/N)")) { + if (stat = do_sms_query("update_filesys", CountArgs(args), args, + NullFunc, NULL)) + com_err(program_name, stat, " filesystem not updated"); + else + Put_message("filesystem sucessfully updated."); } } - else - delete = - Confirm("Are you sure that you want to delete this filsystem.")) -/* - * Deletetions are performed if the user hits 'y' on a list of multiple - * filesystem, or if the user confirms on a unique alias. - */ - if (delete) { - if ( (status = sms_query("delete_filesys", 1, - &name, NullFunc, NULL)) != 0) - com_err(whoami, stat, " filesystem not deleted."); - else - Put_message("Filesystem deleted."); - } - else - Put_message("Filesystem not deleted."); - temp_elem = temp_elem->next; + break; + case SMS_SUCCESS: + break; + default: + com_err(program_name, stat, " in UpdateFS"); } - - FreeQueue(elem); /* free all members of the queue. */ - return (DM_NORMAL); } /* Function Name: ChangeFS @@ -311,52 +416,9 @@ ChangeFS(argc, argv) char **argv; int argc; { - FS_info *info; - struct qelem * elem, temp_elem; - int update, stat, answer; - - elem = temp_elem = GetFSInfo(FS_LABEL, argv[1], (char *) NULL); + struct qelem *elem = GetFSInfo(LABEL, argv[1]); + QueryLoop(elem, NullPrint, RealChangeFS, "Update the Filesystem"); -/* - * This uses the same basic method as the deletion routine above. - */ - - number = QueueCount(elem); - while (temp_elem != NULL) { - char ** info = (char **) temp_elem->q_data; - if (number != 1) { - sprintf(buf, "%s %s %s (y/n/q)? ", "Would you like to change the", - "information about the filesystem:", - info[FS_NAME]); - info = (char **) temp_elem->q_data; - answer = YesNoQuitQuestion(buf, FALSE); - switch(answer) { - case TRUE: - update = TRUE - break; - case FALSE: - upadate = FALSE; - break; - default: - Put_message("Aborting Operation."); - FreeQueue(elem); - return(DM_NORMAL); - } - } - else - update = TRUE; - - if (update) { - char * args; - args = AskFSInfo(info, TRUE); - if ( (stat = sms_query("update_filesys", num_args, - args, NullFunc, NULL)) != 0) - com_err(whoami, stat, " in filesystem not updated"); - else - Put_message("filesystem sucessfully updated."); - } - temp_elem = temp_elem->q_forw; - } FreeQueue(elem); return (DM_NORMAL); } @@ -374,32 +436,251 @@ char **argv; int argc; { char *info[MAX_ARGS_SIZE], **args; - int stat, count; + int stat; + extern Menu nfsphys_menu; if ( !ValidName(argv[1]) ) return(DM_NORMAL); - if ( (stat = sms_query("get_filesys_by_label", 1, argv + 1, - NullFunc, NULL)) == 0) { + if ( (stat = do_sms_query("get_filesys_by_label", 1, argv + 1, + NullFunc, NULL)) == 0) { Put_message ("A Filesystem by that name already exists."); return(DM_NORMAL); - } else if (status != SMS_NOMATCH) { - com_err(whoami, stat, " in AddFS"); + } else if (stat != SMS_NO_MATCH) { + com_err(program_name, stat, " in AddFS"); return(DM_NORMAL); } - while (count = 0; count < 100; count++) - info[count] = NULL; - args = AskFSInfo(info, FALSE ); - - if (stat = sms_query("add_filesys", CountArgs(args), args, - NullFunc, NULL) != 0) - com_err(whoami, stat, " in AddFS"); + args = AskFSInfo(SetDefaults(info, argv[1]), FALSE ); + + stat = do_sms_query("add_filesys", CountArgs(args), args, NullFunc, NULL); + switch (stat) { + case SMS_NFS: + Put_message("That NFS filesystem is not exported."); + if (YesNoQuestion("Fix this now (Y/N)")) { + Do_menu(&nfsphys_menu, 0, NULL); + if (YesNoQuestion("Retry filesystem creation now (Y/N)")) { + if (stat = do_sms_query("add_filesys", CountArgs(args), args, + NullFunc, NULL)) + com_err(program_name, stat, " in AddFS"); + else + Put_message("Created."); + } + } + break; + case SMS_SUCCESS: + break; + default: + com_err(program_name, stat, " in AddFS"); + } FreeInfo(info); return (DM_NORMAL); } +/* Function Name: SortAfter + * Description: choose a sortkey to cause an item to be added after + * the count element in the queue + * Arguments: queue of filesys names & sortkeys, queue count pointer + * Returns: sort key to use. + */ + +/* ARGSUSED */ +char * +SortAfter(elem, count) +struct qelem *elem; +int count; +{ + char *prev, *next, prevnext, *key, keybuf[9]; + + /* first find the two keys we need to insert between */ + prev = "A"; + for (; count > 0; count--) { + prev = ((char **)elem->q_data)[1]; + if (elem->q_forw) + elem = elem->q_forw; + else + break; + } + if (count > 0) + next = "Z"; + else + next = ((char **)elem->q_data)[1]; + + /* now copy the matching characters */ + for (key = keybuf; *prev && *prev == *next; next++) { + *key++ = *prev++; + } + + /* and set the last character */ + if (*prev == 0) + *prev = prevnext = 'A'; + else + prevnext = prev[1]; + if (prevnext == 0) + prevnext = 'A'; + if (*next == 0) + *next = 'Z'; + if (*next - *prev > 1) { + *key++ = (*next + *prev)/2; + } else { + *key++ = *prev; + *key++ = (prevnext + 'Z')/2; + } + *key = 0; + return(Strsave(keybuf)); +} + +/* Function Name: AddFSToGroup + * Description: add a filesystem to an FS group + * Arguments: arc, argv - name of group in argv[1], filesys in argv[2]. + * Returns: DM_NORMAL. + */ + +/* ARGSUSED */ +int +AddFSToGroup(argc, argv) +char **argv; +int argc; +{ + int stat, count; + struct qelem *elem = NULL; + char buf[BUFSIZ], *args[5], *bufp; + + if ((stat = do_sms_query("get_fsgroup_members", 1, argv+1, StoreInfo, + (char *)&elem)) != 0) { + if (stat != SMS_NO_MATCH) + com_err(program_name, stat, " in AddFSToGroup"); + } + if (elem == NULL) { + args[0] = argv[1]; + args[1] = argv[2]; + args[2] = "M"; + stat = do_sms_query("add_filesys_to_fsgroup", 3, args, Scream, NULL); + if (stat) + com_err(program_name, stat, " in AddFSToGroup"); + return(DM_NORMAL); + } + elem = QueueTop(elem); + fsgCount = 1; + Loop(elem, (void *) PrintFSGMembers); + sprintf(buf, "%d", QueueCount(elem)); + bufp = Strsave(buf); + stat = GetValueFromUser("Enter number of filesystem it should follow (0 to make it first):", &bufp); + count = atoi(bufp); + free(bufp); + args[2] = SortAfter(elem, count); + + FreeQueue(QueueTop(elem)); + args[0] = argv[1]; + args[1] = argv[2]; + stat = do_sms_query("add_filesys_to_fsgroup", 3, args, Scream, NULL); + if (stat == SMS_EXISTS) { + Put_message("That filesystem is already a member of the group."); + Put_message("Use the order command if you want to change the sorting order."); + } else if (stat) + com_err(program_name, stat, " in AddFSToGroup"); + return(DM_NORMAL); +} + + +/* Function Name: RemoveFSFromGroup + * Description: delete a filesystem from an FS group + * Arguments: arc, argv - name of group in argv[1]. + * Returns: DM_NORMAL. + */ + +/* ARGSUSED */ +int +RemoveFSFromGroup(argc, argv) +char **argv; +int argc; +{ + int stat; + char buf[BUFSIZ]; + + sprintf(buf, "Delete filesystem %s from FS group %s", argv[2], argv[1]); + if (!Confirm(buf)) + return(DM_NORMAL); + if ((stat = do_sms_query("remove_filesys_from_fsgroup", 2, argv+1, + Scream, NULL)) != 0) { + com_err(program_name, stat, ", not removed."); + } + return(DM_NORMAL); +} + +/* Function Name: ChangeFSGroupOrder + * Description: change the sortkey on a filesys in an FSgroup + * Arguments: arc, argv - name of group in argv[1]. + * Returns: DM_NORMAL. + */ + +/* ARGSUSED */ +int +ChangeFSGroupOrder(argc, argv) +char **argv; +int argc; +{ + int stat, src, dst; + struct qelem *elem = NULL, *top; + char buf[BUFSIZ], *bufp, *args[3]; + + if ((stat = do_sms_query("get_fsgroup_members", 1, argv+1, StoreInfo, + (char *)&elem)) != 0) { + if (stat == SMS_NO_MATCH) { + sprintf(buf, "Ether %s is not a filesystem group or it has no members", argv[1]); + Put_message(buf); + } else + com_err(program_name, stat, " in ChangeFSGroupOrder"); + return(DM_NORMAL); + } + top = QueueTop(elem); + fsgCount = 1; + Loop(top, (void *) PrintFSGMembers); + while (1) { + bufp = Strsave("1"); + stat = GetValueFromUser("Enter number of the filesystem to move:", + &bufp); + src = atoi(bufp); + free(bufp); + if (src < 0) { + Put_message("You must enter a positive number (or 0 to abort)."); + continue; + } else if (src == 0) { + Put_message("Aborted."); + return(DM_NORMAL); + } + for (elem = top; src-- > 1 && elem->q_forw; elem = elem->q_forw); + if (src > 1) { + Put_message("You entered a number that is too high"); + continue; + } + break; + } + bufp = Strsave("0"); + stat = GetValueFromUser("Enter number of filesystem it should follow (0 to make it first):", &bufp); + dst = atoi(bufp); + free(bufp); + if (src == dst || src == dst + 1) { + Put_message("That has no effect on the sorting order!"); + return(DM_NORMAL); + } + args[2] = SortAfter(top, dst); + args[0] = argv[1]; + args[1] = ((char **)elem->q_data)[0]; + if ((stat = do_sms_query("remove_filesys_from_fsgroup", 2, args, + Scream, NULL)) != 0) { + com_err(program_name, stat, " in ChangeFSGroupOrder"); + return(DM_NORMAL); + } + if ((stat = do_sms_query("add_filesys_to_fsgroup", 3, args, + Scream, NULL)) != 0) { + com_err(program_name, stat, " in ChangeFSGroupOrder"); + } + return(DM_NORMAL); +} + + /* -------------- Top Level Menu ---------------- */ /* Function Name: GetFSAlias @@ -416,25 +697,17 @@ GetFSAlias(argc, argv) int argc; char **argv; { - register int stat = 0; - char **info, buf[BUFSIZ]; - struct qelem *top, *elem; - - top = elem = GetFSInfo(FS_ALIAS, argv[1]); - - while (elem != NULL) { - info = (char **) elem->q_data; - sprintf(buf,"Alias: %s\tFilesystem: %s",info[NAME], info[ALIAS_TRANS]); - putmessage(buf); - elem = elem->q_forw; - } + struct qelem *top; + top = GetFSInfo(ALIAS, argv[1]); + Put_message(" "); /* blank line. */ + Loop(top, (void *) PrintFSAlias); FreeQueue(top); return(DM_NORMAL); } /* Function Name: CreateFSAlias - * Description: Create an alias name for a filsystem + * Description: Create an alias name for a filesystem * Arguments: argc, argv - name of alias in argv[1]. * Returns: DM_NORMAL. * NOTES: This requires (name, type, transl) I get {name, translation} @@ -447,30 +720,31 @@ CreateFSAlias(argc, argv) int argc; char **argv; { - register int stat = 0; + register int stat; struct qelem *elem, *top; - char *args[3], buf[BUFSIZ], **info; - int num_args; + char *args[MAX_ARGS_SIZE], buf[BUFSIZ], **info; elem = NULL; if (!ValidName(argv[1])) return(DM_NORMAL); - args[0] = argv[1]; - args[1] = FS_ALIAS_TYPE; + args[ALIAS_NAME] = Strsave(argv[1]); + args[ALIAS_TYPE] = Strsave(FS_ALIAS_TYPE); + args[ALIAS_TRANS] = Strsave("*"); /* * Check to see if this alias already exists in the database, if so then * print out values, free memory used and then exit. */ - if ( (stat = sms_query("get_alias", 2, args, StoreInfo, &elem)) == 0) { - top = elem; + if ( (stat = do_sms_query("get_alias", 3, args, StoreInfo, + (char *)&elem)) == 0) { + top = elem = QueueTop(elem); while (elem != NULL) { info = (char **) elem->q_data; - sprintf(buf,"The alias: %s\tcurrently describes the filesystem %s", - info[NAME], info[ALIAS_TRANS]); + sprintf(buf,"The alias: %s currently describes the filesystem %s", + info[ALIAS_NAME], info[ALIAS_TRANS]); Put_message(buf); elem = elem->q_forw; } @@ -478,23 +752,57 @@ char **argv; return(DM_NORMAL); } else if ( stat != SMS_NO_MATCH) { - com_err(whoami, stat, " in CreateFSAlias."); + com_err(program_name, stat, " in CreateFSAlias."); return(DM_NORMAL); } - args[ALIAS_TRANS] = NULL; /* set to zero */ + args[ALIAS_TRANS]= args[ALIAS_END] = NULL; /* set to NULL initially. */ GetValueFromUser("Which filesystem will this alias point to?", - args[ALIAS_TRANS]); + &args[ALIAS_TRANS]); - if ( (stat = sms_query("add_alias", 3, args, NullFunc, NULL)) != 0) - com_err(whoami, stat, " in CreateFSAlias."); + if ( (stat = do_sms_query("add_alias", 3, args, NullFunc, NULL)) != 0) + com_err(program_name, stat, " in CreateFSAlias."); - free(args[ALIAS_TRANS]); + FreeInfo(args); return (DM_NORMAL); } + +/* Function Name: RealDeleteFSAlias + * Description: Does the real deletion work. + * Arguments: info - array of char *'s containing all useful info. + * one_item - a Boolean that is true if only one item + * in queue that dumped us here. + * Returns: none. + */ + +void +RealDeleteFSAlias(info, one_item) +char ** info; +Bool one_item; +{ + int stat; + char temp_buf[BUFSIZ]; + +/* + * Deletetions are performed if the user hits 'y' on a list of multiple + * filesystem, or if the user confirms on a unique alias. + */ + sprintf(temp_buf, + "Are you sure that you want to delete the filesystem alias %s", + info[ALIAS_NAME]); + if(!one_item || Confirm(temp_buf)) { + if ( (stat = do_sms_query("delete_alias", CountArgs(info), + info, Scream, NULL)) != 0 ) + com_err(program_name, stat, " filesystem alias not deleted."); + else + Put_message("Filesystem alias deleted."); + } + else + Put_message("Filesystem alias not deleted."); +} /* Function Name: DeleteFSAlias - * Description: Delete an alias name for a filsystem + * Description: Delete an alias name for a filesystem * Arguments: argc, argv - name of alias in argv[1]. * Returns: DM_NORMAL. * NOTES: This requires (name, type, transl) I get {name, translation} @@ -507,71 +815,10 @@ DeleteFSAlias(argc, argv) int argc; char **argv; { - register int stat; - char *args[3], buf[BUFSIZ], **info; - int num_args, delete; - struct qelem *elem, *top; - - if (!ValidName(argv[1])) - return(DM_NORMAL); - - top = elem = GetFSInfo(FS_ALIAS, argv[1]); - -/* - * 1) If there are no (zero) match in elements then we exit immediately. - * 2) If there is exactly 1 element then we ask for confirmation only if in - * verbose mode, via the Confirm function. - * 3) If there is more than 1 filesystem alias to be deleted then we ask - * about each one, and delete on yes only, and about if the user hits - * quit. - */ - number = QueueCount(top); - while (elem != NULL) { - char **info = (char **) elem->q_data; - - if (number != 1) { - sprintf(buf, "%s %s for the filesystem %s.", - "Confirm that you want to delete\n the alias", - info[NAME], info[ALIAS_TRANS]); - Put_message(buf); - - answer = YesNoQuitQuestion("\nDelete this filesystem alias?", - FALSE); - switch(answer) { - case TRUE: - delete = TRUE; - break; - case FALSE: - delete = FALSE; - break; - default: /* Quit. */ - Put_message("Aborting Delete Operation."); - FreeQueue(top); - return(DM_NORMAL); - } - } - else { - sprintf(buf, "Are you sure that you want to delete %s", - "this filesystem alias?"); - delete = Confirm(buf); - } -/* - * Deletetions are performed if the user hits 'y' on a list of multiple - * filesystem aliases, or if the user confirms on a unique alias. - */ - if (delete) { - if ( (status = sms_query("delete_filesys", 1, - &name, NullFunc, NULL)) != 0) - com_err(whoami, stat, " filesystem alias not deleted."); - else - Put_message("Filesystem alias deleted."); - } - else - Put_message("Filesystem alias not deleted."); - elem = elem->q_forw; - } - - FreeQueue(Top); + struct qelem *elem = GetFSInfo(ALIAS, argv[1]); + QueryLoop(elem, PrintFSAlias, RealDeleteFSAlias, + "Delete the Filesystem Alias"); + FreeQueue(elem); return (DM_NORMAL); } @@ -585,29 +832,43 @@ int AttachHelp() { static char *message[] = { - "These are the options:\n", - "get - get information about a filesystem.", - "add - add a new filesystem to the data base.", - "update - update the information in the database on a filesystem.", - "delete - delete a filesystem from the database.\n", - "check - check information about association of a name and a filesys.", - "alias - associate a name with a filsystem.", - "unalias - disassociate a name with a filesystem.", - "\twhere a name is: user, group, or project\n", - "verbose - toggle the request for delete confirmation\n", + "These are the options:", + "", + "get - get information about a filesystem.", + "add - add a new filesystem to the data base.", + "update - update the information in the database on a filesystem.", + "delete - delete a filesystem from the database.", + "check - check information about association of a name and a filesys.", + "alias - associate a name with a filesystem.", + "unalias - disassociate a name with a filesystem.", + "verbose - toggle the request for delete confirmation.", NULL, }; return(PrintHelp(message)); } -/* - * 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: +/* Function Name: FSGroupHelp + * Description: Print help info on fsgroups. + * Arguments: none + * Returns: DM_NORMAL. */ + +int +FSGroupHelp() +{ + static char *message[] = { + "A filesystem group is a named sorted list of filesystems.", + "", + "To create, modify, or delete a group itself, use the menu above", + " this one, and manipulate a filesystem of type FSGROUP.", + "Options here are:", + " get - get info about a group and show its members", + " add - add a new member to a group.", + " remove - remove a member from a group.", + " order - change the sorting order of a group.", + NULL + }; + + return(PrintHelp(message)); +}