source: trunk/athena/bin/xquota/nfs.c @ 1760

Revision 1760, 3.8 KB checked in by kit, 35 years ago (diff)
support for users w/o quota.
Line 
1/*
2 * Disk quota reporting program.
3 */
4#include <stdio.h>
5#include <mntent.h>
6#include <strings.h>
7
8#include <sys/param.h>
9#include <sys/file.h>
10#include <sys/stat.h>
11#include <ufs/quota.h>
12
13#include <rpc/rpc.h>
14#include <rpc/pmap_prot.h>
15#include <sys/socket.h>
16#include <netdb.h>
17#include <rpcsvc/rquota.h>
18#include <sys/time.h>
19
20#include "xquota.h"
21
22static int callaurpc();
23
24/************************************************************
25 *
26 * stolen from ucb's quota. (Modified somewhat)
27 *
28 ************************************************************/
29
30int
31getnfsquota(host, path, uid, dqp)
32        char *host, *path;
33        int uid;
34        struct dqblk *dqp;
35{
36        struct getquota_args gq_args;
37        struct getquota_rslt gq_rslt;
38        extern char *index();
39
40        gq_args.gqa_pathp = path;
41        gq_args.gqa_uid = uid;
42        if (callaurpc(host, RQUOTAPROG, RQUOTAVERS, RQUOTAPROC_GETQUOTA,
43                      xdr_getquota_args, (char *) &gq_args, xdr_getquota_rslt,
44                      (char *) &gq_rslt) != 0) {
45                return (QUOTA_ERROR);
46        }
47        switch (gq_rslt.gqr_status) {
48        case Q_OK:
49                {
50                struct timeval tv;
51
52                gettimeofday(&tv, NULL);
53                dqp->dqb_bhardlimit =
54                    gq_rslt.gqr_rquota.rq_bhardlimit *
55                    gq_rslt.gqr_rquota.rq_bsize / DEV_BSIZE;
56                dqp->dqb_bsoftlimit =
57                    gq_rslt.gqr_rquota.rq_bsoftlimit *
58                    gq_rslt.gqr_rquota.rq_bsize / DEV_BSIZE;
59                dqp->dqb_curblocks =
60                    gq_rslt.gqr_rquota.rq_curblocks *
61                    gq_rslt.gqr_rquota.rq_bsize / DEV_BSIZE;
62                dqp->dqb_fhardlimit = gq_rslt.gqr_rquota.rq_fhardlimit;
63                dqp->dqb_fsoftlimit = gq_rslt.gqr_rquota.rq_fsoftlimit;
64                dqp->dqb_curfiles = gq_rslt.gqr_rquota.rq_curfiles;
65                dqp->dqb_btimelimit =
66                    tv.tv_sec + gq_rslt.gqr_rquota.rq_btimeleft;
67                dqp->dqb_ftimelimit =
68                    tv.tv_sec + gq_rslt.gqr_rquota.rq_ftimeleft;
69                return (QUOTA_OK);
70                }
71
72        case Q_NOQUOTA:
73                return(QUOTA_NONE);
74                break;
75
76        case Q_EPERM:
77                fprintf(stderr, "quota permission error, host: %s\n", host);
78                return(QUOTA_PERMISSION);
79                break;
80
81        default:
82                fprintf(stderr, "bad rpc result, host: %s\n",  host);
83                break;
84        }
85        return (QUOTA_ERROR);
86}
87
88static int
89callaurpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
90        char *host;
91        xdrproc_t inproc, outproc;
92        char *in, *out;
93{
94        struct sockaddr_in server_addr;
95        enum clnt_stat clnt_stat;
96        struct hostent *hp;
97        struct timeval timeout, tottimeout;
98
99        static CLIENT *client = NULL;
100        static int socket = RPC_ANYSOCK;
101        static int valid = 0;
102        static int oldprognum, oldversnum;
103        static char oldhost[256];
104
105        if (valid && oldprognum == prognum && oldversnum == versnum
106                && strcmp(oldhost, host) == 0) {
107                /* reuse old client */         
108        }
109        else {
110                valid = 0;
111                close(socket);
112                socket = RPC_ANYSOCK;
113                if (client) {
114                        clnt_destroy(client);
115                        client = NULL;
116                }
117                if ((hp = gethostbyname(host)) == NULL)
118                        return ((int) RPC_UNKNOWNHOST);
119                timeout.tv_usec = 0;
120                timeout.tv_sec = 6;
121                bcopy(hp->h_addr, &server_addr.sin_addr, hp->h_length);
122                server_addr.sin_family = AF_INET;
123                /* ping the remote end via tcp to see if it is up */
124                server_addr.sin_port =  htons(PMAPPORT);
125                if ((client = clnttcp_create(&server_addr, PMAPPROG,
126                    PMAPVERS, &socket, 0, 0)) == NULL) {
127                        return ((int) rpc_createerr.cf_stat);
128                } else {
129                        /* the fact we succeeded means the machine is up */
130                        close(socket);
131                        socket = RPC_ANYSOCK;
132                        clnt_destroy(client);
133                        client = NULL;
134                }
135                /* now really create a udp client handle */
136                server_addr.sin_port =  0;
137                if ((client = clntudp_create(&server_addr, prognum,
138                    versnum, timeout, &socket)) == NULL)
139                        return ((int) rpc_createerr.cf_stat);
140                client->cl_auth = authunix_create_default();
141                valid = 1;
142                oldprognum = prognum;
143                oldversnum = versnum;
144                strcpy(oldhost, host);
145        }
146        tottimeout.tv_sec = 25;
147        tottimeout.tv_usec = 0;
148        clnt_stat = clnt_call(client, procnum, inproc, in,
149            outproc, out, tottimeout);
150        /*
151         * if call failed, empty cache
152         */
153        if (clnt_stat != RPC_SUCCESS)
154                valid = 0;
155        return ((int) clnt_stat);
156}
Note: See TracBrowser for help on using the repository browser.