3 * This is the file nfs.c for the Moira Client, which allows users
4 * to quickly and easily maintain most parts of the Moira database.
5 * It Contains: All functions for manipulating NFS Physical directories.
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>
17 #include <moira_site.h>
28 char **AskNFSInfo(char **info);
30 #define TYPE_NFS "NFS"
32 #define DEFAULT_DIR "/u1/lockers"
33 #define DEFAULT_DEVICE "/dev/ra1c"
34 #define DEFAULT_STATUS DEFAULT_YES /* active. */
35 #define DEFAULT_ALLOC "0"
36 #define DEFAULT_SIZE "0"
38 /* Function Name: UpdatePrint
39 * Description: store a useful string for updates to print.
40 * Arguments: info - info about NFS service stored in array of strings.
41 * Returns: useful string.
44 static char *UpdatePrint(char **info)
46 char temp_buf[BUFSIZ];
47 sprintf(temp_buf, "Machine %s Directory %s", info[NFS_NAME], info[NFS_DIR]);
48 return strdup(temp_buf); /* Small memory leak here, but no good way
49 to avoid it that I see. */
52 /* Function Name: PrintNFSInfo
53 * Description: Prints NFS Physical service information.
54 * Arguments: info - the information.
55 * Returns: directory of this nfs server, for DeleteNFSService().
58 static char *PrintNFSInfo(char **info)
60 char buf[BUFSIZ], status_buf[BUFSIZ];
61 int status = atoi(info[NFS_STATUS]);
64 status_buf[0] = '\0'; /* clear string. */
66 if (status & MR_FS_STUDENT)
68 strcat(status_buf, "Student");
71 if (status & MR_FS_FACULTY)
74 strcat(status_buf, " and ");
75 strcat(status_buf, "Faculty");
78 if (status & MR_FS_STAFF)
81 strcat(status_buf, " and ");
82 strcat(status_buf, "Staff");
85 if (status & MR_FS_MISC)
88 strcat(status_buf, " and ");
89 strcat(status_buf, "Miscellaneous");
91 /* Add another type here. */
92 if (status & MR_FS_GROUPQUOTA)
95 strcat(status_buf, " / ");
96 strcat(status_buf, "Group Quotas Enabled");
99 if (status_buf[0] == '\0')
100 strcat(status_buf, "-- None --");
103 sprintf(buf, "Machine: %-20s Directory: %-15s Device: %s",
104 info[NFS_NAME], info[NFS_DIR], info[NFS_DEVICE]);
106 sprintf(buf, "Status: %s", status_buf);
108 sprintf(buf, "Quota Allocated: %-17s Size: %s",
109 info[NFS_ALLOC], info[NFS_SIZE]);
111 sprintf(buf, MOD_FORMAT, info[NFS_MODBY], info[NFS_MODTIME],
114 return info[NFS_DIR];
117 /* Function Name: AskNFSInfo.
118 * Description: This function askes the user for information about a
119 * machine and saves it into a structure.
120 * Arguments: info - a pointer the the structure to put the
122 * Returns: the arglist to make the update call with.
125 char **AskNFSInfo(char **info)
127 /* Also need name of the machine in this structure. */
129 if (GetValueFromUser("Device for this filsystem", &info[NFS_DEVICE]) ==
132 if (GetFSTypes(&info[NFS_STATUS], TRUE) == SUB_ERROR)
134 if (GetValueFromUser("Allocated Space for this filsystem:",
135 &info[NFS_ALLOC]) == SUB_ERROR)
137 if (GetValueFromUser("Size of this Filsystem:", &info[NFS_SIZE]) ==
141 FreeAndClear(&info[NFS_MODTIME], TRUE);
142 FreeAndClear(&info[NFS_MODBY], TRUE);
143 FreeAndClear(&info[NFS_MODWITH], TRUE);
149 /* Function Name: ShowNFSService
150 * Description: This function prints all exported partitions.
151 * Arguments: argc, argv - argv[1] - name of machine.
152 * Returns: DM_NORMAL.
155 int ShowNFSService(int argc, char **argv)
158 struct mqelem *elem = NULL;
161 if (!ValidName(argv[1]))
164 args[0] = canonicalize_hostname(strdup(argv[1]));
165 args[1] = strdup(DEFAULT_DIR);
166 if (GetValueFromUser("Directory:", &args[1]) == SUB_ERROR)
169 if ((stat = do_mr_query("get_nfsphys", 2, args, StoreInfo, &elem)))
170 com_err(program_name, stat, " in ShowNFSServices.");
172 free(args[1]); /* prevents memory leaks. */
174 elem = QueueTop(elem);
175 Loop(elem, (void (*)(char **)) PrintNFSInfo);
181 /* Function Name: AddNFSService
182 * Description: Adds a new partition to the nfsphys relation
183 * Arguments: arc, argv - argv[1] - machine name.
184 * Returns: DM_NORMAL.
187 int AddNFSService(int argc, char **argv)
189 char **add_args, *args[10];
190 char *info[MAX_ARGS_SIZE];
193 args[0] = canonicalize_hostname(strdup(argv[1]));
194 args[1] = strdup(DEFAULT_DIR);
195 if (GetValueFromUser("Directory:", &args[1]) == SUB_ERROR)
198 if (!ValidName(args[0]) || !ValidName(args[1]))
201 if (!(stat = do_mr_query("get_nfsphys", 2, args, NULL, NULL)))
203 if (stat != MR_NO_MATCH)
205 com_err(program_name, stat, " in get_nfsphys.");
209 info[NFS_NAME] = strdup(args[0]);
210 info[NFS_DIR] = args[1]; /* already saved. */
211 info[NFS_DEVICE] = strdup(DEFAULT_DEVICE);
212 info[NFS_STATUS] = strdup(DEFAULT_STATUS);
213 info[NFS_ALLOC] = strdup(DEFAULT_ALLOC);
214 info[NFS_SIZE] = strdup(DEFAULT_SIZE);
215 info[NFS_MODBY] = info[NFS_MODWITH] = info[NFS_MODTIME] = NULL;
216 info[NFS_END] = NULL;
218 if (!(add_args = AskNFSInfo(info)))
220 Put_message("Aborted.");
224 if ((stat = do_mr_query("add_nfsphys", CountArgs(add_args), add_args,
226 com_err(program_name, stat, " in AdsNFSService");
233 /* Function Name: RealUpdateNFSService
234 * Description: performs the actual update of the nfs service.
235 * Arguments: info - info about NFS service stored in array of strings.
236 * junk - an unused boolean.
240 static void RealUpdateNFSService(char **info, Bool junk)
245 if (!(args = AskNFSInfo(info)))
247 Put_message("Aborted.");
251 if ((stat = do_mr_query("update_nfsphys", CountArgs(args), args,
253 com_err(program_name, stat, " in RealUpdateNFSService");
256 /* Function Name: UpdateNFSService
257 * Description: Update the values for an nfsphys entry.
258 * Arguments: argc, argv - argv[1] - machine name.
259 * Returns: DM_NORMAL.
262 int UpdateNFSService(int argc, char **argv)
265 struct mqelem *elem = NULL;
268 if (!ValidName(argv[1]))
271 args[0] = canonicalize_hostname(strdup(argv[1]));
272 args[1] = strdup(DEFAULT_DIR);
273 if (GetValueFromUser("Directory:", &args[1]) == SUB_ERROR)
276 if ((stat = do_mr_query("get_nfsphys", 2, args, StoreInfo, &elem)))
278 com_err(program_name, stat, " in UpdateNFSService.");
282 free(args[1]); /* stop memory leaks. */
284 elem = QueueTop(elem);
285 QueryLoop(elem, UpdatePrint, RealUpdateNFSService, "Update NFS Service for");
291 /* Function Name: FSPartPrint
292 * Description: print filesystem partition usage.
293 * Arguments: info - the filesystem information.
297 static void FSPartPrint(char **info)
300 sprintf(buf, "NFS Filesystem %s uses that partition.", info[FS_NAME]);
304 /* Function Name: RealDeleteNFSService
305 * Description: Actually Deletes the filesystem (some checks are made).
306 * Arguments: info - info about NFS service stored in array of strings.
307 * one_item - if TRUE then only one item on the queue, and
312 static void RealDeleteNFSService(char **info, Bool one_item)
314 char temp_buf[BUFSIZ], *args[10];
315 struct mqelem *elem = NULL;
319 "Are you sure that you want to delete the %s directory on %s",
320 info[NFS_DIR], info[NFS_NAME]);
323 * Check to be sure that it is not used by any of the nfs packs.
326 if (!one_item || Confirm(temp_buf))
328 args[0] = info[NFS_NAME];
329 args[1] = info[NFS_DIR];
331 switch ((stat = do_mr_query("get_filesys_by_nfsphys", CountArgs(args),
332 args, StoreInfo, &elem)))
334 case MR_NO_MATCH: /* it is unused, delete it. */
335 if ((stat = do_mr_query("delete_nfsphys", 2, info, NULL, NULL)))
336 com_err(program_name, stat, " in DeleteNFSService");
338 Put_message("Physical Filesystem Deleted.");
340 case MR_SUCCESS: /* it is used, print filesys's that use it. */
341 elem = QueueTop(elem);
342 Put_message("The following fileystems are using this partition,");
343 Put_message("and must be removed before it can be deleted.");
345 Loop(elem, FSPartPrint);
351 com_err(program_name, stat, " while checking usage of partition");
355 Put_message("Physical filesystem not deleted.");
358 /* Function Name: DeleteNFSService
359 * Description: Delete an nfsphys entry.
360 * Arguments: argc, argv - name of the machine in argv[1].
361 * Returns: DM_NORMAL.
364 int DeleteNFSService(int argc, char **argv)
367 struct mqelem *elem = NULL;
370 if (!ValidName(argv[1]))
373 args[0] = canonicalize_hostname(strdup(argv[1]));
374 args[1] = strdup(DEFAULT_DIR);
375 if (GetValueFromUser("Directory:", &args[1]) == SUB_ERROR)
378 switch ((stat = do_mr_query("get_nfsphys", 2, args, StoreInfo, &elem)))
381 Put_message("This filsystem does not exist!");
386 com_err(program_name, stat, " in DeleteNFSService");
390 free(args[1]); /* stop memory leaks, in your neighborhood. */
392 QueryLoop(elem, PrintNFSInfo, RealDeleteNFSService,
393 "Delete the Physical Filesystem on Directory");