1 #include <u.h>
2 #include <libc.h>
3 #include <thread.h>
4 #include <bio.h>
5 #include <fcall.h>
6 #include "object.h"
7 #include "parse.h"
8 #include "print.h"
9 #include "catset.h"
10 #include "../debug.h"
11
12 // #include <pool.h>
13
14 char *user, *mapname, *svrname;
15 int p[2];
16 int mfd[2];
17 int debug = 0; //DBGSERVER|DBGSTATE|DBGPICKLE|DBGPLAY;
18 Biobuf *f;
19 char *file;
20
21 Object *root;
22
23 Object ** otab; // object table
24 int notab; // no of entries used
25 int sotab; // no of entries mallocated (invariant sotab >= notab)
26 int hotab; // no of holes in otab;
27
28 char usage[] = "Usage: %s [-f] [-l] [mapfile]\n";
29
30 char *startdir;
31
32 Object **catobjects; /* for quickly finding category objects */
33 int ncat = 0;
34
35 void
post(char * name,char * envname,int srvfd)36 post(char *name, char *envname, int srvfd)
37 {
38 int fd;
39 char buf[32];
40
41 fd = create(name, OWRITE, 0666);
42 if(fd < 0)
43 return;
44 sprint(buf, "%d",srvfd);
45 if(write(fd, buf, strlen(buf)) != strlen(buf))
46 sysfatal("srv write: %r");
47 close(fd);
48 putenv(envname, name);
49 }
50
51 int
robusthandler(void *,char * s)52 robusthandler(void*, char *s)
53 {
54 if (debug) fprint(2, "inthandler: %s\n", s);
55 return (s && (strstr(s, "interrupted") || strstr(s, "hangup")));
56 }
57
58 long
robustread(int fd,void * buf,long sz)59 robustread(int fd, void *buf, long sz)
60 {
61 long r;
62 char err[32];
63
64 do {
65 r = read(fd , buf, sz);
66 if (r < 0)
67 rerrstr(err, sizeof(err));
68 } while (r < 0 && robusthandler(nil, err));
69 return r;
70 }
71
72 void
delobject(Object * o)73 delobject(Object *o)
74 {
75 /* Free an object and all its descendants */
76 Object *oo;
77 int i;
78
79 for (i = 0; i < o->nchildren; i++){
80 oo = o->children[i];
81 if (oo->parent == o)
82 delobject(oo);
83 }
84 freeobject(o, "r");
85 }
86
87 void
threadmain(int argc,char * argv[])88 threadmain(int argc, char *argv[]) {
89 char *q;
90 char *srvname;
91 char *mntpt;
92 int list;
93
94 mntpt = "/mnt";
95 user = strdup(getuser());
96 srvname = nil;
97 list = 0;
98
99 // mainmem->flags |= POOL_NOREUSE;
100
101 ARGBEGIN{
102 case 'l':
103 list = 1;
104 break;
105 case 'm':
106 mntpt = ARGF();
107 break;
108 case 'd':
109 debug = strtoul(ARGF(), nil, 0);
110 break;
111 case 's':
112 srvname = ARGF();
113 break;
114 case 'f':
115 fflag = 1;
116 break;
117 default:
118 fprint(2, usage, argv0);
119 exits("usage");
120 }ARGEND
121
122 switch (argc) {
123 default:
124 fprint(2, usage, argv0);
125 exits("usage");
126 case 0:
127 mapname = DEFAULTMAP;
128 break;
129 case 1:
130 mapname = argv[0];
131 break;
132 }
133
134 quotefmtinstall();
135
136 if((f = Bopen(mapname, OREAD)) == nil)
137 sysfatal("%s: %r", mapname);
138 free(file);
139 file = strdup(mapname);
140 free(startdir);
141 startdir = strdup(mapname);
142 if ((q = strrchr(startdir, '/')))
143 *q = '\0';
144 else
145 startdir[0] = '\0';
146 inittokenlist();
147 getobject(Root, nil);
148 Bterm(f);
149 f = nil;
150 root->parent = root;
151
152 if(list){
153 listfiles(root);
154 threadexits(nil);
155 }
156
157 if(pipe(p) < 0)
158 sysfatal("pipe failed: %r");
159 mfd[0] = p[0];
160 mfd[1] = p[0];
161
162 threadnotify(robusthandler, 1);
163 user = strdup(getuser());
164
165 if(debug)
166 fmtinstall('F', fcallfmt);
167
168 procrfork(io, nil, STACKSIZE, RFFDG); //RFNOTEG?
169
170 close(p[0]); /* don't deadlock if child fails */
171
172 if(srvname){
173 srvname = smprint("/srv/jukefs.%s", srvname);
174 remove(srvname);
175 post(srvname, "jukefs", p[1]);
176 }
177 if(mount(p[1], -1, mntpt, MBEFORE, "") < 0)
178 sysfatal("mount failed: %r");
179 threadexits(nil);
180 }
181
182 void
reread(void)183 reread(void)
184 {
185 int i;
186 extern int catnr;
187 char *q;
188
189 assert(f == nil);
190 if((f = Bopen(mapname, OREAD)) == nil)
191 fprint(2, "reread: %s: %r\n", mapname);
192 freetree(root);
193 root = nil;
194 for(i = 0; i< ntoken; i++){
195 free(tokenlist[i].name);
196 catsetfree(&tokenlist[i].categories);
197 }
198 catnr = 0;
199 free(tokenlist);
200 free(catobjects);
201 catobjects = nil;
202 ncat = 0;
203 tokenlist = nil;
204 ntoken = Ntoken;
205 inittokenlist();
206 free(file);
207 file = strdup(mapname);
208 free(startdir);
209 startdir = strdup(mapname);
210 if ((q = strrchr(startdir, '/')))
211 *q = '\0';
212 else
213 startdir[0] = '\0';
214 getobject(Root, nil);
215 root->parent = root;
216 Bterm(f);
217 f = nil;
218 }
219