-#ifndef lint
- static char rcsid_module_c[] = "$Header$";
-#endif lint
-
-/* This is the file nfs.c for allmaint, the SMS client that allows
- * a user to maintaint most important parts of the SMS database.
- * It Contains: The nfs maintanance code.
- *
+/* $Id$
+ *
+ * This is the file nfs.c for the Moira Client, which allows users
+ * to quickly and easily maintain most parts of the Moira database.
+ * It Contains: All functions for manipulating NFS Physical directories.
+ *
* Created: 5/6/88
* By: Chris D. Peterson
*
- * $Source$
- * $Author$
- * $Header$
- *
- * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
- *
- * For further information on copyright and distribution
- * see the file mit-copyright.h
+ * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
*/
+#include <mit-copyright.h>
+#include <moira.h>
+#include <moira_site.h>
+#include "defs.h"
+#include "f_defs.h"
+#include "globals.h"
+
#include <stdio.h>
-#include <strings.h>
-#include <sms.h>
-#include <menu.h>
+#include <stdlib.h>
+#include <string.h>
-#include "mit-copyright.h"
-#include "allmaint.h"
-#include "allmaint_funcs.h"
-#include "globals.h"
-#include "infodefs.h"
+RCSID("$Header$");
-/* #include <sys/types.h> */
+char **AskNFSInfo(char **info);
#define TYPE_NFS "NFS"
-#define DEFAULT_DIR "/mit"
-#define DEFAULT_STATUS "1"
+#define DEFAULT_DIR "/u1/lockers"
+#define DEFAULT_DEVICE "/dev/ra1c"
+#define DEFAULT_STATUS DEFAULT_YES /* active. */
#define DEFAULT_ALLOC "0"
-#define DEFAULT_SIZE "400000"
+#define DEFAULT_SIZE "0"
+
+/* Function Name: UpdatePrint
+ * Description: store a useful string for updates to print.
+ * Arguments: info - info about NFS service stored in array of strings.
+ * Returns: useful string.
+ */
+
+static char *UpdatePrint(char **info)
+{
+ char temp_buf[BUFSIZ];
+ sprintf(temp_buf, "Machine %s Directory %s", info[NFS_NAME], info[NFS_DIR]);
+ return strdup(temp_buf); /* Small memory leak here, but no good way
+ to avoid it that I see. */
+}
/* Function Name: PrintNFSInfo
* Description: Prints NFS Physical service information.
* Arguments: info - the information.
- * Returns: none.
+ * Returns: directory of this nfs server, for DeleteNFSService().
*/
-void
-PrintNFSInfo(info)
-char ** info;
+static char *PrintNFSInfo(char **info)
{
- char temp_buf[BUFSIZ];
- int status = atoi(info[NFS_STATUS]);
-
- sprintf(temp_buf,"Machine: %s,\tDirectory: %s,\tDevice: %s",
- info[NFS_NAME], info[NFS_DIR], info[NFS_DEVICE]);
- Put_message(temp_buf);
- sprintf(temp_buf, "Status: %s,\tQuota Allocated: %s.\tSize: %s",
- status ? "Active" : "Inactive", info[NFS_ALLOC], info[NFS_SIZE]);
- Put_message(temp_buf);
- sprintf(temp_buf, "Last Modification by %s at %s with %s.",
- info[U_MODBY], info[U_MODTIME], info[U_MODWITH]);
- Put_message(temp_buf);
+ char buf[BUFSIZ], status_buf[BUFSIZ];
+ int status = atoi(info[NFS_STATUS]);
+ Bool is_one = FALSE;
+
+ status_buf[0] = '\0'; /* clear string. */
+
+ if (status & MR_FS_STUDENT)
+ {
+ strcat(status_buf, "Student");
+ is_one = TRUE;
+ }
+ if (status & MR_FS_FACULTY)
+ {
+ if (is_one)
+ strcat(status_buf, " and ");
+ strcat(status_buf, "Faculty");
+ is_one = TRUE;
+ }
+ if (status & MR_FS_STAFF)
+ {
+ if (is_one)
+ strcat(status_buf, " and ");
+ strcat(status_buf, "Staff");
+ is_one = TRUE;
+ }
+ if (status & MR_FS_MISC)
+ {
+ if (is_one)
+ strcat(status_buf, " and ");
+ strcat(status_buf, "Miscellaneous");
+ }
+ /* Add another type here. */
+ if (status & MR_FS_GROUPQUOTA)
+ {
+ if (is_one)
+ strcat(status_buf, " / ");
+ strcat(status_buf, "Group Quotas Enabled");
+ }
+
+ if (status_buf[0] == '\0')
+ strcat(status_buf, "-- None --");
+
+ Put_message("");
+ sprintf(buf, "Machine: %-20s Directory: %-15s Device: %s",
+ info[NFS_NAME], info[NFS_DIR], info[NFS_DEVICE]);
+ Put_message(buf);
+ sprintf(buf, "Status: %s", status_buf);
+ Put_message(buf);
+ sprintf(buf, "Quota Allocated: %-17s Size: %s",
+ info[NFS_ALLOC], info[NFS_SIZE]);
+ Put_message(buf);
+ sprintf(buf, MOD_FORMAT, info[NFS_MODBY], info[NFS_MODTIME],
+ info[NFS_MODWITH]);
+ Put_message(buf);
+ return info[NFS_DIR];
}
+
/* Function Name: AskNFSInfo.
- * 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.
* Returns: the arglist to make the update call with.
*/
-char **
-AskNFSInfo(info)
-char ** info;
+char **AskNFSInfo(char **info)
{
- /* Also need name of the machine in this structure. */
-
- GetValueFromUser("Directory for filesystem:", &info[NFS_DIR]);
- GetValueFromUser("Device for this filsystem", &info[NFS_DEVICE]);
-
- Put_message("\nTypes: Student, Faculty, Project, Staff, and Other.\n");
- GetValueFromUser("Please enter one or more of the above types:"
- ,&info[NFS_STATUS]);
-
- GetValueFromUser("Allocated Space for this filsystem:",&info[NFS_ALLOC]);
- GetValueFromUser("Size of this Filsystem:",&info[NFS_SIZE]);
-
- FreeAndClear(&info[NFS_MODTIME], TRUE);
- FreeAndClear(&info[NFS_MODBY], TRUE);
- FreeAndClear(&info[NFS_MODWITH], TRUE);
-
- return(info);
+ /* Also need name of the machine in this structure. */
+
+ if (GetValueFromUser("Device for this filsystem", &info[NFS_DEVICE]) ==
+ SUB_ERROR)
+ return NULL;
+ if (GetFSTypes(&info[NFS_STATUS], TRUE) == SUB_ERROR)
+ return NULL;
+ if (GetValueFromUser("Allocated Space for this filsystem:",
+ &info[NFS_ALLOC]) == SUB_ERROR)
+ return NULL;
+ if (GetValueFromUser("Size of this Filsystem:", &info[NFS_SIZE]) ==
+ SUB_ERROR)
+ return NULL;
+
+ FreeAndClear(&info[NFS_MODTIME], TRUE);
+ FreeAndClear(&info[NFS_MODBY], TRUE);
+ FreeAndClear(&info[NFS_MODWITH], TRUE);
+
+ return info;
}
+
/* Function Name: ShowNFSService
* Description: This function prints all exported partitions.
* Arguments: argc, argv - argv[1] - name of machine.
- * argv[2] - name of directroy.
* Returns: DM_NORMAL.
*/
-/* ARGSUSED */
-int
-ShowNFSService(argc, argv)
-int argc;
-char **argv;
+int ShowNFSService(int argc, char **argv)
{
- register int stat;
- struct qelem * top, *elem = NULL;
-
- if ( (stat = sms_query("get_nfsphys", 2, argv + 1,
- StoreInfo, (char *) &elem)) != 0)
- com_err(program_name, stat, " in ShowNFSServices.");
-
- top = elem;
- while (elem != NULL) {
- char ** info = (char **) elem->q_data;
- PrintNFSInfo(info);
- elem = elem->q_forw;
- }
- FreeQueue(top);
- return (DM_NORMAL);
+ int stat;
+ struct mqelem *elem = NULL;
+ char *args[10];
+
+ if (!ValidName(argv[1]))
+ return DM_NORMAL;
+
+ args[0] = canonicalize_hostname(strdup(argv[1]));
+ args[1] = strdup(DEFAULT_DIR);
+ if (GetValueFromUser("Directory:", &args[1]) == SUB_ERROR)
+ return DM_NORMAL;
+
+ if ((stat = do_mr_query("get_nfsphys", 2, args, StoreInfo, &elem)))
+ com_err(program_name, stat, " in ShowNFSServices.");
+ free(args[0]);
+ free(args[1]); /* prevents memory leaks. */
+
+ elem = QueueTop(elem);
+ Loop(elem, (void (*)(char **)) PrintNFSInfo);
+
+ FreeQueue(elem);
+ return DM_NORMAL;
}
/* Function Name: AddNFSService
* Description: Adds a new partition to the nfsphys relation
- * Arguments: arc, argv -
- * argv[1] - machine name.
- * argv[2] - directory.
+ * Arguments: arc, argv - argv[1] - machine name.
* Returns: DM_NORMAL.
*/
-/* ARGSUSED */
-int
-AddNFSService(argc, argv)
-char **argv;
-int argc;
+int AddNFSService(int argc, char **argv)
{
- char **args;
- static char *info[MAX_ARGS_SIZE];
- int stat;
-
- if ( (stat = sms_query("get_nfsphys", 2, argv + 1,
- NullFunc, (char *) NULL)) == 0) {
- Put_message("This service already exists.");
- if (stat != SMS_NO_MATCH)
- com_err(program_name, stat, " in get_nfsphys.");
+ char **add_args, *args[10];
+ char *info[MAX_ARGS_SIZE];
+ int stat;
+
+ args[0] = canonicalize_hostname(strdup(argv[1]));
+ args[1] = strdup(DEFAULT_DIR);
+ if (GetValueFromUser("Directory:", &args[1]) == SUB_ERROR)
+ return DM_NORMAL;
+
+ if (!ValidName(args[0]) || !ValidName(args[1]))
+ return DM_NORMAL;
+
+ if (!(stat = do_mr_query("get_nfsphys", 2, args, NULL, NULL)))
+ stat = MR_EXISTS;
+ if (stat != MR_NO_MATCH)
+ {
+ com_err(program_name, stat, " in get_nfsphys.");
+ return DM_NORMAL;
}
-
- if ( (info[NFS_NAME] = CanonicalizeHostname(argv[1])) == NULL) {
- Put_message("Unknown host, try again...");
- return(DM_NORMAL);
+
+ info[NFS_NAME] = strdup(args[0]);
+ info[NFS_DIR] = args[1]; /* already saved. */
+ info[NFS_DEVICE] = strdup(DEFAULT_DEVICE);
+ info[NFS_STATUS] = strdup(DEFAULT_STATUS);
+ info[NFS_ALLOC] = strdup(DEFAULT_ALLOC);
+ info[NFS_SIZE] = strdup(DEFAULT_SIZE);
+ info[NFS_MODBY] = info[NFS_MODWITH] = info[NFS_MODTIME] = NULL;
+ info[NFS_END] = NULL;
+
+ if (!(add_args = AskNFSInfo(info)))
+ {
+ Put_message("Aborted.");
+ return DM_NORMAL;
}
- info[NFS_NAME] = Strsave(info[NFS_NAME]);
- info[NFS_DEVICE] = Strsave(argv[2]);
- info[NFS_DIR] = Strsave(DEFAULT_DIR);
- info[NFS_STATUS] = Strsave(DEFAULT_STATUS);
- info[NFS_ALLOC] = Strsave(DEFAULT_ALLOC);
- info[NFS_SIZE] = Strsave(DEFAULT_SIZE);
- info[NFS_SIZE + 1] = NULL; /* NULL terminate. */
-
- args = AskNFSInfo(info);
-
- if ((stat = sms_query("add_nfsphys", CountArgs(args), args,
- Scream, (char *) NULL)) != 0)
- com_err(program_name, stat, " in AdsNFSService");
-
- FreeInfo(info);
- return (DM_NORMAL);
+ if ((stat = do_mr_query("add_nfsphys", CountArgs(add_args), add_args,
+ NULL, NULL)))
+ com_err(program_name, stat, " in AdsNFSService");
+
+ FreeInfo(info);
+ free(args[0]);
+ return DM_NORMAL;
+}
+
+/* Function Name: RealUpdateNFSService
+ * Description: performs the actual update of the nfs service.
+ * Arguments: info - info about NFS service stored in array of strings.
+ * junk - an unused boolean.
+ * Returns: none.
+ */
+
+static void RealUpdateNFSService(char **info, Bool junk)
+{
+ char **args;
+ int stat;
+
+ if (!(args = AskNFSInfo(info)))
+ {
+ Put_message("Aborted.");
+ return;
+ }
+
+ if ((stat = do_mr_query("update_nfsphys", CountArgs(args), args,
+ NULL, NULL)))
+ com_err(program_name, stat, " in RealUpdateNFSService");
}
/* Function Name: UpdateNFSService
* Description: Update the values for an nfsphys entry.
- * Arguments: argc, argv -
- * argv[1] - machine name.
- * argv[2] - directory.
+ * Arguments: argc, argv - argv[1] - machine name.
* Returns: DM_NORMAL.
*/
-/* ARGSUSED. */
-int
-UpdateNFSService(argc, argv)
-char **argv;
-int argc;
+int UpdateNFSService(int argc, char **argv)
{
- register int stat;
- Bool update, one_service;
- char **args, **info, buf[BUFSIZ];
- struct qelem *elem, *top;
- elem = NULL;
-
- if ( (argv[1] = CanonicalizeHostname(argv[1])) == NULL) {
- Put_message("Unknown host, try again...");
- return(DM_NORMAL);
+ int stat;
+ struct mqelem *elem = NULL;
+ char *args[10];
+
+ if (!ValidName(argv[1]))
+ return DM_NORMAL;
+
+ args[0] = canonicalize_hostname(strdup(argv[1]));
+ args[1] = strdup(DEFAULT_DIR);
+ if (GetValueFromUser("Directory:", &args[1]) == SUB_ERROR)
+ return DM_NORMAL;
+
+ if ((stat = do_mr_query("get_nfsphys", 2, args, StoreInfo, &elem)))
+ {
+ com_err(program_name, stat, " in UpdateNFSService.");
+ return DM_NORMAL;
}
+ free(args[0]);
+ free(args[1]); /* stop memory leaks. */
- if ( (stat = sms_query("get_nfsphys", 2, argv + 1,
- StoreInfo, (char *) &elem)) != 0) {
- com_err(program_name, stat, " in UpdateNFSService.");
- return (DM_NORMAL);
- }
+ elem = QueueTop(elem);
+ QueryLoop(elem, UpdatePrint, RealUpdateNFSService, "Update NFS Service for");
- top = elem = QueueTop(elem);
- one_service = ( QueueCount(top) == 1 );
- while (elem != NULL) {
- info = (char **) elem->q_data;
- if (!one_service) { /* If more than one then query through them. */
- sprintf(buf,"Update - %s\tDirectory: %s? (y/n/q)", info[NFS_NAME],
- info[NFS_DIR]);
- switch( YesNoQuitQuestion(buf, FALSE)) {
- case TRUE:
- update = TRUE;
- break;
- case FALSE:
- update = FALSE;
- break;
- default:
- FreeQueue(top);
- Put_message("Aborting update.");
- return(DM_NORMAL);
- }
- }
- else
- update = TRUE;
-
- if (update) { /* actually perform update */
- args = AskNFSInfo(info);
- if ((stat = sms_query("update_nfsphys", CountArgs(args), args,
- Scream, (char *)NULL)) != 0)
- com_err(program_name, stat, (char *) NULL);
+ FreeQueue(elem);
+ return DM_NORMAL;
+}
+
+/* Function Name: FSPartPrint
+ * Description: print filesystem partition usage.
+ * Arguments: info - the filesystem information.
+ * Returns: none.
+ */
+
+static void FSPartPrint(char **info)
+{
+ char buf[BUFSIZ];
+ sprintf(buf, "NFS Filesystem %s uses that partition.", info[FS_NAME]);
+ Put_message(buf);
+}
+
+/* Function Name: RealDeleteNFSService
+ * Description: Actually Deletes the filesystem (some checks are made).
+ * Arguments: info - info about NFS service stored in array of strings.
+ * one_item - if TRUE then only one item on the queue, and
+ * we should confirm.
+ * Returns: none.
+ */
+
+static void RealDeleteNFSService(char **info, Bool one_item)
+{
+ char temp_buf[BUFSIZ], *args[10];
+ struct mqelem *elem = NULL;
+ int stat;
+
+ sprintf(temp_buf,
+ "Are you sure that you want to delete the %s directory on %s",
+ info[NFS_DIR], info[NFS_NAME]);
+
+ /*
+ * Check to be sure that it is not used by any of the nfs packs.
+ */
+
+ if (!one_item || Confirm(temp_buf))
+ {
+ args[0] = info[NFS_NAME];
+ args[1] = info[NFS_DIR];
+ args[2] = NULL;
+ switch ((stat = do_mr_query("get_filesys_by_nfsphys", CountArgs(args),
+ args, StoreInfo, &elem)))
+ {
+ case MR_NO_MATCH: /* it is unused, delete it. */
+ if ((stat = do_mr_query("delete_nfsphys", 2, info, NULL, NULL)))
+ com_err(program_name, stat, " in DeleteNFSService");
+ else
+ Put_message("Physical Filesystem Deleted.");
+ break;
+ case MR_SUCCESS: /* it is used, print filesys's that use it. */
+ elem = QueueTop(elem);
+ Put_message("The following fileystems are using this partition,");
+ Put_message("and must be removed before it can be deleted.");
+ Put_message("");
+ Loop(elem, FSPartPrint);
+
+ FreeQueue(elem);
+ Put_message("");
+ break;
+ default:
+ com_err(program_name, stat, " while checking usage of partition");
}
- elem = elem->q_forw;
}
-
- FreeQueue(top);
- return (DM_NORMAL);
+ else
+ Put_message("Physical filesystem not deleted.");
}
/* Function Name: DeleteNFSService
* Description: Delete an nfsphys entry.
- * Arguments: argc, argv - name of file system in argv[1].
- * directory of file system in argv[2].
+ * Arguments: argc, argv - name of the machine in argv[1].
* Returns: DM_NORMAL.
*/
-/* ARGSUSED */
-int
-DeleteNFSService(argc, argv)
-int argc;
-char **argv;
+int DeleteNFSService(int argc, char **argv)
{
- register int stat;
- struct qelem *top, *elem = NULL;
- char * dir = argv[2];
- int length;
- Bool delete_ok = TRUE;
-
- argv[1] = CanonicalizeHostname(argv[1]);
-
- stat = sms_query("get_nfsphys", 2, argv + 1, NullFunc, (char *) NULL);
- if (stat == SMS_NO_MATCH) {
- Put_message("This filsystem does not exist!");
- return(DM_NORMAL);
- }
- if (stat) {
- com_err(program_name, stat, " in DeleteNFSService");
- return(DM_NORMAL);
- }
-
- stat = sms_query("get_filesys_by_machine", 1, argv + 1, StoreInfo,
- &elem);
- if (stat && stat != SMS_NO_MATCH)
- com_err(program_name, stat, " while checking usage of partition");
-
- length = strlen( dir );
- top = elem = QueueTop(elem);
- while (elem != NULL) {
- char buf[BUFSIZ];
- char ** info = (char ** ) elem->q_data;
- if ( (strcmp(info[FS_TYPE], TYPE_NFS) == 0) &&
- (strcmp(info[FS_PACK], dir, length) == 0) ) {
- sprintf(buf, "Filesystem %s uses that partition", info[FS_NAME]);
- Put_message(buf);
- delete_ok = FALSE;
- }
- elem = elem->q_forw;
+ int stat;
+ struct mqelem *elem = NULL;
+ char *args[10];
+
+ if (!ValidName(argv[1]))
+ return DM_NORMAL;
+
+ args[0] = canonicalize_hostname(strdup(argv[1]));
+ args[1] = strdup(DEFAULT_DIR);
+ if (GetValueFromUser("Directory:", &args[1]) == SUB_ERROR)
+ return DM_NORMAL;
+
+ switch ((stat = do_mr_query("get_nfsphys", 2, args, StoreInfo, &elem)))
+ {
+ case MR_NO_MATCH:
+ Put_message("This filsystem does not exist!");
+ return DM_NORMAL;
+ case MR_SUCCESS:
+ break;
+ default:
+ com_err(program_name, stat, " in DeleteNFSService");
+ return DM_NORMAL;
}
+ free(args[0]);
+ free(args[1]); /* stop memory leaks, in your neighborhood. */
- if ( delete_ok &&
- Confirm("Do you really want to delete this Filesystem? (y/n) ")) {
- if ( (stat = sms_query("delete_nfsphys", 2, argv + 1,
- Scream, (char *) NULL )) !=0 )
- com_err(program_name, stat, " in DeleteNFSService");
- }
- else
- Put_message("Operation Aborted.\n");
+ QueryLoop(elem, PrintNFSInfo, RealDeleteNFSService,
+ "Delete the Physical Filesystem on Directory");
- FreeQueue(top);
- return(DM_NORMAL);
+ FreeQueue(elem);
+ return DM_NORMAL;
}
-
-
-/*
- * 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:
- */