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