]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/9nfs/nfsmount.c
python: update python build configuration to new ape capabilities like getaddrinfo...
[plan9front.git] / sys / src / cmd / 9nfs / nfsmount.c
1 #include "all.h"
2
3 /*
4  *      Cf. /lib/rfc/rfc1094
5  */
6
7 static int      mntnull(int, Rpccall*, Rpccall*);
8 static int      mntmnt(int, Rpccall*, Rpccall*);
9 static int      mntdump(int, Rpccall*, Rpccall*);
10 static int      mntumnt(int, Rpccall*, Rpccall*);
11 static int      mntumntall(int, Rpccall*, Rpccall*);
12 static int      mntexport(int, Rpccall*, Rpccall*);
13
14 Procmap mntproc[] = {
15         0, mntnull,
16         1, mntmnt,
17         2, mntdump,
18         3, mntumnt,
19         4, mntumntall,
20         5, mntexport,
21         0, 0
22 };
23
24 long            starttime;
25 static int      noauth;
26 char *          config;
27 Session *       head;
28 Session *       tail;
29 int staletime = 10*60;
30
31 void
32 mnttimer(long now)
33 {
34         Session *s;
35
36         for(s=head; s; s=s->next)
37                 fidtimer(s, now);
38 }
39
40 static void
41 usage(void)
42 {
43         sysfatal("usage: %s %s [-ns] [-a dialstring] [-c uidmap] [-f srvfile] "
44                 "[-T staletime]", argv0, commonopts);
45 }
46
47 void
48 mntinit(int argc, char **argv)
49 {
50         int tries;
51
52         config = "config";
53         starttime = time(0);
54         clog("nfs mount server init, starttime = %lud\n", starttime);
55         tries = 0;
56         ARGBEGIN{
57         case 'a':
58                 ++tries;
59                 srvinit(-1, 0, EARGF(usage()));
60                 break;
61         case 'c':
62                 config = EARGF(usage());
63                 break;
64         case 'f':
65                 ++tries;
66                 srvinit(-1, EARGF(usage()), 0);
67                 break;
68         case 'n':
69                 ++noauth;
70                 break;
71         case 's':
72                 ++tries;
73                 srvinit(1, 0, 0);
74                 break;
75         case 'T':
76                 staletime = atoi(EARGF(usage()));
77                 break;
78         default:
79                 if(argopt(ARGC()) < 0)
80                         sysfatal("usage: %s %s [-ns] [-a dialstring] "
81                                 "[-c uidmap] [-f srvfile] [-T staletime]",
82                                 argv0, commonopts);
83                 break;
84         }ARGEND
85 noauth=1;       /* ZZZ */
86         if(tries == 0 && head == 0)
87                 srvinit(-1, 0, "tcp!fs");
88         if(head == 0)
89                 panic("can't initialize services");
90         readunixidmaps(config);
91 }
92
93 void
94 srvinit(int fd, char *file, char *addr)
95 {
96         char fdservice[16], *naddr;
97         Session *s;
98         Xfile *xp;
99         Xfid *xf;
100         Fid *f;
101
102         s = calloc(1, sizeof(Session));
103         s->spec = "";
104         s->fd = -1;
105         if(fd >= 0){
106                 s->fd = fd;
107                 sprint(fdservice, "/fd/%d", s->fd);
108                 s->service = strstore(fdservice);
109                 chat("fd = %d\n", s->fd);
110         }else if(file){
111                 chat("file = \"%s\"\n", file);
112                 s->service = file;
113                 s->fd = open(file, ORDWR);
114                 if(s->fd < 0){
115                         clog("can't open %s: %r\n", file);
116                         goto error;
117                 }
118         }else if(addr){
119                 chat("addr = \"%s\"\n", addr);
120                 naddr = netmkaddr(addr, 0, "9fs");
121                 s->service = addr;
122                 s->fd = dial(naddr, 0, 0, 0);
123                 if(s->fd < 0){
124                         clog("can't dial %s: %r\n", naddr);
125                         goto error;
126                 }
127         }
128
129         chat("version...");
130         s->tag = NOTAG-1;
131         s->f.msize = Maxfdata+IOHDRSZ;
132         s->f.version = "9P2000";
133         xmesg(s, Tversion);
134         messagesize = IOHDRSZ+s->f.msize;
135         chat("version spec %s size %d\n", s->f.version, s->f.msize);
136
137         s->tag = 0;
138
139         chat("authenticate...");
140         if(authhostowner(s) < 0){
141                 clog("auth failed %r\n");
142                 goto error;
143         }
144
145         chat("attach as none...");
146         f = newfid(s);
147         s->f.fid = f - s->fids;
148         s->f.afid = ~0x0UL;
149         s->f.uname = "none";
150         s->f.aname = s->spec;
151         if(xmesg(s, Tattach)){
152                 clog("attach failed\n");
153                 goto error;
154         }
155
156         xp = xfile(&s->f.qid, s, 1);
157         s->root = xp;
158         xp->parent = xp;
159         xp->name = "/";
160         xf = xfid("none", xp, 1);
161         xf->urfid = f;
162         clog("service=%s uid=%s fid=%ld\n",
163                 s->service, xf->uid, xf->urfid - s->fids);
164         if(tail)
165                 tail->next = s;
166         else
167                 head = s;
168         tail = s;
169         return;
170
171 error:
172         if(s->fd >= 0)
173                 close(s->fd);
174         free(s);
175 }
176
177 static int
178 mntnull(int n, Rpccall *cmd, Rpccall *reply)
179 {
180         USED(n, cmd, reply);
181         chat("mntnull\n");
182         return 0;
183 }
184
185 static char*
186 Str2str(String s, char *buf, int nbuf)
187 {
188         int i;
189         i = s.n;
190         if(i >= nbuf)
191                 i = nbuf-1;
192         memmove(buf, s.s, i);
193         buf[i] = 0;
194         return buf;
195 }
196
197 static int
198 mntmnt(int n, Rpccall *cmd, Rpccall *reply)
199 {
200         int i;
201         char dom[64];
202         uchar *argptr = cmd->args;
203         uchar *dataptr = reply->results;
204         Authunix au;
205         Xfile *xp;
206         String root;
207
208         chat("mntmnt...\n");
209         if(n < 8)
210                 return garbage(reply, "n too small");
211         argptr += string2S(argptr, &root);
212         if(argptr != &((uchar *)cmd->args)[n])
213                 return garbage(reply, "bad count");
214         clog("host=%I, port=%ld, root=\"%.*s\"...",
215                 cmd->host, cmd->port, utfnlen(root.s, root.n), root.s);
216         if(auth2unix(&cmd->cred, &au) != 0){
217                 chat("auth flavor=%ld, count=%ld\n",
218                         cmd->cred.flavor, cmd->cred.count);
219                 for(i=0; i<cmd->cred.count; i++)
220                         chat(" %.2ux", ((uchar *)cmd->cred.data)[i]);
221                 chat("\n");
222                 clog("auth: bad credentials");
223                 return error(reply, 1);
224         }
225         clog("auth: %ld %.*s u=%ld g=%ld",
226                 au.stamp, utfnlen(au.mach.s, au.mach.n), au.mach.s, au.uid, au.gid);
227         for(i=0; i<au.gidlen; i++)
228                 chat(", %ld", au.gids[i]);
229         chat("...");
230         if(getdom(cmd->host, dom, sizeof(dom))<0){
231                 clog("auth: unknown ip address");
232                 return error(reply, 1);
233         }
234         chat("dom=%s...", dom);
235         xp = xfroot(root.s, root.n);
236         if(xp == 0){
237                 chat("xp=0...");
238                 clog("mntmnt: no fs");
239                 return error(reply, 3);
240         }
241
242         PLONG(0);
243         dataptr += xp2fhandle(xp, dataptr);
244         chat("OK\n");
245         return dataptr - (uchar *)reply->results;
246 }
247
248 static int
249 mntdump(int n, Rpccall *cmd, Rpccall *reply)
250 {
251         if(n != 0)
252                 return garbage(reply, "mntdump");
253         USED(cmd);
254         chat("mntdump...");
255         return error(reply, FALSE);
256 }
257
258 static int
259 mntumnt(int n, Rpccall *cmd, Rpccall *reply)
260 {
261         if(n <= 0)
262                 return garbage(reply, "mntumnt");
263         USED(cmd);
264         chat("mntumnt\n");
265         return 0;
266 }
267
268 static int
269 mntumntall(int n, Rpccall *cmd, Rpccall *reply)
270 {
271         if(n != 0)
272                 return garbage(reply, "mntumntall");
273         USED(cmd);
274         chat("mntumntall\n");
275         return 0;
276 }
277
278 static int
279 mntexport(int n, Rpccall *cmd, Rpccall *reply)
280 {
281         uchar *dataptr = reply->results;
282         Authunix au;
283         int i;
284
285         chat("mntexport...");
286         if(n != 0)
287                 return garbage(reply, "mntexport");
288         if(auth2unix(&cmd->cred, &au) != 0){
289                 chat("auth flavor=%ld, count=%ld\n",
290                         cmd->cred.flavor, cmd->cred.count);
291                 for(i=0; i<cmd->cred.count; i++)
292                         chat(" %.2ux", ((uchar *)cmd->cred.data)[i]);
293                 chat("...");
294                 au.mach.n = 0;
295         }else
296                 chat("%ld@%.*s...", au.uid, utfnlen(au.mach.s, au.mach.n), au.mach.s);
297         PLONG(TRUE);
298         PLONG(1);
299         PPTR("/", 1);
300         if(au.mach.n > 0){
301                 PLONG(TRUE);
302                 PLONG(au.mach.n);
303                 PPTR(au.mach.s, au.mach.n);
304         }
305         PLONG(FALSE);
306         PLONG(FALSE);
307         chat("OK\n");
308         return dataptr - (uchar *)reply->results;
309 }
310
311 Xfile *
312 xfroot(char *name, int n)
313 {
314         Session *s;
315         char *p;
316
317         if(n <= 0)
318                 n = strlen(name);
319         chat("xfroot: %.*s...", utfnlen(name, n), name);
320         if(n == 1 && name[0] == '/')
321                 return head->root;
322         for(s=head; s; s=s->next){
323                 if(strncmp(name, s->service, n) == 0)
324                         return s->root;
325                 p = strrchr(s->service, '!');   /* for -a tcp!foo */
326                 if(p && strncmp(name, p+1, n) == 0)
327                         return s->root;
328                 p = strrchr(s->service, '/');   /* for -f /srv/foo */
329                 if(p && strncmp(name, p+1, n) == 0)
330                         return s->root;
331         }
332         return 0;
333 }