0e8b52b334ba3e69e8bd676c64c7f3d66827e51a
[nfs-utils.git] / support / nfs / nfsexport.c
1 /*
2  * support/nfs/export.c
3  *
4  * Add or delete an NFS export in knfsd.
5  *
6  * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
7  */
8
9 #include "config.h"
10
11 #include <string.h>
12 #include <sys/types.h>
13 #include <asm/types.h>
14 #include <sys/stat.h>
15 #include <unistd.h>
16 #include <fcntl.h>
17
18 #include "nfslib.h"
19
20         /* if /proc/net/rpc/... exists, then 
21          * write to it, as that interface is more stable.
22          * Write:
23          *  client fsidtype fsid path
24          * to /proc/net/rpc/nfsd.fh/channel
25          * and
26          *  client path expiry flags anonuid anongid fsid
27          * to /proc/net/rpc/nfsd.export/channel
28          */
29
30 static int
31 exp_unexp(struct nfsctl_export *exp, int export)
32 {
33         FILE *f;
34         struct stat stb;
35         __u32 fsid;
36         char fsidstr[8];
37         __u16 dev;
38         __u32 inode;
39
40
41         f = fopen("/proc/net/rpc/nfsd.export/channel", "w");
42         if (f == NULL) return -1;
43         qword_print(f, exp->ex_client);
44         qword_print(f, exp->ex_path);
45         if (export) {
46                 qword_printint(f, 0x7fffffff);
47                 qword_printint(f, exp->ex_flags);
48                 qword_printint(f, exp->ex_anon_uid);
49                 qword_printint(f, exp->ex_anon_gid);
50                 qword_printint(f, exp->ex_dev);
51         } else
52                 qword_printint(f, 1);
53
54         qword_eol(f);
55         fclose(f);
56
57         if (stat(exp->ex_path, &stb) != 0)
58                 return -1;
59         f = fopen("/proc/net/rpc/nfsd.fh/channel", "w");
60         if (f==NULL) return -1;
61         if (exp->ex_flags & NFSEXP_FSID) {
62                 qword_print(f,exp->ex_client);
63                 qword_printint(f,1);
64                 fsid = exp->ex_dev;
65                 qword_printhex(f, (char*)&fsid, 4);
66                 if (export) {
67                         qword_printint(f, 0x7fffffff);
68                         qword_print(f, exp->ex_path);
69                 } else
70                         qword_printint(f, 1);
71
72                 qword_eol(f);
73         }
74         qword_print(f,exp->ex_client);
75         qword_printint(f,0);
76         dev = htons(major(stb.st_dev)); memcpy(fsidstr, &dev, 2);
77         dev = htons(minor(stb.st_dev)); memcpy(fsidstr+2, &dev, 2);
78         inode = stb.st_ino; memcpy(fsidstr+4, &inode, 4);
79         
80         qword_printhex(f, fsidstr, 8);
81         if (export) {
82                 qword_printint(f, 0x7fffffff);
83                 qword_print(f, exp->ex_path);
84         } else
85                 qword_printint(f, 1);
86         qword_eol(f);
87         fclose(f);
88         return 0;
89 }
90
91 int
92 nfsexport(struct nfsctl_export *exp)
93 {
94         struct nfsctl_arg       arg;
95         int fd;
96         if ((fd=open("/proc/net/rpc/nfsd.fh/channel", O_RDWR))>= 0) {
97                 close(fd);
98                 return exp_unexp(exp, 1);
99         }
100         arg.ca_version = NFSCTL_VERSION;
101         memcpy(&arg.ca_export, exp, sizeof(arg.ca_export));
102         return nfsctl(NFSCTL_EXPORT, &arg, NULL);
103 }
104
105 int
106 nfsunexport(struct nfsctl_export *exp)
107 {
108         struct nfsctl_arg       arg;
109
110         int fd;
111         if ((fd=open("/proc/net/rpc/nfsd.fh/channel", O_RDWR))>= 0) {
112                 close(fd);
113                 return exp_unexp(exp, 0);
114         }
115
116         arg.ca_version = NFSCTL_VERSION;
117         memcpy(&arg.ca_export, exp, sizeof(arg.ca_export));
118         return nfsctl(NFSCTL_UNEXPORT, &arg, NULL);
119 }