1 5cc53af9 2006-02-12 devnull #include <u.h>
2 5cc53af9 2006-02-12 devnull #include <sys/types.h>
3 5cc53af9 2006-02-12 devnull #include <pwd.h>
4 5cc53af9 2006-02-12 devnull #include <netdb.h>
5 5cdb1798 2005-10-29 devnull #include "common.h"
6 5cdb1798 2005-10-29 devnull #include <auth.h>
7 5cdb1798 2005-10-29 devnull #include <ndb.h>
10 5cdb1798 2005-10-29 devnull * number of predefined fd's
12 5cdb1798 2005-10-29 devnull int nsysfile=3;
14 5cdb1798 2005-10-29 devnull static char err[Errlen];
17 5cdb1798 2005-10-29 devnull * return the date
19 5cdb1798 2005-10-29 devnull extern char *
20 5cdb1798 2005-10-29 devnull thedate(void)
22 5cdb1798 2005-10-29 devnull static char now[64];
23 5cdb1798 2005-10-29 devnull char *cp;
25 5cdb1798 2005-10-29 devnull strcpy(now, ctime(time(0)));
26 5cdb1798 2005-10-29 devnull cp = strchr(now, '\n');
29 5cdb1798 2005-10-29 devnull return now;
33 5cdb1798 2005-10-29 devnull * return the user id of the current user
35 5cdb1798 2005-10-29 devnull extern char *
36 5cdb1798 2005-10-29 devnull getlog(void)
38 5cdb1798 2005-10-29 devnull return getuser();
42 5cdb1798 2005-10-29 devnull * return the lock name (we use one lock per directory)
44 5cdb1798 2005-10-29 devnull static String *
45 5cdb1798 2005-10-29 devnull lockname(char *path)
47 5cdb1798 2005-10-29 devnull String *lp;
48 5cdb1798 2005-10-29 devnull char *cp;
51 5cdb1798 2005-10-29 devnull * get the name of the lock file
53 5cdb1798 2005-10-29 devnull lp = s_new();
54 5cdb1798 2005-10-29 devnull cp = strrchr(path, '/');
56 5cdb1798 2005-10-29 devnull s_nappend(lp, path, cp - path + 1);
57 5cdb1798 2005-10-29 devnull s_append(lp, "L.mbox");
59 5cdb1798 2005-10-29 devnull return lp;
63 5cdb1798 2005-10-29 devnull syscreatelocked(char *path, int mode, int perm)
65 5cdb1798 2005-10-29 devnull return create(path, mode, DMEXCL|perm);
69 5cdb1798 2005-10-29 devnull sysopenlocked(char *path, int mode)
71 5cdb1798 2005-10-29 devnull /* return open(path, OEXCL|mode);/**/
72 5cdb1798 2005-10-29 devnull return open(path, mode); /* until system call is fixed */
76 5cdb1798 2005-10-29 devnull sysunlockfile(int fd)
78 5cdb1798 2005-10-29 devnull return close(fd);
82 5cdb1798 2005-10-29 devnull * try opening a lock file. If it doesn't exist try creating it.
84 5cdb1798 2005-10-29 devnull static int
85 5cdb1798 2005-10-29 devnull openlockfile(Mlock *l)
92 5cdb1798 2005-10-29 devnull fd = open(s_to_c(l->name), OREAD);
93 5cdb1798 2005-10-29 devnull if(fd >= 0){
94 5cdb1798 2005-10-29 devnull l->fd = fd;
95 5cdb1798 2005-10-29 devnull return 0;
98 5cdb1798 2005-10-29 devnull d = dirstat(s_to_c(l->name));
99 5cdb1798 2005-10-29 devnull if(d == nil){
100 5cdb1798 2005-10-29 devnull /* file doesn't exist */
101 5cdb1798 2005-10-29 devnull /* try creating it */
102 5cdb1798 2005-10-29 devnull fd = create(s_to_c(l->name), OREAD, DMEXCL|0666);
103 5cdb1798 2005-10-29 devnull if(fd >= 0){
104 5cdb1798 2005-10-29 devnull nulldir(&nd);
105 5cdb1798 2005-10-29 devnull nd.mode = DMEXCL|0666;
106 5cdb1798 2005-10-29 devnull if(dirfwstat(fd, &nd) < 0){
107 5cdb1798 2005-10-29 devnull /* if we can't chmod, don't bother */
108 5cdb1798 2005-10-29 devnull /* live without the lock but log it */
109 5cdb1798 2005-10-29 devnull syslog(0, "mail", "lock error: %s: %r", s_to_c(l->name));
110 5cdb1798 2005-10-29 devnull remove(s_to_c(l->name));
112 5cdb1798 2005-10-29 devnull l->fd = fd;
113 5cdb1798 2005-10-29 devnull return 0;
116 5cdb1798 2005-10-29 devnull /* couldn't create */
117 5cdb1798 2005-10-29 devnull /* do we have write access to the directory? */
118 5cdb1798 2005-10-29 devnull p = strrchr(s_to_c(l->name), '/');
119 5cdb1798 2005-10-29 devnull if(p != 0){
121 5cdb1798 2005-10-29 devnull fd = access(s_to_c(l->name), 2);
122 5cdb1798 2005-10-29 devnull *p = '/';
123 5cdb1798 2005-10-29 devnull if(fd < 0){
124 5cdb1798 2005-10-29 devnull /* live without the lock but log it */
125 5cdb1798 2005-10-29 devnull syslog(0, "mail", "lock error: %s: %r", s_to_c(l->name));
126 5cdb1798 2005-10-29 devnull return 0;
128 5cdb1798 2005-10-29 devnull } else {
129 5cdb1798 2005-10-29 devnull fd = access(".", 2);
130 5cdb1798 2005-10-29 devnull if(fd < 0){
131 5cdb1798 2005-10-29 devnull /* live without the lock but log it */
132 5cdb1798 2005-10-29 devnull syslog(0, "mail", "lock error: %s: %r", s_to_c(l->name));
133 5cdb1798 2005-10-29 devnull return 0;
137 5cdb1798 2005-10-29 devnull free(d);
139 5cdb1798 2005-10-29 devnull return 1; /* try again later */
142 5cdb1798 2005-10-29 devnull #define LSECS 5*60
145 5cdb1798 2005-10-29 devnull * Set a lock for a particular file. The lock is a file in the same directory
146 5cdb1798 2005-10-29 devnull * and has L. prepended to the name of the last element of the file name.
148 5cdb1798 2005-10-29 devnull extern Mlock *
149 5cdb1798 2005-10-29 devnull syslock(char *path)
151 5cdb1798 2005-10-29 devnull Mlock *l;
152 5cdb1798 2005-10-29 devnull int tries;
154 5cdb1798 2005-10-29 devnull l = mallocz(sizeof(Mlock), 1);
155 5cdb1798 2005-10-29 devnull if(l == 0)
156 5cdb1798 2005-10-29 devnull return nil;
158 5cdb1798 2005-10-29 devnull l->name = lockname(path);
161 5cdb1798 2005-10-29 devnull * wait LSECS seconds for it to unlock
163 5cdb1798 2005-10-29 devnull for(tries = 0; tries < LSECS*2; tries++){
164 5cdb1798 2005-10-29 devnull switch(openlockfile(l)){
166 5cdb1798 2005-10-29 devnull return l;
168 5cdb1798 2005-10-29 devnull sleep(500);
170 5cdb1798 2005-10-29 devnull default:
171 5cdb1798 2005-10-29 devnull goto noway;
176 5cdb1798 2005-10-29 devnull s_free(l->name);
177 5cdb1798 2005-10-29 devnull free(l);
178 5cdb1798 2005-10-29 devnull return nil;
182 5cdb1798 2005-10-29 devnull * like lock except don't wait
184 5cdb1798 2005-10-29 devnull extern Mlock *
185 5cdb1798 2005-10-29 devnull trylock(char *path)
187 5cdb1798 2005-10-29 devnull Mlock *l;
188 5cdb1798 2005-10-29 devnull char buf[1];
191 5cdb1798 2005-10-29 devnull l = malloc(sizeof(Mlock));
192 5cdb1798 2005-10-29 devnull if(l == 0)
193 5cdb1798 2005-10-29 devnull return 0;
195 5cdb1798 2005-10-29 devnull l->name = lockname(path);
196 5cdb1798 2005-10-29 devnull if(openlockfile(l) != 0){
197 5cdb1798 2005-10-29 devnull s_free(l->name);
198 5cdb1798 2005-10-29 devnull free(l);
199 5cdb1798 2005-10-29 devnull return 0;
202 5cdb1798 2005-10-29 devnull /* fork process to keep lock alive */
203 5cdb1798 2005-10-29 devnull switch(l->pid = rfork(RFPROC)){
204 5cdb1798 2005-10-29 devnull default:
207 5cdb1798 2005-10-29 devnull fd = l->fd;
208 5cdb1798 2005-10-29 devnull for(;;){
209 5cdb1798 2005-10-29 devnull sleep(1000*60);
210 5cdb1798 2005-10-29 devnull if(pread(fd, buf, 1, 0) < 0)
213 5cdb1798 2005-10-29 devnull _exits(0);
215 5cdb1798 2005-10-29 devnull return l;
218 5cdb1798 2005-10-29 devnull extern void
219 5cdb1798 2005-10-29 devnull syslockrefresh(Mlock *l)
221 5cdb1798 2005-10-29 devnull char buf[1];
223 5cdb1798 2005-10-29 devnull pread(l->fd, buf, 1, 0);
226 5cdb1798 2005-10-29 devnull extern void
227 5cdb1798 2005-10-29 devnull sysunlock(Mlock *l)
229 5cdb1798 2005-10-29 devnull if(l == 0)
231 5cdb1798 2005-10-29 devnull if(l->name){
232 5cdb1798 2005-10-29 devnull s_free(l->name);
234 5cdb1798 2005-10-29 devnull if(l->fd >= 0)
235 5cdb1798 2005-10-29 devnull close(l->fd);
236 5cdb1798 2005-10-29 devnull if(l->pid > 0)
237 5cdb1798 2005-10-29 devnull postnote(PNPROC, l->pid, "time to die");
238 5cdb1798 2005-10-29 devnull free(l);
242 5cdb1798 2005-10-29 devnull * Open a file. The modes are:
244 5cdb1798 2005-10-29 devnull * l - locked
245 5cdb1798 2005-10-29 devnull * a - set append permissions
246 5cdb1798 2005-10-29 devnull * r - readable
247 5cdb1798 2005-10-29 devnull * w - writable
248 5cdb1798 2005-10-29 devnull * A - append only (doesn't exist in Bio)
250 5cdb1798 2005-10-29 devnull extern Biobuf *
251 5cdb1798 2005-10-29 devnull sysopen(char *path, char *mode, ulong perm)
253 5cdb1798 2005-10-29 devnull int sysperm;
254 5cdb1798 2005-10-29 devnull int sysmode;
256 5cdb1798 2005-10-29 devnull int docreate;
257 5cdb1798 2005-10-29 devnull int append;
258 5cdb1798 2005-10-29 devnull int truncate;
259 5cdb1798 2005-10-29 devnull Dir *d, nd;
260 5cdb1798 2005-10-29 devnull Biobuf *bp;
263 5cdb1798 2005-10-29 devnull * decode the request
265 5cdb1798 2005-10-29 devnull sysperm = 0;
266 5cdb1798 2005-10-29 devnull sysmode = -1;
267 5cdb1798 2005-10-29 devnull docreate = 0;
268 5cdb1798 2005-10-29 devnull append = 0;
269 5cdb1798 2005-10-29 devnull truncate = 0;
270 5cdb1798 2005-10-29 devnull for(; mode && *mode; mode++)
271 5cdb1798 2005-10-29 devnull switch(*mode){
272 5cdb1798 2005-10-29 devnull case 'A':
273 5cdb1798 2005-10-29 devnull sysmode = OWRITE;
274 5cdb1798 2005-10-29 devnull append = 1;
276 5cdb1798 2005-10-29 devnull case 'c':
277 5cdb1798 2005-10-29 devnull docreate = 1;
279 5cdb1798 2005-10-29 devnull case 'l':
280 5cdb1798 2005-10-29 devnull sysperm |= DMEXCL;
281 1b827fbc 2006-05-21 devnull sysmode |= OLOCK;
283 5cdb1798 2005-10-29 devnull case 'a':
284 5cdb1798 2005-10-29 devnull sysperm |= DMAPPEND;
286 5cdb1798 2005-10-29 devnull case 'w':
287 5cdb1798 2005-10-29 devnull if(sysmode == -1)
288 5cdb1798 2005-10-29 devnull sysmode = OWRITE;
290 5cdb1798 2005-10-29 devnull sysmode = ORDWR;
292 5cdb1798 2005-10-29 devnull case 'r':
293 5cdb1798 2005-10-29 devnull if(sysmode == -1)
294 5cdb1798 2005-10-29 devnull sysmode = OREAD;
296 5cdb1798 2005-10-29 devnull sysmode = ORDWR;
298 5cdb1798 2005-10-29 devnull case 't':
299 5cdb1798 2005-10-29 devnull truncate = 1;
301 5cdb1798 2005-10-29 devnull default:
304 5cdb1798 2005-10-29 devnull switch(sysmode){
305 5cdb1798 2005-10-29 devnull case OREAD:
306 5cdb1798 2005-10-29 devnull case OWRITE:
307 5cdb1798 2005-10-29 devnull case ORDWR:
309 5cdb1798 2005-10-29 devnull default:
310 5cdb1798 2005-10-29 devnull if(sysperm&DMAPPEND)
311 5cdb1798 2005-10-29 devnull sysmode = OWRITE;
313 5cdb1798 2005-10-29 devnull sysmode = OREAD;
318 5cdb1798 2005-10-29 devnull * create file if we need to
320 5cdb1798 2005-10-29 devnull if(truncate)
321 5cdb1798 2005-10-29 devnull sysmode |= OTRUNC;
322 5cdb1798 2005-10-29 devnull fd = open(path, sysmode);
323 5cdb1798 2005-10-29 devnull if(fd < 0){
324 5cdb1798 2005-10-29 devnull d = dirstat(path);
325 5cdb1798 2005-10-29 devnull if(d == nil){
326 5cdb1798 2005-10-29 devnull if(docreate == 0)
327 5cdb1798 2005-10-29 devnull return 0;
329 5cdb1798 2005-10-29 devnull fd = create(path, sysmode, sysperm|perm);
330 5cdb1798 2005-10-29 devnull if(fd < 0)
331 5cdb1798 2005-10-29 devnull return 0;
332 5cdb1798 2005-10-29 devnull nulldir(&nd);
333 5cdb1798 2005-10-29 devnull nd.mode = sysperm|perm;
334 5cdb1798 2005-10-29 devnull dirfwstat(fd, &nd);
335 5cdb1798 2005-10-29 devnull } else {
336 5cdb1798 2005-10-29 devnull free(d);
337 5cdb1798 2005-10-29 devnull return 0;
341 5cdb1798 2005-10-29 devnull bp = (Biobuf*)malloc(sizeof(Biobuf));
342 5cdb1798 2005-10-29 devnull if(bp == 0){
343 5cdb1798 2005-10-29 devnull close(fd);
344 5cdb1798 2005-10-29 devnull return 0;
346 5cdb1798 2005-10-29 devnull memset(bp, 0, sizeof(Biobuf));
347 5cdb1798 2005-10-29 devnull Binit(bp, fd, sysmode&~OTRUNC);
349 5cdb1798 2005-10-29 devnull if(append)
350 5cdb1798 2005-10-29 devnull Bseek(bp, 0, 2);
351 5cdb1798 2005-10-29 devnull return bp;
355 5cdb1798 2005-10-29 devnull * close the file, etc.
358 5cdb1798 2005-10-29 devnull sysclose(Biobuf *bp)
362 5cdb1798 2005-10-29 devnull rv = Bterm(bp);
363 5cdb1798 2005-10-29 devnull close(Bfildes(bp));
364 5cdb1798 2005-10-29 devnull free(bp);
365 5cdb1798 2005-10-29 devnull return rv;
369 5cdb1798 2005-10-29 devnull * create a file
372 5cdb1798 2005-10-29 devnull syscreate(char *file, int mode, ulong perm)
374 5cdb1798 2005-10-29 devnull return create(file, mode, perm);
378 5cdb1798 2005-10-29 devnull * make a directory
381 5cdb1798 2005-10-29 devnull sysmkdir(char *file, ulong perm)
385 5cdb1798 2005-10-29 devnull if((fd = create(file, OREAD, DMDIR|perm)) < 0)
386 5cdb1798 2005-10-29 devnull return -1;
387 5cdb1798 2005-10-29 devnull close(fd);
388 5cdb1798 2005-10-29 devnull return 0;
392 5cdb1798 2005-10-29 devnull * change the group of a file
395 5cdb1798 2005-10-29 devnull syschgrp(char *file, char *group)
399 5cdb1798 2005-10-29 devnull if(group == 0)
400 5cdb1798 2005-10-29 devnull return -1;
401 5cdb1798 2005-10-29 devnull nulldir(&nd);
402 5cdb1798 2005-10-29 devnull nd.gid = group;
403 5cdb1798 2005-10-29 devnull return dirwstat(file, &nd);
406 5cdb1798 2005-10-29 devnull extern int
407 5cdb1798 2005-10-29 devnull sysdirreadall(int fd, Dir **d)
409 5cdb1798 2005-10-29 devnull return dirreadall(fd, d);
413 5cdb1798 2005-10-29 devnull * read in the system name
415 5cc53af9 2006-02-12 devnull static char *unix_hostname_read(void);
416 5cdb1798 2005-10-29 devnull extern char *
417 5cdb1798 2005-10-29 devnull sysname_read(void)
419 5cdb1798 2005-10-29 devnull static char name[128];
420 5cdb1798 2005-10-29 devnull char *cp;
422 5cdb1798 2005-10-29 devnull cp = getenv("site");
423 5cdb1798 2005-10-29 devnull if(cp == 0 || *cp == 0)
424 5cdb1798 2005-10-29 devnull cp = alt_sysname_read();
425 5cdb1798 2005-10-29 devnull if(cp == 0 || *cp == 0)
426 5cdb1798 2005-10-29 devnull cp = "kremvax";
427 5cdb1798 2005-10-29 devnull strecpy(name, name+sizeof name, cp);
428 5cdb1798 2005-10-29 devnull return name;
430 5cdb1798 2005-10-29 devnull extern char *
431 5cdb1798 2005-10-29 devnull alt_sysname_read(void)
433 5cc53af9 2006-02-12 devnull char *cp;
434 5cdb1798 2005-10-29 devnull static char name[128];
436 5cc53af9 2006-02-12 devnull cp = getenv("sysname");
437 5cc53af9 2006-02-12 devnull if(cp == 0 || *cp == 0)
438 5cc53af9 2006-02-12 devnull cp = unix_hostname_read();
439 5cc53af9 2006-02-12 devnull if(cp == 0 || *cp == 0)
440 5cc53af9 2006-02-12 devnull return 0;
441 5cc53af9 2006-02-12 devnull strecpy(name, name+sizeof name, cp);
442 5cdb1798 2005-10-29 devnull return name;
444 5cc53af9 2006-02-12 devnull static char *
445 5cc53af9 2006-02-12 devnull unix_hostname_read(void)
447 5cc53af9 2006-02-12 devnull static char hostname[256];
449 5cc53af9 2006-02-12 devnull if(gethostname(hostname, sizeof hostname) < 0)
450 5cc53af9 2006-02-12 devnull return nil;
451 5cc53af9 2006-02-12 devnull return hostname;
455 5cdb1798 2005-10-29 devnull * get all names
457 5cdb1798 2005-10-29 devnull extern char**
458 5cdb1798 2005-10-29 devnull sysnames_read(void)
460 5cdb1798 2005-10-29 devnull static char **namev;
461 5cc53af9 2006-02-12 devnull struct hostent *h;
462 5cc53af9 2006-02-12 devnull char **p, **a;
464 5cdb1798 2005-10-29 devnull if(namev)
465 5cdb1798 2005-10-29 devnull return namev;
467 5cc53af9 2006-02-12 devnull h = gethostbyname(alt_sysname_read());
468 5cc53af9 2006-02-12 devnull for(p=h->h_aliases; *p; p++)
471 5cc53af9 2006-02-12 devnull namev = malloc((2+p-h->h_aliases)*sizeof namev[0]);
472 5cc53af9 2006-02-12 devnull if(namev == 0)
473 5cc53af9 2006-02-12 devnull return 0;
475 5cc53af9 2006-02-12 devnull a = namev;
476 5cc53af9 2006-02-12 devnull *a++ = strdup(h->h_name);
477 5cc53af9 2006-02-12 devnull for(p=h->h_aliases; *p; p++)
478 5cc53af9 2006-02-12 devnull *a++ = strdup(*p);
481 5cdb1798 2005-10-29 devnull return namev;
485 5cc53af9 2006-02-12 devnull * read in the domain name.
486 5cc53af9 2006-02-12 devnull * chop off beginning pieces until we find one with an mx record.
488 5cdb1798 2005-10-29 devnull extern char *
489 5cdb1798 2005-10-29 devnull domainname_read(void)
491 5cc53af9 2006-02-12 devnull char **namev, *p;
492 5cc53af9 2006-02-12 devnull Ndbtuple *t;
494 5cc53af9 2006-02-12 devnull for(namev = sysnames_read(); *namev; namev++){
495 5cc53af9 2006-02-12 devnull if(strchr(*namev, '.')){
496 5cc53af9 2006-02-12 devnull for(p=*namev-1; p && *++p; p=strchr(p, '.')){
497 5cc53af9 2006-02-12 devnull if((t = dnsquery(nil, p, "mx")) != nil){
498 5cc53af9 2006-02-12 devnull ndbfree(t);
499 5cc53af9 2006-02-12 devnull return p;
504 5cdb1798 2005-10-29 devnull return 0;
508 5cdb1798 2005-10-29 devnull * return true if the last error message meant file
509 5cdb1798 2005-10-29 devnull * did not exist.
511 5cdb1798 2005-10-29 devnull extern int
512 5cdb1798 2005-10-29 devnull e_nonexistent(void)
514 5cdb1798 2005-10-29 devnull rerrstr(err, sizeof(err));
515 5cdb1798 2005-10-29 devnull return strcmp(err, "file does not exist") == 0;
519 5cdb1798 2005-10-29 devnull * return true if the last error message meant file
520 5cdb1798 2005-10-29 devnull * was locked.
522 5cdb1798 2005-10-29 devnull extern int
523 5cdb1798 2005-10-29 devnull e_locked(void)
525 5cdb1798 2005-10-29 devnull rerrstr(err, sizeof(err));
526 5cdb1798 2005-10-29 devnull return strcmp(err, "open/create -- file is locked") == 0;
530 5cdb1798 2005-10-29 devnull * return the length of a file
532 5cdb1798 2005-10-29 devnull extern long
533 5cdb1798 2005-10-29 devnull sysfilelen(Biobuf *fp)
536 5cdb1798 2005-10-29 devnull long rv;
538 5cdb1798 2005-10-29 devnull d = dirfstat(Bfildes(fp));
539 5cdb1798 2005-10-29 devnull if(d == nil)
540 5cdb1798 2005-10-29 devnull return -1;
541 5cdb1798 2005-10-29 devnull rv = d->length;
542 5cdb1798 2005-10-29 devnull free(d);
543 5cdb1798 2005-10-29 devnull return rv;
547 5cdb1798 2005-10-29 devnull * remove a file
549 5cdb1798 2005-10-29 devnull extern int
550 5cdb1798 2005-10-29 devnull sysremove(char *path)
552 5cdb1798 2005-10-29 devnull return remove(path);
556 5cdb1798 2005-10-29 devnull * rename a file, fails unless both are in the same directory
558 5cdb1798 2005-10-29 devnull extern int
559 5cdb1798 2005-10-29 devnull sysrename(char *old, char *new)
562 5cdb1798 2005-10-29 devnull char *obase;
563 5cdb1798 2005-10-29 devnull char *nbase;
565 5cdb1798 2005-10-29 devnull obase = strrchr(old, '/');
566 5cdb1798 2005-10-29 devnull nbase = strrchr(new, '/');
567 5cdb1798 2005-10-29 devnull if(obase){
568 5cdb1798 2005-10-29 devnull if(nbase == 0)
569 5cdb1798 2005-10-29 devnull return -1;
570 5cdb1798 2005-10-29 devnull if(strncmp(old, new, obase-old) != 0)
571 5cdb1798 2005-10-29 devnull return -1;
572 5cdb1798 2005-10-29 devnull nbase++;
573 5cdb1798 2005-10-29 devnull } else {
574 5cdb1798 2005-10-29 devnull if(nbase)
575 5cdb1798 2005-10-29 devnull return -1;
576 5cdb1798 2005-10-29 devnull nbase = new;
578 5cdb1798 2005-10-29 devnull nulldir(&d);
579 5cdb1798 2005-10-29 devnull d.name = nbase;
580 5cdb1798 2005-10-29 devnull return dirwstat(old, &d);
584 5cdb1798 2005-10-29 devnull * see if a file exists
586 5cdb1798 2005-10-29 devnull extern int
587 5cdb1798 2005-10-29 devnull sysexist(char *file)
591 5cdb1798 2005-10-29 devnull d = dirstat(file);
592 5cdb1798 2005-10-29 devnull if(d == nil)
593 5cdb1798 2005-10-29 devnull return 0;
594 5cdb1798 2005-10-29 devnull free(d);
595 5cdb1798 2005-10-29 devnull return 1;
599 5cdb1798 2005-10-29 devnull * return nonzero if file is a directory
601 5cdb1798 2005-10-29 devnull extern int
602 5cdb1798 2005-10-29 devnull sysisdir(char *file)
607 5cdb1798 2005-10-29 devnull d = dirstat(file);
608 5cdb1798 2005-10-29 devnull if(d == nil)
609 5cdb1798 2005-10-29 devnull return 0;
610 5cdb1798 2005-10-29 devnull rv = d->mode & DMDIR;
611 5cdb1798 2005-10-29 devnull free(d);
612 5cdb1798 2005-10-29 devnull return rv;
616 5cdb1798 2005-10-29 devnull * kill a process
618 5cdb1798 2005-10-29 devnull extern int
619 5cdb1798 2005-10-29 devnull syskill(int pid)
621 5cc53af9 2006-02-12 devnull return postnote(PNPROC, pid, "kill");
625 5cdb1798 2005-10-29 devnull * kill a process group
627 5cdb1798 2005-10-29 devnull extern int
628 5cdb1798 2005-10-29 devnull syskillpg(int pid)
630 5cc53af9 2006-02-12 devnull return postnote(PNGROUP, pid, "kill");
633 5cdb1798 2005-10-29 devnull extern int
634 5cdb1798 2005-10-29 devnull sysdetach(void)
636 5cdb1798 2005-10-29 devnull if(rfork(RFENVG|RFNAMEG|RFNOTEG) < 0) {
637 5cdb1798 2005-10-29 devnull werrstr("rfork failed");
638 5cdb1798 2005-10-29 devnull return -1;
640 5cdb1798 2005-10-29 devnull return 0;
644 5cdb1798 2005-10-29 devnull * catch a write on a closed pipe
646 5cdb1798 2005-10-29 devnull static int *closedflag;
647 5cdb1798 2005-10-29 devnull static int
648 5cdb1798 2005-10-29 devnull catchpipe(void *a, char *msg)
650 5cdb1798 2005-10-29 devnull static char *foo = "sys: write on closed pipe";
652 5cdb1798 2005-10-29 devnull USED(a);
653 5cdb1798 2005-10-29 devnull if(strncmp(msg, foo, strlen(foo)) == 0){
654 5cdb1798 2005-10-29 devnull if(closedflag)
655 5cdb1798 2005-10-29 devnull *closedflag = 1;
656 5cdb1798 2005-10-29 devnull return 1;
658 5cdb1798 2005-10-29 devnull return 0;
661 5cdb1798 2005-10-29 devnull pipesig(int *flagp)
663 5cdb1798 2005-10-29 devnull closedflag = flagp;
664 5cdb1798 2005-10-29 devnull atnotify(catchpipe, 1);
667 5cdb1798 2005-10-29 devnull pipesigoff(void)
669 5cdb1798 2005-10-29 devnull atnotify(catchpipe, 0);
672 5cdb1798 2005-10-29 devnull extern int
673 5cdb1798 2005-10-29 devnull holdon(void)
675 605c0ea1 2006-02-08 devnull /* XXX talk to 9term? */
676 605c0ea1 2006-02-08 devnull return -1;
679 5cdb1798 2005-10-29 devnull extern int
680 5cdb1798 2005-10-29 devnull sysopentty(void)
682 605c0ea1 2006-02-08 devnull return open("/dev/tty", ORDWR);
685 5cdb1798 2005-10-29 devnull extern void
686 5cdb1798 2005-10-29 devnull holdoff(int fd)
688 5cdb1798 2005-10-29 devnull write(fd, "holdoff", 7);
689 5cdb1798 2005-10-29 devnull close(fd);
692 5cdb1798 2005-10-29 devnull extern int
693 5cdb1798 2005-10-29 devnull sysfiles(void)
695 5cdb1798 2005-10-29 devnull return 128;
699 5cdb1798 2005-10-29 devnull * expand a path relative to the user's mailbox directory
701 5cdb1798 2005-10-29 devnull * if the path starts with / or ./, don't change it
704 5cdb1798 2005-10-29 devnull extern String *
705 5cdb1798 2005-10-29 devnull mboxpath(char *path, char *user, String *to, int dot)
707 5cc53af9 2006-02-12 devnull char *dir;
708 5cc53af9 2006-02-12 devnull String *s;
710 5cdb1798 2005-10-29 devnull if (dot || *path=='/' || strncmp(path, "./", 2) == 0
711 5cdb1798 2005-10-29 devnull || strncmp(path, "../", 3) == 0) {
712 5cdb1798 2005-10-29 devnull to = s_append(to, path);
713 5cdb1798 2005-10-29 devnull } else {
714 5cc53af9 2006-02-12 devnull if ((dir = homedir(user)) != nil) {
715 5cc53af9 2006-02-12 devnull s = s_copy(dir);
716 5cc53af9 2006-02-12 devnull s_append(s, "/mail/");
717 5cc53af9 2006-02-12 devnull if(access(s_to_c(s), AEXIST) >= 0){
718 5cc53af9 2006-02-12 devnull to = s_append(to, s_to_c(s));
719 5cc53af9 2006-02-12 devnull s_free(s);
720 5cc53af9 2006-02-12 devnull to = s_append(to, path);
721 5cc53af9 2006-02-12 devnull return to;
723 5cc53af9 2006-02-12 devnull s_free(s);
725 605c0ea1 2006-02-08 devnull to = s_append(to, MAILROOT);
726 5cdb1798 2005-10-29 devnull to = s_append(to, "/box/");
727 5cdb1798 2005-10-29 devnull to = s_append(to, user);
728 5cdb1798 2005-10-29 devnull to = s_append(to, "/");
729 5cdb1798 2005-10-29 devnull to = s_append(to, path);
731 5cdb1798 2005-10-29 devnull return to;
734 5cdb1798 2005-10-29 devnull extern String *
735 5cdb1798 2005-10-29 devnull mboxname(char *user, String *to)
737 5cdb1798 2005-10-29 devnull return mboxpath("mbox", user, to, 0);
740 5cdb1798 2005-10-29 devnull extern String *
741 5cdb1798 2005-10-29 devnull deadletter(String *to) /* pass in sender??? */
743 5cdb1798 2005-10-29 devnull char *cp;
745 5cdb1798 2005-10-29 devnull cp = getlog();
746 5cdb1798 2005-10-29 devnull if(cp == 0)
747 5cdb1798 2005-10-29 devnull return 0;
748 5cdb1798 2005-10-29 devnull return mboxpath("dead.letter", cp, to, 0);
751 5cdb1798 2005-10-29 devnull String *
752 5cdb1798 2005-10-29 devnull readlock(String *file)
754 5cdb1798 2005-10-29 devnull char *cp;
756 5cdb1798 2005-10-29 devnull cp = getlog();
757 5cdb1798 2005-10-29 devnull if(cp == 0)
758 5cdb1798 2005-10-29 devnull return 0;
759 5cdb1798 2005-10-29 devnull return mboxpath("reading", cp, file, 0);
762 5cdb1798 2005-10-29 devnull String *
763 5cdb1798 2005-10-29 devnull username(String *from)
765 5cc53af9 2006-02-12 devnull String* s;
766 5cc53af9 2006-02-12 devnull struct passwd* pw;
768 5cc53af9 2006-02-12 devnull setpwent();
769 5cc53af9 2006-02-12 devnull while((pw = getpwent()) != nil){
770 5cc53af9 2006-02-12 devnull if(strcmp(s_to_c(from), pw->pw_name) == 0){
771 5cc53af9 2006-02-12 devnull s = s_new();
772 5cc53af9 2006-02-12 devnull s_append(s, "\"");
773 5cc53af9 2006-02-12 devnull s_append(s, pw->pw_gecos);
774 5cc53af9 2006-02-12 devnull s_append(s, "\"");
775 5cc53af9 2006-02-12 devnull return s;
778 5cc53af9 2006-02-12 devnull return nil;
782 5cc53af9 2006-02-12 devnull homedir(char *user)
784 5cc53af9 2006-02-12 devnull static char buf[1024];
785 5cc53af9 2006-02-12 devnull struct passwd* pw;
787 5cc53af9 2006-02-12 devnull setpwent();
788 5cc53af9 2006-02-12 devnull while((pw = getpwent()) != nil)
789 5cc53af9 2006-02-12 devnull if(strcmp(user, pw->pw_name) == 0){
790 5cc53af9 2006-02-12 devnull strecpy(buf, buf+sizeof buf, pw->pw_dir);
791 5cc53af9 2006-02-12 devnull return buf;
793 5cc53af9 2006-02-12 devnull return nil;
797 5cdb1798 2005-10-29 devnull remoteaddr(int fd, char *dir)
799 5cc53af9 2006-02-12 devnull char *raddr;
800 5cc53af9 2006-02-12 devnull NetConnInfo *nci;
802 5cc53af9 2006-02-12 devnull if((nci = getnetconninfo(dir, fd)) == nil)
803 5cc53af9 2006-02-12 devnull return nil;
804 5cc53af9 2006-02-12 devnull raddr = strdup(nci->raddr);
805 5cc53af9 2006-02-12 devnull freenetconninfo(nci);
806 5cc53af9 2006-02-12 devnull return raddr;
809 cbeb0b26 2006-04-01 devnull /* create a file and */
810 cbeb0b26 2006-04-01 devnull /* 1) ensure the modes we asked for */
811 cbeb0b26 2006-04-01 devnull /* 2) make gid == uid */
812 5cdb1798 2005-10-29 devnull static int
813 5cdb1798 2005-10-29 devnull docreate(char *file, int perm)
816 5cdb1798 2005-10-29 devnull Dir ndir;
819 cbeb0b26 2006-04-01 devnull /* create the mbox */
820 5cdb1798 2005-10-29 devnull fd = create(file, OREAD, perm);
821 5cdb1798 2005-10-29 devnull if(fd < 0){
822 5cdb1798 2005-10-29 devnull fprint(2, "couldn't create %s\n", file);
823 5cdb1798 2005-10-29 devnull return -1;
825 5cdb1798 2005-10-29 devnull d = dirfstat(fd);
826 5cdb1798 2005-10-29 devnull if(d == nil){
827 5cdb1798 2005-10-29 devnull fprint(2, "couldn't stat %s\n", file);
828 5cdb1798 2005-10-29 devnull return -1;
830 5cdb1798 2005-10-29 devnull nulldir(&ndir);
831 5cdb1798 2005-10-29 devnull ndir.mode = perm;
832 5cdb1798 2005-10-29 devnull ndir.gid = d->uid;
833 5cdb1798 2005-10-29 devnull if(dirfwstat(fd, &ndir) < 0)
834 5cdb1798 2005-10-29 devnull fprint(2, "couldn't chmod %s: %r\n", file);
835 5cdb1798 2005-10-29 devnull close(fd);
836 5cdb1798 2005-10-29 devnull return 0;
839 cbeb0b26 2006-04-01 devnull /* create a mailbox */
841 5cdb1798 2005-10-29 devnull creatembox(char *user, char *folder)
843 5cdb1798 2005-10-29 devnull char *p;
844 5cdb1798 2005-10-29 devnull String *mailfile;
845 5cdb1798 2005-10-29 devnull char buf[512];
846 5cdb1798 2005-10-29 devnull Mlock *ml;
848 5cdb1798 2005-10-29 devnull mailfile = s_new();
849 5cdb1798 2005-10-29 devnull if(folder == 0)
850 5cdb1798 2005-10-29 devnull mboxname(user, mailfile);
852 5cdb1798 2005-10-29 devnull snprint(buf, sizeof(buf), "%s/mbox", folder);
853 5cdb1798 2005-10-29 devnull mboxpath(buf, user, mailfile, 0);
856 cbeb0b26 2006-04-01 devnull /* don't destroy existing mailbox */
857 5cdb1798 2005-10-29 devnull if(access(s_to_c(mailfile), 0) == 0){
858 5cdb1798 2005-10-29 devnull fprint(2, "mailbox already exists\n");
859 5cdb1798 2005-10-29 devnull return -1;
861 5cdb1798 2005-10-29 devnull fprint(2, "creating new mbox: %s\n", s_to_c(mailfile));
863 cbeb0b26 2006-04-01 devnull /* make sure preceding levels exist */
864 5cdb1798 2005-10-29 devnull for(p = s_to_c(mailfile); p; p++) {
865 5cdb1798 2005-10-29 devnull if(*p == '/') /* skip leading or consecutive slashes */
866 5cdb1798 2005-10-29 devnull continue;
867 5cdb1798 2005-10-29 devnull p = strchr(p, '/');
868 5cdb1798 2005-10-29 devnull if(p == 0)
871 5cdb1798 2005-10-29 devnull if(access(s_to_c(mailfile), 0) != 0){
872 5cdb1798 2005-10-29 devnull if(docreate(s_to_c(mailfile), DMDIR|0711) < 0)
873 5cdb1798 2005-10-29 devnull return -1;
875 5cdb1798 2005-10-29 devnull *p = '/';
878 cbeb0b26 2006-04-01 devnull /* create the mbox */
879 5cdb1798 2005-10-29 devnull if(docreate(s_to_c(mailfile), 0622|DMAPPEND|DMEXCL) < 0)
880 5cdb1798 2005-10-29 devnull return -1;
883 5cdb1798 2005-10-29 devnull * create the lock file if it doesn't exist
885 5cdb1798 2005-10-29 devnull ml = trylock(s_to_c(mailfile));
886 5cdb1798 2005-10-29 devnull if(ml != nil)
887 5cdb1798 2005-10-29 devnull sysunlock(ml);
889 5cdb1798 2005-10-29 devnull return 0;