2
* $Id: nfsquota.c,v 1.10 2002/08/29 17:22:06 jmarcus Exp $
4
* parts of this are lifted from the bsd quota program and are
5
* therefore under the following copyright:
7
* Copyright (c) 1980, 1990, 1993
8
* The Regents of the University of California. All rights reserved.
10
* This code is derived from software contributed to Berkeley by
11
* Robert Elz at The University of Melbourne.
13
* Ported for AIX (jfs) by Joerg Schumacher (J.Schumacher@tu-bs.de) at the
14
* Technische Universitaet Braunschweig, FRG
19
#endif /* HAVE_CONFIG_H */
26
#else /* STDC_HEADERS */
30
#endif /* HAVE_STRCHR */
31
char *strchr (), *strrchr ();
33
#define memcpy(d,s,n) bcopy ((s), (d), (n))
34
#define memmove(d,s,n) bcopy ((s), (d), (n))
35
#endif /* ! HAVE_MEMCPY */
36
#endif /* STDC_HEADERS */
38
#include <sys/types.h>
39
#include <sys/socket.h>
40
#include <sys/param.h> /* for DEV_BSIZE */
41
#include <sys/time.h> /* <rpc/rpc.h> on ultrix doesn't include this */
42
#include <atalk/logger.h>
46
#endif /* HAVE_NETDB_H */
47
#include <netinet/in.h>
49
#include <rpc/pmap_prot.h>
50
#include <rpcsvc/rquota.h>
52
#include <atalk/afp.h>
56
#ifndef NO_QUOTA_SUPPORT
57
/* lifted (with modifications) from the bsd quota program */
59
callaurpc(vol, prognum, versnum, procnum, inproc, in, outproc, out)
61
u_long prognum, versnum, procnum;
62
xdrproc_t inproc, outproc;
65
enum clnt_stat clnt_stat;
66
struct timeval tottimeout;
68
if (!vol->v_nfsclient) {
70
struct sockaddr_in server_addr;
71
struct timeval timeout;
72
int socket = RPC_ANYSOCK;
74
if ((hp = gethostbyname(vol->v_gvs)) == NULL)
75
return ((int) RPC_UNKNOWNHOST);
78
memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length);
79
server_addr.sin_family = AF_INET;
80
server_addr.sin_port = 0;
82
if ((vol->v_nfsclient = (void *)
83
clntudp_create(&server_addr, prognum, versnum,
84
timeout, &socket)) == NULL)
85
return ((int) rpc_createerr.cf_stat);
87
((CLIENT *) vol->v_nfsclient)->cl_auth = authunix_create_default();
90
tottimeout.tv_sec = 10;
91
tottimeout.tv_usec = 0;
92
clnt_stat = clnt_call((CLIENT *) vol->v_nfsclient, procnum,
93
inproc, in, outproc, out, tottimeout);
94
return ((int) clnt_stat);
98
/* sunos 4 machines structure things a little differently. */
100
#define GQR_STATUS gqr_status
101
#define GQR_RQUOTA gqr_rquota
102
#else /* USE_OLD_RQUOTA */
103
#define GQR_STATUS status
104
#define GQR_RQUOTA getquota_rslt_u.gqr_rquota
105
#endif /* USE_OLD_RQUOTA */
107
int getnfsquota(const struct vol *vol, const int uid, const u_int32_t bsize,
111
struct getquota_args gq_args;
112
struct getquota_rslt gq_rslt;
116
/* figure out the host and path */
117
if ((hostpath = strchr(vol->v_gvs, ':')) == NULL) {
118
LOG(log_error, logtype_afpd, "can't find hostname for %s", vol->v_gvs);
122
if (*(hostpath + 1) != '/')
125
/* separate host from hostpath */
128
gq_args.gqa_pathp = hostpath + 1;
129
gq_args.gqa_uid = uid;
131
if(callaurpc(vol, RQUOTAPROG, RQUOTAVERS, RQUOTAPROC_GETQUOTA,
132
(xdrproc_t) xdr_getquota_args, (char *) &gq_args,
133
(xdrproc_t) xdr_getquota_rslt, (char *) &gq_rslt) != 0) {
134
LOG(log_info, logtype_afpd, "nfsquota: can't retrieve nfs quota information. \
135
make sure that rpc.rquotad is running on %s.", vol->v_gvs);
140
switch (gq_rslt.GQR_STATUS) {
145
LOG(log_error, logtype_afpd, "nfsquota: quota permission error, host: %s\n",
149
case Q_OK: /* we only copy the bits that we need. */
150
gettimeofday(&tv, NULL);
152
#if defined(__svr4__) || defined(TRU64)
153
/* why doesn't using bsize work? */
154
#define NFS_BSIZE gq_rslt.GQR_RQUOTA.rq_bsize / DEV_BSIZE
155
#else /* __svr4__ || TRU64 */
156
/* NOTE: linux' rquotad program doesn't currently report the
157
* correct rq_bsize. */
158
/* NOTE: This is integer division and can introduce rounding errors */
159
#define NFS_BSIZE gq_rslt.GQR_RQUOTA.rq_bsize / bsize
160
#endif /* __svr4__ || TRU64 */
162
dqp->dqb_bhardlimit =
163
gq_rslt.GQR_RQUOTA.rq_bhardlimit*NFS_BSIZE;
164
dqp->dqb_bsoftlimit =
165
gq_rslt.GQR_RQUOTA.rq_bsoftlimit*NFS_BSIZE;
167
gq_rslt.GQR_RQUOTA.rq_curblocks*NFS_BSIZE;
170
dqp->dqb_bwarn = gq_rslt.GQR_RQUOTA.rq_btimeleft;
172
dqp->dqb_btimelimit =
173
tv.tv_sec + gq_rslt.GQR_RQUOTA.rq_btimeleft;
181
LOG(log_info, logtype_afpd, "bad rpc result, host: %s\n", vol->v_gvs);
188
#endif /* ! NO_QUOTA_SUPPORT */