1 | /* |
---|
2 | * Disk quota reporting program. |
---|
3 | * |
---|
4 | * $Id: quota.c,v 1.21 1993-07-25 01:26:09 probe Exp $ |
---|
5 | */ |
---|
6 | |
---|
7 | #ifdef POSIX |
---|
8 | #include <unistd.h> |
---|
9 | #endif |
---|
10 | #include <stdio.h> |
---|
11 | #include <sys/types.h> |
---|
12 | #include <ctype.h> |
---|
13 | #include <errno.h> |
---|
14 | #include <sys/param.h> |
---|
15 | #include <fcntl.h> |
---|
16 | #include <sys/file.h> |
---|
17 | #include <sys/time.h> |
---|
18 | #include <pwd.h> |
---|
19 | #include <grp.h> |
---|
20 | |
---|
21 | #include <rpc/rpc.h> |
---|
22 | #include <rpc/pmap_prot.h> |
---|
23 | #include <rpcsvc/rquota.h> |
---|
24 | #include <rpcsvc/rcquota.h> |
---|
25 | |
---|
26 | #ifdef _IBMR2 |
---|
27 | #include <sys/id.h> |
---|
28 | #include <sys/select.h> |
---|
29 | #include <sys/mntctl.h> |
---|
30 | #include <sys/vmount.h> |
---|
31 | #define dbtob(db) ((unsigned)(db) << UBSHIFT) |
---|
32 | |
---|
33 | #else /* !_IBMR2 */ |
---|
34 | |
---|
35 | #if defined(SOLARIS) |
---|
36 | /* Sorry, we do not yet support UFS for Solaris */ |
---|
37 | #else |
---|
38 | |
---|
39 | #if defined(ultrix) || defined(_I386) |
---|
40 | #include <sys/stat.h> |
---|
41 | #include <sys/quota.h> |
---|
42 | #else |
---|
43 | #include <ufs/quota.h> |
---|
44 | #endif |
---|
45 | |
---|
46 | #ifdef ultrix |
---|
47 | #include <sys/mount.h> |
---|
48 | #include <fstab.h> |
---|
49 | #include <sys/fs_types.h> |
---|
50 | #define mntent fs_data |
---|
51 | struct fs_data mountbuffer[NMOUNT]; |
---|
52 | #else |
---|
53 | #include <mntent.h> |
---|
54 | #endif |
---|
55 | |
---|
56 | #endif /* !SOLARIS */ |
---|
57 | #endif /* !_IBMR2 */ |
---|
58 | |
---|
59 | #ifdef ultrix |
---|
60 | #undef mntent |
---|
61 | #endif |
---|
62 | #include "attach.h" |
---|
63 | #ifdef ultrix |
---|
64 | #define mntent fs_data |
---|
65 | #endif |
---|
66 | |
---|
67 | #if defined(vax) || defined(ibm032) |
---|
68 | #include <qoent.h> |
---|
69 | #endif |
---|
70 | |
---|
71 | |
---|
72 | static char *warningstring = NULL; |
---|
73 | |
---|
74 | int vflag=0, uflag=0, gflag=0, aflag=0; |
---|
75 | #if defined(ultrix) || defined(_I386) |
---|
76 | int qflag=0, done=0; |
---|
77 | #endif |
---|
78 | |
---|
79 | #define user_and_groups (!uflag && !gflag) |
---|
80 | #define QFNAME "quotas" |
---|
81 | |
---|
82 | #define kb(n) (howmany(dbtob(n), 1024)) |
---|
83 | |
---|
84 | #define MAXFS 16 |
---|
85 | #define MAXID 32 |
---|
86 | /* List of id's and filesystems to check */ |
---|
87 | char *fslist[MAXFS], *idlist[MAXID]; |
---|
88 | int fsind = 0, idind = 0, heading_printed; |
---|
89 | |
---|
90 | main(argc, argv) |
---|
91 | char *argv[]; |
---|
92 | { |
---|
93 | register char *cp; |
---|
94 | register int i; |
---|
95 | |
---|
96 | argc--,argv++; |
---|
97 | while (argc > 0) { |
---|
98 | if (argv[0][0] == '-') |
---|
99 | for (cp = &argv[0][1]; *cp; cp++) switch (*cp) { |
---|
100 | |
---|
101 | case 'a': |
---|
102 | aflag=1; |
---|
103 | break; |
---|
104 | |
---|
105 | case 'v': |
---|
106 | vflag=1; |
---|
107 | break; |
---|
108 | |
---|
109 | #ifdef ultrix |
---|
110 | case 'q': |
---|
111 | qflag=1; |
---|
112 | break; |
---|
113 | #endif |
---|
114 | |
---|
115 | case 'g': |
---|
116 | gflag=1; |
---|
117 | break; |
---|
118 | |
---|
119 | case 'u': |
---|
120 | uflag=1; |
---|
121 | break; |
---|
122 | |
---|
123 | case 'f': |
---|
124 | if (fsind < MAXFS) |
---|
125 | { |
---|
126 | if (argc == 1){ |
---|
127 | fprintf(stderr, "quota: No filesystem argument\n"); |
---|
128 | usage(); |
---|
129 | exit(1); |
---|
130 | } |
---|
131 | fslist[fsind++] = argv[1]; |
---|
132 | argv++; |
---|
133 | argc--; |
---|
134 | break; |
---|
135 | } |
---|
136 | else{ |
---|
137 | fprintf(stderr, "quota: too many filesystems\n"); |
---|
138 | exit(1); |
---|
139 | } |
---|
140 | |
---|
141 | default: |
---|
142 | fprintf(stderr, "quota: %c: unknown option\n", |
---|
143 | *cp); |
---|
144 | usage(); |
---|
145 | exit(1); |
---|
146 | } |
---|
147 | else if (idind < MAXID) |
---|
148 | { |
---|
149 | idlist[idind++] = argv[0]; |
---|
150 | } |
---|
151 | else{ |
---|
152 | fprintf(stderr, "quota: too many id's\n"); |
---|
153 | exit(1); |
---|
154 | } |
---|
155 | argv++; |
---|
156 | argc--; |
---|
157 | } |
---|
158 | |
---|
159 | if (gflag && uflag) { |
---|
160 | fprintf(stderr, "quota: Can't use both -g and -u\n"); |
---|
161 | usage(); |
---|
162 | exit(1); |
---|
163 | } |
---|
164 | |
---|
165 | if (aflag && fsind) { |
---|
166 | fprintf(stderr, "quota: Can't use both -a and -f\n"); |
---|
167 | usage(); |
---|
168 | exit(1); |
---|
169 | } |
---|
170 | |
---|
171 | if (uflag && idind == 0){ |
---|
172 | idlist[0] = (char*)malloc(20); |
---|
173 | sprintf(idlist[0],"%d",getuid()); |
---|
174 | idind = 1; |
---|
175 | } |
---|
176 | |
---|
177 | if (gflag && (idind == 0)){ |
---|
178 | fprintf(stderr, "quota: No groups specified\n"); |
---|
179 | usage(); |
---|
180 | exit(1); |
---|
181 | } |
---|
182 | |
---|
183 | lock_attachtab(); |
---|
184 | get_attachtab(); |
---|
185 | unlock_attachtab(); |
---|
186 | |
---|
187 | if (fsind) verify_filesystems(); |
---|
188 | |
---|
189 | if (idind == 0) showid(getuid()); |
---|
190 | else |
---|
191 | for(i=0;i<idind;i++) { |
---|
192 | heading_printed = 0; |
---|
193 | if ((!gflag && getpwnam(idlist[i])) || |
---|
194 | (gflag && getgrnam(idlist[i]))) |
---|
195 | showname(idlist[i]); |
---|
196 | else if (alldigits(idlist[i])) showid(atoi(idlist[i])); |
---|
197 | else showname(idlist[i]); |
---|
198 | } |
---|
199 | |
---|
200 | exit(0); |
---|
201 | } |
---|
202 | |
---|
203 | showid(id) |
---|
204 | int id; |
---|
205 | { |
---|
206 | register struct passwd *pwd = getpwuid(id); |
---|
207 | register struct group *grp = getgrgid(id); |
---|
208 | |
---|
209 | if (id == 0){ |
---|
210 | if (vflag) printf("no disk quota for %s 0\n", |
---|
211 | (gflag ? "gid" : "uid")); |
---|
212 | return; |
---|
213 | } |
---|
214 | |
---|
215 | if (gflag) { |
---|
216 | if (grp == NULL) showquotas(id, "(no group)"); |
---|
217 | else showquotas(id, grp->gr_name); |
---|
218 | } else { |
---|
219 | if (pwd == NULL) showquotas(id, "(no account)"); |
---|
220 | else showquotas(id, pwd->pw_name); |
---|
221 | } |
---|
222 | return; |
---|
223 | } |
---|
224 | |
---|
225 | showname(name) |
---|
226 | char *name; |
---|
227 | { |
---|
228 | register struct passwd *pwd = getpwnam(name); |
---|
229 | register struct group *grp = getgrnam(name); |
---|
230 | |
---|
231 | if (gflag){ |
---|
232 | if (grp == NULL){ |
---|
233 | fprintf(stderr, "quota: %s: unknown group\n", name); |
---|
234 | exit(7); |
---|
235 | return; |
---|
236 | } |
---|
237 | if (grp->gr_gid == 0){ |
---|
238 | if (vflag) printf("no disk quota for %s (gid 0)\n", name); |
---|
239 | return; |
---|
240 | } |
---|
241 | showquotas(grp->gr_gid,name); |
---|
242 | } |
---|
243 | else{ |
---|
244 | if (pwd == NULL){ |
---|
245 | fprintf(stderr, "quota: %s: unknown user\n", name); |
---|
246 | exit(8); |
---|
247 | } |
---|
248 | if (pwd->pw_uid == 0){ |
---|
249 | if (vflag) |
---|
250 | printf("no disk quota for %s (uid 0)\n", name); |
---|
251 | return; |
---|
252 | } |
---|
253 | showquotas(pwd->pw_uid,name); |
---|
254 | } |
---|
255 | } |
---|
256 | |
---|
257 | /* Different enough that it's a mess to ifdef it all individually */ |
---|
258 | showquotas(id,name) |
---|
259 | int id; |
---|
260 | char *name; |
---|
261 | { |
---|
262 | int myuid, ngroups, gidset[NGROUPS]; |
---|
263 | struct getcquota_rslt qvalues; |
---|
264 | struct _attachtab *p; |
---|
265 | void *v; /* Pointer to AFS VolumeStatus */ |
---|
266 | extern void *getafsquota(); |
---|
267 | |
---|
268 | #ifdef _IBMR2 |
---|
269 | int mntsize; |
---|
270 | char *mntbuf; |
---|
271 | int nmount; |
---|
272 | struct vmount *vmt; |
---|
273 | int j; |
---|
274 | #else |
---|
275 | |
---|
276 | register struct mntent *mntp; |
---|
277 | FILE *mtab; |
---|
278 | #ifdef ultrix |
---|
279 | #define mnt_dir fd_path |
---|
280 | #define mnt_fsname fd_devname |
---|
281 | #define Q_GETQUOTA Q_GETDLIM |
---|
282 | int ultlocalquotas=0; |
---|
283 | int loc=0, ret; |
---|
284 | #endif |
---|
285 | #ifdef _I386 |
---|
286 | #define MNTTYPE_42 MNTTYPE_UFS |
---|
287 | int ultlocalquotas=0; |
---|
288 | #endif |
---|
289 | |
---|
290 | #endif /* !_IBMR2 */ |
---|
291 | |
---|
292 | myuid = getuid(); |
---|
293 | |
---|
294 | if (gflag) { /* Must be in group or super-user */ |
---|
295 | if ((ngroups = getgroups(NGROUPS, gidset)) == -1){ |
---|
296 | perror("quota: Couldn't get list of groups."); |
---|
297 | exit(9); |
---|
298 | } |
---|
299 | while(ngroups){ if (id == gidset[ngroups-1]) break; --ngroups;} |
---|
300 | if (!ngroups && myuid != 0){ |
---|
301 | printf("quota: %s (gid %d): permission denied\n", name, id); |
---|
302 | return; |
---|
303 | } |
---|
304 | } |
---|
305 | else{ |
---|
306 | if (id != myuid && myuid != 0){ |
---|
307 | printf("quota: %s (uid %d): permission denied\n", name, id); |
---|
308 | return; |
---|
309 | } |
---|
310 | } |
---|
311 | |
---|
312 | #if defined(SOLARIS) |
---|
313 | /* Don't bother with NFS/UFS yet */ |
---|
314 | #else |
---|
315 | |
---|
316 | #ifdef _IBMR2 |
---|
317 | mntsize = 4096; |
---|
318 | if ((mntbuf = (char *)malloc(mntsize)) == NULL) { |
---|
319 | perror("quota: error allocating memory"); |
---|
320 | exit(9); |
---|
321 | } |
---|
322 | nmount = mntctl(MCTL_QUERY,mntsize,mntbuf); |
---|
323 | if (nmount == -1) { |
---|
324 | perror("quota: mntctl failed"); |
---|
325 | exit(9); |
---|
326 | } |
---|
327 | if (nmount == 0) { |
---|
328 | mntsize = *((int *) mntbuf); |
---|
329 | if ((mntbuf = (char *)realloc(mntbuf, mntsize)) == NULL) { |
---|
330 | perror("quota: error reallocing memory"); |
---|
331 | exit(9); |
---|
332 | } |
---|
333 | nmount = mntctl(MCTL_QUERY,mntsize,mntbuf); |
---|
334 | if (nmount == -1) { |
---|
335 | perror("quota: mntctl failed"); |
---|
336 | exit(9); |
---|
337 | } |
---|
338 | } |
---|
339 | |
---|
340 | vmt = (struct vmount *)mntbuf; |
---|
341 | for(j=0; j<nmount; j++,vmt=(struct vmount *)((char *)vmt+vmt->vmt_length)) |
---|
342 | { |
---|
343 | char *dirp; |
---|
344 | |
---|
345 | dirp = ((char *)vmt+vmt->vmt_data[VMT_STUB].vmt_off); |
---|
346 | if (fsind) { |
---|
347 | int i, l; |
---|
348 | for(i=0;i<fsind;i++){ |
---|
349 | l = strlen(fslist[i]); |
---|
350 | if(!strncmp(((char *)vmt + vmt->vmt_data[VMT_STUB].vmt_off), |
---|
351 | fslist[i], l)) |
---|
352 | break; |
---|
353 | } |
---|
354 | if (i == fsind) continue; /* Punt filesystems not in fslist */ |
---|
355 | } |
---|
356 | |
---|
357 | if (!fsind && !aflag && !own(gflag?myuid:id, dirp)) |
---|
358 | continue; |
---|
359 | |
---|
360 | if (vmt->vmt_gfstype == MNT_NFS) { |
---|
361 | if (!getnfsquota(((char *)vmt+vmt->vmt_data[VMT_HOSTNAME].vmt_off), |
---|
362 | ((char *)vmt+vmt->vmt_data[VMT_OBJECT].vmt_off), |
---|
363 | id, &qvalues)) |
---|
364 | continue; |
---|
365 | } |
---|
366 | else |
---|
367 | continue; |
---|
368 | if (vflag) prquota(dirp, &qvalues, id, name); |
---|
369 | if (user_and_groups || !vflag) warn(dirp, &qvalues); |
---|
370 | } |
---|
371 | |
---|
372 | #else /* !_IBMR2 */ |
---|
373 | |
---|
374 | #ifndef ultrix |
---|
375 | mtab = setmntent(MOUNTED, "r"); |
---|
376 | #else |
---|
377 | ret = getmountent(&loc, mountbuffer, NMOUNT); |
---|
378 | if (ret == 0) { |
---|
379 | perror("getmountent"); |
---|
380 | exit(3); |
---|
381 | } |
---|
382 | #endif |
---|
383 | |
---|
384 | #ifndef ultrix |
---|
385 | while(mntp = getmntent(mtab)) |
---|
386 | #else |
---|
387 | for(mntp = mountbuffer; mntp < &mountbuffer[ret]; mntp++) |
---|
388 | #endif |
---|
389 | { |
---|
390 | if (fsind) |
---|
391 | { |
---|
392 | int i, l; |
---|
393 | |
---|
394 | for(i=0;i<fsind;i++){ |
---|
395 | l = strlen(fslist[i]); |
---|
396 | if(!strncmp(mntp->mnt_dir, fslist[i], l)) |
---|
397 | break; |
---|
398 | } |
---|
399 | if (i == fsind) continue; /* Punt filesystems not |
---|
400 | * in the fslist */ |
---|
401 | } |
---|
402 | |
---|
403 | #ifndef ultrix |
---|
404 | if (strcmp(mntp->mnt_type, MNTTYPE_42) == 0) { |
---|
405 | if (!hasmntopt(mntp, MNTOPT_QUOTA)) |
---|
406 | continue; |
---|
407 | #ifdef _I386 |
---|
408 | ultlocalquotas++; |
---|
409 | continue; |
---|
410 | #else |
---|
411 | #ifndef sun |
---|
412 | if (getlocalquota(mntp,id,&qvalues) < 0) |
---|
413 | continue; |
---|
414 | #else |
---|
415 | continue; |
---|
416 | #endif |
---|
417 | } |
---|
418 | #endif |
---|
419 | #else /* ultrix */ |
---|
420 | if (mntp->fd_fstype == GT_ULTRIX) { |
---|
421 | if (mntp->fd_flags & M_QUOTA) |
---|
422 | ultlocalquotas++; |
---|
423 | continue; |
---|
424 | } |
---|
425 | #endif /* ultrix */ |
---|
426 | |
---|
427 | #ifndef ultrix |
---|
428 | if (!strcmp(mntp->mnt_type, MNTTYPE_NFS)) |
---|
429 | #else |
---|
430 | if (mntp->fd_fstype == GT_NFS) |
---|
431 | #endif |
---|
432 | { |
---|
433 | char host[128]; |
---|
434 | char path[128]; |
---|
435 | int i; |
---|
436 | |
---|
437 | if (!fsind && !aflag && !own(gflag?myuid:id, mntp->mnt_dir)) |
---|
438 | continue; |
---|
439 | |
---|
440 | i = (char *)index(mntp->mnt_fsname, ':') - mntp->mnt_fsname; |
---|
441 | bcopy(mntp->mnt_fsname, host, i); |
---|
442 | host[i] = 0; |
---|
443 | strcpy(path, mntp->mnt_fsname+i+1); |
---|
444 | if (!getnfsquota(host, path, id, &qvalues)) |
---|
445 | continue; |
---|
446 | } |
---|
447 | |
---|
448 | if (vflag) prquota(mntp->mnt_dir, &qvalues, id, name); |
---|
449 | if (user_and_groups || !vflag) warn(mntp->mnt_dir, &qvalues); |
---|
450 | } |
---|
451 | #ifndef ultrix |
---|
452 | endmntent(mtab); |
---|
453 | #endif |
---|
454 | |
---|
455 | #if defined(ultrix) || defined(_I386) |
---|
456 | if (ultlocalquotas) |
---|
457 | ultprintquotas(id,name); |
---|
458 | #endif |
---|
459 | |
---|
460 | #endif /* !_IBMR2 */ |
---|
461 | #endif /* !SOLARIS */ |
---|
462 | |
---|
463 | /* Check afs volumes */ |
---|
464 | for(p = attachtab_first; p!=NULL; p=p->next) { |
---|
465 | /* Only look at AFS mountpoints; others already done */ |
---|
466 | if ((p->fs->type != TYPE_AFS) || (p->status != STATUS_ATTACHED)) |
---|
467 | continue; |
---|
468 | if (fsind) { |
---|
469 | int i, l; |
---|
470 | |
---|
471 | for(i=0;i<fsind;i++){ |
---|
472 | l = strlen(fslist[i]); |
---|
473 | if(!strncmp(p->mntpt, fslist[i], l)) |
---|
474 | break; |
---|
475 | } |
---|
476 | if (i == fsind) continue; /* Punt filesystems not in fslist */ |
---|
477 | } |
---|
478 | |
---|
479 | if (!fsind && !aflag && !own(gflag?myuid:id, p->mntpt)) |
---|
480 | continue; |
---|
481 | |
---|
482 | if ((v = getafsquota(p->mntpt, fsind)) == NULL) |
---|
483 | continue; |
---|
484 | if (vflag) prafsquota(p->mntpt, v, id, name); |
---|
485 | if (user_and_groups || !vflag) afswarn(p->mntpt,v,name); |
---|
486 | } |
---|
487 | |
---|
488 | if (warningstring) { |
---|
489 | printf("\n%s\n", warningstring); |
---|
490 | free(warningstring); |
---|
491 | warningstring = NULL; |
---|
492 | } |
---|
493 | } |
---|
494 | |
---|
495 | /* |
---|
496 | * FUNCTION: |
---|
497 | * own |
---|
498 | * |
---|
499 | * ARGUMENTS: |
---|
500 | * id (int) Id of the person to check. |
---|
501 | * dir (char *) Name of the mountpoint to check. |
---|
502 | * |
---|
503 | * RETURN VALUES: |
---|
504 | * 0 User does not own/maintain the directory in question. |
---|
505 | * 1 User can modify/maintain the directory in question. |
---|
506 | * |
---|
507 | * This routine simply checks the attachtab to see if the id in question |
---|
508 | * is one of the owners of the filesystem in question. In addtion, it |
---|
509 | * performs an access() call to verify the user has write access to the |
---|
510 | * locker. The access checks are done as the invoker, and not done as |
---|
511 | * the passed id, for security reasons. |
---|
512 | */ |
---|
513 | int own(id, dir) |
---|
514 | int id; |
---|
515 | char *dir; |
---|
516 | { |
---|
517 | struct _attachtab *atp; |
---|
518 | int i; |
---|
519 | int status; |
---|
520 | |
---|
521 | atp = attachtab_lookup_mntpt(dir); |
---|
522 | if (!atp) |
---|
523 | return 0; |
---|
524 | |
---|
525 | for(i=0; i<atp->nowners; i++) |
---|
526 | if (atp->owners[i] == id) |
---|
527 | return (access(dir, W_OK) == 0); |
---|
528 | |
---|
529 | return 0; |
---|
530 | } |
---|
531 | |
---|
532 | #ifdef QOTAB |
---|
533 | getlocalquota(mntp, uid, qvp) |
---|
534 | struct mntent *mntp; |
---|
535 | int uid; |
---|
536 | struct getcquota_rslt *qvp; |
---|
537 | { |
---|
538 | struct qoent *qoent; |
---|
539 | FILE *qotab; |
---|
540 | struct dqblk dqblk; |
---|
541 | |
---|
542 | /* First get the options */ |
---|
543 | qotab = setqoent(QOTAB); |
---|
544 | while(qoent = getqoent(qotab)){ |
---|
545 | if (!strcmp(mntp->mnt_dir, qoent->mnt_dir)) |
---|
546 | break; |
---|
547 | else continue; |
---|
548 | } |
---|
549 | |
---|
550 | if (!qoent) { /* this partition has no quota options, use defaults */ |
---|
551 | qvp->rq_group = !strcmp(QOTYPE_DEFAULT, QOTYPE_GROUP); |
---|
552 | qvp->rq_bsize = DEV_BSIZE; |
---|
553 | qvp->gqr_zm.rq_bhardlimit = QO_BZHL_DEFAULT; |
---|
554 | qvp->gqr_zm.rq_bsoftlimit = QO_BZSL_DEFAULT; |
---|
555 | qvp->gqr_zm.rq_fhardlimit = QO_FZHL_DEFAULT; |
---|
556 | qvp->gqr_zm.rq_fsoftlimit = QO_FZSL_DEFAULT; |
---|
557 | } |
---|
558 | else{ |
---|
559 | /* qoent contains options */ |
---|
560 | qvp->rq_group = QO_GROUP(qoent); |
---|
561 | qvp->rq_bsize = DEV_BSIZE; |
---|
562 | qvp->gqr_zm.rq_bhardlimit = qoent->qo_bzhl; |
---|
563 | qvp->gqr_zm.rq_bsoftlimit = qoent->qo_bzsl; |
---|
564 | qvp->gqr_zm.rq_fhardlimit = qoent->qo_fzhl; |
---|
565 | qvp->gqr_zm.rq_fsoftlimit = qoent->qo_fzsl; |
---|
566 | } |
---|
567 | |
---|
568 | /* If this filesystem is group controlled and user quota is being |
---|
569 | * requested, or this is a user controlled filesystem and group |
---|
570 | * quotas are requested, then punt */ |
---|
571 | if ((qvp->rq_group && uflag) || |
---|
572 | (!qvp->rq_group && gflag)) |
---|
573 | return(-1); |
---|
574 | |
---|
575 | if (uflag || gflag || !qvp->rq_group){ |
---|
576 | if (quotactl(Q_GETQUOTA, mntp->mnt_fsname, uid, &dqblk)){ |
---|
577 | /* ouch! quotas are on, but this failed */ |
---|
578 | fprintf(stderr, "quotactl: %s %d\n", mntp->mnt_fsname, uid); |
---|
579 | return(-1); |
---|
580 | } |
---|
581 | |
---|
582 | qvp->rq_ngrps = 1; |
---|
583 | dqblk2rcquota(&dqblk,&(qvp->gqr_rcquota[0]), uid); |
---|
584 | return(0); |
---|
585 | } |
---|
586 | else{ |
---|
587 | int groups[NGROUPS], i; |
---|
588 | |
---|
589 | qvp->rq_ngrps = getgroups(NGROUPS,groups); |
---|
590 | for(i=0;i<qvp->rq_ngrps;i++){ |
---|
591 | if (quotactl(Q_GETQUOTA, mntp->mnt_fsname, groups[i], &dqblk)){ |
---|
592 | /* ouch again! */ |
---|
593 | fprintf(stderr, "quotactl: %s %d\n", mntp->mnt_fsname, groups[i]); |
---|
594 | return(-1); |
---|
595 | } |
---|
596 | dqblk2rcquota(&dqblk, &(qvp->gqr_rcquota[i]), groups[i]); |
---|
597 | } |
---|
598 | return(0); |
---|
599 | } |
---|
600 | } |
---|
601 | #endif |
---|
602 | |
---|
603 | void |
---|
604 | simpleheading(id,name) |
---|
605 | int id; |
---|
606 | char *name; |
---|
607 | { |
---|
608 | printf("Disk quotas for %s %s (%s %d):\n", |
---|
609 | (gflag? "group":"user"), name, |
---|
610 | (gflag? "gid": "uid"), id); |
---|
611 | printf("%-12s %7s%7s%7s%12s%7s%7s%7s%12s\n" |
---|
612 | , "Filesystem" |
---|
613 | , "usage" |
---|
614 | , "quota" |
---|
615 | , "limit" |
---|
616 | , "timeleft" |
---|
617 | , "files" |
---|
618 | , "quota" |
---|
619 | , "limit" |
---|
620 | , "timeleft" |
---|
621 | ); |
---|
622 | heading_printed = 1; |
---|
623 | } |
---|
624 | |
---|
625 | heading(id,name) |
---|
626 | int id; |
---|
627 | char *name; |
---|
628 | { |
---|
629 | printf("Disk quotas for %s (uid %d):\n",name,id); |
---|
630 | printf("%-16s%-6s%-12s%6s%7s%7s %7s%7s%7s\n" |
---|
631 | , "Filesystem" |
---|
632 | , "Type" |
---|
633 | , "ID" |
---|
634 | , "usage", "quota", "limit" |
---|
635 | , "files", "quota", "limit" |
---|
636 | ); |
---|
637 | heading_printed = 1; |
---|
638 | } |
---|
639 | |
---|
640 | prquota(dir, qvp, heading_id, heading_name) |
---|
641 | char *dir; |
---|
642 | register struct getcquota_rslt *qvp; |
---|
643 | int heading_id; |
---|
644 | char *heading_name; |
---|
645 | { |
---|
646 | struct timeval tv; |
---|
647 | char ftimeleft[80], btimeleft[80], idbuf[20]; |
---|
648 | char *cp, *id_name = "", *id_type; |
---|
649 | int i; |
---|
650 | struct rcquota *rqp; |
---|
651 | |
---|
652 | id_type = (qvp->rq_group? "group" : "user"); |
---|
653 | |
---|
654 | |
---|
655 | gettimeofday(&tv, NULL); |
---|
656 | |
---|
657 | for(i=0; i<qvp->rq_ngrps; i++){ |
---|
658 | |
---|
659 | /* If this is root or wheel, then skip */ |
---|
660 | if (qvp->gqr_rcquota[i].rq_id == 0) continue; |
---|
661 | |
---|
662 | rqp = &(qvp->gqr_rcquota[i]); |
---|
663 | |
---|
664 | /* We're not interested in this group if all is zero */ |
---|
665 | if (!rqp->rq_bsoftlimit && !rqp->rq_bhardlimit |
---|
666 | && !rqp->rq_curblocks && !rqp->rq_fsoftlimit |
---|
667 | && !rqp->rq_fhardlimit && !rqp->rq_curfiles) continue; |
---|
668 | |
---|
669 | if (user_and_groups){ |
---|
670 | if (qvp->rq_group){ |
---|
671 | getgroupname(qvp->gqr_rcquota[i].rq_id, idbuf); |
---|
672 | id_name = idbuf; |
---|
673 | } |
---|
674 | else{ /* this is a user quota */ |
---|
675 | getusername(qvp->gqr_rcquota[i].rq_id, idbuf); |
---|
676 | id_name = idbuf; |
---|
677 | } |
---|
678 | } |
---|
679 | |
---|
680 | /* Correct for zero quotas... */ |
---|
681 | if(!rqp->rq_bsoftlimit) |
---|
682 | rqp->rq_bsoftlimit = qvp->gqr_zm.rq_bsoftlimit; |
---|
683 | if(!rqp->rq_bhardlimit) |
---|
684 | rqp->rq_bhardlimit = qvp->gqr_zm.rq_bhardlimit; |
---|
685 | if(!rqp->rq_fsoftlimit) |
---|
686 | rqp->rq_fsoftlimit = qvp->gqr_zm.rq_fsoftlimit; |
---|
687 | if(!rqp->rq_fhardlimit) |
---|
688 | rqp->rq_fhardlimit = qvp->gqr_zm.rq_fhardlimit; |
---|
689 | |
---|
690 | if (!rqp->rq_bsoftlimit && !rqp->rq_bhardlimit && |
---|
691 | !rqp->rq_fsoftlimit && !rqp->rq_fhardlimit) |
---|
692 | /* Skip this entirely for compatibility */ |
---|
693 | continue; |
---|
694 | |
---|
695 | if (rqp->rq_bsoftlimit && |
---|
696 | rqp->rq_curblocks >= rqp->rq_bsoftlimit) { |
---|
697 | if (rqp->rq_btimeleft == 0) { |
---|
698 | strcpy(btimeleft, "NOT STARTED"); |
---|
699 | } else if (rqp->rq_btimeleft > tv.tv_sec) { |
---|
700 | fmttime(btimeleft, rqp->rq_btimeleft - tv.tv_sec); |
---|
701 | } else { |
---|
702 | strcpy(btimeleft, "EXPIRED"); |
---|
703 | } |
---|
704 | } else { |
---|
705 | btimeleft[0] = '\0'; |
---|
706 | } |
---|
707 | if (rqp->rq_fsoftlimit && |
---|
708 | rqp->rq_curfiles >= rqp->rq_fsoftlimit) { |
---|
709 | if (rqp->rq_ftimeleft == 0) { |
---|
710 | strcpy(ftimeleft, "NOT STARTED"); |
---|
711 | } else if (rqp->rq_ftimeleft > tv.tv_sec) { |
---|
712 | fmttime(ftimeleft, rqp->rq_ftimeleft - tv.tv_sec); |
---|
713 | } else { |
---|
714 | strcpy(ftimeleft, "EXPIRED"); |
---|
715 | } |
---|
716 | } else { |
---|
717 | ftimeleft[0] = '\0'; |
---|
718 | } |
---|
719 | |
---|
720 | cp = dir; |
---|
721 | |
---|
722 | if (!user_and_groups){ |
---|
723 | if (!heading_printed) simpleheading(heading_id,heading_name); |
---|
724 | if (strlen(cp) > 15){ |
---|
725 | printf("%s\n",cp); |
---|
726 | cp = ""; |
---|
727 | } |
---|
728 | printf("%-14s %5d%7d%7d%12s%7d%7d%7d%12s\n", |
---|
729 | cp, |
---|
730 | kb(rqp->rq_curblocks), |
---|
731 | kb(rqp->rq_bsoftlimit), |
---|
732 | kb(rqp->rq_bhardlimit), |
---|
733 | btimeleft, |
---|
734 | rqp->rq_curfiles, |
---|
735 | rqp->rq_fsoftlimit, |
---|
736 | rqp->rq_fhardlimit, |
---|
737 | ftimeleft |
---|
738 | ); |
---|
739 | } |
---|
740 | else{ |
---|
741 | if (!heading_printed) heading(heading_id,heading_name); |
---|
742 | if (strlen(cp) > 16){ |
---|
743 | printf("%s\n", cp); |
---|
744 | cp = ""; |
---|
745 | } |
---|
746 | printf("%-16s%-6s%-12.12s%6d%7d%7d%-2s%7d%7d%7d%-2s\n", |
---|
747 | cp, id_type, id_name, |
---|
748 | kb(rqp->rq_curblocks), |
---|
749 | kb(rqp->rq_bsoftlimit), |
---|
750 | kb(rqp->rq_bhardlimit), |
---|
751 | (btimeleft[0]? "<<" : ""), |
---|
752 | rqp->rq_curfiles, |
---|
753 | rqp->rq_fsoftlimit, |
---|
754 | rqp->rq_fhardlimit, |
---|
755 | (ftimeleft[0]? "<<" : "")); |
---|
756 | } |
---|
757 | } |
---|
758 | } |
---|
759 | |
---|
760 | warn(dir, qvp) |
---|
761 | char *dir; |
---|
762 | register struct getcquota_rslt *qvp; |
---|
763 | { |
---|
764 | struct timeval tv; |
---|
765 | int i; |
---|
766 | char buf[1024], idbuf[20]; |
---|
767 | char *id_name, *id_type; |
---|
768 | struct rcquota *rqp; |
---|
769 | |
---|
770 | id_type = (qvp->rq_group? "Group" : "User"); |
---|
771 | |
---|
772 | gettimeofday(&tv, NULL); |
---|
773 | |
---|
774 | for(i=0; i<qvp->rq_ngrps; i++){ |
---|
775 | |
---|
776 | /* If this is root or wheel, then skip */ |
---|
777 | if (qvp->gqr_rcquota[i].rq_id == 0) continue; |
---|
778 | |
---|
779 | if (qvp->rq_group){ |
---|
780 | getgroupname(qvp->gqr_rcquota[i].rq_id, idbuf); |
---|
781 | id_name = idbuf; |
---|
782 | } |
---|
783 | else{ |
---|
784 | getusername(qvp->gqr_rcquota[i].rq_id, idbuf); |
---|
785 | id_name = idbuf; |
---|
786 | } |
---|
787 | |
---|
788 | rqp = &(qvp->gqr_rcquota[i]); |
---|
789 | |
---|
790 | /* Correct for zero quotas... */ |
---|
791 | if(!rqp->rq_bsoftlimit) |
---|
792 | rqp->rq_bsoftlimit = qvp->gqr_zm.rq_bsoftlimit; |
---|
793 | if(!rqp->rq_bhardlimit) |
---|
794 | rqp->rq_bhardlimit = qvp->gqr_zm.rq_bhardlimit; |
---|
795 | if(!rqp->rq_fsoftlimit) |
---|
796 | rqp->rq_fsoftlimit = qvp->gqr_zm.rq_fsoftlimit; |
---|
797 | if(!rqp->rq_fhardlimit) |
---|
798 | rqp->rq_fhardlimit = qvp->gqr_zm.rq_fhardlimit; |
---|
799 | |
---|
800 | /* Now check for over...*/ |
---|
801 | if(rqp->rq_bhardlimit && |
---|
802 | rqp->rq_curblocks >= rqp->rq_bhardlimit){ |
---|
803 | sprintf(buf, |
---|
804 | "Block limit reached for %s %s on %s\n", |
---|
805 | id_type, id_name, dir); |
---|
806 | putwarning(buf); |
---|
807 | } |
---|
808 | |
---|
809 | else if (rqp->rq_bsoftlimit && |
---|
810 | rqp->rq_curblocks >= rqp->rq_bsoftlimit){ |
---|
811 | if (rqp->rq_btimeleft == 0) { |
---|
812 | sprintf(buf, |
---|
813 | "%s %s over disk quota on %s, remove %dK\n", |
---|
814 | id_type, id_name, dir, |
---|
815 | kb(rqp->rq_curblocks - rqp->rq_bsoftlimit + 1)); |
---|
816 | putwarning(buf); |
---|
817 | } |
---|
818 | else if (rqp->rq_btimeleft > tv.tv_sec) { |
---|
819 | char btimeleft[80]; |
---|
820 | |
---|
821 | fmttime(btimeleft, rqp->rq_btimeleft - tv.tv_sec); |
---|
822 | sprintf(buf, |
---|
823 | "%s %s over disk quota on %s, remove %dK within %s\n", |
---|
824 | id_type, id_name, dir, |
---|
825 | kb(rqp->rq_curblocks - rqp->rq_bsoftlimit + 1), |
---|
826 | btimeleft); |
---|
827 | putwarning(buf); |
---|
828 | } |
---|
829 | else { |
---|
830 | sprintf(buf, |
---|
831 | "%s %s over disk quota on %s, time limit has expired, remove %dK\n", |
---|
832 | id_type, id_name, dir, |
---|
833 | kb(rqp->rq_curblocks - rqp->rq_bsoftlimit + 1)); |
---|
834 | putwarning(buf); |
---|
835 | } |
---|
836 | } |
---|
837 | |
---|
838 | if (rqp->rq_fhardlimit && |
---|
839 | rqp->rq_curfiles >= rqp->rq_fhardlimit){ |
---|
840 | sprintf(buf, |
---|
841 | "File count limit reached for %s %s on %s\n", |
---|
842 | id_type, id_name, dir); |
---|
843 | putwarning(buf); |
---|
844 | } |
---|
845 | |
---|
846 | else if (rqp->rq_fsoftlimit && |
---|
847 | rqp->rq_curfiles >= rqp->rq_fsoftlimit) { |
---|
848 | if (rqp->rq_ftimeleft == 0) { |
---|
849 | sprintf(buf, |
---|
850 | "%s %s over file quota on %s, remove %d file%s\n", |
---|
851 | id_type, id_name, dir, |
---|
852 | rqp->rq_curfiles - rqp->rq_fsoftlimit + 1, |
---|
853 | ((rqp->rq_curfiles - rqp->rq_fsoftlimit + 1) > 1 ? |
---|
854 | "s" : "" )); |
---|
855 | putwarning(buf); |
---|
856 | } |
---|
857 | |
---|
858 | else if (rqp->rq_ftimeleft > tv.tv_sec) { |
---|
859 | char ftimeleft[80]; |
---|
860 | |
---|
861 | fmttime(ftimeleft, rqp->rq_ftimeleft - tv.tv_sec); |
---|
862 | sprintf(buf, |
---|
863 | "%s %s over file quota on %s, remove %d file%s within %s\n", |
---|
864 | id_type, id_name, dir, |
---|
865 | rqp->rq_curfiles - rqp->rq_fsoftlimit + 1, |
---|
866 | ((rqp->rq_curfiles - rqp->rq_fsoftlimit + 1) > 1 ? |
---|
867 | "s" : "" ), ftimeleft); |
---|
868 | putwarning(buf); |
---|
869 | } |
---|
870 | else { |
---|
871 | sprintf(buf, |
---|
872 | "%s %s over file quota on %s, time limit has expired, remove %d file%s\n", |
---|
873 | id_type, id_name, dir, |
---|
874 | rqp->rq_curfiles - rqp->rq_fsoftlimit + 1, |
---|
875 | ((rqp->rq_curfiles - rqp->rq_fsoftlimit + 1) > 1 ? |
---|
876 | "s" : "" )); |
---|
877 | putwarning(buf); |
---|
878 | } |
---|
879 | } |
---|
880 | } |
---|
881 | } |
---|
882 | |
---|
883 | usage() |
---|
884 | { |
---|
885 | fprintf(stderr, |
---|
886 | "Usage: quota [-v] [user] [-g group] [-u user] [-f filesystem]\n"); |
---|
887 | } |
---|
888 | |
---|
889 | alldigits(s) |
---|
890 | register char *s; |
---|
891 | { |
---|
892 | register int c; |
---|
893 | |
---|
894 | c = *s++; |
---|
895 | do { |
---|
896 | if (!isdigit(c)) |
---|
897 | return (0); |
---|
898 | } while (c = *s++); |
---|
899 | return (1); |
---|
900 | } |
---|
901 | |
---|
902 | #if !defined(ultrix) && !defined(_I386) && !defined(_IBMR2) && !defined(SOLARIS) |
---|
903 | dqblk2rcquota(dqblkp, rcquotap, uid) |
---|
904 | struct dqblk *dqblkp; |
---|
905 | struct rcquota *rcquotap; |
---|
906 | int uid; |
---|
907 | { |
---|
908 | rcquotap->rq_id = uid; |
---|
909 | rcquotap->rq_bhardlimit = dqblkp->dqb_bhardlimit; |
---|
910 | rcquotap->rq_bsoftlimit = dqblkp->dqb_bsoftlimit; |
---|
911 | rcquotap->rq_curblocks = dqblkp->dqb_curblocks; |
---|
912 | rcquotap->rq_fhardlimit = dqblkp->dqb_fhardlimit; |
---|
913 | rcquotap->rq_fsoftlimit = dqblkp->dqb_fsoftlimit; |
---|
914 | rcquotap->rq_curfiles = dqblkp->dqb_curfiles; |
---|
915 | rcquotap->rq_btimeleft = dqblkp->dqb_btimelimit; |
---|
916 | rcquotap->rq_ftimeleft = dqblkp->dqb_ftimelimit; |
---|
917 | } |
---|
918 | #endif |
---|
919 | |
---|
920 | getgroupname(id,buffer) |
---|
921 | int id; |
---|
922 | char *buffer; |
---|
923 | { |
---|
924 | if (getgrgid(id)) |
---|
925 | strcpy(buffer, (getgrgid(id))->gr_name); |
---|
926 | else{ |
---|
927 | sprintf(buffer, "G%d", id); |
---|
928 | } |
---|
929 | } |
---|
930 | |
---|
931 | getusername(id,buffer) |
---|
932 | int id; |
---|
933 | char *buffer; |
---|
934 | { |
---|
935 | if (getpwuid(id)) |
---|
936 | strcpy(buffer, (getpwuid(id))->pw_name); |
---|
937 | else{ |
---|
938 | sprintf(buffer, "#%d", id); |
---|
939 | } |
---|
940 | } |
---|
941 | |
---|
942 | putwarning(string) |
---|
943 | char *string; |
---|
944 | { |
---|
945 | static int warningmaxsize = 0; |
---|
946 | |
---|
947 | if (warningstring == 0){ |
---|
948 | warningstring = (char*)malloc(10); |
---|
949 | warningstring[0] = '\0'; |
---|
950 | warningmaxsize = 10; |
---|
951 | } |
---|
952 | |
---|
953 | while (strlen(warningstring) + strlen(string) + 1 > warningmaxsize){ |
---|
954 | warningstring = (char*)realloc(warningstring, (warningmaxsize * 3)/2); |
---|
955 | warningmaxsize = (warningmaxsize * 3) / 2; |
---|
956 | } |
---|
957 | |
---|
958 | sprintf(&warningstring[strlen(warningstring)], "%s", string); |
---|
959 | } |
---|
960 | |
---|
961 | fmttime(buf, time) |
---|
962 | char *buf; |
---|
963 | register long time; |
---|
964 | { |
---|
965 | int i; |
---|
966 | static struct { |
---|
967 | int c_secs; /* conversion units in secs */ |
---|
968 | char * c_str; /* unit string */ |
---|
969 | } cunits [] = { |
---|
970 | {60*60*24*28, "months"}, |
---|
971 | {60*60*24*7, "weeks"}, |
---|
972 | {60*60*24, "days"}, |
---|
973 | {60*60, "hours"}, |
---|
974 | {60, "mins"}, |
---|
975 | {1, "secs"} |
---|
976 | }; |
---|
977 | |
---|
978 | if (time <= 0) { |
---|
979 | strcpy(buf, "EXPIRED"); |
---|
980 | return; |
---|
981 | } |
---|
982 | for (i = 0; i < sizeof(cunits)/sizeof(cunits[0]); i++) { |
---|
983 | if (time >= cunits[i].c_secs) |
---|
984 | break; |
---|
985 | } |
---|
986 | sprintf(buf, "%.1f %s", (double)time/cunits[i].c_secs, cunits[i].c_str); |
---|
987 | } |
---|
988 | |
---|
989 | #ifdef SOLARIS |
---|
990 | verify_filesystems() |
---|
991 | { |
---|
992 | } |
---|
993 | #else |
---|
994 | #ifdef _IBMR2 |
---|
995 | verify_filesystems() |
---|
996 | { |
---|
997 | int i, j, found, l; |
---|
998 | int mntsize; |
---|
999 | char *mntbuf; |
---|
1000 | int nmount; |
---|
1001 | struct vmount *vmt; |
---|
1002 | struct _attachtab *atp; |
---|
1003 | |
---|
1004 | mntsize = 4096; |
---|
1005 | if ((mntbuf = (char *)malloc(mntsize)) == NULL) { |
---|
1006 | perror("quota: error allocating memory"); |
---|
1007 | exit(9); |
---|
1008 | } |
---|
1009 | nmount = mntctl(MCTL_QUERY,mntsize,mntbuf); |
---|
1010 | if (nmount == -1) { |
---|
1011 | perror("quota: mntctl failed"); |
---|
1012 | exit(9); |
---|
1013 | } |
---|
1014 | if (nmount == 0) { |
---|
1015 | mntsize = *((int *) mntbuf); |
---|
1016 | if ((mntbuf = (char *)realloc(mntbuf, mntsize)) == NULL) { |
---|
1017 | perror("quota: error reallocing memory"); |
---|
1018 | exit(9); |
---|
1019 | } |
---|
1020 | nmount = mntctl(MCTL_QUERY,mntsize,mntbuf); |
---|
1021 | if (nmount == -1) { |
---|
1022 | perror("quota: mntctl failed"); |
---|
1023 | exit(9); |
---|
1024 | } |
---|
1025 | } |
---|
1026 | |
---|
1027 | for(i=0;i<fsind;i++){ |
---|
1028 | l = strlen(fslist[i]); |
---|
1029 | found = 0; |
---|
1030 | vmt = (struct vmount *)mntbuf; |
---|
1031 | for(j=0;j<nmount;j++) { |
---|
1032 | if (!strncmp(fslist[i], |
---|
1033 | (char *)vmt+vmt->vmt_data[VMT_STUB].vmt_off,l)) { |
---|
1034 | found = 1; |
---|
1035 | break; |
---|
1036 | } |
---|
1037 | vmt = (struct vmount *)((char *)vmt + vmt->vmt_length); |
---|
1038 | } |
---|
1039 | if (!found && (atp = attachtab_lookup(fslist[i]))) { |
---|
1040 | fslist[i] = atp->mntpt; |
---|
1041 | found = 1; |
---|
1042 | break; |
---|
1043 | } |
---|
1044 | if (!found && (attachtab_lookup_mntpt(fslist[i]) == NULL)) { |
---|
1045 | fprintf(stderr, "quota: '%s' matches no mounted filesystems.\n", |
---|
1046 | fslist[i]); |
---|
1047 | exit(10); |
---|
1048 | } |
---|
1049 | } |
---|
1050 | } |
---|
1051 | |
---|
1052 | #else /* _IBMR2 */ |
---|
1053 | |
---|
1054 | verify_filesystems() |
---|
1055 | { |
---|
1056 | struct _attachtab *atp; |
---|
1057 | struct mntent *mntp; |
---|
1058 | FILE *mtab; |
---|
1059 | int i,l, found; |
---|
1060 | #ifdef ultrix |
---|
1061 | int loc=0, ret; |
---|
1062 | #endif |
---|
1063 | |
---|
1064 | for(i=0;i<fsind;i++){ |
---|
1065 | l = strlen(fslist[i]); |
---|
1066 | found = 0; |
---|
1067 | #ifndef ultrix |
---|
1068 | mtab = setmntent(MOUNTED, "r"); |
---|
1069 | #else |
---|
1070 | ret = getmountent(&loc, mountbuffer, NMOUNT); |
---|
1071 | if (ret == 0) { |
---|
1072 | perror("getmountent"); |
---|
1073 | exit(3); |
---|
1074 | } |
---|
1075 | #endif |
---|
1076 | |
---|
1077 | #ifndef ultrix |
---|
1078 | while(mntp = getmntent(mtab)) |
---|
1079 | #else |
---|
1080 | for(mntp = mountbuffer; mntp < &mountbuffer[ret]; mntp++) |
---|
1081 | #endif |
---|
1082 | { |
---|
1083 | if (!strncmp(fslist[i], mntp->mnt_dir,l)){ |
---|
1084 | found = 1; |
---|
1085 | break; |
---|
1086 | } |
---|
1087 | } |
---|
1088 | #ifndef ultrix |
---|
1089 | endmntent(mtab); |
---|
1090 | #endif |
---|
1091 | if (!found && (atp = attachtab_lookup(fslist[i]))) { |
---|
1092 | fslist[i] = atp->mntpt; |
---|
1093 | found = 1; |
---|
1094 | break; |
---|
1095 | } |
---|
1096 | if (!found && (attachtab_lookup_mntpt(fslist[i]) == NULL)) { |
---|
1097 | fprintf(stderr, "quota: '%s' matches no mounted filesystems.\n", |
---|
1098 | fslist[i]); |
---|
1099 | exit(10); |
---|
1100 | } |
---|
1101 | } |
---|
1102 | } |
---|
1103 | #endif /* IBMR2 */ |
---|
1104 | #endif /* SOLARIS */ |
---|
1105 | |
---|
1106 | #if defined(_I386) || defined(ultrix) |
---|
1107 | ultprintquotas(uid, name) |
---|
1108 | int uid; |
---|
1109 | char *name; |
---|
1110 | { |
---|
1111 | register char c, *p; |
---|
1112 | register struct fstab *fs; |
---|
1113 | int myuid; |
---|
1114 | #ifdef _I386 |
---|
1115 | FILE *fptr; |
---|
1116 | struct mntent *buf; |
---|
1117 | #endif |
---|
1118 | |
---|
1119 | myuid = getuid(); |
---|
1120 | if (uid != myuid && myuid != 0) { |
---|
1121 | printf("quota: %s (uid %d): permission denied\n", name, uid); |
---|
1122 | return; |
---|
1123 | } |
---|
1124 | done = 0; |
---|
1125 | #ifdef ultrix |
---|
1126 | setfsent(); |
---|
1127 | while (fs = getfsent()) { |
---|
1128 | #else |
---|
1129 | /* Deal with FSTAB */ |
---|
1130 | fptr = setmntent("/etc/mtab","r"); |
---|
1131 | while((buf = getmntent(fptr)) != NULL) { |
---|
1132 | dev_t qf_gfs; |
---|
1133 | #endif |
---|
1134 | register char *msgi = (char *)0, *msgb = (char *)0; |
---|
1135 | register int enab = 1; |
---|
1136 | dev_t fsdev; |
---|
1137 | struct stat statb; |
---|
1138 | struct dqblk dqblk; |
---|
1139 | char qfilename[MAXPATHLEN + 1], iwarn[8], dwarn[8]; |
---|
1140 | char *vol; |
---|
1141 | |
---|
1142 | #ifdef _I386 |
---|
1143 | if (hasmntopt(buf, MNTOPT_QUOTA) == NULL) |
---|
1144 | continue; |
---|
1145 | vol = buf->mnt_dir; |
---|
1146 | (void) sprintf(qfilename, "%s/%s", buf->mnt_dir, QFNAME); |
---|
1147 | if (stat(qfilename, &statb) < 0) |
---|
1148 | continue; |
---|
1149 | qf_gfs = buf->mnt_gfs; |
---|
1150 | if (quota(Q_SYNC, 0, (gfs_t) qf_gfs, (caddr_t) 0) < 0 && errno == EINVAL) |
---|
1151 | continue; |
---|
1152 | sync(); |
---|
1153 | if (quota(Q_GETDLIM, uid, qf_gfs, (caddr_t) &dqblk) != 0) |
---|
1154 | #else |
---|
1155 | if (stat(fs->fs_spec, &statb) < 0) |
---|
1156 | continue; |
---|
1157 | fsdev = statb.st_rdev; |
---|
1158 | vol = fs->fs_file; |
---|
1159 | (void) sprintf(qfilename, "%s/%s", fs->fs_file, QFNAME); |
---|
1160 | if (stat(qfilename, &statb) < 0 || statb.st_dev != fsdev) |
---|
1161 | continue; |
---|
1162 | if (quota(Q_GETDLIM, uid, fsdev, &dqblk) != 0) |
---|
1163 | #endif |
---|
1164 | { |
---|
1165 | register fd = open(qfilename, O_RDONLY); |
---|
1166 | |
---|
1167 | if (fd < 0) |
---|
1168 | continue; |
---|
1169 | lseek(fd, (long)(uid * sizeof (dqblk)), L_SET); |
---|
1170 | if (read(fd, &dqblk, sizeof dqblk) != sizeof (dqblk)) { |
---|
1171 | close(fd); |
---|
1172 | continue; |
---|
1173 | } |
---|
1174 | close(fd); |
---|
1175 | if (dqblk.dqb_isoftlimit == 0 && |
---|
1176 | dqblk.dqb_bsoftlimit == 0) |
---|
1177 | continue; |
---|
1178 | enab = 0; |
---|
1179 | } |
---|
1180 | if (dqblk.dqb_ihardlimit && |
---|
1181 | dqblk.dqb_curinodes >= dqblk.dqb_ihardlimit) |
---|
1182 | msgi = "File count limit reached on %s"; |
---|
1183 | else if (enab && dqblk.dqb_iwarn == 0) |
---|
1184 | msgi = "Out of inode warnings on %s"; |
---|
1185 | else if (dqblk.dqb_isoftlimit && |
---|
1186 | dqblk.dqb_curinodes >= dqblk.dqb_isoftlimit) |
---|
1187 | msgi = "Too many files on %s"; |
---|
1188 | if (dqblk.dqb_bhardlimit && |
---|
1189 | dqblk.dqb_curblocks >= dqblk.dqb_bhardlimit) |
---|
1190 | msgb = "Block limit reached on %s"; |
---|
1191 | else if (enab && dqblk.dqb_bwarn == 0) |
---|
1192 | msgb = "Out of block warnings on %s"; |
---|
1193 | else if (dqblk.dqb_bsoftlimit && |
---|
1194 | dqblk.dqb_curblocks >= dqblk.dqb_bsoftlimit) |
---|
1195 | msgb = "Over disc quota on %s"; |
---|
1196 | if (dqblk.dqb_iwarn < MAX_IQ_WARN) |
---|
1197 | sprintf(iwarn, "%d", dqblk.dqb_iwarn); |
---|
1198 | else |
---|
1199 | iwarn[0] = '\0'; |
---|
1200 | if (dqblk.dqb_bwarn < MAX_DQ_WARN) |
---|
1201 | sprintf(dwarn, "%d", dqblk.dqb_bwarn); |
---|
1202 | else |
---|
1203 | dwarn[0] = '\0'; |
---|
1204 | if (qflag) { |
---|
1205 | if (msgi != (char *)0 || msgb != (char *)0) |
---|
1206 | ultheading(uid, name); |
---|
1207 | if (msgi != (char *)0) |
---|
1208 | xprintf(msgi, vol); |
---|
1209 | if (msgb != (char *)0) |
---|
1210 | xprintf(msgb, vol); |
---|
1211 | continue; |
---|
1212 | } |
---|
1213 | if (vflag || dqblk.dqb_curblocks || dqblk.dqb_curinodes) { |
---|
1214 | ultheading(uid, name); |
---|
1215 | printf("%10s%8d%c%7d%8d%8s%8d%c%7d%8d%8s\n" |
---|
1216 | , vol |
---|
1217 | , (dqblk.dqb_curblocks / btodb(1024)) |
---|
1218 | , (msgb == (char *)0) ? ' ' : '*' |
---|
1219 | , (dqblk.dqb_bsoftlimit / btodb(1024)) |
---|
1220 | , (dqblk.dqb_bhardlimit / btodb(1024)) |
---|
1221 | , dwarn |
---|
1222 | , dqblk.dqb_curinodes |
---|
1223 | , (msgi == (char *)0) ? ' ' : '*' |
---|
1224 | , dqblk.dqb_isoftlimit |
---|
1225 | , dqblk.dqb_ihardlimit |
---|
1226 | , iwarn |
---|
1227 | ); |
---|
1228 | } |
---|
1229 | } |
---|
1230 | #ifdef _I386 |
---|
1231 | endmntent(fptr); |
---|
1232 | #else |
---|
1233 | endfsent(); |
---|
1234 | #endif |
---|
1235 | if (!done && !qflag) { |
---|
1236 | if (idind) |
---|
1237 | putchar('\n'); |
---|
1238 | xprintf("Disc quotas for %s (uid %d):", name, uid); |
---|
1239 | xprintf("none."); |
---|
1240 | } |
---|
1241 | xprintf(0); |
---|
1242 | } |
---|
1243 | |
---|
1244 | ultheading(uid, name) |
---|
1245 | int uid; |
---|
1246 | char *name; |
---|
1247 | { |
---|
1248 | |
---|
1249 | if (done++) |
---|
1250 | return; |
---|
1251 | xprintf(0); |
---|
1252 | if (qflag) { |
---|
1253 | if (!idind) |
---|
1254 | return; |
---|
1255 | xprintf("User %s (uid %d):", name, uid); |
---|
1256 | xprintf(0); |
---|
1257 | return; |
---|
1258 | } |
---|
1259 | putchar('\n'); |
---|
1260 | #if 0 |
---|
1261 | xprintf("Disc quotas for %s (uid %d):", name, uid); |
---|
1262 | #endif |
---|
1263 | xprintf(0); |
---|
1264 | printf("%10s%8s %7s%8s%8s%8s %7s%8s%8s\n" |
---|
1265 | , "Filsys" |
---|
1266 | , "current" |
---|
1267 | , "quota" |
---|
1268 | , "limit" |
---|
1269 | , "#warns" |
---|
1270 | , "files" |
---|
1271 | , "quota" |
---|
1272 | , "limit" |
---|
1273 | , "#warns" |
---|
1274 | ); |
---|
1275 | } |
---|
1276 | |
---|
1277 | xprintf(fmt, arg1, arg2, arg3, arg4, arg5, arg6) |
---|
1278 | char *fmt; |
---|
1279 | { |
---|
1280 | char buf[100]; |
---|
1281 | static int column; |
---|
1282 | |
---|
1283 | if (fmt == 0 && column || column >= 40) { |
---|
1284 | putchar('\n'); |
---|
1285 | column = 0; |
---|
1286 | } |
---|
1287 | if (fmt == 0) |
---|
1288 | return; |
---|
1289 | sprintf(buf, fmt, arg1, arg2, arg3, arg4, arg5, arg6); |
---|
1290 | if (column != 0 && strlen(buf) < 39) |
---|
1291 | while (column++ < 40) |
---|
1292 | putchar(' '); |
---|
1293 | else if (column) { |
---|
1294 | putchar('\n'); |
---|
1295 | column = 0; |
---|
1296 | } |
---|
1297 | printf("%s", buf); |
---|
1298 | column += strlen(buf); |
---|
1299 | } |
---|
1300 | #endif /* _I386 || ultrix */ |
---|