WIP: the last missing piece of the quota64 puzzle. Not quite there
yet.
This commit is contained in:
parent
46d2decf1a
commit
9dc9c85fe9
@ -36,20 +36,9 @@ static void rquota_service(struct svc_req *request, SVCXPRT *transp);
|
||||
static void sendquota(struct svc_req *request, SVCXPRT *transp);
|
||||
static void initfs(void);
|
||||
static int getfsquota(long id, char *path, struct dqblk *dqblk);
|
||||
static int hasquota(struct fstab *fs, char **qfnamep);
|
||||
|
||||
/*
|
||||
* structure containing informations about ufs filesystems
|
||||
* initialised by initfs()
|
||||
*/
|
||||
struct fs_stat {
|
||||
struct fs_stat *fs_next; /* next element */
|
||||
char *fs_file; /* mount point of the filesystem */
|
||||
char *qfpathname; /* pathname of the quota file */
|
||||
dev_t st_dev; /* device of the filesystem */
|
||||
} fs_stat;
|
||||
static struct fs_stat *fs_begin = NULL;
|
||||
|
||||
static struct quotafile **qfa; /* array of qfs */
|
||||
static int nqf, szqf; /* number of qfs and size of array */
|
||||
static int from_inetd = 1;
|
||||
|
||||
static void
|
||||
@ -75,9 +64,7 @@ main(void)
|
||||
|
||||
if (!from_inetd) {
|
||||
daemon(0, 0);
|
||||
|
||||
(void)rpcb_unset(RQUOTAPROG, RQUOTAVERS, NULL);
|
||||
|
||||
(void)signal(SIGINT, cleanup);
|
||||
(void)signal(SIGTERM, cleanup);
|
||||
(void)signal(SIGHUP, cleanup);
|
||||
@ -119,12 +106,10 @@ rquota_service(struct svc_req *request, SVCXPRT *transp)
|
||||
case NULLPROC:
|
||||
(void)svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL);
|
||||
break;
|
||||
|
||||
case RQUOTAPROC_GETQUOTA:
|
||||
case RQUOTAPROC_GETACTIVEQUOTA:
|
||||
sendquota(request, transp);
|
||||
break;
|
||||
|
||||
default:
|
||||
svcerr_noproc(transp);
|
||||
break;
|
||||
@ -183,39 +168,39 @@ sendquota(struct svc_req *request, SVCXPRT *transp)
|
||||
}
|
||||
}
|
||||
|
||||
/* initialise the fs_tab list from entries in /etc/fstab */
|
||||
static void
|
||||
initfs(void)
|
||||
{
|
||||
struct fs_stat *fs_current = NULL;
|
||||
struct fs_stat *fs_next = NULL;
|
||||
char *qfpathname;
|
||||
struct fstab *fs;
|
||||
struct stat st;
|
||||
|
||||
setfsent();
|
||||
szqf = 8;
|
||||
if ((qfa = malloc(szqf * sizeof *qfa)) == NULL)
|
||||
goto enomem;
|
||||
while ((fs = getfsent())) {
|
||||
if (strcmp(fs->fs_vfstype, "ufs"))
|
||||
continue;
|
||||
if (!hasquota(fs, &qfpathname))
|
||||
if (nqf >= szqf) {
|
||||
szqf *= 2;
|
||||
if ((qfa = reallocf(qfa, szqf * sizeof *qfa)) == NULL)
|
||||
goto enomem;
|
||||
}
|
||||
if ((qfa[nqf] = quota_open(fs, USRQUOTA, O_RDONLY)) == NULL) {
|
||||
if (errno != EOPNOTSUPP)
|
||||
goto fserr;
|
||||
continue;
|
||||
|
||||
fs_current = malloc(sizeof(struct fs_stat));
|
||||
fs_current->fs_next = fs_next; /* next element */
|
||||
|
||||
fs_current->fs_file = malloc(strlen(fs->fs_file) + 1);
|
||||
strcpy(fs_current->fs_file, fs->fs_file);
|
||||
|
||||
fs_current->qfpathname = malloc(strlen(qfpathname) + 1);
|
||||
strcpy(fs_current->qfpathname, qfpathname);
|
||||
|
||||
stat(fs_current->fs_file, &st);
|
||||
fs_current->st_dev = st.st_dev;
|
||||
|
||||
fs_next = fs_current;
|
||||
}
|
||||
++nqf;
|
||||
/* XXX */
|
||||
}
|
||||
endfsent();
|
||||
fs_begin = fs_current;
|
||||
return;
|
||||
enomem:
|
||||
syslog(LOG_ERR, "out of memory");
|
||||
exit(1);
|
||||
fserr:
|
||||
syslog(LOG_ERR, "%s: %s", fs->fs_file, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -225,70 +210,10 @@ initfs(void)
|
||||
static int
|
||||
getfsquota(long id, char *path, struct dqblk *dqblk)
|
||||
{
|
||||
struct quotafile *qf;
|
||||
struct stat st_path;
|
||||
struct fs_stat *fs;
|
||||
int qcmd, ret = 0;
|
||||
int i;
|
||||
|
||||
if (stat(path, &st_path) < 0)
|
||||
return (0);
|
||||
|
||||
qcmd = QCMD(Q_GETQUOTA, USRQUOTA);
|
||||
|
||||
for (fs = fs_begin; fs != NULL; fs = fs->fs_next) {
|
||||
/* where the device is the same as path */
|
||||
if (fs->st_dev != st_path.st_dev)
|
||||
continue;
|
||||
|
||||
/* find the specified filesystem. get and return quota */
|
||||
if (quotactl(fs->fs_file, qcmd, id, dqblk) == 0)
|
||||
return (1);
|
||||
|
||||
if ((qf = quota_open(fs->qfpathname)) == NULL) {
|
||||
syslog(LOG_ERR, "open error: %s: %m", fs->qfpathname);
|
||||
return (0);
|
||||
}
|
||||
if (quota_read(qf, dqblk, id) != 0) {
|
||||
syslog(LOG_ERR, "read error: %s: %m", fs->qfpathname);
|
||||
quota_close(qf);
|
||||
return (0);
|
||||
}
|
||||
quota_close(qf);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if a particular quota is to be enabled.
|
||||
* Comes from quota.c, NetBSD 0.9
|
||||
*/
|
||||
static int
|
||||
hasquota(struct fstab *fs, char **qfnamep)
|
||||
{
|
||||
static char initname, usrname[100];
|
||||
static char buf[BUFSIZ];
|
||||
char *opt, *cp;
|
||||
const char *qfextension[] = INITQFNAMES;
|
||||
|
||||
if (!initname) {
|
||||
sprintf(usrname, "%s%s", qfextension[USRQUOTA], QUOTAFILENAME);
|
||||
initname = 1;
|
||||
}
|
||||
strcpy(buf, fs->fs_mntops);
|
||||
for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) {
|
||||
if ((cp = index(opt, '=')))
|
||||
*cp++ = '\0';
|
||||
if (strcmp(opt, usrname) == 0)
|
||||
break;
|
||||
}
|
||||
if (!opt)
|
||||
return (0);
|
||||
if (cp) {
|
||||
*qfnamep = cp;
|
||||
return (1);
|
||||
}
|
||||
sprintf(buf, "%s/%s.%s", fs->fs_file, QUOTAFILENAME,
|
||||
qfextension[USRQUOTA]);
|
||||
*qfnamep = buf;
|
||||
return (1);
|
||||
for (i = 0; i < nqf; ++i)
|
||||
if (quota_check_path(qfa[i], path) == 1)
|
||||
return (quota_read(qfa[i], dqblk, id) == 0);
|
||||
return (0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user