/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include "common.h"#include <auth.h>#include <ndb.h> /* * number of predefined fd's */int nsysfile=3; static char err[Errlen]; /* * return the date */extern char *thedate(void){ static char now[64]; char *cp; strcpy(now, ctime(time(0))); cp = strchr(now, '\n'); if(cp) *cp = 0; return now;} /* * return the user id of the current user */extern char *getlog(void){ static char user[64]; int fd; int n; fd = open("/dev/user", 0); if(fd < 0) return nil; if((n=read(fd, user, sizeof(user)-1)) <= 0) return nil; close(fd); user[n] = 0; return user;} /* * return the lock name (we use one lock per directory) */static String *lockname(char *path){ String *lp; char *cp; /* * get the name of the lock file */ lp = s_new(); cp = strrchr(path, '/'); if(cp) s_nappend(lp, path, cp - path + 1); s_append(lp, "L.mbox"); return lp;} 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; Dir nd; char *p; fd = open(s_to_c(l->name), OREAD); if(fd >= 0){ l->fd = fd; return 0; } d = dirstat(s_to_c(l->name)); if(d == nil){ /* file doesn't exist */ /* try creating it */ fd = create(s_to_c(l->name), OREAD, DMEXCL|0666); if(fd >= 0){ nulldir(&nd); nd.mode = DMEXCL|0666; if(dirfwstat(fd, &nd) < 0){ /* if we can't chmod, don't bother */ /* live without the lock but log it */ syslog(0, "mail", "lock error: %s: %r", s_to_c(l->name)); remove(s_to_c(l->name)); } l->fd = fd; return 0; } /* couldn't create */ /* do we have write access to the directory? */ p = strrchr(s_to_c(l->name), '/'); if(p != 0){ *p = 0; fd = access(s_to_c(l->name), 2); *p = '/'; if(fd < 0){ /* live without the lock but log it */ syslog(0, "mail", "lock error: %s: %r", s_to_c(l->name)); return 0; } } else { fd = access(".", 2); if(fd < 0){ /* live without the lock but log it */ syslog(0, "mail", "lock error: %s: %r", s_to_c(l->name)); return 0; } } } else free(d); return 1; /* try again later */} #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. */extern Mlock *syslock(char *path){ Mlock *l; int tries; l = mallocz(sizeof(Mlock), 1); if(l == 0) return nil; l->name = lockname(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; default: goto noway; } } noway: s_free(l->name); free(l); return nil;} /* * like lock except don't wait */extern Mlock *trylock(char *path){ Mlock *l; char buf[1]; int fd; l = malloc(sizeof(Mlock)); if(l == 0) return 0; l->name = lockname(path); if(openlockfile(l) != 0){ s_free(l->name); 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(0); } return l;} extern voidsyslockrefresh(Mlock *l){ char buf[1]; pread(l->fd, buf, 1, 0);} extern voidsysunlock(Mlock *l){ if(l == 0) return; if(l->name){ s_free(l->name); } if(l->fd >= 0) 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) */extern Biobuf *sysopen(char *path, char *mode, ulong perm){ int sysperm; int sysmode; int fd; int docreate; int append; int truncate; Dir *d, nd; Biobuf *bp; /* * decode the request */ sysperm = 0; sysmode = -1; docreate = 0; append = 0; truncate = 0; for(; mode && *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;} /* * create a file */intsyscreate(char *file, int mode, ulong perm){ return create(file, mode, perm);} /* * make a directory */intsysmkdir(char *file, ulong perm){ int fd; if((fd = create(file, OREAD, DMDIR|perm)) < 0) return -1; close(fd); return 0;} /* * change the group of a file */intsyschgrp(char *file, char *group){ Dir nd; if(group == 0) return -1; nulldir(&nd); nd.gid = group; return dirwstat(file, &nd);} extern intsysdirreadall(int fd, Dir **d){ return dirreadall(fd, d);} /* * read in the system name */extern char *sysname_read(void){ static char name[128]; char *cp; cp = getenv("site"); if(cp == 0 || *cp == 0) cp = alt_sysname_read(); if(cp == 0 || *cp == 0) cp = "kremvax"; strecpy(name, name+sizeof name, cp); return name;}extern char *alt_sysname_read(void){ static char name[128]; int n, fd; fd = open("/dev/sysname", OREAD); if(fd < 0) return 0; n = read(fd, name, sizeof(name)-1); close(fd); if(n <= 0) return 0; name[n] = 0; return name;} /* * get all names */extern char**sysnames_read(void){ static char **namev; Ndbtuple *t, *nt; int n; char *cp; if(namev) return namev; free(csgetvalue(0, "sys", alt_sysname_read(), "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){ n = 0; namev[n++] = strdup(sysname_read()); cp = alt_sysname_read(); if(cp) namev[n++] = strdup(cp); 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;} Lines 1–500 of 980. Load more
/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include "common.h" #include <auth.h> #include <ndb.h> /* * number of predefined fd's */ int nsysfile=3; static char err[Errlen]; /* * return the date */ extern char * thedate(void) { static char now[64]; char *cp; strcpy(now, ctime(time(0))); cp = strchr(now, '\n'); if(cp) *cp = 0; return now; } /* * return the user id of the current user */ extern char * getlog(void) { static char user[64]; int fd; int n; fd = open("/dev/user", 0); if(fd < 0) return nil; if((n=read(fd, user, sizeof(user)-1)) <= 0) return nil; close(fd); user[n] = 0; return user; } /* * return the lock name (we use one lock per directory) */ static String * lockname(char *path) { String *lp; char *cp; /* * get the name of the lock file */ lp = s_new(); cp = strrchr(path, '/'); if(cp) s_nappend(lp, path, cp - path + 1); s_append(lp, "L.mbox"); return lp; } 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; Dir nd; char *p; fd = open(s_to_c(l->name), OREAD); if(fd >= 0){ l->fd = fd; return 0; } d = dirstat(s_to_c(l->name)); if(d == nil){ /* file doesn't exist */ /* try creating it */ fd = create(s_to_c(l->name), OREAD, DMEXCL|0666); if(fd >= 0){ nulldir(&nd); nd.mode = DMEXCL|0666; if(dirfwstat(fd, &nd) < 0){ /* if we can't chmod, don't bother */ /* live without the lock but log it */ syslog(0, "mail", "lock error: %s: %r", s_to_c(l->name)); remove(s_to_c(l->name)); } l->fd = fd; return 0; } /* couldn't create */ /* do we have write access to the directory? */ p = strrchr(s_to_c(l->name), '/'); if(p != 0){ *p = 0; fd = access(s_to_c(l->name), 2); *p = '/'; if(fd < 0){ /* live without the lock but log it */ syslog(0, "mail", "lock error: %s: %r", s_to_c(l->name)); return 0; } } else { fd = access(".", 2); if(fd < 0){ /* live without the lock but log it */ syslog(0, "mail", "lock error: %s: %r", s_to_c(l->name)); return 0; } } } else free(d); return 1; /* try again later */ } #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. */ extern Mlock * syslock(char *path) { Mlock *l; int tries; l = mallocz(sizeof(Mlock), 1); if(l == 0) return nil; l->name = lockname(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; default: goto noway; } } noway: s_free(l->name); free(l); return nil; } /* * like lock except don't wait */ extern Mlock * trylock(char *path) { Mlock *l; char buf[1]; int fd; l = malloc(sizeof(Mlock)); if(l == 0) return 0; l->name = lockname(path); if(openlockfile(l) != 0){ s_free(l->name); 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(0); } return l; } extern void syslockrefresh(Mlock *l) { char buf[1]; pread(l->fd, buf, 1, 0); } extern void sysunlock(Mlock *l) { if(l == 0) return; if(l->name){ s_free(l->name); } if(l->fd >= 0) 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) */ extern Biobuf * sysopen(char *path, char *mode, ulong perm) { int sysperm; int sysmode; int fd; int docreate; int append; int truncate; Dir *d, nd; Biobuf *bp; /* * decode the request */ sysperm = 0; sysmode = -1; docreate = 0; append = 0; truncate = 0; for(; mode && *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; } /* * create a file */ int syscreate(char *file, int mode, ulong perm) { return create(file, mode, perm); } /* * 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; } /* * change the group of a file */ int syschgrp(char *file, char *group) { Dir nd; if(group == 0) return -1; nulldir(&nd); nd.gid = group; return dirwstat(file, &nd); } extern int sysdirreadall(int fd, Dir **d) { return dirreadall(fd, d); } /* * read in the system name */ extern char * sysname_read(void) { static char name[128]; char *cp; cp = getenv("site"); if(cp == 0 || *cp == 0) cp = alt_sysname_read(); if(cp == 0 || *cp == 0) cp = "kremvax"; strecpy(name, name+sizeof name, cp); return name; } extern char * alt_sysname_read(void) { static char name[128]; int n, fd; fd = open("/dev/sysname", OREAD); if(fd < 0) return 0; n = read(fd, name, sizeof(name)-1); close(fd); if(n <= 0) return 0; name[n] = 0; return name; } /* * get all names */ extern char** sysnames_read(void) { static char **namev; Ndbtuple *t, *nt; int n; char *cp; if(namev) return namev; free(csgetvalue(0, "sys", alt_sysname_read(), "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){ n = 0; namev[n++] = strdup(sysname_read()); cp = alt_sysname_read(); if(cp) namev[n++] = strdup(cp); 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; }