1 /* parts of this are lifted from the bsd quota program and are
2 * therefore under the following copyright:
4 * Copyright (c) 1980, 1990, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * Robert Elz at The University of Melbourne.
10 * Ported for AIX (jfs) by Joerg Schumacher (J.Schumacher@tu-bs.de) at the
11 * Technische Universitaet Braunschweig, FRG
20 #include <sys/types.h>
21 #include <sys/socket.h>
22 #include <sys/param.h> /* for DEV_BSIZE */
23 #include <sys/time.h> /* <rpc/rpc.h> on ultrix doesn't include this */
27 #include <netinet/in.h>
29 #include <rpc/pmap_prot.h>
30 #include <rpcsvc/rquota.h>
32 #include <atalk/afp.h>
36 #ifndef NO_QUOTA_SUPPORT
37 /* lifted (with modifications) from the bsd quota program */
39 callaurpc(vol, prognum, versnum, procnum, inproc, in, outproc, out)
41 u_long prognum, versnum, procnum;
42 xdrproc_t inproc, outproc;
45 enum clnt_stat clnt_stat;
46 struct timeval tottimeout;
48 if (!vol->v_nfsclient) {
50 struct sockaddr_in server_addr;
51 struct timeval timeout;
52 int socket = RPC_ANYSOCK;
54 if ((hp = gethostbyname(vol->v_gvs)) == NULL)
55 return ((int) RPC_UNKNOWNHOST);
58 memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length);
59 server_addr.sin_family = AF_INET;
60 server_addr.sin_port = 0;
62 if ((vol->v_nfsclient = (void *)
63 clntudp_create(&server_addr, prognum, versnum,
64 timeout, &socket)) == NULL)
65 return ((int) rpc_createerr.cf_stat);
67 ((CLIENT *) vol->v_nfsclient)->cl_auth = authunix_create_default();
70 tottimeout.tv_sec = 10;
71 tottimeout.tv_usec = 0;
72 clnt_stat = clnt_call((CLIENT *) vol->v_nfsclient, procnum,
73 inproc, in, outproc, out, tottimeout);
74 return ((int) clnt_stat);
78 /* sunos 4 machines structure things a little differently. */
80 #define GQR_STATUS gqr_status
81 #define GQR_RQUOTA gqr_rquota
83 #define GQR_STATUS status
84 #define GQR_RQUOTA getquota_rslt_u.gqr_rquota
87 int getnfsquota(const struct vol *vol, const int uid, const u_int32_t bsize,
91 struct getquota_args gq_args;
92 struct getquota_rslt gq_rslt;
96 /* figure out the host and path */
97 if ((hostpath = strchr(vol->v_gvs, ':')) == NULL) {
98 syslog(LOG_ERR, "can't find hostname for %s", vol->v_gvs);
102 if (*(hostpath + 1) != '/')
105 /* separate host from hostpath */
108 gq_args.gqa_pathp = hostpath + 1;
109 gq_args.gqa_uid = uid;
111 if(callaurpc(vol, RQUOTAPROG, RQUOTAVERS, RQUOTAPROC_GETQUOTA,
112 (xdrproc_t) xdr_getquota_args, (char *) &gq_args,
113 (xdrproc_t) xdr_getquota_rslt, (char *) &gq_rslt) != 0) {
114 syslog(LOG_INFO, "nfsquota: can't retrieve nfs quota information. \
115 make sure that rpc.rquotad is running on %s.", vol->v_gvs);
120 switch (gq_rslt.GQR_STATUS) {
125 syslog(LOG_ERR, "nfsquota: quota permission error, host: %s\n",
129 case Q_OK: /* we only copy the bits that we need. */
130 gettimeofday(&tv, NULL);
133 /* why doesn't using bsize work? */
134 #define NFS_BSIZE (gq_rslt.GQR_RQUOTA.rq_bsize / DEV_BSIZE)
136 /* NOTE: linux' rquotad program doesn't currently report the
137 * correct rq_bsize. */
138 #define NFS_BSIZE (gq_rslt.GQR_RQUOTA.rq_bsize / bsize)
141 dqp->dqb_bhardlimit =
142 gq_rslt.GQR_RQUOTA.rq_bhardlimit*NFS_BSIZE;
143 dqp->dqb_bsoftlimit =
144 gq_rslt.GQR_RQUOTA.rq_bsoftlimit*NFS_BSIZE;
146 gq_rslt.GQR_RQUOTA.rq_curblocks*NFS_BSIZE;
149 dqp->dqb_bwarn = gq_rslt.GQR_RQUOTA.rq_btimeleft;
151 dqp->dqb_btimelimit =
152 tv.tv_sec + gq_rslt.GQR_RQUOTA.rq_btimeleft;
160 syslog(LOG_INFO, "bad rpc result, host: %s\n", vol->v_gvs);