diff options
Diffstat (limited to 'libexec/rpc.rquotad/rquotad.c')
-rw-r--r-- | libexec/rpc.rquotad/rquotad.c | 331 |
1 files changed, 0 insertions, 331 deletions
diff --git a/libexec/rpc.rquotad/rquotad.c b/libexec/rpc.rquotad/rquotad.c deleted file mode 100644 index 33fa420b17f4e..0000000000000 --- a/libexec/rpc.rquotad/rquotad.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * by Manuel Bouyer (bouyer@ensta.fr) - * - * There is no copyright, you can use it as you want. - */ - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/mount.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <signal.h> - -#include <stdio.h> -#include <fstab.h> -#include <ctype.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <pwd.h> -#include <grp.h> -#include <errno.h> - -#include <syslog.h> -#include <varargs.h> - -#include <ufs/ufs/quota.h> -#include <rpc/rpc.h> -#include <rpc/pmap_clnt.h> -#include <rpcsvc/rquota.h> -#include <arpa/inet.h> - -void rquota_service __P((struct svc_req *request, SVCXPRT *transp)); -void sendquota __P((struct svc_req *request, SVCXPRT *transp)); -void printerr_reply __P((SVCXPRT *transp)); -void initfs __P((void)); -int getfsquota __P((long id, char *path, struct dqblk *dqblk)); -int hasquota __P((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; -struct fs_stat *fs_begin = NULL; - -int from_inetd = 1; - -void -cleanup() -{ - (void) pmap_unset(RQUOTAPROG, RQUOTAVERS); - exit(0); -} - -int -main(argc, argv) - int argc; - char *argv[]; -{ - SVCXPRT *transp; - int sock = 0; - int proto = 0; - struct sockaddr_in from; - int fromlen; - - fromlen = sizeof(from); - if (getsockname(0, (struct sockaddr *)&from, &fromlen) < 0) { - from_inetd = 0; - sock = RPC_ANYSOCK; - proto = IPPROTO_UDP; - } - - if (!from_inetd) { - daemon(0, 0); - - (void) pmap_unset(RQUOTAPROG, RQUOTAVERS); - - (void) signal(SIGINT, cleanup); - (void) signal(SIGTERM, cleanup); - (void) signal(SIGHUP, cleanup); - } - - openlog("rpc.rquotad", LOG_CONS|LOG_PID, LOG_DAEMON); - - /* create and register the service */ - transp = svcudp_create(sock); - if (transp == NULL) { - syslog(LOG_ERR, "couldn't create udp service."); - exit(1); - } - if (!svc_register(transp, RQUOTAPROG, RQUOTAVERS, rquota_service, proto)) { - syslog(LOG_ERR, "unable to register (RQUOTAPROG, RQUOTAVERS, %s).", proto?"udp":"(inetd)"); - exit(1); - } - - initfs(); /* init the fs_stat list */ - svc_run(); - syslog(LOG_ERR, "svc_run returned"); - exit(1); -} - -void -rquota_service(request, transp) - struct svc_req *request; - SVCXPRT *transp; -{ - switch (request->rq_proc) { - case NULLPROC: - (void)svc_sendreply(transp, xdr_void, (char *)NULL); - break; - - case RQUOTAPROC_GETQUOTA: - case RQUOTAPROC_GETACTIVEQUOTA: - sendquota(request, transp); - break; - - default: - svcerr_noproc(transp); - break; - } - if (from_inetd) - exit(0); -} - -/* read quota for the specified id, and send it */ -void -sendquota(request, transp) - struct svc_req *request; - SVCXPRT *transp; -{ - struct getquota_args getq_args; - struct getquota_rslt getq_rslt; - struct dqblk dqblk; - struct timeval timev; - - bzero((char *)&getq_args, sizeof(getq_args)); - if (!svc_getargs(transp, xdr_getquota_args, (caddr_t)&getq_args)) { - svcerr_decode(transp); - return; - } - if (request->rq_cred.oa_flavor != AUTH_UNIX) { - /* bad auth */ - getq_rslt.status = Q_EPERM; - } else if (!getfsquota(getq_args.gqa_uid, getq_args.gqa_pathp, &dqblk)) { - /* failed, return noquota */ - getq_rslt.status = Q_NOQUOTA; - } else { - gettimeofday(&timev, NULL); - getq_rslt.status = Q_OK; - getq_rslt.getquota_rslt_u.gqr_rquota.rq_active = TRUE; - getq_rslt.getquota_rslt_u.gqr_rquota.rq_bsize = DEV_BSIZE; - getq_rslt.getquota_rslt_u.gqr_rquota.rq_bhardlimit = - dqblk.dqb_bhardlimit; - getq_rslt.getquota_rslt_u.gqr_rquota.rq_bsoftlimit = - dqblk.dqb_bsoftlimit; - getq_rslt.getquota_rslt_u.gqr_rquota.rq_curblocks = - dqblk.dqb_curblocks; - getq_rslt.getquota_rslt_u.gqr_rquota.rq_fhardlimit = - dqblk.dqb_ihardlimit; - getq_rslt.getquota_rslt_u.gqr_rquota.rq_fsoftlimit = - dqblk.dqb_isoftlimit; - getq_rslt.getquota_rslt_u.gqr_rquota.rq_curfiles = - dqblk.dqb_curinodes; - getq_rslt.getquota_rslt_u.gqr_rquota.rq_btimeleft = - dqblk.dqb_btime - timev.tv_sec; - getq_rslt.getquota_rslt_u.gqr_rquota.rq_ftimeleft = - dqblk.dqb_itime - timev.tv_sec; - } - if (!svc_sendreply(transp, xdr_getquota_rslt, (char *)&getq_rslt)) { - svcerr_systemerr(transp); - } - if (!svc_freeargs(transp, xdr_getquota_args, (caddr_t)&getq_args)) { - syslog(LOG_ERR, "unable to free arguments"); - exit(1); - } -} - -void -printerr_reply(transp) /* when a reply to a request failed */ - SVCXPRT *transp; -{ - char *name; - struct sockaddr_in *caller; - int save_errno; - - save_errno = errno; - - caller = svc_getcaller(transp); - name = (char *)inet_ntoa(caller->sin_addr); - errno = save_errno; - if (errno == 0) - syslog(LOG_ERR, "couldn't send reply to %s", name); - else - syslog(LOG_ERR, "couldn't send reply to %s: %m", name); -} - -/* initialise the fs_tab list from entries in /etc/fstab */ -void -initfs() -{ - struct fs_stat *fs_current = NULL; - struct fs_stat *fs_next = NULL; - char *qfpathname; - struct fstab *fs; - struct stat st; - - setfsent(); - while ((fs = getfsent())) { - if (strcmp(fs->fs_vfstype, "ufs")) - continue; - if (!hasquota(fs, &qfpathname)) - continue; - - fs_current = (struct fs_stat *) malloc(sizeof(struct fs_stat)); - fs_current->fs_next = fs_next; /* next element */ - - fs_current->fs_file = malloc(sizeof(char) * (strlen(fs->fs_file) + 1)); - strcpy(fs_current->fs_file, fs->fs_file); - - fs_current->qfpathname = malloc(sizeof(char) * (strlen(qfpathname) + 1)); - strcpy(fs_current->qfpathname, qfpathname); - - stat(qfpathname, &st); - fs_current->st_dev = st.st_dev; - - fs_next = fs_current; - } - endfsent(); - fs_begin = fs_current; -} - -/* - * gets the quotas for id, filesystem path. - * Return 0 if fail, 1 otherwise - */ -int -getfsquota(id, path, dqblk) - long id; - char *path; - struct dqblk *dqblk; -{ - struct stat st_path; - struct fs_stat *fs; - int qcmd, fd, ret = 0; - - 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 devise 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 ((fd = open(fs->qfpathname, O_RDONLY)) < 0) { - syslog(LOG_ERR, "open error: %s: %m", fs->qfpathname); - return (0); - } - if (lseek(fd, (off_t)(id * sizeof(struct dqblk)), L_SET) == (off_t)-1) { - close(fd); - return (1); - } - switch (read(fd, dqblk, sizeof(struct dqblk))) { - case 0: - /* - * Convert implicit 0 quota (EOF) - * into an explicit one (zero'ed dqblk) - */ - bzero((caddr_t) dqblk, sizeof(struct dqblk)); - ret = 1; - break; - case sizeof(struct dqblk): /* OK */ - ret = 1; - break; - default: /* ERROR */ - syslog(LOG_ERR, "read error: %s: %m", fs->qfpathname); - close(fd); - return (0); - } - close(fd); - } - return (ret); -} - -/* - * Check to see if a particular quota is to be enabled. - * Comes from quota.c, NetBSD 0.9 - */ -int -hasquota(fs, qfnamep) - struct fstab *fs; - char **qfnamep; -{ - static char initname, usrname[100]; - static char buf[BUFSIZ]; - char *opt, *cp; - 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); -} |