3 * This is the file quota.c for the Moira Client, which allows users
4 * to quickly and easily maintain most parts of the Moira database.
5 * It Contains: Functions for manipulating the quota information.
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>
26 int afsfilsyshelper(int argc, char **argv, void *hint);
27 int afsfilesys(char *name);
29 static char *def_quota = NULL;
31 #define DEFAULT_FILESYS DEFAULT_NONE
32 #define DEFAULT_USER user /* this is the user who started moira. */
33 #define NOBODY "[nobody]"
34 #define DEFAULT_QTYPE "USER"
37 /* Function Name: GetDefaultUserQuota
38 * Description: gets the user quota from moira, and caches the value.
39 * Arguments: override - if true, go to moira and override the cache.
41 * NOTE: Using a queue here is pretty useless, but StoreInfo expects
42 * one, and it works, so why fuck with it.
45 static char *GetDefaultUserQuota(Bool override)
49 struct mqelem *top = NULL;
50 static char *val[] = {"def_quota", NULL};
52 if (override || (def_quota == NULL))
54 if ((status = do_mr_query("get_value", CountArgs(val), val,
57 com_err(program_name, status, " in ShowDefaultQuota");
60 Put_message("No default Quota Found, setting default to 0.");
61 def_quota = strdup("0");
64 Put_message("No default Quota Found, retaining old value.");
70 FreeAndClear(&def_quota, TRUE);
71 def_quota = strdup(info[0]);
78 /* Function Name: PrintDefaultQuota
79 * Description: Prints default quota info in a meaningful way.
80 * Arguments: value of the default quota.
84 static void PrintDefaultQuota(char *quota)
86 char temp_buf[BUFSIZ];
88 sprintf(temp_buf, "The default quota is %s Kb.", quota);
89 Put_message(temp_buf);
92 /* Function Name: PrintQuota
93 * Description: Prints a users quota information.
94 * Arguments: info - a pointer to the quota information:
98 static char *PrintQuota(char **info)
104 if (!strcmp(info[Q_TYPE], "ANY"))
105 sprintf(buf, "Filesystem: %s", info[Q_FILESYS]);
107 sprintf(buf, "Filesystem: %-45s %s %s", info[Q_FILESYS],
108 info[Q_TYPE], info[Q_NAME]);
110 sprintf(buf, "Machine: %-20s Directory: %-15s",
111 info[Q_MACHINE], info[Q_DIRECTORY]);
113 sprintf(buf, "Quota: %s", info[Q_QUOTA]);
115 sprintf(buf, MOD_FORMAT, info[Q_MODBY], info[Q_MODTIME], info[Q_MODWITH]);
117 return info[Q_FILESYS];
121 int afsfilsyshelper(int argc, char **argv, void *hint)
123 *(int *)hint = !strcmp(argv[FS_TYPE], "AFS");
128 int afsfilesys(char *name)
133 if (strchr(name, '*') || strchr(name, '?') || strchr(name, '\\'))
136 status = do_mr_query("get_filesys_by_label", 1, argv, afsfilsyshelper, &ret);
137 if (status == MR_SUCCESS)
143 /* Function Name: GetQuotaArgs
144 * Description: gets quota args from the user
145 * Arguments: quota - if TRUE the get quota too.
146 * Returns: the arguments.
149 static char **GetQuotaArgs(Bool quota)
151 char **args = malloc(MAX_ARGS_SIZE * sizeof(char *));
156 Put_message("Could not allocate memory in GetQuotaArgs.");
160 args[Q_FILESYS] = strdup(DEFAULT_FILESYS);
161 args[Q_TYPE] = strdup(DEFAULT_QTYPE);
162 args[Q_NAME] = strdup(DEFAULT_USER);
165 args[Q_QUOTA] = strdup(GetDefaultUserQuota(FALSE));
166 args[Q_QUOTA + 1] = NULL; /* NULL terminate. */
169 args[Q_NAME + 1] = NULL; /* NULL terminate. */
171 /* Get filesystem. */
173 if (GetValueFromUser("Filesystem", &args[Q_FILESYS]) == SUB_ERROR)
175 if (quota && !ValidName(args[Q_FILESYS]))
178 af = afsfilesys(args[Q_FILESYS]);
179 if (af != 0 && af != 1)
181 if (af == MR_NO_MATCH)
182 Put_message("That filesystem does not exist.");
184 com_err(program_name, af, " in afsfilesys");
189 args[Q_TYPE] = strdup("ANY");
190 args[Q_NAME] = strdup(NOBODY);
194 if (GetTypeFromUser("Quota type", "quota_type", &args[Q_TYPE]) ==
197 if (GetValueFromUser("Name", &args[Q_NAME]) == SUB_ERROR)
199 if (!ValidName(args[Q_NAME]))
203 if (quota) /* Get and check quota. */
205 if (GetValueFromUser("Quota", &args[Q_QUOTA]) == SUB_ERROR)
207 if (!ValidName(args[Q_QUOTA]))
213 /* Function Name: ShowDefaultQuota
214 * Description: This prints out a default quota for the system.
216 * Returns: DM_NORMAL.
219 int ShowDefaultQuota(int argc, char **argv)
221 PrintDefaultQuota(GetDefaultUserQuota(TRUE));
225 /* Function Name: ChangeDefaultQuota
226 * Description: Changes the System Wide default quota.
227 * Arguments: argc, argv - New quota in argv[1].
228 * Returns: DM_NORMAL.
231 int ChangeDefaultQuota(int argc, char *argv[])
234 char temp_buf[BUFSIZ];
235 static char *newval[] = {
236 "def_quota", NULL, NULL
239 if (!ValidName(argv[1]))
242 sprintf(temp_buf, "%s %s", "Are you sure that you want to",
243 "change the default quota for all new users");
244 if (Confirm(temp_buf))
247 if ((status = do_mr_query("update_value", CountArgs(newval),
248 newval, NULL, NULL)) == MR_SUCCESS)
250 FreeAndClear(&def_quota, TRUE);
251 def_quota = strdup(argv[1]);
254 com_err(program_name, status, " in update_value");
257 Put_message("Quota not changed.");
262 /* ------------------------ Filesystem Quotas -------------------- */
264 /* Function Name: GetQuota
265 * Description: Shows the quota of a filesystem w.r.t.
266 * a group, user, or anybody (AFS)
271 int GetQuota(int argc, char **argv)
273 struct mqelem *top = NULL;
277 if (!(args = GetQuotaArgs(FALSE)))
280 if ((status = do_mr_query("get_quota", CountArgs(args), args,
281 StoreInfo, &top)) != MR_SUCCESS)
282 com_err(program_name, status, " in get_quota");
288 Loop(top, (void *) PrintQuota);
294 /* Function Name: GetQuotaByFilesys
295 * Description: Shows all quotas associated with the
301 int GetQuotaByFilesys(int argc, char **argv)
303 struct mqelem *top = NULL;
305 char **args = malloc(2 * sizeof(char *));
309 Put_message("Could not allocate memory in GetQuotaByFilesys.");
313 args[0] = strdup("");
315 if (GetValueFromUser("Filesystem", &args[0]) == SUB_ERROR)
318 if ((status = do_mr_query("get_quota_by_filesys", 1, args,
319 StoreInfo, &top)) != MR_SUCCESS)
320 com_err(program_name, status, " in get_quota_by_filesys");
326 Loop(top, (void *) PrintQuota);
332 /* Function Name: AddQuota
333 * Description: Adds a new quota record for a filesystem
334 * w.r.t. a user, group, or anybody (AFS).
338 int AddQuota(int argc, char **argv)
343 if (!(args = GetQuotaArgs(TRUE)))
346 if ((status = do_mr_query("add_quota", CountArgs(args), args,
347 NULL, NULL)) != MR_SUCCESS)
348 com_err(program_name, status, " in add_quota");
355 /* Function Name: RealUpdateQuota
356 * Description: Performs the actual update of the quota
357 * Arguments: info - the information nesc. to update the quota.
361 static void RealUpdateQuota(char **info)
364 char temp_buf[BUFSIZ];
366 sprintf(temp_buf, "New quota for filesystem %s (in KB)", info[Q_FILESYS]);
367 if (GetValueFromUser(temp_buf, &info[Q_QUOTA]) == SUB_ERROR)
369 Put_message("Not changed.");
373 if ((status = do_mr_query("update_quota", 4, info,
374 NULL, NULL)) != MR_SUCCESS)
376 com_err(program_name, status, " in update_quota");
377 sprintf(temp_buf, "Could not perform quota change on %s",
379 Put_message(temp_buf);
383 /* Function Name: UpdateQuota
384 * Description: Updates an existing quota for a filesytem
385 * w.r.t. a user, group, or anybody.
390 int UpdateQuota(int argc, char **argv)
394 struct mqelem *top = NULL;
396 if (!(args = GetQuotaArgs(FALSE)))
399 if ((status = do_mr_query("get_quota", CountArgs(args), args,
400 StoreInfo, &top)) != MR_SUCCESS)
401 com_err(program_name, status, " in get_quota");
403 FreeInfo(args); /* done with args, free them. */
406 Loop(top, RealUpdateQuota);
413 /* Function Name: RealDeleteQuota
414 * Description: Actually removes the quota
415 * Arguments: info - all information about this quota.
416 * one_item - true if there is only one item in the queue, and
421 static void RealDeleteQuota(char **info, Bool one_item)
424 char temp_buf[BUFSIZ];
426 if (!strcmp(info[Q_TYPE], "ANY"))
428 sprintf(temp_buf, "Do you really want to delete the quota on %s",
433 sprintf(temp_buf, "Do you really want to delete the %s %s's quota on %s",
434 (strcmp(info[Q_TYPE], "USER") ? "group" : "user"), info[Q_NAME],
438 if (!one_item || Confirm(temp_buf))
440 if ((status = do_mr_query("delete_quota", 3, info,
441 NULL, NULL)) != MR_SUCCESS)
442 com_err(program_name, status, " in delete_quota");
444 Put_message("Quota sucessfully removed.");
447 Put_message("Aborted.");
450 /* Function Name: DeleteQuota
451 * Description: Removes the quota record for a filesystem
452 * w.r.t. a user, group, or anybody.
457 int DeleteQuota(int argc, char **argv)
461 struct mqelem *top = NULL;
463 if (!(args = GetQuotaArgs(FALSE)))
466 if ((status = do_mr_query("get_quota", 3, args, StoreInfo, &top)))
467 com_err(program_name, status, " in get_quota");
472 QueryLoop(top, PrintQuota, RealDeleteQuota,
473 "Delete this quota on filesystem");