1 static char *device_name();
4 #include <sys/fs/ufs_quota.h>
7 * define the "quotactl" function as in Solaris 1, based on ioctl().
8 * By Marc Mazuhelli <mazu@dmi.usherb.ca>
9 * The "special" parameter is any file on the file system,
10 * not the block special device name as in Solaris 1.
11 * Thanks to veronica@solution.maths.unsw.edu.au who provided
12 * the idea and the basis for this function.
14 * [ Apparently quotactl used to exist in SunOS but no longer exists in ]
15 * [ Solaris. This is an equivalent. If you are running on a system ]
16 * [ which has quotactl, comment this routine out or use sunquota. ]
20 quotactl(int cmd, char *special, uid_t uid, struct dqblk * addr)
23 int fd = open(special, O_RDONLY);
30 op.addr = (caddr_t) addr;
32 if (ioctl(fd, Q_QUOTACTL, &op) < 0) {
41 /*----------------------------------------------------------------------
42 Return space left in disk quota on file system which given path is in.
44 Args: path - Path name of file or directory on file system of concern
45 over - pointer to flag that is set if the user is over quota
47 Returns: If *over = 0, the number of bytes free in disk quota as per
49 If *over = 1, the number of bytes *over* quota.
50 -1 is returned on an error looking up quota
51 0 is returned if there is no quota
53 BUG: If there's more than 2.1Gb free this function will break
56 disk_quota(path, over)
60 static int no_quota = 0;
67 return(0L); /* If no quota the first time, then none the second. */
69 dprint(5, (debugfile, "quota_check path: %s\n", path ? path : "?"));
70 if(stat(path, &statx) < 0) {
77 dname = device_name(statx.st_dev);
81 dprint(7, (debugfile, "Quota check: UID:%d device: %s\n",
82 getuid(), dname ? dname : "?"));
83 if(quotactl(Q_GETQUOTA, dname, getuid(), (char *)"ax) < 0) {
84 dprint(5, (debugfile, "Quota failed : %s\n",
85 error_description(errno)));
86 return(-1L); /* Something went wrong */
89 dprint(5,(debugfile,"Quota: bsoftlimit:%d bhardlimit:%d curblock:%d\n",
90 quotax.dqb_bsoftlimit, quotax.dqb_bhardlimit, quotax.dqb_curblocks));
92 if(quotax.dqb_bsoftlimit == -1)
95 q = (quotax.dqb_bsoftlimit - quotax.dqb_curblocks) * 512;
101 dprint(5, (debugfile, "disk_quota returning :%d, over:%d\n", q, *over));
106 /*----------------------------------------------------------------------
109 * This routine is here so that ex can get a device name to check
110 * disk quotas. One might wonder, why not use getmntent(), rather
111 * than read /etc/mtab in this crude way? The problem with getmntent
112 * is that it uses stdio, and ex/vi pointedly doesn't.
115 *device_name(st_devArg)
119 #define MTABNAME "/etc/mtab"
122 static char devName[48];
123 static char *answer = (char *) 0;
130 if (st_devArg == st_dev)
133 mtab = read_file(MTABNAME);
135 return((char *)NULL);
137 /* Initialize save data. */
142 for (cur=bol=0, dname=1; cur < nb; ++cur) {
144 if (dname && (mtab[cur] <= ' ')) {
145 /* Space, tab or other such character has been found,
146 presumably marking the end of the device name string. */
149 c = mtab[cur]; /* Save current character. */
150 mtab[cur] = 0; /* C zero-terminated string. */
152 /* Get device number, via stat(). If it's the right
153 number, copy the string and return its address. */
154 if (stat (&mtab[bol], &devStat) == 0) {
155 if (devStat.st_rdev == st_dev) {
156 if ((cur - bol + 1) < sizeof (devName)) {
157 strncpy (devName, &mtab[bol], sizeof(devName));
158 devName[sizeof(devName)-1] = '\0';
159 answer = &devName[0];
166 if (mtab[cur] == '\n') {