Blame


1 3e0d8fb3 2005-12-27 devnull #include <u.h>
2 3e0d8fb3 2005-12-27 devnull #include <libc.h>
3 3e0d8fb3 2005-12-27 devnull #include <auth.h>
4 3e0d8fb3 2005-12-27 devnull #include <fcall.h>
5 3e0d8fb3 2005-12-27 devnull #include <bio.h>
6 3e0d8fb3 2005-12-27 devnull #include <ctype.h>
7 3e0d8fb3 2005-12-27 devnull #include <ip.h>
8 3e0d8fb3 2005-12-27 devnull #include <ndb.h>
9 5c9f76b5 2006-02-14 devnull #include <thread.h>
10 3e0d8fb3 2005-12-27 devnull #include "dns.h"
11 3e0d8fb3 2005-12-27 devnull
12 3e0d8fb3 2005-12-27 devnull enum
13 3e0d8fb3 2005-12-27 devnull {
14 3e0d8fb3 2005-12-27 devnull Maxrequest= 1024,
15 3e0d8fb3 2005-12-27 devnull Ncache= 8,
16 3e0d8fb3 2005-12-27 devnull Maxpath= 128,
17 3e0d8fb3 2005-12-27 devnull Maxreply= 512,
18 3e0d8fb3 2005-12-27 devnull Maxrrr= 16,
19 3e0d8fb3 2005-12-27 devnull Maxfdata= 8192,
20 3e0d8fb3 2005-12-27 devnull
21 3e0d8fb3 2005-12-27 devnull Qdir= 0,
22 3e0d8fb3 2005-12-27 devnull Qdns= 1,
23 3e0d8fb3 2005-12-27 devnull };
24 3e0d8fb3 2005-12-27 devnull
25 3e0d8fb3 2005-12-27 devnull typedef struct Mfile Mfile;
26 3e0d8fb3 2005-12-27 devnull typedef struct Job Job;
27 3e0d8fb3 2005-12-27 devnull typedef struct Network Network;
28 3e0d8fb3 2005-12-27 devnull
29 3e0d8fb3 2005-12-27 devnull int vers; /* incremented each clone/attach */
30 3e0d8fb3 2005-12-27 devnull
31 3e0d8fb3 2005-12-27 devnull struct Mfile
32 3e0d8fb3 2005-12-27 devnull {
33 3e0d8fb3 2005-12-27 devnull Mfile *next; /* next free mfile */
34 3e0d8fb3 2005-12-27 devnull int ref;
35 3e0d8fb3 2005-12-27 devnull
36 3e0d8fb3 2005-12-27 devnull char *user;
37 3e0d8fb3 2005-12-27 devnull Qid qid;
38 3e0d8fb3 2005-12-27 devnull int fid;
39 3e0d8fb3 2005-12-27 devnull
40 3e0d8fb3 2005-12-27 devnull int type; /* reply type */
41 3e0d8fb3 2005-12-27 devnull char reply[Maxreply];
42 3e0d8fb3 2005-12-27 devnull ushort rr[Maxrrr]; /* offset of rr's */
43 3e0d8fb3 2005-12-27 devnull ushort nrr; /* number of rr's */
44 3e0d8fb3 2005-12-27 devnull };
45 3e0d8fb3 2005-12-27 devnull
46 3e0d8fb3 2005-12-27 devnull //
47 3e0d8fb3 2005-12-27 devnull // active local requests
48 3e0d8fb3 2005-12-27 devnull //
49 3e0d8fb3 2005-12-27 devnull struct Job
50 3e0d8fb3 2005-12-27 devnull {
51 3e0d8fb3 2005-12-27 devnull Job *next;
52 3e0d8fb3 2005-12-27 devnull int flushed;
53 3e0d8fb3 2005-12-27 devnull Fcall request;
54 3e0d8fb3 2005-12-27 devnull Fcall reply;
55 3e0d8fb3 2005-12-27 devnull };
56 3e0d8fb3 2005-12-27 devnull Lock joblock;
57 3e0d8fb3 2005-12-27 devnull Job *joblist;
58 3e0d8fb3 2005-12-27 devnull
59 3e0d8fb3 2005-12-27 devnull struct {
60 3e0d8fb3 2005-12-27 devnull Lock lk;
61 3e0d8fb3 2005-12-27 devnull Mfile *inuse; /* active mfile's */
62 3e0d8fb3 2005-12-27 devnull } mfalloc;
63 3e0d8fb3 2005-12-27 devnull
64 3e0d8fb3 2005-12-27 devnull int mfd[2];
65 3e0d8fb3 2005-12-27 devnull int debug;
66 3e0d8fb3 2005-12-27 devnull int traceactivity;
67 3e0d8fb3 2005-12-27 devnull int cachedb;
68 3e0d8fb3 2005-12-27 devnull ulong now;
69 3e0d8fb3 2005-12-27 devnull int testing;
70 3e0d8fb3 2005-12-27 devnull char *trace;
71 3e0d8fb3 2005-12-27 devnull int needrefresh;
72 3e0d8fb3 2005-12-27 devnull int resolver;
73 3e0d8fb3 2005-12-27 devnull uchar ipaddr[IPaddrlen]; /* my ip address */
74 3e0d8fb3 2005-12-27 devnull int maxage;
75 3e0d8fb3 2005-12-27 devnull char *zonerefreshprogram;
76 3e0d8fb3 2005-12-27 devnull int sendnotifies;
77 3e0d8fb3 2005-12-27 devnull
78 3e0d8fb3 2005-12-27 devnull void rversion(Job*);
79 3e0d8fb3 2005-12-27 devnull void rauth(Job*);
80 3e0d8fb3 2005-12-27 devnull void rflush(Job*);
81 3e0d8fb3 2005-12-27 devnull void rattach(Job*, Mfile*);
82 3e0d8fb3 2005-12-27 devnull char* rwalk(Job*, Mfile*);
83 3e0d8fb3 2005-12-27 devnull void ropen(Job*, Mfile*);
84 3e0d8fb3 2005-12-27 devnull void rcreate(Job*, Mfile*);
85 3e0d8fb3 2005-12-27 devnull void rread(Job*, Mfile*);
86 3e0d8fb3 2005-12-27 devnull void rwrite(Job*, Mfile*, Request*);
87 3e0d8fb3 2005-12-27 devnull void rclunk(Job*, Mfile*);
88 3e0d8fb3 2005-12-27 devnull void rremove(Job*, Mfile*);
89 3e0d8fb3 2005-12-27 devnull void rstat(Job*, Mfile*);
90 3e0d8fb3 2005-12-27 devnull void rwstat(Job*, Mfile*);
91 3e0d8fb3 2005-12-27 devnull void sendmsg(Job*, char*);
92 5c9f76b5 2006-02-14 devnull void mountinit(char*);
93 3e0d8fb3 2005-12-27 devnull void io(void);
94 3e0d8fb3 2005-12-27 devnull int fillreply(Mfile*, int);
95 3e0d8fb3 2005-12-27 devnull Job* newjob(void);
96 3e0d8fb3 2005-12-27 devnull void freejob(Job*);
97 3e0d8fb3 2005-12-27 devnull void setext(char*, int, char*);
98 3e0d8fb3 2005-12-27 devnull
99 b7f150b0 2006-02-24 devnull char *tcpaddr = "tcp!*!domain";
100 b7f150b0 2006-02-24 devnull char *udpaddr = "udp!*!domain";
101 3e0d8fb3 2005-12-27 devnull char *logfile = "dns";
102 3e0d8fb3 2005-12-27 devnull char *dbfile;
103 3e0d8fb3 2005-12-27 devnull char mntpt[Maxpath];
104 3e0d8fb3 2005-12-27 devnull char *LOG;
105 3e0d8fb3 2005-12-27 devnull
106 3e0d8fb3 2005-12-27 devnull void
107 3e0d8fb3 2005-12-27 devnull usage(void)
108 3e0d8fb3 2005-12-27 devnull {
109 c7a7e3c4 2006-02-24 devnull fprint(2, "usage: dns [-dnrst] [-a maxage] [-f ndb-file] [-T tcpaddr] [-U udpaddr] [-x service] [-z zoneprog]\n");
110 5c9f76b5 2006-02-14 devnull threadexitsall("usage");
111 3e0d8fb3 2005-12-27 devnull }
112 3e0d8fb3 2005-12-27 devnull
113 3e0d8fb3 2005-12-27 devnull void
114 49a1496c 2006-02-20 devnull checkaddress(void)
115 49a1496c 2006-02-20 devnull {
116 49a1496c 2006-02-20 devnull char *u, *t;
117 49a1496c 2006-02-20 devnull
118 49a1496c 2006-02-20 devnull u = strchr(udpaddr, '!');
119 49a1496c 2006-02-20 devnull t = strchr(tcpaddr, '!');
120 49a1496c 2006-02-20 devnull if(u && t && strcmp(u, t) != 0)
121 49a1496c 2006-02-20 devnull fprint(2, "warning: announce mismatch %s %s\n", udpaddr, tcpaddr);
122 49a1496c 2006-02-20 devnull }
123 49a1496c 2006-02-20 devnull
124 49a1496c 2006-02-20 devnull void
125 5c9f76b5 2006-02-14 devnull threadmain(int argc, char *argv[])
126 3e0d8fb3 2005-12-27 devnull {
127 5c9f76b5 2006-02-14 devnull int serveudp, servetcp;
128 5c9f76b5 2006-02-14 devnull char *service;
129 3e0d8fb3 2005-12-27 devnull
130 5c9f76b5 2006-02-14 devnull serveudp = 0;
131 5c9f76b5 2006-02-14 devnull servetcp = 0;
132 5c9f76b5 2006-02-14 devnull service = "dns";
133 3e0d8fb3 2005-12-27 devnull ARGBEGIN{
134 3e0d8fb3 2005-12-27 devnull case 'd':
135 3e0d8fb3 2005-12-27 devnull debug = 1;
136 3e0d8fb3 2005-12-27 devnull traceactivity = 1;
137 3e0d8fb3 2005-12-27 devnull break;
138 3e0d8fb3 2005-12-27 devnull case 'f':
139 5c9f76b5 2006-02-14 devnull dbfile = EARGF(usage());
140 3e0d8fb3 2005-12-27 devnull break;
141 5c9f76b5 2006-02-14 devnull case 'x':
142 5c9f76b5 2006-02-14 devnull service = EARGF(usage());
143 3e0d8fb3 2005-12-27 devnull break;
144 3e0d8fb3 2005-12-27 devnull case 'r':
145 3e0d8fb3 2005-12-27 devnull resolver = 1;
146 3e0d8fb3 2005-12-27 devnull break;
147 3e0d8fb3 2005-12-27 devnull case 's':
148 19256e0d 2006-02-17 devnull serveudp = 1;
149 3e0d8fb3 2005-12-27 devnull cachedb = 1;
150 3e0d8fb3 2005-12-27 devnull break;
151 49a1496c 2006-02-20 devnull case 't':
152 5c9f76b5 2006-02-14 devnull servetcp = 1;
153 5c9f76b5 2006-02-14 devnull cachedb = 1;
154 5c9f76b5 2006-02-14 devnull break;
155 3e0d8fb3 2005-12-27 devnull case 'a':
156 5c9f76b5 2006-02-14 devnull maxage = atoi(EARGF(usage()));
157 3e0d8fb3 2005-12-27 devnull break;
158 3e0d8fb3 2005-12-27 devnull case 'z':
159 5c9f76b5 2006-02-14 devnull zonerefreshprogram = EARGF(usage());
160 3e0d8fb3 2005-12-27 devnull break;
161 3e0d8fb3 2005-12-27 devnull case 'n':
162 3e0d8fb3 2005-12-27 devnull sendnotifies = 1;
163 3e0d8fb3 2005-12-27 devnull break;
164 49a1496c 2006-02-20 devnull case 'U':
165 b7f150b0 2006-02-24 devnull udpaddr = estrdup(netmkaddr(EARGF(usage()), "udp", "domain"));
166 49a1496c 2006-02-20 devnull break;
167 49a1496c 2006-02-20 devnull case 'T':
168 b7f150b0 2006-02-24 devnull tcpaddr = estrdup(netmkaddr(EARGF(usage()), "tcp", "domain"));
169 49a1496c 2006-02-20 devnull break;
170 49a1496c 2006-02-20 devnull default:
171 49a1496c 2006-02-20 devnull usage();
172 3e0d8fb3 2005-12-27 devnull }ARGEND
173 49a1496c 2006-02-20 devnull
174 49a1496c 2006-02-20 devnull if(argc)
175 49a1496c 2006-02-20 devnull usage();
176 49a1496c 2006-02-20 devnull if(serveudp && servetcp)
177 49a1496c 2006-02-20 devnull checkaddress();
178 3e0d8fb3 2005-12-27 devnull
179 5c9f76b5 2006-02-14 devnull rfork(RFNOTEG);
180 3e0d8fb3 2005-12-27 devnull
181 3e0d8fb3 2005-12-27 devnull /* start syslog before we fork */
182 3e0d8fb3 2005-12-27 devnull fmtinstall('F', fcallfmt);
183 3e0d8fb3 2005-12-27 devnull dninit();
184 19256e0d 2006-02-17 devnull if(myipaddr(ipaddr, mntpt) < 0)
185 3e0d8fb3 2005-12-27 devnull sysfatal("can't read my ip address");
186 3e0d8fb3 2005-12-27 devnull
187 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "starting dns on %I", ipaddr);
188 3e0d8fb3 2005-12-27 devnull
189 3e0d8fb3 2005-12-27 devnull opendatabase();
190 3e0d8fb3 2005-12-27 devnull
191 5c9f76b5 2006-02-14 devnull mountinit(service);
192 3e0d8fb3 2005-12-27 devnull
193 3e0d8fb3 2005-12-27 devnull now = time(0);
194 3e0d8fb3 2005-12-27 devnull srand(now*getpid());
195 3e0d8fb3 2005-12-27 devnull db2cache(1);
196 3e0d8fb3 2005-12-27 devnull
197 5c9f76b5 2006-02-14 devnull if(serveudp)
198 5c9f76b5 2006-02-14 devnull proccreate(dnudpserver, nil, STACK);
199 5c9f76b5 2006-02-14 devnull if(servetcp)
200 5c9f76b5 2006-02-14 devnull proccreate(dntcpserver, nil, STACK);
201 3e0d8fb3 2005-12-27 devnull if(sendnotifies)
202 5c9f76b5 2006-02-14 devnull proccreate(notifyproc, nil, STACK);
203 3e0d8fb3 2005-12-27 devnull
204 3e0d8fb3 2005-12-27 devnull io();
205 3e0d8fb3 2005-12-27 devnull }
206 3e0d8fb3 2005-12-27 devnull
207 3e0d8fb3 2005-12-27 devnull /*
208 3e0d8fb3 2005-12-27 devnull * if a mount point is specified, set the cs extention to be the mount point
209 3e0d8fb3 2005-12-27 devnull * with '_'s replacing '/'s
210 3e0d8fb3 2005-12-27 devnull */
211 3e0d8fb3 2005-12-27 devnull void
212 3e0d8fb3 2005-12-27 devnull setext(char *ext, int n, char *p)
213 3e0d8fb3 2005-12-27 devnull {
214 3e0d8fb3 2005-12-27 devnull int i, c;
215 3e0d8fb3 2005-12-27 devnull
216 3e0d8fb3 2005-12-27 devnull n--;
217 3e0d8fb3 2005-12-27 devnull for(i = 0; i < n; i++){
218 3e0d8fb3 2005-12-27 devnull c = p[i];
219 3e0d8fb3 2005-12-27 devnull if(c == 0)
220 3e0d8fb3 2005-12-27 devnull break;
221 3e0d8fb3 2005-12-27 devnull if(c == '/')
222 3e0d8fb3 2005-12-27 devnull c = '_';
223 3e0d8fb3 2005-12-27 devnull ext[i] = c;
224 3e0d8fb3 2005-12-27 devnull }
225 3e0d8fb3 2005-12-27 devnull ext[i] = 0;
226 3e0d8fb3 2005-12-27 devnull }
227 3e0d8fb3 2005-12-27 devnull
228 3e0d8fb3 2005-12-27 devnull void
229 5c9f76b5 2006-02-14 devnull mountinit(char *service)
230 3e0d8fb3 2005-12-27 devnull {
231 3e0d8fb3 2005-12-27 devnull int p[2];
232 3e0d8fb3 2005-12-27 devnull
233 3e0d8fb3 2005-12-27 devnull if(pipe(p) < 0)
234 3e0d8fb3 2005-12-27 devnull abort(); /* "pipe failed" */;
235 5c9f76b5 2006-02-14 devnull if(post9pservice(p[1], service) < 0)
236 5c9f76b5 2006-02-14 devnull fprint(2, "post9pservice dns: %r\n");
237 5c9f76b5 2006-02-14 devnull close(p[1]);
238 3e0d8fb3 2005-12-27 devnull mfd[0] = mfd[1] = p[0];
239 3e0d8fb3 2005-12-27 devnull }
240 3e0d8fb3 2005-12-27 devnull
241 3e0d8fb3 2005-12-27 devnull Mfile*
242 3e0d8fb3 2005-12-27 devnull newfid(int fid, int needunused)
243 3e0d8fb3 2005-12-27 devnull {
244 3e0d8fb3 2005-12-27 devnull Mfile *mf;
245 3e0d8fb3 2005-12-27 devnull
246 3e0d8fb3 2005-12-27 devnull lock(&mfalloc.lk);
247 3e0d8fb3 2005-12-27 devnull for(mf = mfalloc.inuse; mf != nil; mf = mf->next){
248 3e0d8fb3 2005-12-27 devnull if(mf->fid == fid){
249 3e0d8fb3 2005-12-27 devnull unlock(&mfalloc.lk);
250 3e0d8fb3 2005-12-27 devnull if(needunused)
251 3e0d8fb3 2005-12-27 devnull return nil;
252 3e0d8fb3 2005-12-27 devnull return mf;
253 3e0d8fb3 2005-12-27 devnull }
254 3e0d8fb3 2005-12-27 devnull }
255 387ae1db 2006-02-02 devnull if(!needunused){
256 387ae1db 2006-02-02 devnull unlock(&mfalloc.lk);
257 387ae1db 2006-02-02 devnull return nil;
258 387ae1db 2006-02-02 devnull }
259 3e0d8fb3 2005-12-27 devnull mf = emalloc(sizeof(*mf));
260 3e0d8fb3 2005-12-27 devnull if(mf == nil)
261 3e0d8fb3 2005-12-27 devnull sysfatal("out of memory");
262 3e0d8fb3 2005-12-27 devnull mf->fid = fid;
263 3e0d8fb3 2005-12-27 devnull mf->next = mfalloc.inuse;
264 3e0d8fb3 2005-12-27 devnull mfalloc.inuse = mf;
265 3e0d8fb3 2005-12-27 devnull unlock(&mfalloc.lk);
266 3e0d8fb3 2005-12-27 devnull return mf;
267 3e0d8fb3 2005-12-27 devnull }
268 3e0d8fb3 2005-12-27 devnull
269 3e0d8fb3 2005-12-27 devnull void
270 3e0d8fb3 2005-12-27 devnull freefid(Mfile *mf)
271 3e0d8fb3 2005-12-27 devnull {
272 3e0d8fb3 2005-12-27 devnull Mfile **l;
273 3e0d8fb3 2005-12-27 devnull
274 3e0d8fb3 2005-12-27 devnull lock(&mfalloc.lk);
275 3e0d8fb3 2005-12-27 devnull for(l = &mfalloc.inuse; *l != nil; l = &(*l)->next){
276 3e0d8fb3 2005-12-27 devnull if(*l == mf){
277 3e0d8fb3 2005-12-27 devnull *l = mf->next;
278 3e0d8fb3 2005-12-27 devnull if(mf->user)
279 3e0d8fb3 2005-12-27 devnull free(mf->user);
280 3e0d8fb3 2005-12-27 devnull free(mf);
281 3e0d8fb3 2005-12-27 devnull unlock(&mfalloc.lk);
282 3e0d8fb3 2005-12-27 devnull return;
283 3e0d8fb3 2005-12-27 devnull }
284 3e0d8fb3 2005-12-27 devnull }
285 3e0d8fb3 2005-12-27 devnull sysfatal("freeing unused fid");
286 3e0d8fb3 2005-12-27 devnull }
287 3e0d8fb3 2005-12-27 devnull
288 3e0d8fb3 2005-12-27 devnull Mfile*
289 3e0d8fb3 2005-12-27 devnull copyfid(Mfile *mf, int fid)
290 3e0d8fb3 2005-12-27 devnull {
291 3e0d8fb3 2005-12-27 devnull Mfile *nmf;
292 3e0d8fb3 2005-12-27 devnull
293 3e0d8fb3 2005-12-27 devnull nmf = newfid(fid, 1);
294 3e0d8fb3 2005-12-27 devnull if(nmf == nil)
295 3e0d8fb3 2005-12-27 devnull return nil;
296 3e0d8fb3 2005-12-27 devnull nmf->fid = fid;
297 3e0d8fb3 2005-12-27 devnull nmf->user = estrdup(mf->user);
298 3e0d8fb3 2005-12-27 devnull nmf->qid.type = mf->qid.type;
299 3e0d8fb3 2005-12-27 devnull nmf->qid.path = mf->qid.path;
300 3e0d8fb3 2005-12-27 devnull nmf->qid.vers = vers++;
301 3e0d8fb3 2005-12-27 devnull return nmf;
302 3e0d8fb3 2005-12-27 devnull }
303 3e0d8fb3 2005-12-27 devnull
304 3e0d8fb3 2005-12-27 devnull Job*
305 3e0d8fb3 2005-12-27 devnull newjob(void)
306 3e0d8fb3 2005-12-27 devnull {
307 3e0d8fb3 2005-12-27 devnull Job *job;
308 3e0d8fb3 2005-12-27 devnull
309 3e0d8fb3 2005-12-27 devnull job = emalloc(sizeof(*job));
310 3e0d8fb3 2005-12-27 devnull lock(&joblock);
311 3e0d8fb3 2005-12-27 devnull job->next = joblist;
312 3e0d8fb3 2005-12-27 devnull joblist = job;
313 3e0d8fb3 2005-12-27 devnull job->request.tag = -1;
314 3e0d8fb3 2005-12-27 devnull unlock(&joblock);
315 3e0d8fb3 2005-12-27 devnull return job;
316 3e0d8fb3 2005-12-27 devnull }
317 3e0d8fb3 2005-12-27 devnull
318 3e0d8fb3 2005-12-27 devnull void
319 3e0d8fb3 2005-12-27 devnull freejob(Job *job)
320 3e0d8fb3 2005-12-27 devnull {
321 3e0d8fb3 2005-12-27 devnull Job **l;
322 3e0d8fb3 2005-12-27 devnull
323 3e0d8fb3 2005-12-27 devnull lock(&joblock);
324 3e0d8fb3 2005-12-27 devnull for(l = &joblist; *l; l = &(*l)->next){
325 3e0d8fb3 2005-12-27 devnull if((*l) == job){
326 3e0d8fb3 2005-12-27 devnull *l = job->next;
327 3e0d8fb3 2005-12-27 devnull free(job);
328 3e0d8fb3 2005-12-27 devnull break;
329 3e0d8fb3 2005-12-27 devnull }
330 3e0d8fb3 2005-12-27 devnull }
331 3e0d8fb3 2005-12-27 devnull unlock(&joblock);
332 3e0d8fb3 2005-12-27 devnull }
333 3e0d8fb3 2005-12-27 devnull
334 3e0d8fb3 2005-12-27 devnull void
335 3e0d8fb3 2005-12-27 devnull flushjob(int tag)
336 3e0d8fb3 2005-12-27 devnull {
337 3e0d8fb3 2005-12-27 devnull Job *job;
338 3e0d8fb3 2005-12-27 devnull
339 3e0d8fb3 2005-12-27 devnull lock(&joblock);
340 3e0d8fb3 2005-12-27 devnull for(job = joblist; job; job = job->next){
341 3e0d8fb3 2005-12-27 devnull if(job->request.tag == tag && job->request.type != Tflush){
342 3e0d8fb3 2005-12-27 devnull job->flushed = 1;
343 3e0d8fb3 2005-12-27 devnull break;
344 3e0d8fb3 2005-12-27 devnull }
345 3e0d8fb3 2005-12-27 devnull }
346 3e0d8fb3 2005-12-27 devnull unlock(&joblock);
347 3e0d8fb3 2005-12-27 devnull }
348 3e0d8fb3 2005-12-27 devnull
349 3e0d8fb3 2005-12-27 devnull void
350 5c9f76b5 2006-02-14 devnull ioproc0(void *v)
351 3e0d8fb3 2005-12-27 devnull {
352 3e0d8fb3 2005-12-27 devnull long n;
353 3e0d8fb3 2005-12-27 devnull Mfile *mf;
354 3e0d8fb3 2005-12-27 devnull uchar mdata[IOHDRSZ + Maxfdata];
355 3e0d8fb3 2005-12-27 devnull Request req;
356 3e0d8fb3 2005-12-27 devnull Job *job;
357 3e0d8fb3 2005-12-27 devnull
358 5c9f76b5 2006-02-14 devnull USED(v);
359 5c9f76b5 2006-02-14 devnull
360 3e0d8fb3 2005-12-27 devnull for(;;){
361 3e0d8fb3 2005-12-27 devnull n = read9pmsg(mfd[0], mdata, sizeof mdata);
362 19256e0d 2006-02-17 devnull if(n <= 0){
363 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "error reading mntpt: %r");
364 5c9f76b5 2006-02-14 devnull break;
365 3e0d8fb3 2005-12-27 devnull }
366 3e0d8fb3 2005-12-27 devnull job = newjob();
367 3e0d8fb3 2005-12-27 devnull if(convM2S(mdata, n, &job->request) != n){
368 3e0d8fb3 2005-12-27 devnull freejob(job);
369 3e0d8fb3 2005-12-27 devnull continue;
370 3e0d8fb3 2005-12-27 devnull }
371 3e0d8fb3 2005-12-27 devnull if(debug)
372 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "%F", &job->request);
373 3e0d8fb3 2005-12-27 devnull
374 3e0d8fb3 2005-12-27 devnull getactivity(&req);
375 3e0d8fb3 2005-12-27 devnull req.aborttime = now + 60; /* don't spend more than 60 seconds */
376 387ae1db 2006-02-02 devnull
377 387ae1db 2006-02-02 devnull mf = nil;
378 387ae1db 2006-02-02 devnull switch(job->request.type){
379 387ae1db 2006-02-02 devnull case Tversion:
380 387ae1db 2006-02-02 devnull case Tauth:
381 387ae1db 2006-02-02 devnull case Tflush:
382 387ae1db 2006-02-02 devnull break;
383 387ae1db 2006-02-02 devnull case Tattach:
384 387ae1db 2006-02-02 devnull mf = newfid(job->request.fid, 1);
385 387ae1db 2006-02-02 devnull if(mf == nil){
386 387ae1db 2006-02-02 devnull sendmsg(job, "fid in use");
387 387ae1db 2006-02-02 devnull goto skip;
388 387ae1db 2006-02-02 devnull }
389 387ae1db 2006-02-02 devnull break;
390 387ae1db 2006-02-02 devnull default:
391 387ae1db 2006-02-02 devnull mf = newfid(job->request.fid, 0);
392 387ae1db 2006-02-02 devnull if(mf == nil){
393 387ae1db 2006-02-02 devnull sendmsg(job, "unknown fid");
394 387ae1db 2006-02-02 devnull goto skip;
395 387ae1db 2006-02-02 devnull }
396 387ae1db 2006-02-02 devnull break;
397 387ae1db 2006-02-02 devnull }
398 3e0d8fb3 2005-12-27 devnull
399 3e0d8fb3 2005-12-27 devnull switch(job->request.type){
400 3e0d8fb3 2005-12-27 devnull default:
401 3e0d8fb3 2005-12-27 devnull syslog(1, logfile, "unknown request type %d", job->request.type);
402 3e0d8fb3 2005-12-27 devnull break;
403 3e0d8fb3 2005-12-27 devnull case Tversion:
404 3e0d8fb3 2005-12-27 devnull rversion(job);
405 3e0d8fb3 2005-12-27 devnull break;
406 3e0d8fb3 2005-12-27 devnull case Tauth:
407 3e0d8fb3 2005-12-27 devnull rauth(job);
408 3e0d8fb3 2005-12-27 devnull break;
409 3e0d8fb3 2005-12-27 devnull case Tflush:
410 3e0d8fb3 2005-12-27 devnull rflush(job);
411 3e0d8fb3 2005-12-27 devnull break;
412 3e0d8fb3 2005-12-27 devnull case Tattach:
413 3e0d8fb3 2005-12-27 devnull rattach(job, mf);
414 3e0d8fb3 2005-12-27 devnull break;
415 3e0d8fb3 2005-12-27 devnull case Twalk:
416 3e0d8fb3 2005-12-27 devnull rwalk(job, mf);
417 3e0d8fb3 2005-12-27 devnull break;
418 3e0d8fb3 2005-12-27 devnull case Topen:
419 3e0d8fb3 2005-12-27 devnull ropen(job, mf);
420 3e0d8fb3 2005-12-27 devnull break;
421 3e0d8fb3 2005-12-27 devnull case Tcreate:
422 3e0d8fb3 2005-12-27 devnull rcreate(job, mf);
423 3e0d8fb3 2005-12-27 devnull break;
424 3e0d8fb3 2005-12-27 devnull case Tread:
425 3e0d8fb3 2005-12-27 devnull rread(job, mf);
426 3e0d8fb3 2005-12-27 devnull break;
427 3e0d8fb3 2005-12-27 devnull case Twrite:
428 3e0d8fb3 2005-12-27 devnull rwrite(job, mf, &req);
429 3e0d8fb3 2005-12-27 devnull break;
430 3e0d8fb3 2005-12-27 devnull case Tclunk:
431 3e0d8fb3 2005-12-27 devnull rclunk(job, mf);
432 3e0d8fb3 2005-12-27 devnull break;
433 3e0d8fb3 2005-12-27 devnull case Tremove:
434 3e0d8fb3 2005-12-27 devnull rremove(job, mf);
435 3e0d8fb3 2005-12-27 devnull break;
436 3e0d8fb3 2005-12-27 devnull case Tstat:
437 3e0d8fb3 2005-12-27 devnull rstat(job, mf);
438 3e0d8fb3 2005-12-27 devnull break;
439 3e0d8fb3 2005-12-27 devnull case Twstat:
440 3e0d8fb3 2005-12-27 devnull rwstat(job, mf);
441 3e0d8fb3 2005-12-27 devnull break;
442 3e0d8fb3 2005-12-27 devnull }
443 387ae1db 2006-02-02 devnull skip:
444 3e0d8fb3 2005-12-27 devnull freejob(job);
445 3e0d8fb3 2005-12-27 devnull putactivity();
446 3e0d8fb3 2005-12-27 devnull }
447 3e0d8fb3 2005-12-27 devnull }
448 3e0d8fb3 2005-12-27 devnull
449 3e0d8fb3 2005-12-27 devnull void
450 5c9f76b5 2006-02-14 devnull io(void)
451 5c9f76b5 2006-02-14 devnull {
452 5c9f76b5 2006-02-14 devnull int i;
453 5c9f76b5 2006-02-14 devnull
454 5c9f76b5 2006-02-14 devnull for(i=0; i<Maxactive; i++)
455 5c9f76b5 2006-02-14 devnull proccreate(ioproc0, 0, STACK);
456 5c9f76b5 2006-02-14 devnull }
457 5c9f76b5 2006-02-14 devnull
458 5c9f76b5 2006-02-14 devnull void
459 3e0d8fb3 2005-12-27 devnull rversion(Job *job)
460 3e0d8fb3 2005-12-27 devnull {
461 3e0d8fb3 2005-12-27 devnull if(job->request.msize > IOHDRSZ + Maxfdata)
462 3e0d8fb3 2005-12-27 devnull job->reply.msize = IOHDRSZ + Maxfdata;
463 3e0d8fb3 2005-12-27 devnull else
464 3e0d8fb3 2005-12-27 devnull job->reply.msize = job->request.msize;
465 3e0d8fb3 2005-12-27 devnull if(strncmp(job->request.version, "9P2000", 6) != 0)
466 3e0d8fb3 2005-12-27 devnull sendmsg(job, "unknown 9P version");
467 3e0d8fb3 2005-12-27 devnull else{
468 3e0d8fb3 2005-12-27 devnull job->reply.version = "9P2000";
469 3e0d8fb3 2005-12-27 devnull sendmsg(job, 0);
470 3e0d8fb3 2005-12-27 devnull }
471 3e0d8fb3 2005-12-27 devnull }
472 3e0d8fb3 2005-12-27 devnull
473 3e0d8fb3 2005-12-27 devnull void
474 3e0d8fb3 2005-12-27 devnull rauth(Job *job)
475 3e0d8fb3 2005-12-27 devnull {
476 3e0d8fb3 2005-12-27 devnull sendmsg(job, "dns: authentication not required");
477 3e0d8fb3 2005-12-27 devnull }
478 3e0d8fb3 2005-12-27 devnull
479 3e0d8fb3 2005-12-27 devnull /*
480 3e0d8fb3 2005-12-27 devnull * don't flush till all the slaves are done
481 3e0d8fb3 2005-12-27 devnull */
482 3e0d8fb3 2005-12-27 devnull void
483 3e0d8fb3 2005-12-27 devnull rflush(Job *job)
484 3e0d8fb3 2005-12-27 devnull {
485 3e0d8fb3 2005-12-27 devnull flushjob(job->request.oldtag);
486 3e0d8fb3 2005-12-27 devnull sendmsg(job, 0);
487 3e0d8fb3 2005-12-27 devnull }
488 3e0d8fb3 2005-12-27 devnull
489 3e0d8fb3 2005-12-27 devnull void
490 3e0d8fb3 2005-12-27 devnull rattach(Job *job, Mfile *mf)
491 3e0d8fb3 2005-12-27 devnull {
492 3e0d8fb3 2005-12-27 devnull if(mf->user != nil)
493 3e0d8fb3 2005-12-27 devnull free(mf->user);
494 3e0d8fb3 2005-12-27 devnull mf->user = estrdup(job->request.uname);
495 3e0d8fb3 2005-12-27 devnull mf->qid.vers = vers++;
496 3e0d8fb3 2005-12-27 devnull mf->qid.type = QTDIR;
497 3e0d8fb3 2005-12-27 devnull mf->qid.path = 0LL;
498 3e0d8fb3 2005-12-27 devnull job->reply.qid = mf->qid;
499 3e0d8fb3 2005-12-27 devnull sendmsg(job, 0);
500 3e0d8fb3 2005-12-27 devnull }
501 3e0d8fb3 2005-12-27 devnull
502 3e0d8fb3 2005-12-27 devnull char*
503 3e0d8fb3 2005-12-27 devnull rwalk(Job *job, Mfile *mf)
504 3e0d8fb3 2005-12-27 devnull {
505 3e0d8fb3 2005-12-27 devnull char *err;
506 3e0d8fb3 2005-12-27 devnull char **elems;
507 3e0d8fb3 2005-12-27 devnull int nelems;
508 3e0d8fb3 2005-12-27 devnull int i;
509 3e0d8fb3 2005-12-27 devnull Mfile *nmf;
510 3e0d8fb3 2005-12-27 devnull Qid qid;
511 3e0d8fb3 2005-12-27 devnull
512 3e0d8fb3 2005-12-27 devnull err = 0;
513 3e0d8fb3 2005-12-27 devnull nmf = nil;
514 3e0d8fb3 2005-12-27 devnull elems = job->request.wname;
515 3e0d8fb3 2005-12-27 devnull nelems = job->request.nwname;
516 3e0d8fb3 2005-12-27 devnull job->reply.nwqid = 0;
517 3e0d8fb3 2005-12-27 devnull
518 3e0d8fb3 2005-12-27 devnull if(job->request.newfid != job->request.fid){
519 3e0d8fb3 2005-12-27 devnull /* clone fid */
520 3e0d8fb3 2005-12-27 devnull if(job->request.newfid<0){
521 3e0d8fb3 2005-12-27 devnull err = "clone newfid out of range";
522 3e0d8fb3 2005-12-27 devnull goto send;
523 3e0d8fb3 2005-12-27 devnull }
524 3e0d8fb3 2005-12-27 devnull nmf = copyfid(mf, job->request.newfid);
525 3e0d8fb3 2005-12-27 devnull if(nmf == nil){
526 3e0d8fb3 2005-12-27 devnull err = "clone bad newfid";
527 3e0d8fb3 2005-12-27 devnull goto send;
528 3e0d8fb3 2005-12-27 devnull }
529 3e0d8fb3 2005-12-27 devnull mf = nmf;
530 3e0d8fb3 2005-12-27 devnull }
531 3e0d8fb3 2005-12-27 devnull /* else nmf will be nil */
532 3e0d8fb3 2005-12-27 devnull
533 3e0d8fb3 2005-12-27 devnull qid = mf->qid;
534 3e0d8fb3 2005-12-27 devnull if(nelems > 0){
535 3e0d8fb3 2005-12-27 devnull /* walk fid */
536 3e0d8fb3 2005-12-27 devnull for(i=0; i<nelems && i<MAXWELEM; i++){
537 3e0d8fb3 2005-12-27 devnull if((qid.type & QTDIR) == 0){
538 3e0d8fb3 2005-12-27 devnull err = "not a directory";
539 3e0d8fb3 2005-12-27 devnull break;
540 3e0d8fb3 2005-12-27 devnull }
541 3e0d8fb3 2005-12-27 devnull if(strcmp(elems[i], "..") == 0 || strcmp(elems[i], ".") == 0){
542 3e0d8fb3 2005-12-27 devnull qid.type = QTDIR;
543 3e0d8fb3 2005-12-27 devnull qid.path = Qdir;
544 3e0d8fb3 2005-12-27 devnull Found:
545 3e0d8fb3 2005-12-27 devnull job->reply.wqid[i] = qid;
546 3e0d8fb3 2005-12-27 devnull job->reply.nwqid++;
547 3e0d8fb3 2005-12-27 devnull continue;
548 3e0d8fb3 2005-12-27 devnull }
549 3e0d8fb3 2005-12-27 devnull if(strcmp(elems[i], "dns") == 0){
550 3e0d8fb3 2005-12-27 devnull qid.type = QTFILE;
551 3e0d8fb3 2005-12-27 devnull qid.path = Qdns;
552 3e0d8fb3 2005-12-27 devnull goto Found;
553 3e0d8fb3 2005-12-27 devnull }
554 3e0d8fb3 2005-12-27 devnull err = "file does not exist";
555 3e0d8fb3 2005-12-27 devnull break;
556 3e0d8fb3 2005-12-27 devnull }
557 3e0d8fb3 2005-12-27 devnull }
558 3e0d8fb3 2005-12-27 devnull
559 3e0d8fb3 2005-12-27 devnull send:
560 3e0d8fb3 2005-12-27 devnull if(nmf != nil && (err!=nil || job->reply.nwqid<nelems))
561 3e0d8fb3 2005-12-27 devnull freefid(nmf);
562 3e0d8fb3 2005-12-27 devnull if(err == nil)
563 3e0d8fb3 2005-12-27 devnull mf->qid = qid;
564 3e0d8fb3 2005-12-27 devnull sendmsg(job, err);
565 3e0d8fb3 2005-12-27 devnull return err;
566 3e0d8fb3 2005-12-27 devnull }
567 3e0d8fb3 2005-12-27 devnull
568 3e0d8fb3 2005-12-27 devnull void
569 3e0d8fb3 2005-12-27 devnull ropen(Job *job, Mfile *mf)
570 3e0d8fb3 2005-12-27 devnull {
571 3e0d8fb3 2005-12-27 devnull int mode;
572 3e0d8fb3 2005-12-27 devnull char *err;
573 3e0d8fb3 2005-12-27 devnull
574 3e0d8fb3 2005-12-27 devnull err = 0;
575 3e0d8fb3 2005-12-27 devnull mode = job->request.mode;
576 3e0d8fb3 2005-12-27 devnull if(mf->qid.type & QTDIR){
577 3e0d8fb3 2005-12-27 devnull if(mode)
578 3e0d8fb3 2005-12-27 devnull err = "permission denied";
579 3e0d8fb3 2005-12-27 devnull }
580 3e0d8fb3 2005-12-27 devnull job->reply.qid = mf->qid;
581 3e0d8fb3 2005-12-27 devnull job->reply.iounit = 0;
582 3e0d8fb3 2005-12-27 devnull sendmsg(job, err);
583 3e0d8fb3 2005-12-27 devnull }
584 3e0d8fb3 2005-12-27 devnull
585 3e0d8fb3 2005-12-27 devnull void
586 3e0d8fb3 2005-12-27 devnull rcreate(Job *job, Mfile *mf)
587 3e0d8fb3 2005-12-27 devnull {
588 3e0d8fb3 2005-12-27 devnull USED(mf);
589 3e0d8fb3 2005-12-27 devnull sendmsg(job, "creation permission denied");
590 3e0d8fb3 2005-12-27 devnull }
591 3e0d8fb3 2005-12-27 devnull
592 3e0d8fb3 2005-12-27 devnull void
593 3e0d8fb3 2005-12-27 devnull rread(Job *job, Mfile *mf)
594 3e0d8fb3 2005-12-27 devnull {
595 3e0d8fb3 2005-12-27 devnull int i, n, cnt;
596 3e0d8fb3 2005-12-27 devnull long off;
597 3e0d8fb3 2005-12-27 devnull Dir dir;
598 3e0d8fb3 2005-12-27 devnull uchar buf[Maxfdata];
599 3e0d8fb3 2005-12-27 devnull char *err;
600 3e0d8fb3 2005-12-27 devnull long clock;
601 3e0d8fb3 2005-12-27 devnull
602 3e0d8fb3 2005-12-27 devnull n = 0;
603 3e0d8fb3 2005-12-27 devnull err = 0;
604 3e0d8fb3 2005-12-27 devnull off = job->request.offset;
605 3e0d8fb3 2005-12-27 devnull cnt = job->request.count;
606 3e0d8fb3 2005-12-27 devnull if(mf->qid.type & QTDIR){
607 3e0d8fb3 2005-12-27 devnull clock = time(0);
608 3e0d8fb3 2005-12-27 devnull if(off == 0){
609 3e0d8fb3 2005-12-27 devnull dir.name = "dns";
610 3e0d8fb3 2005-12-27 devnull dir.qid.type = QTFILE;
611 3e0d8fb3 2005-12-27 devnull dir.qid.vers = vers;
612 3e0d8fb3 2005-12-27 devnull dir.qid.path = Qdns;
613 3e0d8fb3 2005-12-27 devnull dir.mode = 0666;
614 3e0d8fb3 2005-12-27 devnull dir.length = 0;
615 3e0d8fb3 2005-12-27 devnull dir.uid = mf->user;
616 3e0d8fb3 2005-12-27 devnull dir.gid = mf->user;
617 3e0d8fb3 2005-12-27 devnull dir.muid = mf->user;
618 3e0d8fb3 2005-12-27 devnull dir.atime = clock; /* wrong */
619 3e0d8fb3 2005-12-27 devnull dir.mtime = clock; /* wrong */
620 3e0d8fb3 2005-12-27 devnull n = convD2M(&dir, buf, sizeof buf);
621 3e0d8fb3 2005-12-27 devnull }
622 3e0d8fb3 2005-12-27 devnull job->reply.data = (char*)buf;
623 3e0d8fb3 2005-12-27 devnull } else {
624 3e0d8fb3 2005-12-27 devnull for(i = 1; i <= mf->nrr; i++)
625 3e0d8fb3 2005-12-27 devnull if(mf->rr[i] > off)
626 3e0d8fb3 2005-12-27 devnull break;
627 3e0d8fb3 2005-12-27 devnull if(i > mf->nrr)
628 3e0d8fb3 2005-12-27 devnull goto send;
629 3e0d8fb3 2005-12-27 devnull if(off + cnt > mf->rr[i])
630 3e0d8fb3 2005-12-27 devnull n = mf->rr[i] - off;
631 3e0d8fb3 2005-12-27 devnull else
632 3e0d8fb3 2005-12-27 devnull n = cnt;
633 3e0d8fb3 2005-12-27 devnull job->reply.data = mf->reply + off;
634 3e0d8fb3 2005-12-27 devnull }
635 3e0d8fb3 2005-12-27 devnull send:
636 3e0d8fb3 2005-12-27 devnull job->reply.count = n;
637 3e0d8fb3 2005-12-27 devnull sendmsg(job, err);
638 3e0d8fb3 2005-12-27 devnull }
639 3e0d8fb3 2005-12-27 devnull
640 3e0d8fb3 2005-12-27 devnull void
641 3e0d8fb3 2005-12-27 devnull rwrite(Job *job, Mfile *mf, Request *req)
642 3e0d8fb3 2005-12-27 devnull {
643 3e0d8fb3 2005-12-27 devnull int cnt, rooted, status;
644 3e0d8fb3 2005-12-27 devnull long n;
645 3e0d8fb3 2005-12-27 devnull char *err, *p, *atype;
646 3e0d8fb3 2005-12-27 devnull RR *rp, *tp, *neg;
647 3e0d8fb3 2005-12-27 devnull int wantsav;
648 5c9f76b5 2006-02-14 devnull static char *dumpfile;
649 3e0d8fb3 2005-12-27 devnull
650 3e0d8fb3 2005-12-27 devnull err = 0;
651 3e0d8fb3 2005-12-27 devnull cnt = job->request.count;
652 3e0d8fb3 2005-12-27 devnull if(mf->qid.type & QTDIR){
653 3e0d8fb3 2005-12-27 devnull err = "can't write directory";
654 3e0d8fb3 2005-12-27 devnull goto send;
655 3e0d8fb3 2005-12-27 devnull }
656 3e0d8fb3 2005-12-27 devnull if(cnt >= Maxrequest){
657 3e0d8fb3 2005-12-27 devnull err = "request too long";
658 3e0d8fb3 2005-12-27 devnull goto send;
659 3e0d8fb3 2005-12-27 devnull }
660 3e0d8fb3 2005-12-27 devnull job->request.data[cnt] = 0;
661 3e0d8fb3 2005-12-27 devnull if(cnt > 0 && job->request.data[cnt-1] == '\n')
662 3e0d8fb3 2005-12-27 devnull job->request.data[cnt-1] = 0;
663 3e0d8fb3 2005-12-27 devnull
664 3e0d8fb3 2005-12-27 devnull /*
665 3e0d8fb3 2005-12-27 devnull * special commands
666 3e0d8fb3 2005-12-27 devnull */
667 5c9f76b5 2006-02-14 devnull p = job->request.data;
668 5c9f76b5 2006-02-14 devnull if(strcmp(p, "debug")==0){
669 3e0d8fb3 2005-12-27 devnull debug ^= 1;
670 3e0d8fb3 2005-12-27 devnull goto send;
671 5c9f76b5 2006-02-14 devnull } else if(strcmp(p, "dump")==0){
672 5c9f76b5 2006-02-14 devnull if(dumpfile == nil)
673 5c9f76b5 2006-02-14 devnull dumpfile = unsharp("#9/ndb/dnsdump");
674 5c9f76b5 2006-02-14 devnull dndump(dumpfile);
675 3e0d8fb3 2005-12-27 devnull goto send;
676 5c9f76b5 2006-02-14 devnull } else if(strncmp(p, "dump ", 5) == 0){
677 19256e0d 2006-02-17 devnull if(*(p+5))
678 19256e0d 2006-02-17 devnull dndump(p+5);
679 19256e0d 2006-02-17 devnull else
680 19256e0d 2006-02-17 devnull err = "bad filename";
681 5c9f76b5 2006-02-14 devnull goto send;
682 5c9f76b5 2006-02-14 devnull } else if(strcmp(p, "refresh")==0){
683 3e0d8fb3 2005-12-27 devnull needrefresh = 1;
684 3e0d8fb3 2005-12-27 devnull goto send;
685 3e0d8fb3 2005-12-27 devnull }
686 3e0d8fb3 2005-12-27 devnull
687 3e0d8fb3 2005-12-27 devnull /*
688 3e0d8fb3 2005-12-27 devnull * kill previous reply
689 3e0d8fb3 2005-12-27 devnull */
690 3e0d8fb3 2005-12-27 devnull mf->nrr = 0;
691 3e0d8fb3 2005-12-27 devnull mf->rr[0] = 0;
692 3e0d8fb3 2005-12-27 devnull
693 3e0d8fb3 2005-12-27 devnull /*
694 3e0d8fb3 2005-12-27 devnull * break up request (into a name and a type)
695 3e0d8fb3 2005-12-27 devnull */
696 3e0d8fb3 2005-12-27 devnull atype = strchr(job->request.data, ' ');
697 3e0d8fb3 2005-12-27 devnull if(atype == 0){
698 3e0d8fb3 2005-12-27 devnull err = "illegal request";
699 3e0d8fb3 2005-12-27 devnull goto send;
700 3e0d8fb3 2005-12-27 devnull } else
701 3e0d8fb3 2005-12-27 devnull *atype++ = 0;
702 3e0d8fb3 2005-12-27 devnull
703 3e0d8fb3 2005-12-27 devnull /*
704 3e0d8fb3 2005-12-27 devnull * tracing request
705 3e0d8fb3 2005-12-27 devnull */
706 3e0d8fb3 2005-12-27 devnull if(strcmp(atype, "trace") == 0){
707 3e0d8fb3 2005-12-27 devnull if(trace)
708 3e0d8fb3 2005-12-27 devnull free(trace);
709 3e0d8fb3 2005-12-27 devnull if(*job->request.data)
710 3e0d8fb3 2005-12-27 devnull trace = estrdup(job->request.data);
711 3e0d8fb3 2005-12-27 devnull else
712 3e0d8fb3 2005-12-27 devnull trace = 0;
713 3e0d8fb3 2005-12-27 devnull goto send;
714 3e0d8fb3 2005-12-27 devnull }
715 3e0d8fb3 2005-12-27 devnull
716 3e0d8fb3 2005-12-27 devnull mf->type = rrtype(atype);
717 3e0d8fb3 2005-12-27 devnull if(mf->type < 0){
718 3e0d8fb3 2005-12-27 devnull err = "unknown type";
719 3e0d8fb3 2005-12-27 devnull goto send;
720 3e0d8fb3 2005-12-27 devnull }
721 3e0d8fb3 2005-12-27 devnull
722 3e0d8fb3 2005-12-27 devnull p = atype - 2;
723 3e0d8fb3 2005-12-27 devnull if(p >= job->request.data && *p == '.'){
724 3e0d8fb3 2005-12-27 devnull rooted = 1;
725 3e0d8fb3 2005-12-27 devnull *p = 0;
726 3e0d8fb3 2005-12-27 devnull } else
727 3e0d8fb3 2005-12-27 devnull rooted = 0;
728 3e0d8fb3 2005-12-27 devnull
729 3e0d8fb3 2005-12-27 devnull p = job->request.data;
730 3e0d8fb3 2005-12-27 devnull if(*p == '!'){
731 3e0d8fb3 2005-12-27 devnull wantsav = 1;
732 3e0d8fb3 2005-12-27 devnull p++;
733 3e0d8fb3 2005-12-27 devnull } else
734 3e0d8fb3 2005-12-27 devnull wantsav = 0;
735 3e0d8fb3 2005-12-27 devnull dncheck(0, 1);
736 3e0d8fb3 2005-12-27 devnull rp = dnresolve(p, Cin, mf->type, req, 0, 0, Recurse, rooted, &status);
737 3e0d8fb3 2005-12-27 devnull dncheck(0, 1);
738 3e0d8fb3 2005-12-27 devnull neg = rrremneg(&rp);
739 3e0d8fb3 2005-12-27 devnull if(neg){
740 3e0d8fb3 2005-12-27 devnull status = neg->negrcode;
741 3e0d8fb3 2005-12-27 devnull rrfreelist(neg);
742 3e0d8fb3 2005-12-27 devnull }
743 3e0d8fb3 2005-12-27 devnull if(rp == 0){
744 3e0d8fb3 2005-12-27 devnull switch(status){
745 3e0d8fb3 2005-12-27 devnull case Rname:
746 3e0d8fb3 2005-12-27 devnull err = "name does not exist";
747 3e0d8fb3 2005-12-27 devnull break;
748 3e0d8fb3 2005-12-27 devnull case Rserver:
749 3e0d8fb3 2005-12-27 devnull err = "dns failure";
750 3e0d8fb3 2005-12-27 devnull break;
751 3e0d8fb3 2005-12-27 devnull default:
752 3e0d8fb3 2005-12-27 devnull err = "resource does not exist";
753 3e0d8fb3 2005-12-27 devnull break;
754 3e0d8fb3 2005-12-27 devnull }
755 3e0d8fb3 2005-12-27 devnull } else {
756 3e0d8fb3 2005-12-27 devnull lock(&joblock);
757 3e0d8fb3 2005-12-27 devnull if(!job->flushed){
758 3e0d8fb3 2005-12-27 devnull /* format data to be read later */
759 3e0d8fb3 2005-12-27 devnull n = 0;
760 3e0d8fb3 2005-12-27 devnull mf->nrr = 0;
761 3e0d8fb3 2005-12-27 devnull for(tp = rp; mf->nrr < Maxrrr-1 && n < Maxreply && tp &&
762 3e0d8fb3 2005-12-27 devnull tsame(mf->type, tp->type); tp = tp->next){
763 3e0d8fb3 2005-12-27 devnull mf->rr[mf->nrr++] = n;
764 3e0d8fb3 2005-12-27 devnull if(wantsav)
765 3e0d8fb3 2005-12-27 devnull n += snprint(mf->reply+n, Maxreply-n, "%Q", tp);
766 3e0d8fb3 2005-12-27 devnull else
767 3e0d8fb3 2005-12-27 devnull n += snprint(mf->reply+n, Maxreply-n, "%R", tp);
768 3e0d8fb3 2005-12-27 devnull }
769 3e0d8fb3 2005-12-27 devnull mf->rr[mf->nrr] = n;
770 3e0d8fb3 2005-12-27 devnull }
771 3e0d8fb3 2005-12-27 devnull unlock(&joblock);
772 3e0d8fb3 2005-12-27 devnull rrfreelist(rp);
773 3e0d8fb3 2005-12-27 devnull }
774 3e0d8fb3 2005-12-27 devnull
775 3e0d8fb3 2005-12-27 devnull send:
776 3e0d8fb3 2005-12-27 devnull dncheck(0, 1);
777 3e0d8fb3 2005-12-27 devnull job->reply.count = cnt;
778 3e0d8fb3 2005-12-27 devnull sendmsg(job, err);
779 3e0d8fb3 2005-12-27 devnull }
780 3e0d8fb3 2005-12-27 devnull
781 3e0d8fb3 2005-12-27 devnull void
782 3e0d8fb3 2005-12-27 devnull rclunk(Job *job, Mfile *mf)
783 3e0d8fb3 2005-12-27 devnull {
784 3e0d8fb3 2005-12-27 devnull freefid(mf);
785 3e0d8fb3 2005-12-27 devnull sendmsg(job, 0);
786 3e0d8fb3 2005-12-27 devnull }
787 3e0d8fb3 2005-12-27 devnull
788 3e0d8fb3 2005-12-27 devnull void
789 3e0d8fb3 2005-12-27 devnull rremove(Job *job, Mfile *mf)
790 3e0d8fb3 2005-12-27 devnull {
791 3e0d8fb3 2005-12-27 devnull USED(mf);
792 3e0d8fb3 2005-12-27 devnull sendmsg(job, "remove permission denied");
793 3e0d8fb3 2005-12-27 devnull }
794 3e0d8fb3 2005-12-27 devnull
795 3e0d8fb3 2005-12-27 devnull void
796 3e0d8fb3 2005-12-27 devnull rstat(Job *job, Mfile *mf)
797 3e0d8fb3 2005-12-27 devnull {
798 3e0d8fb3 2005-12-27 devnull Dir dir;
799 3e0d8fb3 2005-12-27 devnull uchar buf[IOHDRSZ+Maxfdata];
800 3e0d8fb3 2005-12-27 devnull
801 3e0d8fb3 2005-12-27 devnull if(mf->qid.type & QTDIR){
802 3e0d8fb3 2005-12-27 devnull dir.name = ".";
803 3e0d8fb3 2005-12-27 devnull dir.mode = DMDIR|0555;
804 3e0d8fb3 2005-12-27 devnull } else {
805 3e0d8fb3 2005-12-27 devnull dir.name = "dns";
806 3e0d8fb3 2005-12-27 devnull dir.mode = 0666;
807 3e0d8fb3 2005-12-27 devnull }
808 3e0d8fb3 2005-12-27 devnull dir.qid = mf->qid;
809 3e0d8fb3 2005-12-27 devnull dir.length = 0;
810 3e0d8fb3 2005-12-27 devnull dir.uid = mf->user;
811 3e0d8fb3 2005-12-27 devnull dir.gid = mf->user;
812 3e0d8fb3 2005-12-27 devnull dir.muid = mf->user;
813 3e0d8fb3 2005-12-27 devnull dir.atime = dir.mtime = time(0);
814 3e0d8fb3 2005-12-27 devnull job->reply.nstat = convD2M(&dir, buf, sizeof buf);
815 3e0d8fb3 2005-12-27 devnull job->reply.stat = buf;
816 3e0d8fb3 2005-12-27 devnull sendmsg(job, 0);
817 3e0d8fb3 2005-12-27 devnull }
818 3e0d8fb3 2005-12-27 devnull
819 3e0d8fb3 2005-12-27 devnull void
820 3e0d8fb3 2005-12-27 devnull rwstat(Job *job, Mfile *mf)
821 3e0d8fb3 2005-12-27 devnull {
822 3e0d8fb3 2005-12-27 devnull USED(mf);
823 3e0d8fb3 2005-12-27 devnull sendmsg(job, "wstat permission denied");
824 3e0d8fb3 2005-12-27 devnull }
825 3e0d8fb3 2005-12-27 devnull
826 3e0d8fb3 2005-12-27 devnull void
827 3e0d8fb3 2005-12-27 devnull sendmsg(Job *job, char *err)
828 3e0d8fb3 2005-12-27 devnull {
829 3e0d8fb3 2005-12-27 devnull int n;
830 3e0d8fb3 2005-12-27 devnull uchar mdata[IOHDRSZ + Maxfdata];
831 3e0d8fb3 2005-12-27 devnull char ename[ERRMAX];
832 3e0d8fb3 2005-12-27 devnull
833 3e0d8fb3 2005-12-27 devnull if(err){
834 3e0d8fb3 2005-12-27 devnull job->reply.type = Rerror;
835 3e0d8fb3 2005-12-27 devnull snprint(ename, sizeof(ename), "dns: %s", err);
836 3e0d8fb3 2005-12-27 devnull job->reply.ename = ename;
837 3e0d8fb3 2005-12-27 devnull }else{
838 3e0d8fb3 2005-12-27 devnull job->reply.type = job->request.type+1;
839 3e0d8fb3 2005-12-27 devnull }
840 3e0d8fb3 2005-12-27 devnull job->reply.tag = job->request.tag;
841 3e0d8fb3 2005-12-27 devnull n = convS2M(&job->reply, mdata, sizeof mdata);
842 3e0d8fb3 2005-12-27 devnull if(n == 0){
843 3e0d8fb3 2005-12-27 devnull syslog(1, logfile, "sendmsg convS2M of %F returns 0", &job->reply);
844 3e0d8fb3 2005-12-27 devnull abort();
845 3e0d8fb3 2005-12-27 devnull }
846 3e0d8fb3 2005-12-27 devnull lock(&joblock);
847 3e0d8fb3 2005-12-27 devnull if(job->flushed == 0)
848 3e0d8fb3 2005-12-27 devnull if(write(mfd[1], mdata, n)!=n)
849 3e0d8fb3 2005-12-27 devnull sysfatal("mount write");
850 3e0d8fb3 2005-12-27 devnull unlock(&joblock);
851 3e0d8fb3 2005-12-27 devnull if(debug)
852 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "%F %d", &job->reply, n);
853 3e0d8fb3 2005-12-27 devnull }
854 3e0d8fb3 2005-12-27 devnull
855 3e0d8fb3 2005-12-27 devnull /*
856 3e0d8fb3 2005-12-27 devnull * the following varies between dnsdebug and dns
857 3e0d8fb3 2005-12-27 devnull */
858 3e0d8fb3 2005-12-27 devnull void
859 3e0d8fb3 2005-12-27 devnull logreply(int id, uchar *addr, DNSmsg *mp)
860 3e0d8fb3 2005-12-27 devnull {
861 3e0d8fb3 2005-12-27 devnull RR *rp;
862 3e0d8fb3 2005-12-27 devnull
863 3e0d8fb3 2005-12-27 devnull syslog(0, LOG, "%d: rcvd %I flags:%s%s%s%s%s", id, addr,
864 3e0d8fb3 2005-12-27 devnull mp->flags & Fauth ? " auth" : "",
865 3e0d8fb3 2005-12-27 devnull mp->flags & Ftrunc ? " trunc" : "",
866 3e0d8fb3 2005-12-27 devnull mp->flags & Frecurse ? " rd" : "",
867 3e0d8fb3 2005-12-27 devnull mp->flags & Fcanrec ? " ra" : "",
868 3e0d8fb3 2005-12-27 devnull mp->flags & (Fauth|Rname) == (Fauth|Rname) ?
869 3e0d8fb3 2005-12-27 devnull " nx" : "");
870 3e0d8fb3 2005-12-27 devnull for(rp = mp->qd; rp != nil; rp = rp->next)
871 3e0d8fb3 2005-12-27 devnull syslog(0, LOG, "%d: rcvd %I qd %s", id, addr, rp->owner->name);
872 3e0d8fb3 2005-12-27 devnull for(rp = mp->an; rp != nil; rp = rp->next)
873 3e0d8fb3 2005-12-27 devnull syslog(0, LOG, "%d: rcvd %I an %R", id, addr, rp);
874 3e0d8fb3 2005-12-27 devnull for(rp = mp->ns; rp != nil; rp = rp->next)
875 3e0d8fb3 2005-12-27 devnull syslog(0, LOG, "%d: rcvd %I ns %R", id, addr, rp);
876 3e0d8fb3 2005-12-27 devnull for(rp = mp->ar; rp != nil; rp = rp->next)
877 3e0d8fb3 2005-12-27 devnull syslog(0, LOG, "%d: rcvd %I ar %R", id, addr, rp);
878 3e0d8fb3 2005-12-27 devnull }
879 3e0d8fb3 2005-12-27 devnull
880 3e0d8fb3 2005-12-27 devnull void
881 3e0d8fb3 2005-12-27 devnull logsend(int id, int subid, uchar *addr, char *sname, char *rname, int type)
882 3e0d8fb3 2005-12-27 devnull {
883 3e0d8fb3 2005-12-27 devnull char buf[12];
884 3e0d8fb3 2005-12-27 devnull
885 3e0d8fb3 2005-12-27 devnull syslog(0, LOG, "%d.%d: sending to %I/%s %s %s",
886 3e0d8fb3 2005-12-27 devnull id, subid, addr, sname, rname, rrname(type, buf, sizeof buf));
887 3e0d8fb3 2005-12-27 devnull }
888 3e0d8fb3 2005-12-27 devnull
889 3e0d8fb3 2005-12-27 devnull RR*
890 3e0d8fb3 2005-12-27 devnull getdnsservers(int class)
891 3e0d8fb3 2005-12-27 devnull {
892 3e0d8fb3 2005-12-27 devnull return dnsservers(class);
893 3e0d8fb3 2005-12-27 devnull }