]>
Commit | Line | Data |
---|---|---|
c441a31a | 1 | /* $Id$ |
7ac48069 | 2 | * |
3 | * This is the file quota.c for the Moira Client, which allows users | |
59ec8dae | 4 | * to quickly and easily maintain most parts of the Moira database. |
0a2c64cb | 5 | * It Contains: Functions for manipulating the quota information. |
5eaef520 | 6 | * |
0a2c64cb | 7 | * Created: 7/10/88 |
8 | * By: Chris D. Peterson | |
73c83e3d | 9 | * |
7ac48069 | 10 | * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology. |
11 | * For copying and distribution information, please see the file | |
12 | * <mit-copyright.h>. | |
73c83e3d | 13 | */ |
14 | ||
7ac48069 | 15 | #include <mit-copyright.h> |
8defc06b | 16 | #include <moira.h> |
17 | #include <moira_site.h> | |
0a2c64cb | 18 | #include "defs.h" |
19 | #include "f_defs.h" | |
73c83e3d | 20 | #include "globals.h" |
73c83e3d | 21 | |
7ac48069 | 22 | #include <stdio.h> |
23 | #include <stdlib.h> | |
24 | #include <string.h> | |
25 | ||
26 | int afsfilsyshelper(int argc, char **argv, void *hint); | |
27 | int afsfilesys(char *name); | |
28 | ||
5eaef520 | 29 | static char *def_quota = NULL; |
30 | ||
73c83e3d | 31 | #define DEFAULT_FILESYS DEFAULT_NONE |
8defc06b | 32 | #define DEFAULT_USER user /* this is the user who started moira. */ |
6966e6fe | 33 | #define NOBODY "[nobody]" |
b124ed18 | 34 | #define DEFAULT_QTYPE "USER" |
bf96ab95 | 35 | |
73c83e3d | 36 | |
37 | /* Function Name: GetDefaultUserQuota | |
8defc06b | 38 | * Description: gets the user quota from moira, and caches the value. |
39 | * Arguments: override - if true, go to moira and override the cache. | |
73c83e3d | 40 | * Returns: none. |
41 | * NOTE: Using a queue here is pretty useless, but StoreInfo expects | |
42 | * one, and it works, so why fuck with it. | |
43 | */ | |
44 | ||
5eaef520 | 45 | static char *GetDefaultUserQuota(Bool override) |
73c83e3d | 46 | { |
44d12d58 | 47 | int status; |
5eaef520 | 48 | char **info; |
600b459e | 49 | struct mqelem *top = NULL; |
73c83e3d | 50 | static char *val[] = {"def_quota", NULL}; |
51 | ||
5eaef520 | 52 | if (override || (def_quota == NULL)) |
53 | { | |
54 | if ((status = do_mr_query("get_value", CountArgs(val), val, | |
7ac48069 | 55 | StoreInfo, &top))) |
5eaef520 | 56 | { |
57 | com_err(program_name, status, " in ShowDefaultQuota"); | |
58 | if (!def_quota) | |
59 | { | |
60 | Put_message("No default Quota Found, setting default to 0."); | |
7ac48069 | 61 | def_quota = strdup("0"); |
5eaef520 | 62 | } |
63 | else | |
64 | Put_message("No default Quota Found, retaining old value."); | |
65 | } | |
66 | else | |
67 | { | |
68 | top = QueueTop(top); | |
7ac48069 | 69 | info = top->q_data; |
5eaef520 | 70 | FreeAndClear(&def_quota, TRUE); |
7ac48069 | 71 | def_quota = strdup(info[0]); |
5eaef520 | 72 | FreeQueue(top); |
73c83e3d | 73 | } |
73c83e3d | 74 | } |
5eaef520 | 75 | return def_quota; |
73c83e3d | 76 | } |
5eaef520 | 77 | |
73c83e3d | 78 | /* Function Name: PrintDefaultQuota |
79 | * Description: Prints default quota info in a meaningful way. | |
80 | * Arguments: value of the default quota. | |
81 | * Returns: none. | |
82 | */ | |
83 | ||
5eaef520 | 84 | static void PrintDefaultQuota(char *quota) |
73c83e3d | 85 | { |
5eaef520 | 86 | char temp_buf[BUFSIZ]; |
87 | Put_message(""); | |
88 | sprintf(temp_buf, "The default quota is %s Kb.", quota); | |
89 | Put_message(temp_buf); | |
73c83e3d | 90 | } |
91 | ||
92 | /* Function Name: PrintQuota | |
93 | * Description: Prints a users quota information. | |
94 | * Arguments: info - a pointer to the quota information: | |
95 | * Returns: none. | |
96 | */ | |
97 | ||
5eaef520 | 98 | static char *PrintQuota(char **info) |
73c83e3d | 99 | { |
5eaef520 | 100 | char buf[BUFSIZ]; |
101 | ||
102 | Put_message(""); | |
103 | ||
104 | if (!strcmp(info[Q_TYPE], "ANY")) | |
105 | sprintf(buf, "Filesystem: %s", info[Q_FILESYS]); | |
106 | else | |
107 | sprintf(buf, "Filesystem: %-45s %s %s", info[Q_FILESYS], | |
108 | info[Q_TYPE], info[Q_NAME]); | |
109 | Put_message(buf); | |
110 | sprintf(buf, "Machine: %-20s Directory: %-15s", | |
111 | info[Q_MACHINE], info[Q_DIRECTORY]); | |
112 | Put_message(buf); | |
113 | sprintf(buf, "Quota: %s", info[Q_QUOTA]); | |
114 | Put_message(buf); | |
115 | sprintf(buf, MOD_FORMAT, info[Q_MODBY], info[Q_MODTIME], info[Q_MODWITH]); | |
116 | Put_message(buf); | |
117 | return info[Q_FILESYS]; | |
73c83e3d | 118 | } |
119 | ||
bf96ab95 | 120 | |
7ac48069 | 121 | int afsfilsyshelper(int argc, char **argv, void *hint) |
bf96ab95 | 122 | { |
7ac48069 | 123 | *(int *)hint = !strcmp(argv[FS_TYPE], "AFS"); |
124 | return MR_CONT; | |
bf96ab95 | 125 | } |
126 | ||
127 | ||
5eaef520 | 128 | int afsfilesys(char *name) |
bf96ab95 | 129 | { |
5eaef520 | 130 | int status, ret = 0; |
131 | char *argv[1]; | |
132 | ||
133 | if (strchr(name, '*') || strchr(name, '?') || strchr(name, '\\')) | |
134 | return 0; | |
135 | argv[0] = name; | |
136 | status = do_mr_query("get_filesys_by_label", 1, argv, afsfilsyshelper, &ret); | |
137 | if (status == MR_SUCCESS) | |
138 | return ret; | |
139 | return status; | |
bf96ab95 | 140 | } |
141 | ||
142 | ||
73c83e3d | 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. | |
147 | */ | |
148 | ||
5eaef520 | 149 | static char **GetQuotaArgs(Bool quota) |
73c83e3d | 150 | { |
5eaef520 | 151 | char **args = malloc(MAX_ARGS_SIZE * sizeof(char *)); |
6d8848f6 | 152 | int af; |
5eaef520 | 153 | |
154 | if (!args) | |
155 | { | |
156 | Put_message("Could not allocate memory in GetQuotaArgs."); | |
157 | return NULL; | |
158 | } | |
73c83e3d | 159 | |
7ac48069 | 160 | args[Q_FILESYS] = strdup(DEFAULT_FILESYS); |
161 | args[Q_TYPE] = strdup(DEFAULT_QTYPE); | |
162 | args[Q_NAME] = strdup(DEFAULT_USER); | |
5eaef520 | 163 | if (quota) |
164 | { | |
7ac48069 | 165 | args[Q_QUOTA] = strdup(GetDefaultUserQuota(FALSE)); |
5eaef520 | 166 | args[Q_QUOTA + 1] = NULL; /* NULL terminate. */ |
167 | } | |
168 | else | |
169 | args[Q_NAME + 1] = NULL; /* NULL terminate. */ | |
73c83e3d | 170 | |
171 | /* Get filesystem. */ | |
172 | ||
245b2337 | 173 | if (GetValueFromUser("Filesystem", &args[Q_FILESYS]) == SUB_ERROR) |
5eaef520 | 174 | return NULL; |
bf96ab95 | 175 | if (quota && !ValidName(args[Q_FILESYS])) |
5eaef520 | 176 | return NULL; |
177 | ||
6d8848f6 | 178 | af = afsfilesys(args[Q_FILESYS]); |
5eaef520 | 179 | if (af != 0 && af != 1) |
180 | { | |
6d8848f6 | 181 | if (af == MR_NO_MATCH) |
182 | Put_message("That filesystem does not exist."); | |
183 | else | |
184 | com_err(program_name, af, " in afsfilesys"); | |
5eaef520 | 185 | return NULL; |
186 | } | |
187 | if (af) | |
188 | { | |
7ac48069 | 189 | args[Q_TYPE] = strdup("ANY"); |
190 | args[Q_NAME] = strdup(NOBODY); | |
5eaef520 | 191 | } |
192 | else | |
193 | { | |
245b2337 | 194 | if (GetTypeFromUser("Quota type", "quota_type", &args[Q_TYPE]) == |
195 | SUB_ERROR) | |
5eaef520 | 196 | return NULL; |
245b2337 | 197 | if (GetValueFromUser("Name", &args[Q_NAME]) == SUB_ERROR) |
5eaef520 | 198 | return NULL; |
199 | if (!ValidName(args[Q_NAME])) | |
200 | return NULL; | |
201 | } | |
73c83e3d | 202 | |
5eaef520 | 203 | if (quota) /* Get and check quota. */ |
204 | { | |
245b2337 | 205 | if (GetValueFromUser("Quota", &args[Q_QUOTA]) == SUB_ERROR) |
5eaef520 | 206 | return NULL; |
207 | if (!ValidName(args[Q_QUOTA])) | |
208 | return NULL; | |
209 | } | |
210 | return args; | |
211 | } | |
73c83e3d | 212 | |
73c83e3d | 213 | /* Function Name: ShowDefaultQuota |
214 | * Description: This prints out a default quota for the system. | |
215 | * Arguments: none | |
216 | * Returns: DM_NORMAL. | |
217 | */ | |
218 | ||
7ac48069 | 219 | int ShowDefaultQuota(int argc, char **argv) |
73c83e3d | 220 | { |
221 | PrintDefaultQuota(GetDefaultUserQuota(TRUE)); | |
5eaef520 | 222 | return DM_NORMAL; |
73c83e3d | 223 | } |
224 | ||
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. | |
229 | */ | |
230 | ||
5eaef520 | 231 | int ChangeDefaultQuota(int argc, char *argv[]) |
73c83e3d | 232 | { |
44d12d58 | 233 | int status; |
5eaef520 | 234 | char temp_buf[BUFSIZ]; |
235 | static char *newval[] = { | |
236 | "def_quota", NULL, NULL | |
237 | }; | |
238 | ||
239 | if (!ValidName(argv[1])) | |
240 | return DM_NORMAL; | |
241 | ||
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)) | |
245 | { | |
246 | newval[1] = argv[1]; | |
247 | if ((status = do_mr_query("update_value", CountArgs(newval), | |
7ac48069 | 248 | newval, NULL, NULL)) == MR_SUCCESS) |
5eaef520 | 249 | { |
73c83e3d | 250 | FreeAndClear(&def_quota, TRUE); |
7ac48069 | 251 | def_quota = strdup(argv[1]); |
73c83e3d | 252 | } |
5eaef520 | 253 | else |
254 | com_err(program_name, status, " in update_value"); | |
73c83e3d | 255 | } |
5eaef520 | 256 | else |
257 | Put_message("Quota not changed."); | |
73c83e3d | 258 | |
5eaef520 | 259 | return DM_NORMAL; |
73c83e3d | 260 | } |
261 | ||
b124ed18 | 262 | /* ------------------------ Filesystem Quotas -------------------- */ |
73c83e3d | 263 | |
b124ed18 | 264 | /* Function Name: GetQuota |
265 | * Description: Shows the quota of a filesystem w.r.t. | |
266 | * a group, user, or anybody (AFS) | |
267 | * Arguments: none | |
268 | * Returns: DM_NORMAL | |
73c83e3d | 269 | */ |
270 | ||
7ac48069 | 271 | int GetQuota(int argc, char **argv) |
73c83e3d | 272 | { |
600b459e | 273 | struct mqelem *top = NULL; |
44d12d58 | 274 | int status; |
5eaef520 | 275 | char **args; |
73c83e3d | 276 | |
5eaef520 | 277 | if (!(args = GetQuotaArgs(FALSE))) |
278 | return DM_NORMAL; | |
73c83e3d | 279 | |
5eaef520 | 280 | if ((status = do_mr_query("get_quota", CountArgs(args), args, |
7ac48069 | 281 | StoreInfo, &top)) != MR_SUCCESS) |
b124ed18 | 282 | com_err(program_name, status, " in get_quota"); |
283 | ||
284 | FreeInfo(args); | |
73c83e3d | 285 | free(args); |
286 | ||
287 | top = QueueTop(top); | |
a6da9354 | 288 | Loop(top, (void (*)(char **)) PrintQuota); |
b124ed18 | 289 | |
73c83e3d | 290 | FreeQueue(top); |
5eaef520 | 291 | return DM_NORMAL; |
73c83e3d | 292 | } |
293 | ||
b124ed18 | 294 | /* Function Name: GetQuotaByFilesys |
295 | * Description: Shows all quotas associated with the | |
296 | * given filesystem | |
297 | * Arguments: none | |
298 | * Returns: DM_NORMAL | |
73c83e3d | 299 | */ |
300 | ||
7ac48069 | 301 | int GetQuotaByFilesys(int argc, char **argv) |
b124ed18 | 302 | { |
600b459e | 303 | struct mqelem *top = NULL; |
44d12d58 | 304 | int status; |
5eaef520 | 305 | char **args = malloc(2 * sizeof(char *)); |
b124ed18 | 306 | |
5eaef520 | 307 | if (!args) |
308 | { | |
309 | Put_message("Could not allocate memory in GetQuotaByFilesys."); | |
310 | return DM_NORMAL; | |
311 | } | |
b124ed18 | 312 | |
7ac48069 | 313 | args[0] = strdup(""); |
0b48ba68 | 314 | args[1] = NULL; |
245b2337 | 315 | if (GetValueFromUser("Filesystem", &args[0]) == SUB_ERROR) |
5eaef520 | 316 | return DM_NORMAL; |
b124ed18 | 317 | |
5eaef520 | 318 | if ((status = do_mr_query("get_quota_by_filesys", 1, args, |
7ac48069 | 319 | StoreInfo, &top)) != MR_SUCCESS) |
b124ed18 | 320 | com_err(program_name, status, " in get_quota_by_filesys"); |
321 | ||
322 | FreeInfo(args); | |
323 | free(args); | |
324 | ||
325 | top = QueueTop(top); | |
a6da9354 | 326 | Loop(top, (void (*)(char **)) PrintQuota); |
b124ed18 | 327 | |
328 | FreeQueue(top); | |
5eaef520 | 329 | return DM_NORMAL; |
b124ed18 | 330 | } |
331 | ||
332 | /* Function Name: AddQuota | |
333 | * Description: Adds a new quota record for a filesystem | |
334 | * w.r.t. a user, group, or anybody (AFS). | |
335 | * Arguments: None | |
336 | * Returns: DM_NORMAL | |
337 | */ | |
7ac48069 | 338 | int AddQuota(int argc, char **argv) |
73c83e3d | 339 | { |
5eaef520 | 340 | char **args; |
44d12d58 | 341 | int status; |
73c83e3d | 342 | |
5eaef520 | 343 | if (!(args = GetQuotaArgs(TRUE))) |
344 | return DM_NORMAL; | |
345 | ||
346 | if ((status = do_mr_query("add_quota", CountArgs(args), args, | |
7ac48069 | 347 | NULL, NULL)) != MR_SUCCESS) |
b124ed18 | 348 | com_err(program_name, status, " in add_quota"); |
5eaef520 | 349 | |
73c83e3d | 350 | FreeInfo(args); |
351 | free(args); | |
5eaef520 | 352 | return DM_NORMAL; |
73c83e3d | 353 | } |
354 | ||
b124ed18 | 355 | /* Function Name: RealUpdateQuota |
356 | * Description: Performs the actual update of the quota | |
357 | * Arguments: info - the information nesc. to update the quota. | |
73c83e3d | 358 | * Returns: none. |
359 | */ | |
360 | ||
5eaef520 | 361 | static void RealUpdateQuota(char **info) |
73c83e3d | 362 | { |
44d12d58 | 363 | int status; |
73c83e3d | 364 | char temp_buf[BUFSIZ]; |
365 | ||
366 | sprintf(temp_buf, "New quota for filesystem %s (in KB)", info[Q_FILESYS]); | |
5eaef520 | 367 | if (GetValueFromUser(temp_buf, &info[Q_QUOTA]) == SUB_ERROR) |
368 | { | |
245b2337 | 369 | Put_message("Not changed."); |
370 | return; | |
5eaef520 | 371 | } |
b124ed18 | 372 | |
7ac48069 | 373 | if ((status = do_mr_query("update_quota", 4, info, |
374 | NULL, NULL)) != MR_SUCCESS) | |
375 | { | |
5eaef520 | 376 | com_err(program_name, status, " in update_quota"); |
377 | sprintf(temp_buf, "Could not perform quota change on %s", | |
378 | info[Q_FILESYS]); | |
379 | Put_message(temp_buf); | |
380 | } | |
73c83e3d | 381 | } |
b124ed18 | 382 | |
383 | /* Function Name: UpdateQuota | |
384 | * Description: Updates an existing quota for a filesytem | |
385 | * w.r.t. a user, group, or anybody. | |
386 | * Arguments: None | |
387 | * Returns: DM_NORMAL | |
73c83e3d | 388 | */ |
389 | ||
7ac48069 | 390 | int UpdateQuota(int argc, char **argv) |
73c83e3d | 391 | { |
392 | int status; | |
393 | char **args; | |
600b459e | 394 | struct mqelem *top = NULL; |
73c83e3d | 395 | |
5eaef520 | 396 | if (!(args = GetQuotaArgs(FALSE))) |
397 | return DM_NORMAL; | |
398 | ||
399 | if ((status = do_mr_query("get_quota", CountArgs(args), args, | |
7ac48069 | 400 | StoreInfo, &top)) != MR_SUCCESS) |
b124ed18 | 401 | com_err(program_name, status, " in get_quota"); |
5eaef520 | 402 | |
73c83e3d | 403 | FreeInfo(args); /* done with args, free them. */ |
404 | free(args); | |
405 | top = QueueTop(top); | |
b124ed18 | 406 | Loop(top, RealUpdateQuota); |
73c83e3d | 407 | |
408 | FreeQueue(top); | |
5eaef520 | 409 | return DM_NORMAL; |
73c83e3d | 410 | } |
b124ed18 | 411 | |
412 | ||
413 | /* Function Name: RealDeleteQuota | |
414 | * Description: Actually removes the quota | |
415 | * Arguments: info - all information about this quota. | |
73c83e3d | 416 | * one_item - true if there is only one item in the queue, and |
417 | * we should confirm. | |
418 | * Returns: none. | |
419 | */ | |
420 | ||
5eaef520 | 421 | static void RealDeleteQuota(char **info, Bool one_item) |
73c83e3d | 422 | { |
44d12d58 | 423 | int status; |
73c83e3d | 424 | char temp_buf[BUFSIZ]; |
425 | ||
b124ed18 | 426 | if (!strcmp(info[Q_TYPE], "ANY")) |
5eaef520 | 427 | { |
428 | sprintf(temp_buf, "Do you really want to delete the quota on %s", | |
429 | info[Q_FILESYS]); | |
430 | } | |
b124ed18 | 431 | else |
5eaef520 | 432 | { |
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], | |
435 | info[Q_FILESYS]); | |
436 | } | |
437 | ||
438 | if (!one_item || Confirm(temp_buf)) | |
439 | { | |
440 | if ((status = do_mr_query("delete_quota", 3, info, | |
7ac48069 | 441 | NULL, NULL)) != MR_SUCCESS) |
5eaef520 | 442 | com_err(program_name, status, " in delete_quota"); |
443 | else | |
444 | Put_message("Quota sucessfully removed."); | |
445 | } | |
73c83e3d | 446 | else |
447 | Put_message("Aborted."); | |
448 | } | |
449 | ||
b124ed18 | 450 | /* Function Name: DeleteQuota |
451 | * Description: Removes the quota record for a filesystem | |
452 | * w.r.t. a user, group, or anybody. | |
453 | * Arguments: None | |
454 | * Returns: DM_NORMAL | |
73c83e3d | 455 | */ |
456 | ||
7ac48069 | 457 | int DeleteQuota(int argc, char **argv) |
73c83e3d | 458 | { |
44d12d58 | 459 | int status; |
73c83e3d | 460 | char **args; |
600b459e | 461 | struct mqelem *top = NULL; |
73c83e3d | 462 | |
5eaef520 | 463 | if (!(args = GetQuotaArgs(FALSE))) |
464 | return DM_NORMAL; | |
73c83e3d | 465 | |
7ac48069 | 466 | if ((status = do_mr_query("get_quota", 3, args, StoreInfo, &top))) |
b124ed18 | 467 | com_err(program_name, status, " in get_quota"); |
73c83e3d | 468 | |
469 | FreeInfo(args); | |
470 | free(args); | |
471 | top = QueueTop(top); | |
b124ed18 | 472 | QueryLoop(top, PrintQuota, RealDeleteQuota, |
473 | "Delete this quota on filesystem"); | |
73c83e3d | 474 | |
475 | FreeQueue(top); | |
5eaef520 | 476 | return DM_NORMAL; |
73c83e3d | 477 | } |