890 lines · 13.1 KB · C
RawDownload
#include <u.h>#include <sys/types.h>#include <pwd.h>#include <netdb.h>#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){	return getuser();} /* *  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;			sysmode |= OLOCK;			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 */static char *unix_hostname_read(void);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){	char *cp;	static char name[128]; 	cp = getenv("sysname");	if(cp == 0 || *cp == 0)		cp = unix_hostname_read();	if(cp == 0 || *cp == 0)		return 0;	strecpy(name, name+sizeof name, cp);	return name;}static char *unix_hostname_read(void){	static char hostname[256]; 	if(gethostname(hostname, sizeof hostname) < 0)		return nil;	return hostname;} /* *  get all names */extern char**sysnames_read(void){	static char **namev;	struct hostent *h;	char **p, **a; 	if(namev)		return namev; 	h = gethostbyname(alt_sysname_read());	for(p=h->h_aliases; *p; p++)		;		namev = malloc((2+p-h->h_aliases)*sizeof namev[0]);	if(namev == 0)		return 0; 	a = namev;	*a++ = strdup(h->h_name);	for(p=h->h_aliases; *p; p++)		*a++ = strdup(*p);	*a = 0; 	return namev;} /* *  read in the domain name. *  chop off beginning pieces until we find one with an mx record. */extern char *domainname_read(void){	char **namev, *p;	Ndbtuple *t; 	for(namev = sysnames_read(); *namev; namev++){		if(strchr(*namev, '.')){			for(p=*namev-1; p && *++p; p=strchr(p, '.')){				if((t = dnsquery(nil, p, "mx")) != nil){					ndbfree(t);					return p;				}

Lines 1–500 of 890.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t