]> arthur.barton.de Git - netatalk.git/blob - etc/afpd/nfsquota.c
autoconf POSIX.1 sys/wait.h check
[netatalk.git] / etc / afpd / nfsquota.c
1 /*
2  * $Id: nfsquota.c,v 1.3 2001-06-20 18:33:04 rufustfirefly Exp $
3  *
4  * parts of this are lifted from the bsd quota program and are
5  * therefore under the following copyright:
6  *
7  * Copyright (c) 1980, 1990, 1993
8  *      The Regents of the University of California.  All rights reserved.
9  *
10  * This code is derived from software contributed to Berkeley by
11  * Robert Elz at The University of Melbourne.
12  *
13  * Ported for AIX (jfs) by Joerg Schumacher (J.Schumacher@tu-bs.de) at the
14  * Technische Universitaet Braunschweig, FRG
15  */
16
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif /* HAVE_CONFIG_H */
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <sys/param.h> /* for DEV_BSIZE */
26 #include <sys/time.h>  /* <rpc/rpc.h> on ultrix doesn't include this */
27 #include <syslog.h>
28
29 #ifdef HAVE_NETDB_H
30 #include <netdb.h>
31 #endif /* HAVE_NETDB_H */
32 #include <netinet/in.h>
33 #include <rpc/rpc.h>
34 #include <rpc/pmap_prot.h>
35 #include <rpcsvc/rquota.h>
36
37 #include <atalk/afp.h>
38
39 #include "unix.h"
40
41 #ifndef NO_QUOTA_SUPPORT
42 /* lifted (with modifications) from the bsd quota program */
43 static int 
44 callaurpc(vol, prognum, versnum, procnum, inproc, in, outproc, out)
45         struct vol *vol;
46         u_long prognum, versnum, procnum;
47         xdrproc_t inproc, outproc;
48         char *in, *out;
49 {
50         enum clnt_stat clnt_stat;
51         struct timeval tottimeout;
52  
53         if (!vol->v_nfsclient) {
54           struct hostent *hp;
55           struct sockaddr_in server_addr;
56           struct timeval timeout;
57           int socket = RPC_ANYSOCK;
58           
59           if ((hp = gethostbyname(vol->v_gvs)) == NULL)
60             return ((int) RPC_UNKNOWNHOST);
61           timeout.tv_usec = 0;
62           timeout.tv_sec = 6;
63           memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length);
64           server_addr.sin_family = AF_INET;
65           server_addr.sin_port =  0;
66           
67           if ((vol->v_nfsclient = (void *) 
68                clntudp_create(&server_addr, prognum, versnum, 
69                               timeout, &socket)) == NULL)
70             return ((int) rpc_createerr.cf_stat);
71           
72           ((CLIENT *) vol->v_nfsclient)->cl_auth = authunix_create_default();
73         }
74
75         tottimeout.tv_sec = 10;
76         tottimeout.tv_usec = 0;
77         clnt_stat = clnt_call((CLIENT *) vol->v_nfsclient, procnum,
78                               inproc, in, outproc, out, tottimeout);
79         return ((int) clnt_stat);
80 }
81
82
83 /* sunos 4 machines structure things a little differently. */
84 #ifdef USE_OLD_RQUOTA
85 #define GQR_STATUS gqr_status
86 #define GQR_RQUOTA gqr_rquota
87 #else /* USE_OLD_RQUOTA */
88 #define GQR_STATUS status
89 #define GQR_RQUOTA getquota_rslt_u.gqr_rquota
90 #endif /* USE_OLD_RQUOTA */
91
92 int getnfsquota(const struct vol *vol, const int uid, const u_int32_t bsize,
93                 struct dqblk *dqp)
94 {
95
96   struct getquota_args gq_args;
97   struct getquota_rslt gq_rslt;
98   struct timeval tv;
99   char *hostpath;
100  
101   /* figure out the host and path */
102   if ((hostpath = strchr(vol->v_gvs, ':')) == NULL) {
103     syslog(LOG_ERR, "can't find hostname for %s", vol->v_gvs);
104     return AFPERR_PARAM;
105   }
106  
107   if (*(hostpath + 1) != '/') 
108     return AFPERR_PARAM;
109
110   /* separate host from hostpath */
111   *hostpath = '\0';
112   
113   gq_args.gqa_pathp = hostpath + 1;
114   gq_args.gqa_uid = uid;
115
116   if(callaurpc(vol, RQUOTAPROG, RQUOTAVERS, RQUOTAPROC_GETQUOTA, 
117                (xdrproc_t) xdr_getquota_args, (char *) &gq_args,
118                (xdrproc_t) xdr_getquota_rslt, (char *) &gq_rslt) != 0) {
119     syslog(LOG_INFO, "nfsquota: can't retrieve nfs quota information. \
120 make sure that rpc.rquotad is running on %s.", vol->v_gvs);
121     *hostpath = ':';
122     return AFPERR_PARAM;
123   }
124  
125   switch (gq_rslt.GQR_STATUS) {
126   case Q_NOQUOTA:
127     break;
128
129   case Q_EPERM:
130     syslog(LOG_ERR, "nfsquota: quota permission error, host: %s\n",
131            vol->v_gvs);
132     break;
133
134   case Q_OK: /* we only copy the bits that we need. */
135     gettimeofday(&tv, NULL);
136
137 #ifdef __svr4__
138     /* why doesn't using bsize work? */
139 #define NFS_BSIZE (gq_rslt.GQR_RQUOTA.rq_bsize / DEV_BSIZE)
140 #else /* __svr4__ */
141     /* NOTE: linux' rquotad program doesn't currently report the
142      * correct rq_bsize. */
143 #define NFS_BSIZE (gq_rslt.GQR_RQUOTA.rq_bsize / bsize)
144 #endif /* __svr4__ */
145
146     dqp->dqb_bhardlimit =
147       gq_rslt.GQR_RQUOTA.rq_bhardlimit*NFS_BSIZE;
148     dqp->dqb_bsoftlimit =
149       gq_rslt.GQR_RQUOTA.rq_bsoftlimit*NFS_BSIZE;
150     dqp->dqb_curblocks =
151       gq_rslt.GQR_RQUOTA.rq_curblocks*NFS_BSIZE;
152
153 #ifdef ultrix
154     dqp->dqb_bwarn = gq_rslt.GQR_RQUOTA.rq_btimeleft;
155 #else /* ultrix */
156     dqp->dqb_btimelimit =
157       tv.tv_sec + gq_rslt.GQR_RQUOTA.rq_btimeleft;
158 #endif /* ultrix */
159
160     *hostpath = ':';
161     return AFP_OK;
162     break;
163
164   default:
165     syslog(LOG_INFO, "bad rpc result, host: %s\n", vol->v_gvs);
166     break;
167   }
168
169   *hostpath = ':';
170   return AFPERR_PARAM;
171 }
172 #endif /* ! NO_QUOTA_SUPPORT */