]>
Commit | Line | Data |
---|---|---|
c441a31a | 1 | /* $Id$ |
7ac48069 | 2 | * |
3 | * This is the file attach.c for the Moira Client, which allows users | |
59ec8dae | 4 | * to quickly and easily maintain most parts of the Moira database. |
5eaef520 | 5 | * It Contains: Functions for maintaining data used by Hesiod |
6 | * to map courses/projects/users to their file systems, | |
7 | * and maintain filesys info. | |
8 | * | |
08345b74 | 9 | * Created: 5/4/88 |
10 | * By: Chris D. Peterson | |
08345b74 | 11 | * |
7ac48069 | 12 | * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology. |
13 | * For copying and distribution information, please see the file | |
14 | * <mit-copyright.h>. | |
08345b74 | 15 | */ |
16 | ||
7ac48069 | 17 | #include <mit-copyright.h> |
8defc06b | 18 | #include <moira.h> |
19 | #include <moira_site.h> | |
08345b74 | 20 | |
0a2c64cb | 21 | #include "defs.h" |
22 | #include "f_defs.h" | |
461c03b6 | 23 | #include "globals.h" |
461c03b6 | 24 | |
7ac48069 | 25 | #include <sys/stat.h> |
26 | ||
27 | #include <ctype.h> | |
28 | #include <stdio.h> | |
29 | #include <stdlib.h> | |
30 | #include <string.h> | |
533bacb3 | 31 | #ifdef HAVE_UNISTD_H |
7ac48069 | 32 | #include <unistd.h> |
533bacb3 | 33 | #endif /* HAVE_UNISTD_H */ |
7ac48069 | 34 | |
35 | RCSID("$Header$"); | |
36 | ||
37 | char *canonicalize_cell(char *c); | |
38 | int GetAliasValue(int argc, char **argv, void *retval); | |
39 | void RealDeleteFS(char **info, Bool one_item); | |
600b459e | 40 | char *SortAfter(struct mqelem *elem, int count); |
7ac48069 | 41 | void RealDeleteFSAlias(char **info, Bool one_item); |
42 | ||
08345b74 | 43 | #define FS_ALIAS_TYPE "FILESYS" |
44 | ||
461c03b6 | 45 | #define LABEL 0 |
46 | #define MACHINE 1 | |
47 | #define GROUP 2 | |
48 | #define ALIAS 3 | |
1d4e1e0f | 49 | #define ALIAS_CHECK 4 |
50 | #define FS_ALIASES 5 | |
08345b74 | 51 | |
6966e6fe | 52 | #define NO_MACHINE ("[NONE]") |
9e2516d6 | 53 | |
1104552d | 54 | #define DEFAULT_TYPE ("AFS") |
85ca828a | 55 | #define DEFAULT_MACHINE DEFAULT_NONE |
56 | #define DEFAULT_PACK DEFAULT_NONE | |
7f6743f7 | 57 | #define DEFAULT_ACCESS ("w") |
85ca828a | 58 | #define DEFAULT_COMMENTS DEFAULT_COMMENT |
59 | #define DEFAULT_OWNER (user) | |
60 | #define DEFAULT_OWNERS (user) | |
61 | #define DEFAULT_CREATE DEFAULT_YES | |
7f6743f7 | 62 | #define DEFAULT_L_TYPE ("PROJECT") |
7cb7d352 | 63 | #define DEFAULT_CELL ("athena.mit.edu") |
85ca828a | 64 | |
65 | /* Function Name: SetDefaults | |
66 | * Description: sets the default values for filesystem additions. | |
5eaef520 | 67 | * Arguments: info - an array of char pointers to recieve defaults. |
85ca828a | 68 | * Returns: char ** (this array, now filled). |
69 | */ | |
70 | ||
5eaef520 | 71 | static char **SetDefaults(char **info, char *name) |
85ca828a | 72 | { |
5eaef520 | 73 | char buf[BUFSIZ]; |
74 | ||
7ac48069 | 75 | info[FS_NAME] = strdup(name); |
76 | info[FS_TYPE] = strdup(DEFAULT_TYPE); | |
77 | info[FS_MACHINE] = strdup(DEFAULT_MACHINE); | |
78 | info[FS_PACK] = strdup(DEFAULT_PACK); | |
5eaef520 | 79 | sprintf(buf, "/mit/%s", name); |
7ac48069 | 80 | info[FS_M_POINT] = strdup(buf); |
81 | info[FS_ACCESS] = strdup(DEFAULT_ACCESS); | |
82 | info[FS_COMMENTS] = strdup(DEFAULT_COMMENTS); | |
83 | info[FS_OWNER] = strdup(DEFAULT_OWNER); | |
84 | info[FS_OWNERS] = strdup(DEFAULT_OWNERS); | |
85 | info[FS_CREATE] = strdup(DEFAULT_CREATE); | |
86 | info[FS_L_TYPE] = strdup(DEFAULT_L_TYPE); | |
5eaef520 | 87 | info[FS_MODTIME] = info[FS_MODBY] = info[FS_MODWITH] = info[FS_END] = NULL; |
88 | return info; | |
85ca828a | 89 | } |
90 | ||
08345b74 | 91 | /* Function Name: GetFSInfo |
92 | * Description: Stores the info in a queue. | |
93 | * Arguments: type - type of information to get. | |
94 | * name - name of the item to get information on. | |
95 | * Returns: a pointer to the first element in the queue. | |
96 | */ | |
97 | ||
600b459e | 98 | static struct mqelem *GetFSInfo(int type, char *name) |
08345b74 | 99 | { |
5eaef520 | 100 | int stat; |
600b459e | 101 | struct mqelem *elem = NULL; |
5eaef520 | 102 | char *args[5]; |
08345b74 | 103 | |
5eaef520 | 104 | switch (type) |
105 | { | |
461c03b6 | 106 | case LABEL: |
5eaef520 | 107 | if ((stat = do_mr_query("get_filesys_by_label", 1, &name, |
7ac48069 | 108 | StoreInfo, &elem))) |
5eaef520 | 109 | { |
110 | com_err(program_name, stat, " in GetFSInfo"); | |
111 | return NULL; | |
08345b74 | 112 | } |
5eaef520 | 113 | break; |
461c03b6 | 114 | case MACHINE: |
5eaef520 | 115 | if ((stat = do_mr_query("get_filesys_by_machine", 1, &name, |
7ac48069 | 116 | StoreInfo, &elem))) |
5eaef520 | 117 | { |
118 | com_err(program_name, stat, " in GetFSInfo"); | |
119 | return NULL; | |
08345b74 | 120 | } |
5eaef520 | 121 | break; |
461c03b6 | 122 | case GROUP: |
5eaef520 | 123 | if ((stat = do_mr_query("get_filesys_by_group", 1, &name, |
7ac48069 | 124 | StoreInfo, &elem))) |
5eaef520 | 125 | { |
126 | com_err(program_name, stat, " in GetFSInfo"); | |
127 | return NULL; | |
08345b74 | 128 | } |
5eaef520 | 129 | break; |
461c03b6 | 130 | case ALIAS: |
1d4e1e0f | 131 | case ALIAS_CHECK: |
5eaef520 | 132 | args[ALIAS_NAME] = name; |
133 | args[ALIAS_TYPE] = FS_ALIAS_TYPE; | |
134 | args[ALIAS_TRANS] = "*"; | |
7ac48069 | 135 | if ((stat = do_mr_query("get_alias", 3, args, StoreInfo, &elem))) |
5eaef520 | 136 | { |
1d4e1e0f | 137 | if (type != ALIAS_CHECK || stat != MR_NO_MATCH) |
138 | com_err(program_name, stat, " in get_alias."); | |
5eaef520 | 139 | return NULL; |
08345b74 | 140 | } |
1d4e1e0f | 141 | break; |
142 | case FS_ALIASES: | |
143 | args[ALIAS_NAME] = "*"; | |
144 | args[ALIAS_TYPE] = FS_ALIAS_TYPE; | |
145 | args[ALIAS_TRANS] = name; | |
146 | if ((stat = do_mr_query("get_alias", 3, args, StoreInfo, &elem))) | |
147 | { | |
148 | if (stat != MR_NO_MATCH) | |
149 | com_err(program_name, stat, " in get_alias."); | |
150 | return NULL; | |
151 | } | |
152 | break; | |
08345b74 | 153 | } |
154 | ||
5eaef520 | 155 | return QueueTop(elem); |
08345b74 | 156 | } |
157 | ||
85ca828a | 158 | /* Function Name: PrintFSAlias |
159 | * Description: Prints a filesystem alias | |
160 | * Arguments: info - an array contains the strings of info. | |
402461ad | 161 | * Returns: the name of the filesys - used be QueryLoop(). |
85ca828a | 162 | */ |
163 | ||
5eaef520 | 164 | static char *PrintFSAlias(char **info) |
85ca828a | 165 | { |
5eaef520 | 166 | char buf[BUFSIZ]; |
85ca828a | 167 | |
5eaef520 | 168 | sprintf(buf, "Alias: %-25s Filesystem: %s", info[ALIAS_NAME], |
169 | info[ALIAS_TRANS]); | |
170 | Put_message(buf); | |
171 | return info[ALIAS_NAME]; | |
85ca828a | 172 | } |
173 | ||
1d4e1e0f | 174 | static char aliasbuf[256]; |
175 | ||
176 | static char *PrintFSAliasList(char **info) | |
177 | { | |
178 | if (strlen(aliasbuf) == 0) | |
179 | snprintf(aliasbuf, sizeof(aliasbuf), "Aliases: %s", info[ALIAS_NAME]); | |
180 | else | |
181 | { | |
182 | strncat(aliasbuf, ", ", sizeof(aliasbuf)); | |
183 | strncat(aliasbuf, info[ALIAS_NAME], sizeof(aliasbuf)); | |
184 | } | |
185 | } | |
186 | ||
187 | static char labelbuf[256]; | |
188 | ||
189 | static char *GetFSLabel(char **info) | |
190 | { | |
191 | snprintf(labelbuf, sizeof(labelbuf), info[ALIAS_TRANS]); | |
192 | } | |
193 | ||
9e2516d6 | 194 | static int fsgCount = 1; |
195 | ||
7ac48069 | 196 | static void PrintFSGMembers(char **info) |
9e2516d6 | 197 | { |
5eaef520 | 198 | char print_buf[BUFSIZ]; |
9e2516d6 | 199 | |
5eaef520 | 200 | sprintf(print_buf, " %d. Filesystem: %-32s (sort key: %s)", |
201 | fsgCount++, info[0], info[1]); | |
202 | Put_message(print_buf); | |
9e2516d6 | 203 | } |
204 | ||
205 | ||
08345b74 | 206 | /* Function Name: PrintFSInfo |
207 | * Description: Prints the filesystem information. | |
208 | * Arguments: info - a pointer to the filesystem information. | |
209 | * Returns: none. | |
210 | */ | |
211 | ||
5eaef520 | 212 | static char *PrintFSInfo(char **info) |
08345b74 | 213 | { |
5eaef520 | 214 | char print_buf[BUFSIZ]; |
1d4e1e0f | 215 | struct mqelem *top; |
5eaef520 | 216 | |
217 | FORMFEED; | |
218 | ||
219 | if (!strcmp(info[FS_TYPE], "FSGROUP") || !strcmp(info[FS_TYPE], "MUL")) | |
220 | { | |
221 | int stat; | |
600b459e | 222 | struct mqelem *elem = NULL; |
5eaef520 | 223 | |
224 | if (!strcmp(info[FS_TYPE], "MUL")) | |
225 | sprintf(print_buf, "%20s Multiple Filesystem: %s", " ", info[FS_NAME]); | |
226 | else | |
227 | sprintf(print_buf, "%20s Filesystem Group: %s", " ", info[FS_NAME]); | |
228 | Put_message(print_buf); | |
229 | ||
1d4e1e0f | 230 | top = GetFSInfo(FS_ALIASES, info[FS_NAME]); |
231 | if (top != NULL) { | |
232 | *aliasbuf = 0; | |
233 | Loop(top, (void (*)(char **))PrintFSAliasList); | |
234 | Put_message(aliasbuf); | |
235 | FreeQueue(top); /* clean the queue. */ | |
236 | } | |
237 | ||
5eaef520 | 238 | sprintf(print_buf, "Comments: %s", info[FS_COMMENTS]); |
239 | Put_message(print_buf); | |
240 | sprintf(print_buf, MOD_FORMAT, info[FS_MODBY], info[FS_MODTIME], | |
241 | info[FS_MODWITH]); | |
242 | Put_message(print_buf); | |
243 | Put_message("Containing the filesystems (in order):"); | |
244 | if ((stat = do_mr_query("get_fsgroup_members", 1, &info[FS_NAME], | |
7ac48069 | 245 | StoreInfo, &elem))) |
5eaef520 | 246 | { |
247 | if (stat == MR_NO_MATCH) | |
248 | Put_message(" [no members]"); | |
249 | else | |
250 | com_err(program_name, stat, " in PrintFSInfo"); | |
251 | } | |
252 | else | |
253 | { | |
254 | fsgCount = 1; | |
255 | Loop(QueueTop(elem), PrintFSGMembers); | |
256 | FreeQueue(elem); | |
9e2516d6 | 257 | } |
9e2516d6 | 258 | } |
5eaef520 | 259 | else |
260 | { | |
261 | sprintf(print_buf, "%20s Filesystem: %s", " ", info[FS_NAME]); | |
262 | Put_message(print_buf); | |
1d4e1e0f | 263 | |
264 | top = GetFSInfo(FS_ALIASES, info[FS_NAME]); | |
265 | if (top != NULL) { | |
266 | *aliasbuf = 0; | |
267 | Loop(top, (void (*)(char **))PrintFSAliasList); | |
268 | Put_message(aliasbuf); | |
269 | FreeQueue(top); /* clean the queue. */ | |
270 | } | |
271 | ||
5eaef520 | 272 | sprintf(print_buf, "Type: %-40s Machine: %-15s", |
273 | info[FS_TYPE], info[FS_MACHINE]); | |
274 | Put_message(print_buf); | |
275 | sprintf(print_buf, "Default Access: %-2s Packname: %-17s Mountpoint %s ", | |
276 | info[FS_ACCESS], info[FS_PACK], info[FS_M_POINT]); | |
277 | Put_message(print_buf); | |
278 | sprintf(print_buf, "Comments: %s", info[FS_COMMENTS]); | |
279 | Put_message(print_buf); | |
280 | sprintf(print_buf, "User Ownership: %-30s Group Ownership: %s", | |
281 | info[FS_OWNER], info[FS_OWNERS]); | |
282 | Put_message(print_buf); | |
283 | sprintf(print_buf, "Update Fileserver: %-27s Locker Type: %s", | |
284 | atoi(info[FS_CREATE]) ? "ON" : "OFF", info[FS_L_TYPE]); | |
285 | Put_message(print_buf); | |
286 | sprintf(print_buf, MOD_FORMAT, info[FS_MODBY], info[FS_MODTIME], | |
287 | info[FS_MODWITH]); | |
288 | Put_message(print_buf); | |
289 | } | |
290 | return info[FS_NAME]; | |
08345b74 | 291 | } |
292 | ||
5eaef520 | 293 | char *canonicalize_cell(char *c) |
7cb7d352 | 294 | { |
533bacb3 | 295 | #ifdef _WIN32 |
296 | return c; | |
297 | #else /* !_WIN32 */ | |
5eaef520 | 298 | struct stat stbuf; |
299 | char path[512]; | |
300 | int count; | |
301 | ||
302 | sprintf(path, "/afs/%s", c); | |
303 | if (lstat(path, &stbuf) || !stbuf.st_mode & S_IFLNK) | |
304 | return c; | |
305 | count = readlink(path, path, sizeof(path)); | |
306 | if (count < 1) | |
307 | return c; | |
308 | path[count] = 0; | |
309 | free(c); | |
7ac48069 | 310 | return strdup(path); |
533bacb3 | 311 | #endif /* _WIN32 */ |
7cb7d352 | 312 | } |
313 | ||
314 | ||
7ac48069 | 315 | int GetAliasValue(int argc, char **argv, void *retval) |
7cb7d352 | 316 | { |
7ac48069 | 317 | *(char **)retval = strdup(argv[2]); |
5eaef520 | 318 | return MR_CONT; |
7cb7d352 | 319 | } |
320 | ||
08345b74 | 321 | /* Function Name: AskFSInfo. |
5eaef520 | 322 | * Description: This function askes the user for information about a |
08345b74 | 323 | * machine and saves it into a structure. |
324 | * Arguments: info - a pointer the the structure to put the | |
325 | * info into. | |
326 | * name - add a newname field? (T/F) | |
327 | * Returns: none. | |
328 | */ | |
329 | ||
5eaef520 | 330 | static char **AskFSInfo(char **info, Bool name) |
08345b74 | 331 | { |
5eaef520 | 332 | char temp_buf[BUFSIZ], *newname, access_type[32]; |
333 | int fsgroup = 0, newdefaults = 0; | |
334 | ||
335 | Put_message(""); | |
336 | sprintf(temp_buf, "Changing Attributes of filesystem %s.", info[FS_NAME]); | |
337 | Put_message(temp_buf); | |
338 | Put_message(""); | |
339 | ||
340 | if (name) | |
341 | { | |
7ac48069 | 342 | newname = strdup(info[FS_NAME]); |
5eaef520 | 343 | if (GetValueFromUser("The new name for this filesystem", |
344 | &newname) == SUB_ERROR) | |
345 | return NULL; | |
08345b74 | 346 | } |
347 | ||
5eaef520 | 348 | strcpy(temp_buf, info[FS_TYPE]); |
349 | if (GetTypeFromUser("Filesystem's Type", "filesys", &info[FS_TYPE]) == | |
350 | SUB_ERROR) | |
351 | return NULL; | |
352 | if (!strcasecmp(info[FS_TYPE], "FSGROUP") || | |
353 | !strcasecmp(info[FS_TYPE], "MUL")) | |
354 | fsgroup++; | |
355 | if (strcasecmp(info[FS_TYPE], temp_buf)) | |
356 | newdefaults++; | |
357 | if (fsgroup) | |
358 | { | |
359 | free(info[FS_MACHINE]); | |
7ac48069 | 360 | info[FS_MACHINE] = strdup(NO_MACHINE); |
5eaef520 | 361 | } |
362 | else | |
363 | { | |
364 | if (!strcasecmp(info[FS_TYPE], "AFS")) | |
365 | { | |
366 | if (!name || newdefaults) | |
367 | { | |
368 | free(info[FS_MACHINE]); | |
7ac48069 | 369 | info[FS_MACHINE] = strdup(DEFAULT_CELL); |
7cb7d352 | 370 | } |
5eaef520 | 371 | if (GetValueFromUser("Filesystem's Cell", &info[FS_MACHINE]) == |
7cb7d352 | 372 | SUB_ERROR) |
5eaef520 | 373 | return NULL; |
374 | info[FS_MACHINE] = canonicalize_cell(info[FS_MACHINE]); | |
375 | } | |
376 | else | |
377 | { | |
378 | if (GetValueFromUser("Filesystem's Machine", &info[FS_MACHINE]) == | |
379 | SUB_ERROR) | |
380 | return NULL; | |
381 | info[FS_MACHINE] = canonicalize_hostname(info[FS_MACHINE]); | |
7cb7d352 | 382 | } |
9e2516d6 | 383 | } |
5eaef520 | 384 | if (!fsgroup) |
385 | { | |
386 | if (!strcasecmp(info[FS_TYPE], "AFS")) | |
387 | { | |
388 | char *path, *args[3], *p; | |
389 | int status, depth; | |
390 | if (GetTypeFromUser("Filesystem's lockertype", "lockertype", | |
391 | &info[FS_L_TYPE]) == SUB_ERROR) | |
392 | return NULL; | |
393 | if (!name || newdefaults) | |
394 | { | |
395 | free(info[FS_PACK]); | |
396 | lowercase(info[FS_MACHINE]); | |
397 | sprintf(temp_buf, "%s:%s", info[FS_MACHINE], info[FS_L_TYPE]); | |
398 | args[0] = temp_buf; | |
399 | args[1] = "AFSPATH"; | |
400 | args[2] = "*"; | |
401 | path = "???"; | |
402 | status = do_mr_query("get_alias", 3, args, GetAliasValue, &path); | |
403 | if (status == MR_SUCCESS) | |
404 | { | |
405 | p = strchr(path, ':'); | |
406 | if (p) | |
407 | { | |
408 | *p = '\0'; | |
409 | depth = atoi(++p); | |
410 | } | |
411 | else | |
412 | depth = 0; | |
413 | sprintf(temp_buf, "/afs/%s/%s", info[FS_MACHINE], path); | |
414 | if (depth >= 0) | |
415 | { | |
416 | for (p = info[FS_NAME]; | |
417 | *p && (p - info[FS_NAME]) < depth; p++) | |
418 | { | |
419 | if (islower(*p)) | |
420 | { | |
421 | strcat(temp_buf, "/x"); | |
422 | temp_buf[strlen(temp_buf) - 1] = *p; | |
423 | } | |
424 | else | |
425 | { | |
426 | sprintf(temp_buf, "/afs/%s/%s/other", | |
427 | info[FS_MACHINE], path); | |
428 | break; | |
d678d80c | 429 | } |
b7e66e09 | 430 | } |
5eaef520 | 431 | } |
432 | else if (depth == -1) | |
433 | { | |
434 | if (isdigit(info[FS_NAME][0])) | |
435 | { | |
436 | strcat(temp_buf, "/"); | |
437 | depth = strlen(temp_buf); | |
438 | for (p = info[FS_NAME]; *p && isdigit(*p); p++) | |
439 | { | |
440 | temp_buf[depth++] = *p; | |
441 | temp_buf[depth] = 0; | |
b7e66e09 | 442 | } |
5eaef520 | 443 | } |
444 | else | |
445 | strcat(temp_buf, "/other"); | |
446 | } | |
447 | else | |
448 | { | |
b7e66e09 | 449 | /* no default */ |
7cb7d352 | 450 | } |
5eaef520 | 451 | strcat(temp_buf, "/"); |
452 | strcat(temp_buf, info[FS_NAME]); | |
453 | free(path); | |
7cb7d352 | 454 | } |
5eaef520 | 455 | else |
456 | { | |
457 | sprintf(temp_buf, "/afs/%s/%s/%s", info[FS_MACHINE], | |
458 | lowercase(info[FS_L_TYPE]), info[FS_NAME]); | |
459 | } | |
7ac48069 | 460 | info[FS_PACK] = strdup(temp_buf); |
7cb7d352 | 461 | } |
462 | } | |
5eaef520 | 463 | if (GetValueFromUser("Filesystem's Pack Name", &info[FS_PACK]) == |
464 | SUB_ERROR) | |
465 | return NULL; | |
466 | if (GetValueFromUser("Filesystem's Mount Point", &info[FS_M_POINT]) == | |
467 | SUB_ERROR) | |
468 | return NULL; | |
469 | sprintf(access_type, "fs_access_%s", info[FS_TYPE]); | |
470 | if (GetTypeFromUser("Filesystem's Default Access", access_type, | |
471 | &info[FS_ACCESS]) == SUB_ERROR) | |
472 | return NULL; | |
9e2516d6 | 473 | } |
5eaef520 | 474 | if (GetValueFromUser("Comments about this Filesystem", &info[FS_COMMENTS]) |
475 | == SUB_ERROR) | |
476 | return NULL; | |
477 | if (GetValueFromUser("Filesystem's owner (user)", &info[FS_OWNER]) == | |
478 | SUB_ERROR) | |
479 | return NULL; | |
480 | if (GetValueFromUser("Filesystem's owners (group)", &info[FS_OWNERS]) == | |
481 | SUB_ERROR) | |
482 | return NULL; | |
483 | if (!fsgroup) | |
484 | if (GetYesNoValueFromUser("Propagate changes to fileserver", | |
485 | &info[FS_CREATE]) == SUB_ERROR) | |
486 | return NULL; | |
487 | if (strcasecmp(info[FS_TYPE], "AFS")) | |
488 | { | |
489 | if (GetTypeFromUser("Filesystem's lockertype", "lockertype", | |
490 | &info[FS_L_TYPE]) == SUB_ERROR) | |
491 | return NULL; | |
7cb7d352 | 492 | } |
08345b74 | 493 | |
5eaef520 | 494 | FreeAndClear(&info[FS_MODTIME], TRUE); |
495 | FreeAndClear(&info[FS_MODBY], TRUE); | |
496 | FreeAndClear(&info[FS_MODWITH], TRUE); | |
08345b74 | 497 | |
5eaef520 | 498 | if (name) /* slide the newname into the #2 slot. */ |
499 | SlipInNewName(info, newname); | |
08345b74 | 500 | |
5eaef520 | 501 | return info; |
08345b74 | 502 | } |
503 | ||
7cb7d352 | 504 | |
08345b74 | 505 | /* --------------- Filesystem Menu ------------- */ |
506 | ||
507 | /* Function Name: GetFS | |
508 | * Description: Get Filesystem information by name. | |
509 | * Arguments: argc, argv - name of filsys in argv[1]. | |
510 | * Returns: DM_NORMAL. | |
511 | */ | |
512 | ||
5eaef520 | 513 | int GetFS(int argc, char **argv) |
08345b74 | 514 | { |
600b459e | 515 | struct mqelem *top; |
1d4e1e0f | 516 | char *fs_label; |
517 | ||
518 | fs_label = argv[1]; | |
519 | ||
520 | top = GetFSInfo(ALIAS_CHECK, argv[1]); | |
521 | if (top != NULL) { | |
522 | Loop(top, (void (*)(char **))GetFSLabel); | |
523 | fs_label = labelbuf; | |
524 | } | |
08345b74 | 525 | |
1d4e1e0f | 526 | top = GetFSInfo(LABEL, fs_label); /* get info. */ |
7ac48069 | 527 | Loop(top, (void (*)(char **))PrintFSInfo); |
5eaef520 | 528 | FreeQueue(top); /* clean the queue. */ |
529 | return DM_NORMAL; | |
ef1e47d8 | 530 | } |
531 | ||
532 | /* Function Name: GetFSM | |
533 | * Description: Get Filesystem information by machine. | |
534 | * Arguments: argc, argv - name of server in argv[1]. | |
535 | * Returns: DM_NORMAL. | |
536 | */ | |
537 | ||
5eaef520 | 538 | int GetFSM(int argc, char **argv) |
ef1e47d8 | 539 | { |
600b459e | 540 | struct mqelem *top; |
ef1e47d8 | 541 | |
7ac48069 | 542 | argv[1] = canonicalize_hostname(strdup(argv[1])); |
5eaef520 | 543 | top = GetFSInfo(MACHINE, argv[1]); /* get info. */ |
7ac48069 | 544 | Loop(top, (void (*)(char **))PrintFSInfo); |
5eaef520 | 545 | FreeQueue(top); /* clean the queue. */ |
546 | return DM_NORMAL; | |
08345b74 | 547 | } |
548 | ||
402461ad | 549 | /* Function Name: RealDeleteFS |
550 | * Description: Does the real deletion work. | |
551 | * Arguments: info - array of char *'s containing all useful info. | |
5eaef520 | 552 | * one_item - a Boolean that is true if only one item |
402461ad | 553 | * in queue that dumped us here. |
554 | * Returns: none. | |
555 | */ | |
556 | ||
5eaef520 | 557 | void RealDeleteFS(char **info, Bool one_item) |
402461ad | 558 | { |
5eaef520 | 559 | int stat; |
560 | char temp_buf[BUFSIZ]; | |
561 | ||
562 | /* | |
563 | * Deletions are performed if the user hits 'y' on a list of multiple | |
564 | * filesystem, or if the user confirms on a unique alias. | |
565 | */ | |
566 | sprintf(temp_buf, "Are you sure that you want to delete filesystem %s", | |
567 | info[FS_NAME]); | |
568 | if (!one_item || Confirm(temp_buf)) | |
569 | { | |
570 | if ((stat = do_mr_query("delete_filesys", 1, | |
7ac48069 | 571 | &info[FS_NAME], NULL, NULL))) |
5eaef520 | 572 | com_err(program_name, stat, " filesystem not deleted."); |
573 | else | |
574 | Put_message("Filesystem deleted."); | |
402461ad | 575 | } |
5eaef520 | 576 | else |
577 | Put_message("Filesystem not deleted."); | |
402461ad | 578 | } |
579 | ||
08345b74 | 580 | /* Function Name: DeleteFS |
581 | * Description: Delete a filesystem give its name. | |
582 | * Arguments: argc, argv - argv[1] is the name of the filesystem. | |
583 | * Returns: none. | |
584 | */ | |
585 | ||
5eaef520 | 586 | int DeleteFS(int argc, char **argv) |
08345b74 | 587 | { |
600b459e | 588 | struct mqelem *elem = GetFSInfo(LABEL, argv[1]); |
5eaef520 | 589 | QueryLoop(elem, PrintFSInfo, RealDeleteFS, "Delete the Filesystem"); |
08345b74 | 590 | |
5eaef520 | 591 | FreeQueue(elem); |
592 | return DM_NORMAL; | |
08345b74 | 593 | } |
594 | ||
402461ad | 595 | /* Function Name: RealChangeFS |
596 | * Description: performs the actual change to the filesys. | |
5eaef520 | 597 | * Arguments: info - the information |
402461ad | 598 | * junk - an unused boolean. |
599 | * Returns: none. | |
600 | */ | |
601 | ||
5eaef520 | 602 | static void RealChangeFS(char **info, Bool junk) |
402461ad | 603 | { |
5eaef520 | 604 | int stat; |
605 | char **args; | |
606 | extern Menu nfsphys_menu; | |
607 | ||
608 | args = AskFSInfo(info, TRUE); | |
609 | if (!args) | |
610 | { | |
611 | Put_message("Aborted."); | |
612 | return; | |
9777ade9 | 613 | } |
7ac48069 | 614 | stat = do_mr_query("update_filesys", CountArgs(args), args, NULL, NULL); |
5eaef520 | 615 | switch (stat) |
616 | { | |
8defc06b | 617 | case MR_NFS: |
5eaef520 | 618 | Put_message("That NFS filesystem is not exported."); |
619 | if (YesNoQuestion("Fix this now (Y/N)", TRUE) == TRUE) | |
620 | { | |
621 | Do_menu(&nfsphys_menu, 0, NULL); | |
622 | if (YesNoQuestion("Retry filesystem update now (Y/N)", TRUE) == TRUE) | |
623 | { | |
624 | if ((stat = do_mr_query("update_filesys", CountArgs(args), args, | |
7ac48069 | 625 | NULL, NULL))) |
5eaef520 | 626 | com_err(program_name, stat, " filesystem not updated"); |
627 | else | |
628 | Put_message("filesystem sucessfully updated."); | |
bff71786 | 629 | } |
630 | } | |
5eaef520 | 631 | break; |
8defc06b | 632 | case MR_SUCCESS: |
5eaef520 | 633 | break; |
bff71786 | 634 | default: |
5eaef520 | 635 | com_err(program_name, stat, " in UpdateFS"); |
bff71786 | 636 | } |
402461ad | 637 | } |
638 | ||
08345b74 | 639 | /* Function Name: ChangeFS |
640 | * Description: change the information in a filesys record. | |
641 | * Arguments: arc, argv - value of filsys in argv[1]. | |
642 | * Returns: DM_NORMAL. | |
643 | */ | |
644 | ||
5eaef520 | 645 | int ChangeFS(int argc, char **argv) |
08345b74 | 646 | { |
600b459e | 647 | struct mqelem *elem = GetFSInfo(LABEL, argv[1]); |
5eaef520 | 648 | QueryLoop(elem, NullPrint, RealChangeFS, "Update the Filesystem"); |
08345b74 | 649 | |
5eaef520 | 650 | FreeQueue(elem); |
651 | return DM_NORMAL; | |
08345b74 | 652 | } |
653 | ||
654 | /* Function Name: AddFS | |
655 | * Description: change the information in a filesys record. | |
656 | * Arguments: arc, argv - name of filsys in argv[1]. | |
657 | * Returns: DM_NORMAL. | |
658 | */ | |
659 | ||
5eaef520 | 660 | int AddFS(int argc, char **argv) |
08345b74 | 661 | { |
5eaef520 | 662 | char *info[MAX_ARGS_SIZE], **args, buf[BUFSIZ]; |
663 | int stat; | |
664 | extern Menu nfsphys_menu; | |
665 | ||
666 | if (!ValidName(argv[1])) | |
667 | return DM_NORMAL; | |
668 | ||
669 | if (!(stat = do_mr_query("get_filesys_by_label", 1, argv + 1, | |
7ac48069 | 670 | NULL, NULL))) |
5eaef520 | 671 | { |
672 | Put_message ("A Filesystem by that name already exists."); | |
673 | return DM_NORMAL; | |
674 | } | |
675 | else if (stat != MR_NO_MATCH) | |
676 | { | |
677 | com_err(program_name, stat, " in AddFS"); | |
678 | return DM_NORMAL; | |
679 | } | |
680 | ||
681 | if (!(args = AskFSInfo(SetDefaults(info, argv[1]), FALSE))) | |
682 | { | |
683 | Put_message("Aborted."); | |
684 | return DM_NORMAL; | |
44b10c87 | 685 | } |
461c03b6 | 686 | |
7ac48069 | 687 | stat = do_mr_query("add_filesys", CountArgs(args), args, NULL, NULL); |
5eaef520 | 688 | switch (stat) |
689 | { | |
8defc06b | 690 | case MR_NFS: |
5eaef520 | 691 | Put_message("That NFS filesystem is not exported."); |
692 | if (YesNoQuestion("Fix this now (Y/N)", TRUE) == TRUE) | |
693 | { | |
694 | Do_menu(&nfsphys_menu, 0, NULL); | |
695 | if (YesNoQuestion("Retry filesystem creation now (Y/N)", TRUE) | |
696 | == TRUE) { | |
697 | if ((stat = do_mr_query("add_filesys", CountArgs(args), args, | |
7ac48069 | 698 | NULL, NULL))) |
5eaef520 | 699 | com_err(program_name, stat, " in AddFS"); |
700 | else | |
701 | Put_message("Created."); | |
702 | } | |
bff71786 | 703 | } |
5eaef520 | 704 | break; |
8defc06b | 705 | case MR_SUCCESS: |
5eaef520 | 706 | break; |
bff71786 | 707 | default: |
5eaef520 | 708 | com_err(program_name, stat, " in AddFS"); |
bff71786 | 709 | } |
08345b74 | 710 | |
5eaef520 | 711 | if (stat == MR_SUCCESS && !strcasecmp(info[FS_L_TYPE], "HOMEDIR")) |
712 | { | |
713 | static char *val[] = {"def_quota", NULL}; | |
714 | static char *def_quota = NULL; | |
715 | char *argv[Q_QUOTA + 1]; | |
600b459e | 716 | struct mqelem *top = NULL; |
5eaef520 | 717 | |
718 | if (!def_quota) | |
719 | { | |
720 | stat = do_mr_query("get_value", CountArgs(val), val, | |
7ac48069 | 721 | StoreInfo, &top); |
5eaef520 | 722 | if (stat != MR_SUCCESS) |
723 | com_err(program_name, stat, " getting default quota"); | |
724 | else | |
725 | { | |
726 | top = QueueTop(top); | |
7ac48069 | 727 | def_quota = strdup(((char **)top->q_data)[0]); |
5eaef520 | 728 | FreeQueue(top); |
7cce48da | 729 | } |
730 | } | |
5eaef520 | 731 | if (def_quota) |
732 | { | |
733 | sprintf(buf, "Give user %s a quota of %s on filesys %s (Y/N)", | |
734 | info[FS_NAME], def_quota, info[FS_NAME]); | |
735 | if (YesNoQuestion(buf, 1) == TRUE) | |
736 | { | |
737 | argv[Q_NAME] = argv[Q_FILESYS] = info[FS_NAME]; | |
738 | if (!strcmp(info[FS_TYPE], "NFS")) | |
739 | argv[Q_TYPE] = "USER"; | |
740 | else | |
741 | argv[Q_TYPE] = "ANY"; | |
742 | argv[Q_QUOTA] = def_quota; | |
7ac48069 | 743 | if ((stat = do_mr_query("add_quota", Q_QUOTA + 1, argv, NULL, |
5eaef520 | 744 | NULL))) |
745 | com_err(program_name, stat, " while adding quota"); | |
7cce48da | 746 | } |
747 | } | |
5eaef520 | 748 | } |
749 | else if (stat == MR_SUCCESS) | |
750 | { | |
751 | if (YesNoQuestion("Assign a quota on this filesystem (Y/N)", 1) == TRUE) | |
752 | { | |
753 | parsed_argc = 1; | |
754 | parsed_argv[0] = info[FS_NAME]; | |
7ac48069 | 755 | AddQuota(parsed_argc, parsed_argv); |
d25fad50 | 756 | } |
7cce48da | 757 | } |
758 | ||
5eaef520 | 759 | FreeInfo(info); |
760 | return DM_NORMAL; | |
08345b74 | 761 | } |
762 | ||
9e2516d6 | 763 | /* Function Name: SortAfter |
5eaef520 | 764 | * Description: choose a sortkey to cause an item to be added after |
9e2516d6 | 765 | * the count element in the queue |
766 | * Arguments: queue of filesys names & sortkeys, queue count pointer | |
767 | * Returns: sort key to use. | |
768 | */ | |
769 | ||
600b459e | 770 | char *SortAfter(struct mqelem *elem, int count) |
9e2516d6 | 771 | { |
5eaef520 | 772 | char *prev, *next, prevnext, *key, keybuf[9]; |
773 | ||
774 | /* first find the two keys we need to insert between */ | |
775 | prev = "A"; | |
776 | for (; count > 0; count--) | |
777 | { | |
778 | prev = ((char **)elem->q_data)[1]; | |
779 | if (elem->q_forw) | |
780 | elem = elem->q_forw; | |
781 | else | |
782 | break; | |
9e2516d6 | 783 | } |
5eaef520 | 784 | if (count > 0) |
785 | next = "Z"; | |
786 | else | |
787 | next = ((char **)elem->q_data)[1]; | |
788 | ||
789 | /* now copy the matching characters */ | |
790 | for (key = keybuf; *prev && *prev == *next; next++) | |
791 | *key++ = *prev++; | |
792 | ||
793 | /* and set the last character */ | |
794 | if (*prev == 0) | |
795 | *prev = prevnext = 'A'; | |
796 | else | |
797 | prevnext = prev[1]; | |
798 | if (prevnext == 0) | |
799 | prevnext = 'A'; | |
800 | if (*next == 0) | |
801 | *next = 'Z'; | |
802 | if (*next - *prev > 1) | |
803 | *key++ = (*next + *prev) / 2; | |
804 | else | |
805 | { | |
806 | *key++ = *prev; | |
807 | *key++ = (prevnext + 'Z') / 2; | |
9e2516d6 | 808 | } |
5eaef520 | 809 | *key = 0; |
7ac48069 | 810 | return strdup(keybuf); |
9e2516d6 | 811 | } |
812 | ||
813 | /* Function Name: AddFSToGroup | |
814 | * Description: add a filesystem to an FS group | |
815 | * Arguments: arc, argv - name of group in argv[1], filesys in argv[2]. | |
816 | * Returns: DM_NORMAL. | |
817 | */ | |
818 | ||
5eaef520 | 819 | int AddFSToGroup(int argc, char **argv) |
9e2516d6 | 820 | { |
5eaef520 | 821 | int stat, count; |
600b459e | 822 | struct mqelem *elem = NULL; |
5eaef520 | 823 | char buf[BUFSIZ], *args[5], *bufp; |
824 | ||
825 | if ((stat = do_mr_query("get_fsgroup_members", 1, argv + 1, StoreInfo, | |
7ac48069 | 826 | &elem))) |
5eaef520 | 827 | { |
828 | if (stat != MR_NO_MATCH) | |
829 | com_err(program_name, stat, " in AddFSToGroup"); | |
9e2516d6 | 830 | } |
5eaef520 | 831 | if (elem == NULL) |
832 | { | |
833 | args[0] = argv[1]; | |
834 | args[1] = argv[2]; | |
835 | args[2] = "M"; | |
7ac48069 | 836 | stat = do_mr_query("add_filesys_to_fsgroup", 3, args, NULL, NULL); |
5eaef520 | 837 | if (stat) |
838 | com_err(program_name, stat, " in AddFSToGroup"); | |
839 | return DM_NORMAL; | |
9e2516d6 | 840 | } |
5eaef520 | 841 | elem = QueueTop(elem); |
842 | fsgCount = 1; | |
843 | Loop(elem, PrintFSGMembers); | |
844 | sprintf(buf, "%d", QueueCount(elem)); | |
7ac48069 | 845 | bufp = strdup(buf); |
5eaef520 | 846 | if (GetValueFromUser("Enter number of filesystem it should follow " |
847 | "(0 to make it first):", &bufp) == SUB_ERROR) | |
848 | return DM_NORMAL; | |
849 | count = atoi(bufp); | |
850 | free(bufp); | |
851 | args[2] = SortAfter(elem, count); | |
852 | ||
853 | FreeQueue(QueueTop(elem)); | |
854 | args[0] = argv[1]; | |
855 | args[1] = argv[2]; | |
7ac48069 | 856 | stat = do_mr_query("add_filesys_to_fsgroup", 3, args, NULL, NULL); |
5eaef520 | 857 | if (stat == MR_EXISTS) |
858 | { | |
859 | Put_message("That filesystem is already a member of the group."); | |
860 | Put_message("Use the order command if you want to change the " | |
861 | "sorting order."); | |
862 | } | |
863 | else if (stat) | |
864 | com_err(program_name, stat, " in AddFSToGroup"); | |
865 | return DM_NORMAL; | |
9e2516d6 | 866 | } |
867 | ||
868 | ||
869 | /* Function Name: RemoveFSFromGroup | |
870 | * Description: delete a filesystem from an FS group | |
871 | * Arguments: arc, argv - name of group in argv[1]. | |
872 | * Returns: DM_NORMAL. | |
873 | */ | |
874 | ||
5eaef520 | 875 | int RemoveFSFromGroup(int argc, char **argv) |
9e2516d6 | 876 | { |
5eaef520 | 877 | int stat; |
878 | char buf[BUFSIZ]; | |
879 | ||
880 | sprintf(buf, "Delete filesystem %s from FS group %s", argv[2], argv[1]); | |
881 | if (!Confirm(buf)) | |
882 | return DM_NORMAL; | |
883 | if ((stat = do_mr_query("remove_filesys_from_fsgroup", 2, argv + 1, | |
7ac48069 | 884 | NULL, NULL))) |
5eaef520 | 885 | com_err(program_name, stat, ", not removed."); |
886 | return DM_NORMAL; | |
9e2516d6 | 887 | } |
888 | ||
889 | /* Function Name: ChangeFSGroupOrder | |
890 | * Description: change the sortkey on a filesys in an FSgroup | |
891 | * Arguments: arc, argv - name of group in argv[1]. | |
892 | * Returns: DM_NORMAL. | |
893 | */ | |
894 | ||
5eaef520 | 895 | int ChangeFSGroupOrder(int argc, char **argv) |
9e2516d6 | 896 | { |
5eaef520 | 897 | int stat, src, dst, i; |
600b459e | 898 | struct mqelem *elem = NULL, *top, *tmpelem; |
5eaef520 | 899 | char buf[BUFSIZ], *bufp, *args[3]; |
900 | ||
901 | if ((stat = do_mr_query("get_fsgroup_members", 1, argv + 1, StoreInfo, | |
7ac48069 | 902 | &elem))) |
5eaef520 | 903 | { |
904 | if (stat == MR_NO_MATCH) | |
905 | { | |
906 | sprintf(buf, | |
907 | "Ether %s is not a filesystem group or it has no members", | |
908 | argv[1]); | |
909 | Put_message(buf); | |
910 | } | |
911 | else | |
912 | com_err(program_name, stat, " in ChangeFSGroupOrder"); | |
913 | return DM_NORMAL; | |
9e2516d6 | 914 | } |
5eaef520 | 915 | top = QueueTop(elem); |
916 | fsgCount = 1; | |
917 | Loop(top, PrintFSGMembers); | |
918 | while (1) | |
919 | { | |
7ac48069 | 920 | bufp = strdup("1"); |
5eaef520 | 921 | if (GetValueFromUser("Enter number of the filesystem to move:", |
922 | &bufp) == SUB_ERROR) | |
923 | return DM_NORMAL; | |
924 | src = atoi(bufp); | |
925 | free(bufp); | |
926 | if (src < 0) | |
927 | { | |
928 | Put_message("You must enter a positive number (or 0 to abort)."); | |
929 | continue; | |
9e2516d6 | 930 | } |
5eaef520 | 931 | else if (src == 0) |
932 | { | |
933 | Put_message("Aborted."); | |
934 | return DM_NORMAL; | |
9e2516d6 | 935 | } |
5eaef520 | 936 | for (elem = top, i = src; i-- > 1 && elem->q_forw; elem = elem->q_forw) |
937 | ; | |
938 | if (i > 0) | |
939 | { | |
940 | Put_message("You entered a number that is too high"); | |
941 | continue; | |
942 | } | |
943 | break; | |
9e2516d6 | 944 | } |
5eaef520 | 945 | while (1) |
946 | { | |
7ac48069 | 947 | bufp = strdup("0"); |
5eaef520 | 948 | if (GetValueFromUser("Enter number of filesystem it should follow " |
949 | "(0 to make it first):", &bufp) == SUB_ERROR) | |
950 | return DM_NORMAL; | |
951 | dst = atoi(bufp); | |
952 | free(bufp); | |
953 | if (src == dst || src == dst + 1) | |
954 | { | |
955 | Put_message("That has no effect on the sorting order!"); | |
956 | return DM_NORMAL; | |
860a8dbe | 957 | } |
5eaef520 | 958 | if (dst < 0) |
959 | { | |
960 | Put_message("You must enter a non-negative number."); | |
961 | continue; | |
860a8dbe | 962 | } |
5eaef520 | 963 | for (tmpelem = top, i = dst; i-- > 1 && tmpelem->q_forw; |
964 | tmpelem = tmpelem->q_forw) | |
965 | ; | |
966 | if (i > 0) | |
967 | { | |
968 | Put_message("You entered a number that is too high"); | |
969 | continue; | |
860a8dbe | 970 | } |
5eaef520 | 971 | break; |
9e2516d6 | 972 | } |
5eaef520 | 973 | args[2] = SortAfter(top, dst); |
974 | args[0] = argv[1]; | |
975 | args[1] = ((char **)elem->q_data)[0]; | |
976 | if ((stat = do_mr_query("remove_filesys_from_fsgroup", 2, args, | |
7ac48069 | 977 | NULL, NULL))) |
5eaef520 | 978 | { |
979 | com_err(program_name, stat, " in ChangeFSGroupOrder"); | |
980 | return DM_NORMAL; | |
9e2516d6 | 981 | } |
5eaef520 | 982 | if ((stat = do_mr_query("add_filesys_to_fsgroup", 3, args, |
7ac48069 | 983 | NULL, NULL))) |
5eaef520 | 984 | com_err(program_name, stat, " in ChangeFSGroupOrder"); |
985 | return DM_NORMAL; | |
9e2516d6 | 986 | } |
987 | ||
988 | ||
08345b74 | 989 | /* -------------- Top Level Menu ---------------- */ |
990 | ||
991 | /* Function Name: GetFSAlias | |
992 | * Description: Gets the value for a Filesystem Alias. | |
993 | * Arguments: argc, argv - name of alias in argv[1]. | |
994 | * Returns: DM_NORMAL. | |
995 | * NOTES: There should only be one filesystem per alias, thus | |
996 | * this will work correctly. | |
997 | */ | |
998 | ||
5eaef520 | 999 | int GetFSAlias(int argc, char **argv) |
08345b74 | 1000 | { |
600b459e | 1001 | struct mqelem *top; |
08345b74 | 1002 | |
5eaef520 | 1003 | top = GetFSInfo(ALIAS, argv[1]); |
1004 | Put_message(" "); /* blank line. */ | |
a6da9354 | 1005 | Loop(top, (void (*)(char **))PrintFSAlias); |
5eaef520 | 1006 | FreeQueue(top); |
1007 | return DM_NORMAL; | |
08345b74 | 1008 | } |
1009 | ||
1010 | /* Function Name: CreateFSAlias | |
6c7a2fcf | 1011 | * Description: Create an alias name for a filesystem |
08345b74 | 1012 | * Arguments: argc, argv - name of alias in argv[1]. |
1013 | * Returns: DM_NORMAL. | |
1014 | * NOTES: This requires (name, type, transl) I get {name, translation} | |
5eaef520 | 1015 | * from the user. I provide type, which is well-known. |
08345b74 | 1016 | */ |
1017 | ||
5eaef520 | 1018 | int CreateFSAlias(int argc, char **argv) |
08345b74 | 1019 | { |
44d12d58 | 1020 | int stat; |
600b459e | 1021 | struct mqelem *elem, *top; |
5eaef520 | 1022 | char *args[MAX_ARGS_SIZE], buf[BUFSIZ], **info; |
1023 | ||
1024 | elem = NULL; | |
1025 | ||
1026 | if (!ValidName(argv[1])) | |
1027 | return DM_NORMAL; | |
1028 | ||
7ac48069 | 1029 | args[ALIAS_NAME] = strdup(argv[1]); |
1030 | args[ALIAS_TYPE] = strdup(FS_ALIAS_TYPE); | |
1031 | args[ALIAS_TRANS] = strdup("*"); | |
5eaef520 | 1032 | |
1033 | /* | |
1034 | * Check to see if this alias already exists in the database, if so then | |
1035 | * print out values, free memory used and then exit. | |
1036 | */ | |
1037 | ||
7ac48069 | 1038 | if (!(stat = do_mr_query("get_alias", 3, args, StoreInfo, &elem))) |
5eaef520 | 1039 | { |
1040 | top = elem = QueueTop(elem); | |
1041 | while (elem) | |
1042 | { | |
7ac48069 | 1043 | info = elem->q_data; |
5eaef520 | 1044 | sprintf(buf, "The alias: %s currently describes the filesystem %s", |
1045 | info[ALIAS_NAME], info[ALIAS_TRANS]); | |
1046 | Put_message(buf); | |
1047 | elem = elem->q_forw; | |
08345b74 | 1048 | } |
5eaef520 | 1049 | FreeQueue(top); |
1050 | return DM_NORMAL; | |
08345b74 | 1051 | } |
5eaef520 | 1052 | else if (stat != MR_NO_MATCH) |
1053 | { | |
1054 | com_err(program_name, stat, " in CreateFSAlias."); | |
1055 | return DM_NORMAL; | |
08345b74 | 1056 | } |
1057 | ||
7ac48069 | 1058 | args[ALIAS_TRANS] = strdup(""); |
5eaef520 | 1059 | args[ALIAS_END] = NULL; |
1060 | if (GetValueFromUser("Which filesystem will this alias point to?", | |
1061 | &args[ALIAS_TRANS]) == SUB_ERROR) | |
1062 | return DM_NORMAL; | |
08345b74 | 1063 | |
7ac48069 | 1064 | if ((stat = do_mr_query("add_alias", 3, args, NULL, NULL))) |
5eaef520 | 1065 | com_err(program_name, stat, " in CreateFSAlias."); |
08345b74 | 1066 | |
5eaef520 | 1067 | FreeInfo(args); |
1068 | return DM_NORMAL; | |
08345b74 | 1069 | } |
5eaef520 | 1070 | |
402461ad | 1071 | /* Function Name: RealDeleteFSAlias |
1072 | * Description: Does the real deletion work. | |
1073 | * Arguments: info - array of char *'s containing all useful info. | |
5eaef520 | 1074 | * one_item - a Boolean that is true if only one item |
402461ad | 1075 | * in queue that dumped us here. |
1076 | * Returns: none. | |
1077 | */ | |
1078 | ||
5eaef520 | 1079 | void RealDeleteFSAlias(char **info, Bool one_item) |
402461ad | 1080 | { |
5eaef520 | 1081 | int stat; |
1082 | char temp_buf[BUFSIZ]; | |
1083 | ||
1084 | /* | |
1085 | * Deletions are performed if the user hits 'y' on a list of multiple | |
1086 | * filesystem, or if the user confirms on a unique alias. | |
1087 | */ | |
1088 | sprintf(temp_buf, | |
1089 | "Are you sure that you want to delete the filesystem alias %s", | |
1090 | info[ALIAS_NAME]); | |
1091 | if (!one_item || Confirm(temp_buf)) | |
1092 | { | |
1093 | if ((stat = do_mr_query("delete_alias", CountArgs(info), | |
7ac48069 | 1094 | info, NULL, NULL))) |
5eaef520 | 1095 | com_err(program_name, stat, " filesystem alias not deleted."); |
1096 | else | |
1097 | Put_message("Filesystem alias deleted."); | |
402461ad | 1098 | } |
5eaef520 | 1099 | else |
1100 | Put_message("Filesystem alias not deleted."); | |
402461ad | 1101 | } |
08345b74 | 1102 | |
1103 | /* Function Name: DeleteFSAlias | |
6c7a2fcf | 1104 | * Description: Delete an alias name for a filesystem |
08345b74 | 1105 | * Arguments: argc, argv - name of alias in argv[1]. |
1106 | * Returns: DM_NORMAL. | |
1107 | * NOTES: This requires (name, type, transl) I get {name, translation} | |
5eaef520 | 1108 | * from the user. I provide type, which is well-known. |
08345b74 | 1109 | */ |
1110 | ||
5eaef520 | 1111 | int DeleteFSAlias(int argc, char **argv) |
08345b74 | 1112 | { |
600b459e | 1113 | struct mqelem *elem = GetFSInfo(ALIAS, argv[1]); |
5eaef520 | 1114 | QueryLoop(elem, PrintFSAlias, RealDeleteFSAlias, |
1115 | "Delete the Filesystem Alias"); | |
1116 | FreeQueue(elem); | |
1117 | return DM_NORMAL; | |
08345b74 | 1118 | } |
1119 | ||
1120 | /* Function Name: AttachHelp | |
1121 | * Description: Print help info on attachmaint. | |
1122 | * Arguments: none | |
1123 | * Returns: DM_NORMAL. | |
1124 | */ | |
1125 | ||
5eaef520 | 1126 | int AttachHelp(void) |
08345b74 | 1127 | { |
5eaef520 | 1128 | static char *message[] = { |
1129 | "These are the options:", | |
1130 | "", | |
1131 | "get - get information about a filesystem.", | |
1132 | "add - add a new filesystem to the data base.", | |
1133 | "update - update the information in the database on a filesystem.", | |
1134 | "delete - delete a filesystem from the database.", | |
1135 | "check - check information about association of a name and a filesys.", | |
1136 | "alias - associate a name with a filesystem.", | |
1137 | "unalias - disassociate a name with a filesystem.", | |
1138 | "verbose - toggle the request for delete confirmation.", | |
1139 | NULL, | |
1140 | }; | |
1141 | ||
1142 | return PrintHelp(message); | |
08345b74 | 1143 | } |
9e2516d6 | 1144 | |
1145 | /* Function Name: FSGroupHelp | |
1146 | * Description: Print help info on fsgroups. | |
1147 | * Arguments: none | |
1148 | * Returns: DM_NORMAL. | |
1149 | */ | |
1150 | ||
7ac48069 | 1151 | int FSGroupHelp(int argc, char **argv) |
9e2516d6 | 1152 | { |
5eaef520 | 1153 | static char *message[] = { |
1154 | "A filesystem group is a named sorted list of filesystems.", | |
1155 | "", | |
1156 | "To create, modify, or delete a group itself, use the menu above", | |
1157 | " this one, and manipulate a filesystem of type FSGROUP.", | |
1158 | "Options here are:", | |
1159 | " get - get info about a group and show its members", | |
1160 | " add - add a new member to a group.", | |
1161 | " remove - remove a member from a group.", | |
1162 | " order - change the sorting order of a group.", | |
1163 | NULL | |
1164 | }; | |
1165 | ||
1166 | return PrintHelp(message); | |
9e2516d6 | 1167 | } |