]> arthur.barton.de Git - netatalk.git/blob - etc/afpd/nfsquota.c
AC_HEADER_STDC autoconf change
[netatalk.git] / etc / afpd / nfsquota.c
1 /*
2  * $Id: nfsquota.c,v 1.4 2001-09-06 20:00:59 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
23 /* STDC check */
24 #if STDC_HEADERS
25 #include <string.h>
26 #else /* STDC_HEADERS */
27 #ifndef HAVE_STRCHR
28 #define strchr index
29 #define strrchr index
30 #endif /* HAVE_STRCHR */
31 char *strchr (), *strrchr ();
32 #ifndef HAVE_MEMCPY
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 */
37
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 <syslog.h>
43
44 #ifdef HAVE_NETDB_H
45 #include <netdb.h>
46 #endif /* HAVE_NETDB_H */
47 #include <netinet/in.h>
48 #include <rpc/rpc.h>
49 #include <rpc/pmap_prot.h>
50 #include <rpcsvc/rquota.h>
51
52 #include <atalk/afp.h>
53
54 #include "unix.h"
55
56 #ifndef NO_QUOTA_SUPPORT
57 /* lifted (with modifications) from the bsd quota program */
58 static int 
59 callaurpc(vol, prognum, versnum, procnum, inproc, in, outproc, out)
60         struct vol *vol;
61         u_long prognum, versnum, procnum;
62         xdrproc_t inproc, outproc;
63         char *in, *out;
64 {
65         enum clnt_stat clnt_stat;
66         struct timeval tottimeout;
67  
68         if (!vol->v_nfsclient) {
69           struct hostent *hp;
70           struct sockaddr_in server_addr;
71           struct timeval timeout;
72           int socket = RPC_ANYSOCK;
73           
74           if ((hp = gethostbyname(vol->v_gvs)) == NULL)
75             return ((int) RPC_UNKNOWNHOST);
76           timeout.tv_usec = 0;
77           timeout.tv_sec = 6;
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;
81           
82           if ((vol->v_nfsclient = (void *) 
83                clntudp_create(&server_addr, prognum, versnum, 
84                               timeout, &socket)) == NULL)
85             return ((int) rpc_createerr.cf_stat);
86           
87           ((CLIENT *) vol->v_nfsclient)->cl_auth = authunix_create_default();
88         }
89
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);
95 }
96
97
98 /* sunos 4 machines structure things a little differently. */
99 #ifdef USE_OLD_RQUOTA
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 */
106
107 int getnfsquota(const struct vol *vol, const int uid, const u_int32_t bsize,
108                 struct dqblk *dqp)
109 {
110
111   struct getquota_args gq_args;
112   struct getquota_rslt gq_rslt;
113   struct timeval tv;
114   char *hostpath;
115  
116   /* figure out the host and path */
117   if ((hostpath = strchr(vol->v_gvs, ':')) == NULL) {
118     syslog(LOG_ERR, "can't find hostname for %s", vol->v_gvs);
119     return AFPERR_PARAM;
120   }
121  
122   if (*(hostpath + 1) != '/') 
123     return AFPERR_PARAM;
124
125   /* separate host from hostpath */
126   *hostpath = '\0';
127   
128   gq_args.gqa_pathp = hostpath + 1;
129   gq_args.gqa_uid = uid;
130
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     syslog(LOG_INFO, "nfsquota: can't retrieve nfs quota information. \
135 make sure that rpc.rquotad is running on %s.", vol->v_gvs);
136     *hostpath = ':';
137     return AFPERR_PARAM;
138   }
139  
140   switch (gq_rslt.GQR_STATUS) {
141   case Q_NOQUOTA:
142     break;
143
144   case Q_EPERM:
145     syslog(LOG_ERR, "nfsquota: quota permission error, host: %s\n",
146            vol->v_gvs);
147     break;
148
149   case Q_OK: /* we only copy the bits that we need. */
150     gettimeofday(&tv, NULL);
151
152 #ifdef __svr4__
153     /* why doesn't using bsize work? */
154 #define NFS_BSIZE (gq_rslt.GQR_RQUOTA.rq_bsize / DEV_BSIZE)
155 #else /* __svr4__ */
156     /* NOTE: linux' rquotad program doesn't currently report the
157      * correct rq_bsize. */
158 #define NFS_BSIZE (gq_rslt.GQR_RQUOTA.rq_bsize / bsize)
159 #endif /* __svr4__ */
160
161     dqp->dqb_bhardlimit =
162       gq_rslt.GQR_RQUOTA.rq_bhardlimit*NFS_BSIZE;
163     dqp->dqb_bsoftlimit =
164       gq_rslt.GQR_RQUOTA.rq_bsoftlimit*NFS_BSIZE;
165     dqp->dqb_curblocks =
166       gq_rslt.GQR_RQUOTA.rq_curblocks*NFS_BSIZE;
167
168 #ifdef ultrix
169     dqp->dqb_bwarn = gq_rslt.GQR_RQUOTA.rq_btimeleft;
170 #else /* ultrix */
171     dqp->dqb_btimelimit =
172       tv.tv_sec + gq_rslt.GQR_RQUOTA.rq_btimeleft;
173 #endif /* ultrix */
174
175     *hostpath = ':';
176     return AFP_OK;
177     break;
178
179   default:
180     syslog(LOG_INFO, "bad rpc result, host: %s\n", vol->v_gvs);
181     break;
182   }
183
184   *hostpath = ':';
185   return AFPERR_PARAM;
186 }
187 #endif /* ! NO_QUOTA_SUPPORT */