* Copyright (c) 1991 The Regents of the University of California.
* %sccs.include.proprietary.c%
"@(#) Copyright (c) 1991 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)quot.c 5.3 (Berkeley) %G%";
#include <ufs/ufs/dinode.h>
#define ISIZ (MAXBSIZE/sizeof(struct dinode))
#define sblock sb_un.u_sblock
struct dinode itab
[MAXBSIZE
/sizeof(struct dinode
)];
#define DUHASH 8209 /* smallest prime >= 4 * NDU */
#define HASH(u) ((u) % DUHASH)
struct du
*duhash
[DUHASH
];
while ((ch
= getopt(argc
, argv
, "cfhnv")) != EOF
)
case 'h': /* undocumented */
case 'v': /* undocumented */
fputs("usage: quot [-cfn] [filesystem ...]\n", stderr
);
(void)gettimeofday(&now
, NULL
);
if (check(*argv
, (char *)NULL
) == 0)
register struct fstab
*fs
;
char dev
[MAXNAMLEN
+ 10], *rindex();
while (fs
= getfsent()) {
if (strcmp(fs
->fs_vfstype
, "ufs") ||
(strcmp(fs
->fs_type
, FSTAB_RO
) &&
strcmp(fs
->fs_type
, FSTAB_RW
) &&
strcmp(fs
->fs_type
, FSTAB_RQ
)))
cp
= rindex(fs
->fs_spec
, '/');
(void)sprintf(dev
, "%s/r%s", _PATH_DEV
, cp
+ 1);
if (check(dev
, fs
->fs_file
) == 0)
register int i
, j
, nfiles
;
* Initialize tables between checks; because of the qsort done in
* report() the hash tables must be rebuilt each time.
for (i
= 0; i
< TSIZE
; i
++)
for (dp
= duhash
; dp
< &duhash
[DUHASH
]; dp
++)
fd
= open(file
, O_RDONLY
);
fprintf(stderr
, "quot: ");
register struct fstab
*fs
= getfsspec(file
);
if (fsdir
!= NULL
&& *fsdir
!= '\0')
bread(fd
, (off_t
)SBOFF
, (char *)&sblock
, SBSIZE
);
dev_bsize
= sblock
.fs_fsize
/ fsbtodb(&sblock
, 1);
if (isdigit(c
= getchar()))
else while (c
!= '\n' && c
!= EOF
)
nfiles
= sblock
.fs_ipg
* sblock
.fs_ncg
;
for (ino
= 0; ino
< nfiles
; ) {
iblk
= fsbtodb(&sblock
, itod(&sblock
, ino
));
bread(fd
, (off_t
)iblk
* dev_bsize
, itab
, (int)sblock
.fs_bsize
);
for (j
= 0; j
< INOPB(&sblock
) && ino
< nfiles
; j
++, ino
++) {
register struct dinode
*ip
;
if ((ip
->di_mode
& IFMT
) == 0)
* By default, take block count in inode. Otherwise (-h),
* take the size field and estimate the blocks allocated.
* The latter does not account for holes in files.
size
= ip
->di_blocks
/ 2;
blks
= lblkno(&sblock
, ip
->di_size
);
frags
= blks
* sblock
.fs_frag
+
numfrags(&sblock
, dblksize(&sblock
, ip
, blks
));
size
= frags
* sblock
.fs_fsize
/ 1024;
if ((ip
->di_mode
&IFMT
) != IFDIR
&& (ip
->di_mode
&IFMT
) != IFREG
)
hp
= &duhash
[HASH(ip
->di_uid
)];
for (dp
= *hp
; dp
; dp
= dp
->next
)
if (dp
->uid
== ip
->di_uid
)
#define DAY (60 * 60 * 24) /* seconds per day */
if (now
.tv_sec
- ip
->di_atime
.ts_sec
> 30 * DAY
)
if (now
.tv_sec
- ip
->di_atime
.ts_sec
> 60 * DAY
)
if (now
.tv_sec
- ip
->di_atime
.ts_sec
> 90 * DAY
)
if (scanf("%d", &fino
) <= 0)
while ((n
= getchar()) != '\n' && n
!= EOF
)
if (np
= user_from_uid(dp
->uid
, 1))
printf("%u\t", ip
->di_uid
);
while ((n
= getchar()) == ' ' || n
== '\t')
while (n
!= EOF
&& n
!= '\n') {
(void)lseek(fd
, bno
, L_SET
);
if (read(fd
, buf
, cnt
) != cnt
) {
fprintf(stderr
, "quot: read error at block %ld\n", bno
);
register struct du
*p1
, *p2
;
if (p1
->blocks
> p2
->blocks
)
if (p1
->blocks
< p2
->blocks
)
s1
= user_from_uid(p1
->uid
, 1);
s2
= user_from_uid(p2
->uid
, 1);
for (i
= 0; i
< TSIZE
- 1; i
++)
printf("%d\t%d\t%ld\n", i
, sizes
[i
], t
);
TSIZE
- 1, sizes
[TSIZE
- 1], overflow
+ t
);
qsort(du
, ndu
, sizeof (du
[0]), qcmp
);
for (dp
= du
; dp
< &du
[ndu
]; dp
++) {
printf("%5D\t", dp
->blocks
);
printf("%5D\t", dp
->nfiles
);
if (cp
= user_from_uid(dp
->uid
, 1))
printf("#%-8d", dp
->uid
);
printf("\t%5D\t%5D\t%5D",
dp
->blocks30
, dp
->blocks60
, dp
->blocks90
);