#include "common.h"#include <auth.h>#include <ndb.h> /* * return the date */char*thedate(void){ static char now[64]; strcpy(now, ctime(time(0))); now[28] = 0; return now;} /* * return the user id of the current user */char *getlog(void){ return getuser();} /* * return the lock name (we use one lock per directory) */static voidlockname(Mlock *l, char *path){ char *e, *q; seprint(l->name, e = l->name+sizeof l->name, "%s", path); q = strrchr(l->name, '/'); if(q == nil) q = l->name; else q++; seprint(q, e, "%s", "L.mbox");} intsyscreatelocked(char *path, int mode, int perm){ return create(path, mode, DMEXCL|perm);} intsysopenlocked(char *path, int mode){/* return open(path, OEXCL|mode);/**/ return open(path, mode); /* until system call is fixed */} intsysunlockfile(int fd){ return close(fd);} /* * try opening a lock file. If it doesn't exist try creating it. */static intopenlockfile(Mlock *l){ int fd; Dir *d, nd; char *p; l->fd = open(l->name, OREAD); if(l->fd >= 0) return 0; if(d = dirstat(l->name)){ free(d); return 1; /* try again later */ } l->fd = create(l->name, OREAD, DMEXCL|0666); if(l->fd >= 0){ nulldir(&nd); nd.mode = DMEXCL|0666; if(dirfwstat(l->fd, &nd) < 0){ /* if we can't chmod, don't bother */ /* live without the lock but log it */ close(l->fd); l->fd = -1; syslog(0, "mail", "lock error: %s: %r", l->name); remove(l->name); } return 0; } /* couldn't create; let's see what we can whine about */ p = strrchr(l->name, '/'); if(p != 0){ *p = 0; fd = access(l->name, 2); *p = '/'; }else fd = access(".", 2); if(fd < 0) /* live without the lock but log it */ syslog(0, "mail", "lock error: %s: %r", l->name); close(fd); return 0;} #define LSECS 5*60 /* * Set a lock for a particular file. The lock is a file in the same directory * and has L. prepended to the name of the last element of the file name. */Mlock*syslock(char *path){ Mlock *l; int tries; l = mallocz(sizeof(Mlock), 1); if(l == 0) return nil; lockname(l, path); /* * wait LSECS seconds for it to unlock */ for(tries = 0; tries < LSECS*2; tries++) switch(openlockfile(l)){ case 0: return l; case 1: sleep(500); break; } free(l); return nil;} /* * like lock except don't wait */Mlock *trylock(char *path){ char buf[1]; int fd; Mlock *l; l = mallocz(sizeof(Mlock), 1); if(l == 0) return 0; lockname(l, path); if(openlockfile(l) != 0){ free(l); return 0; } /* fork process to keep lock alive */ switch(l->pid = rfork(RFPROC)){ default: break; case 0: fd = l->fd; for(;;){ sleep(1000*60); if(pread(fd, buf, 1, 0) < 0) break; } _exits(nil); } return l;} voidsyslockrefresh(Mlock *l){ char buf[1]; pread(l->fd, buf, 1, 0);} voidsysunlock(Mlock *l){ if(l == 0) return; close(l->fd); if(l->pid > 0) postnote(PNPROC, l->pid, "time to die"); free(l);} /* * Open a file. The modes are: * * l - locked * a - set append permissions * r - readable * w - writable * A - append only (doesn't exist in Bio) */Biobuf*sysopen(char *path, char *mode, ulong perm){ int sysperm, sysmode, fd, docreate, append, truncate; Dir *d, nd; Biobuf *bp; /* * decode the request */ sysperm = 0; sysmode = -1; docreate = 0; append = 0; truncate = 0; for(; *mode; mode++) switch(*mode){ case 'A': sysmode = OWRITE; append = 1; break; case 'c': docreate = 1; break; case 'l': sysperm |= DMEXCL; break; case 'a': sysperm |= DMAPPEND; break; case 'w': if(sysmode == -1) sysmode = OWRITE; else sysmode = ORDWR; break; case 'r': if(sysmode == -1) sysmode = OREAD; else sysmode = ORDWR; break; case 't': truncate = 1; break; default: break; } switch(sysmode){ case OREAD: case OWRITE: case ORDWR: break; default: if(sysperm&DMAPPEND) sysmode = OWRITE; else sysmode = OREAD; break; } /* * create file if we need to */ if(truncate) sysmode |= OTRUNC; fd = open(path, sysmode); if(fd < 0){ d = dirstat(path); if(d == nil){ if(docreate == 0) return 0; fd = create(path, sysmode, sysperm|perm); if(fd < 0) return 0; nulldir(&nd); nd.mode = sysperm|perm; dirfwstat(fd, &nd); } else { free(d); return 0; } } bp = (Biobuf*)malloc(sizeof(Biobuf)); if(bp == 0){ close(fd); return 0; } memset(bp, 0, sizeof(Biobuf)); Binit(bp, fd, sysmode&~OTRUNC); if(append) Bseek(bp, 0, 2); return bp;} /* * close the file, etc. */intsysclose(Biobuf *bp){ int rv; rv = Bterm(bp); close(Bfildes(bp)); free(bp); return rv;} /* * make a directory */intsysmkdir(char *file, ulong perm){ int fd; if((fd = create(file, OREAD, DMDIR|perm)) < 0) return -1; close(fd); return 0;} /* * read in the system name */char *sysname_read(void){ static char name[128]; char *s, *c; c = s = getenv("site"); if(!c) c = alt_sysname_read(); if(!c) c = "kremvax"; strecpy(name, name+sizeof name, c); free(s); return name;} char *alt_sysname_read(void){ return sysname();} /* * get all names */char**sysnames_read(void){ int n; Ndbtuple *t, *nt; static char **namev; if(namev) return namev; free(csgetvalue(0, "sys", sysname(), "dom", &t)); n = 0; for(nt = t; nt; nt = nt->entry) if(strcmp(nt->attr, "dom") == 0) n++; namev = (char**)malloc(sizeof(char *)*(n+3)); if(namev){ namev[0] = strdup(sysname_read()); namev[1] = strdup(alt_sysname_read()); n = 2; for(nt = t; nt; nt = nt->entry) if(strcmp(nt->attr, "dom") == 0) namev[n++] = strdup(nt->val); namev[n] = 0; } if(t) ndbfree(t); return namev;} /* * read in the domain name */char*domainname_read(void){ char **p; for(p = sysnames_read(); *p; p++) if(strchr(*p, '.')) return *p; return 0;} /* * rename a file, fails unless both are in the same directory */intsysrename(char *old, char *new){ Dir d; char *obase; char *nbase; obase = strrchr(old, '/'); nbase = strrchr(new, '/'); if(obase){ if(nbase == 0) return -1; if(strncmp(old, new, obase-old) != 0) return -1; nbase++; } else { if(nbase) return -1; nbase = new; } nulldir(&d); d.name = nbase; return dirwstat(old, &d);} intsysexist(char *file){ return access(file, AEXIST) == 0;} static char yankeepig[] = "die: yankee pig dog"; intsyskill(int pid){ return postnote(PNPROC, pid, yankeepig);} intsyskillpg(int pid){ return postnote(PNGROUP, pid, yankeepig);} intsysdetach(void){ if(rfork(RFENVG|RFNAMEG|RFNOTEG) < 0) { werrstr("rfork failed"); return -1; } return 0;} /* * catch a write on a closed pipe */static int *closedflag;static intcatchpipe(void *, char *msg){ static char *foo = "sys: write on closed pipe"; if(strncmp(msg, foo, strlen(foo)) == 0){ if(closedflag) *closedflag = 1; return 1; } return 0;}voidpipesig(int *flagp){ closedflag = flagp; atnotify(catchpipe, 1);}voidpipesigoff(void){ atnotify(catchpipe, 0);} intislikeatty(int fd){ char buf[64]; int l; if(fd2path(fd, buf, sizeof buf) != 0) return 0; Lines 1–500 of 705. Load more
#include "common.h" #include <auth.h> #include <ndb.h> /* * return the date */ char* thedate(void) { static char now[64]; strcpy(now, ctime(time(0))); now[28] = 0; return now; } /* * return the user id of the current user */ char * getlog(void) { return getuser(); } /* * return the lock name (we use one lock per directory) */ static void lockname(Mlock *l, char *path) { char *e, *q; seprint(l->name, e = l->name+sizeof l->name, "%s", path); q = strrchr(l->name, '/'); if(q == nil) q = l->name; else q++; seprint(q, e, "%s", "L.mbox"); } int syscreatelocked(char *path, int mode, int perm) { return create(path, mode, DMEXCL|perm); } int sysopenlocked(char *path, int mode) { /* return open(path, OEXCL|mode);/**/ return open(path, mode); /* until system call is fixed */ } int sysunlockfile(int fd) { return close(fd); } /* * try opening a lock file. If it doesn't exist try creating it. */ static int openlockfile(Mlock *l) { int fd; Dir *d, nd; char *p; l->fd = open(l->name, OREAD); if(l->fd >= 0) return 0; if(d = dirstat(l->name)){ free(d); return 1; /* try again later */ } l->fd = create(l->name, OREAD, DMEXCL|0666); if(l->fd >= 0){ nulldir(&nd); nd.mode = DMEXCL|0666; if(dirfwstat(l->fd, &nd) < 0){ /* if we can't chmod, don't bother */ /* live without the lock but log it */ close(l->fd); l->fd = -1; syslog(0, "mail", "lock error: %s: %r", l->name); remove(l->name); } return 0; } /* couldn't create; let's see what we can whine about */ p = strrchr(l->name, '/'); if(p != 0){ *p = 0; fd = access(l->name, 2); *p = '/'; }else fd = access(".", 2); if(fd < 0) /* live without the lock but log it */ syslog(0, "mail", "lock error: %s: %r", l->name); close(fd); return 0; } #define LSECS 5*60 /* * Set a lock for a particular file. The lock is a file in the same directory * and has L. prepended to the name of the last element of the file name. */ Mlock* syslock(char *path) { Mlock *l; int tries; l = mallocz(sizeof(Mlock), 1); if(l == 0) return nil; lockname(l, path); /* * wait LSECS seconds for it to unlock */ for(tries = 0; tries < LSECS*2; tries++) switch(openlockfile(l)){ case 0: return l; case 1: sleep(500); break; } free(l); return nil; } /* * like lock except don't wait */ Mlock * trylock(char *path) { char buf[1]; int fd; Mlock *l; l = mallocz(sizeof(Mlock), 1); if(l == 0) return 0; lockname(l, path); if(openlockfile(l) != 0){ free(l); return 0; } /* fork process to keep lock alive */ switch(l->pid = rfork(RFPROC)){ default: break; case 0: fd = l->fd; for(;;){ sleep(1000*60); if(pread(fd, buf, 1, 0) < 0) break; } _exits(nil); } return l; } void syslockrefresh(Mlock *l) { char buf[1]; pread(l->fd, buf, 1, 0); } void sysunlock(Mlock *l) { if(l == 0) return; close(l->fd); if(l->pid > 0) postnote(PNPROC, l->pid, "time to die"); free(l); } /* * Open a file. The modes are: * * l - locked * a - set append permissions * r - readable * w - writable * A - append only (doesn't exist in Bio) */ Biobuf* sysopen(char *path, char *mode, ulong perm) { int sysperm, sysmode, fd, docreate, append, truncate; Dir *d, nd; Biobuf *bp; /* * decode the request */ sysperm = 0; sysmode = -1; docreate = 0; append = 0; truncate = 0; for(; *mode; mode++) switch(*mode){ case 'A': sysmode = OWRITE; append = 1; break; case 'c': docreate = 1; break; case 'l': sysperm |= DMEXCL; break; case 'a': sysperm |= DMAPPEND; break; case 'w': if(sysmode == -1) sysmode = OWRITE; else sysmode = ORDWR; break; case 'r': if(sysmode == -1) sysmode = OREAD; else sysmode = ORDWR; break; case 't': truncate = 1; break; default: break; } switch(sysmode){ case OREAD: case OWRITE: case ORDWR: break; default: if(sysperm&DMAPPEND) sysmode = OWRITE; else sysmode = OREAD; break; } /* * create file if we need to */ if(truncate) sysmode |= OTRUNC; fd = open(path, sysmode); if(fd < 0){ d = dirstat(path); if(d == nil){ if(docreate == 0) return 0; fd = create(path, sysmode, sysperm|perm); if(fd < 0) return 0; nulldir(&nd); nd.mode = sysperm|perm; dirfwstat(fd, &nd); } else { free(d); return 0; } } bp = (Biobuf*)malloc(sizeof(Biobuf)); if(bp == 0){ close(fd); return 0; } memset(bp, 0, sizeof(Biobuf)); Binit(bp, fd, sysmode&~OTRUNC); if(append) Bseek(bp, 0, 2); return bp; } /* * close the file, etc. */ int sysclose(Biobuf *bp) { int rv; rv = Bterm(bp); close(Bfildes(bp)); free(bp); return rv; } /* * make a directory */ int sysmkdir(char *file, ulong perm) { int fd; if((fd = create(file, OREAD, DMDIR|perm)) < 0) return -1; close(fd); return 0; } /* * read in the system name */ char * sysname_read(void) { static char name[128]; char *s, *c; c = s = getenv("site"); if(!c) c = alt_sysname_read(); if(!c) c = "kremvax"; strecpy(name, name+sizeof name, c); free(s); return name; } char * alt_sysname_read(void) { return sysname(); } /* * get all names */ char** sysnames_read(void) { int n; Ndbtuple *t, *nt; static char **namev; if(namev) return namev; free(csgetvalue(0, "sys", sysname(), "dom", &t)); n = 0; for(nt = t; nt; nt = nt->entry) if(strcmp(nt->attr, "dom") == 0) n++; namev = (char**)malloc(sizeof(char *)*(n+3)); if(namev){ namev[0] = strdup(sysname_read()); namev[1] = strdup(alt_sysname_read()); n = 2; for(nt = t; nt; nt = nt->entry) if(strcmp(nt->attr, "dom") == 0) namev[n++] = strdup(nt->val); namev[n] = 0; } if(t) ndbfree(t); return namev; } /* * read in the domain name */ char* domainname_read(void) { char **p; for(p = sysnames_read(); *p; p++) if(strchr(*p, '.')) return *p; return 0; } /* * rename a file, fails unless both are in the same directory */ int sysrename(char *old, char *new) { Dir d; char *obase; char *nbase; obase = strrchr(old, '/'); nbase = strrchr(new, '/'); if(obase){ if(nbase == 0) return -1; if(strncmp(old, new, obase-old) != 0) return -1; nbase++; } else { if(nbase) return -1; nbase = new; } nulldir(&d); d.name = nbase; return dirwstat(old, &d); } int sysexist(char *file) { return access(file, AEXIST) == 0; } static char yankeepig[] = "die: yankee pig dog"; int syskill(int pid) { return postnote(PNPROC, pid, yankeepig); } int syskillpg(int pid) { return postnote(PNGROUP, pid, yankeepig); } int sysdetach(void) { if(rfork(RFENVG|RFNAMEG|RFNOTEG) < 0) { werrstr("rfork failed"); return -1; } return 0; } /* * catch a write on a closed pipe */ static int *closedflag; static int catchpipe(void *, char *msg) { static char *foo = "sys: write on closed pipe"; if(strncmp(msg, foo, strlen(foo)) == 0){ if(closedflag) *closedflag = 1; return 1; } return 0; } void pipesig(int *flagp) { closedflag = flagp; atnotify(catchpipe, 1); } void pipesigoff(void) { atnotify(catchpipe, 0); } int islikeatty(int fd) { char buf[64]; int l; if(fd2path(fd, buf, sizeof buf) != 0) return 0;