xref: /plan9/sys/src/cmd/upas/common/libsys.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include "common.h"
2bd389b36SDavid du Colombier #include <auth.h>
3*219b2ee8SDavid du Colombier #include <ndb.h>
43e12c5d1SDavid du Colombier 
53e12c5d1SDavid du Colombier /*
63e12c5d1SDavid du Colombier  *  number of predefined fd's
73e12c5d1SDavid du Colombier  */
83e12c5d1SDavid du Colombier int nsysfile=3;
93e12c5d1SDavid du Colombier int nofile=128;
103e12c5d1SDavid du Colombier 
113e12c5d1SDavid du Colombier static char err[ERRLEN];
123e12c5d1SDavid du Colombier 
133e12c5d1SDavid du Colombier /*
143e12c5d1SDavid du Colombier  *  return the date
153e12c5d1SDavid du Colombier  */
163e12c5d1SDavid du Colombier extern char *
173e12c5d1SDavid du Colombier thedate(void)
183e12c5d1SDavid du Colombier {
193e12c5d1SDavid du Colombier 	static char now[64];
203e12c5d1SDavid du Colombier 	char *cp;
213e12c5d1SDavid du Colombier 
223e12c5d1SDavid du Colombier 	strcpy(now, ctime(time(0)));
233e12c5d1SDavid du Colombier 	cp = strchr(now, '\n');
243e12c5d1SDavid du Colombier 	if(cp)
253e12c5d1SDavid du Colombier 		*cp = 0;
263e12c5d1SDavid du Colombier 	return now;
273e12c5d1SDavid du Colombier }
283e12c5d1SDavid du Colombier 
293e12c5d1SDavid du Colombier /*
303e12c5d1SDavid du Colombier  *  return the user id of the current user
313e12c5d1SDavid du Colombier  */
323e12c5d1SDavid du Colombier extern char *
333e12c5d1SDavid du Colombier getlog(void)
343e12c5d1SDavid du Colombier {
353e12c5d1SDavid du Colombier 	static char user[64];
363e12c5d1SDavid du Colombier 	int fd;
373e12c5d1SDavid du Colombier 	int n;
383e12c5d1SDavid du Colombier 
393e12c5d1SDavid du Colombier 	fd = open("/dev/user", 0);
403e12c5d1SDavid du Colombier 	if(fd < 0)
413e12c5d1SDavid du Colombier 		return "Liz.Bimmler";
423e12c5d1SDavid du Colombier 	if((n=read(fd, user, sizeof(user)-1)) <= 0)
433e12c5d1SDavid du Colombier 		strcpy(user, "Liz.Bimmler");
443e12c5d1SDavid du Colombier 	close(fd);
453e12c5d1SDavid du Colombier 	user[n] = 0;
463e12c5d1SDavid du Colombier 	return user;
473e12c5d1SDavid du Colombier }
483e12c5d1SDavid du Colombier 
493e12c5d1SDavid du Colombier /*
503e12c5d1SDavid du Colombier  *  return the lock name
513e12c5d1SDavid du Colombier  */
523e12c5d1SDavid du Colombier static String *
533e12c5d1SDavid du Colombier lockname(char *path)
543e12c5d1SDavid du Colombier {
553e12c5d1SDavid du Colombier 	String *lp;
563e12c5d1SDavid du Colombier 	char *cp;
573e12c5d1SDavid du Colombier 
583e12c5d1SDavid du Colombier 	/*
593e12c5d1SDavid du Colombier 	 *  get the name of the lock file
603e12c5d1SDavid du Colombier 	 */
613e12c5d1SDavid du Colombier 	lp = s_new();
623e12c5d1SDavid du Colombier 	cp = strrchr(path, '/');
633e12c5d1SDavid du Colombier 	if(cp){
643e12c5d1SDavid du Colombier 		cp++;
653e12c5d1SDavid du Colombier 		s_nappend(lp, path, cp - path);
663e12c5d1SDavid du Colombier 	} else {
673e12c5d1SDavid du Colombier 
683e12c5d1SDavid du Colombier 		cp = path;
693e12c5d1SDavid du Colombier 	}
703e12c5d1SDavid du Colombier 	s_append(lp, "L.");
713e12c5d1SDavid du Colombier 	s_nappend(lp, cp, NAMELEN-3);
723e12c5d1SDavid du Colombier 
733e12c5d1SDavid du Colombier 	return lp;
743e12c5d1SDavid du Colombier }
753e12c5d1SDavid du Colombier 
763e12c5d1SDavid du Colombier /*
773e12c5d1SDavid du Colombier  *  try opening a lock file.  If it doesn't exist try creating it.
783e12c5d1SDavid du Colombier  */
793e12c5d1SDavid du Colombier static int
803e12c5d1SDavid du Colombier openlockfile(char *path)
813e12c5d1SDavid du Colombier {
823e12c5d1SDavid du Colombier 	int fd;
833e12c5d1SDavid du Colombier 	Dir d;
843e12c5d1SDavid du Colombier 
853e12c5d1SDavid du Colombier 	fd = open(path, OWRITE);
863e12c5d1SDavid du Colombier 	if(fd >= 0)
873e12c5d1SDavid du Colombier 		return fd;
883e12c5d1SDavid du Colombier 	if(dirstat(path, &d) < 0){
893e12c5d1SDavid du Colombier 		fd = create(path, OWRITE, CHEXCL|0666);
903e12c5d1SDavid du Colombier 		if(fd >= 0){
913e12c5d1SDavid du Colombier 			if(dirfstat(fd, &d) >= 0){
923e12c5d1SDavid du Colombier 				d.mode |= CHEXCL|0666;
933e12c5d1SDavid du Colombier 				dirfwstat(fd, &d);
943e12c5d1SDavid du Colombier 			}
953e12c5d1SDavid du Colombier 			return fd;
963e12c5d1SDavid du Colombier 		}
973e12c5d1SDavid du Colombier 	}
983e12c5d1SDavid du Colombier 	return -1;
993e12c5d1SDavid du Colombier }
1003e12c5d1SDavid du Colombier 
1013e12c5d1SDavid du Colombier #define LSECS 5*60
1023e12c5d1SDavid du Colombier 
1033e12c5d1SDavid du Colombier /*
1043e12c5d1SDavid du Colombier  *  Set a lock for a particular file.  The lock is a file in the same directory
1053e12c5d1SDavid du Colombier  *  and has L. prepended to the name of the last element of the file name.
1063e12c5d1SDavid du Colombier  */
1073e12c5d1SDavid du Colombier extern Lock *
1083e12c5d1SDavid du Colombier lock(char *path)
1093e12c5d1SDavid du Colombier {
1103e12c5d1SDavid du Colombier 	Lock *l;
1113e12c5d1SDavid du Colombier 	int tries;
1123e12c5d1SDavid du Colombier 
1133e12c5d1SDavid du Colombier 	l = malloc(sizeof(Lock));
1143e12c5d1SDavid du Colombier 	if(l == 0)
1153e12c5d1SDavid du Colombier 		return 0;
1163e12c5d1SDavid du Colombier 
1173e12c5d1SDavid du Colombier 	/*
1183e12c5d1SDavid du Colombier 	 *  wait LSECS seconds for it to unlock
1193e12c5d1SDavid du Colombier 	 */
1203e12c5d1SDavid du Colombier 	l->name = lockname(path);
1213e12c5d1SDavid du Colombier 	for(tries = 0; tries < LSECS*2; tries++){
1223e12c5d1SDavid du Colombier 		l->fd = openlockfile(s_to_c(l->name));
1233e12c5d1SDavid du Colombier 		if(l->fd >= 0)
1243e12c5d1SDavid du Colombier 			return l;
1253e12c5d1SDavid du Colombier 		sleep(500);	/* wait 1/2 second */
1263e12c5d1SDavid du Colombier 	}
1273e12c5d1SDavid du Colombier 
1283e12c5d1SDavid du Colombier 	s_free(l->name);
1293e12c5d1SDavid du Colombier 	free(l);
1303e12c5d1SDavid du Colombier 	return 0;
1313e12c5d1SDavid du Colombier }
1323e12c5d1SDavid du Colombier 
1333e12c5d1SDavid du Colombier /*
1343e12c5d1SDavid du Colombier  *  like lock except don't wait
1353e12c5d1SDavid du Colombier  */
1363e12c5d1SDavid du Colombier extern Lock *
1373e12c5d1SDavid du Colombier trylock(char *path)
1383e12c5d1SDavid du Colombier {
1393e12c5d1SDavid du Colombier 	Lock *l;
1403e12c5d1SDavid du Colombier 
1413e12c5d1SDavid du Colombier 	l = malloc(sizeof(Lock));
1423e12c5d1SDavid du Colombier 	if(l == 0)
1433e12c5d1SDavid du Colombier 		return 0;
1443e12c5d1SDavid du Colombier 
1453e12c5d1SDavid du Colombier 	l->name = lockname(path);
1463e12c5d1SDavid du Colombier 	l->fd = openlockfile(s_to_c(l->name));
1473e12c5d1SDavid du Colombier 
1483e12c5d1SDavid du Colombier 	if(l->fd < 0){
1493e12c5d1SDavid du Colombier 		s_free(l->name);
1503e12c5d1SDavid du Colombier 		free(l);
1513e12c5d1SDavid du Colombier 		return 0;
1523e12c5d1SDavid du Colombier 	}
1533e12c5d1SDavid du Colombier 	return l;
1543e12c5d1SDavid du Colombier }
1553e12c5d1SDavid du Colombier 
1563e12c5d1SDavid du Colombier extern void
1573e12c5d1SDavid du Colombier unlock(Lock *l)
1583e12c5d1SDavid du Colombier {
1593e12c5d1SDavid du Colombier 	if(l == 0)
1603e12c5d1SDavid du Colombier 		return;
1613e12c5d1SDavid du Colombier 	if(l->name){
1623e12c5d1SDavid du Colombier 		s_free(l->name);
1633e12c5d1SDavid du Colombier 	}
1643e12c5d1SDavid du Colombier 	if(l->fd >= 0)
1653e12c5d1SDavid du Colombier 		close(l->fd);
1663e12c5d1SDavid du Colombier 	free(l);
1673e12c5d1SDavid du Colombier }
1683e12c5d1SDavid du Colombier 
1693e12c5d1SDavid du Colombier /*
1703e12c5d1SDavid du Colombier  *  Open a file.  The modes are:
1713e12c5d1SDavid du Colombier  *
1723e12c5d1SDavid du Colombier  *	l	- locked
1733e12c5d1SDavid du Colombier  *	a	- set append permissions
1743e12c5d1SDavid du Colombier  *	r	- readable
1753e12c5d1SDavid du Colombier  *	w	- writable
1763e12c5d1SDavid du Colombier  *	A	- append only (doesn't exist in Bio)
1773e12c5d1SDavid du Colombier  */
1783e12c5d1SDavid du Colombier extern Biobuf *
1793e12c5d1SDavid du Colombier sysopen(char *path, char *mode, ulong perm)
1803e12c5d1SDavid du Colombier {
1813e12c5d1SDavid du Colombier 	int sysperm;
1823e12c5d1SDavid du Colombier 	int sysmode;
1833e12c5d1SDavid du Colombier 	int fd;
1843e12c5d1SDavid du Colombier 	int docreate;
1853e12c5d1SDavid du Colombier 	int append;
1863e12c5d1SDavid du Colombier 	Dir d;
1873e12c5d1SDavid du Colombier 	Biobuf *bp;
1883e12c5d1SDavid du Colombier 
1893e12c5d1SDavid du Colombier 	/*
1903e12c5d1SDavid du Colombier 	 *  decode the request
1913e12c5d1SDavid du Colombier 	 */
1923e12c5d1SDavid du Colombier 	sysperm = 0;
1933e12c5d1SDavid du Colombier 	sysmode = -1;
1943e12c5d1SDavid du Colombier 	docreate = 0;
1953e12c5d1SDavid du Colombier 	append = 0;
1963e12c5d1SDavid du Colombier  	for(; mode && *mode; mode++)
1973e12c5d1SDavid du Colombier 		switch(*mode){
1983e12c5d1SDavid du Colombier 		case 'A':
1993e12c5d1SDavid du Colombier 			sysmode = OWRITE;
2003e12c5d1SDavid du Colombier 			append = 1;
2013e12c5d1SDavid du Colombier 			break;
2023e12c5d1SDavid du Colombier 		case 'c':
2033e12c5d1SDavid du Colombier 			docreate = 1;
2043e12c5d1SDavid du Colombier 			break;
2053e12c5d1SDavid du Colombier 		case 'l':
2063e12c5d1SDavid du Colombier 			sysperm |= CHEXCL;
2073e12c5d1SDavid du Colombier 			break;
2083e12c5d1SDavid du Colombier 		case 'a':
2093e12c5d1SDavid du Colombier 			sysperm |= CHAPPEND;
2103e12c5d1SDavid du Colombier 			break;
2113e12c5d1SDavid du Colombier 		case 'w':
2123e12c5d1SDavid du Colombier 			if(sysmode == -1)
2133e12c5d1SDavid du Colombier 				sysmode = OWRITE;
2143e12c5d1SDavid du Colombier 			else
2153e12c5d1SDavid du Colombier 				sysmode = ORDWR;
2163e12c5d1SDavid du Colombier 			break;
2173e12c5d1SDavid du Colombier 		case 'r':
2183e12c5d1SDavid du Colombier 			if(sysmode == -1)
2193e12c5d1SDavid du Colombier 				sysmode = OREAD;
2203e12c5d1SDavid du Colombier 			else
2213e12c5d1SDavid du Colombier 				sysmode = ORDWR;
2223e12c5d1SDavid du Colombier 			break;
2233e12c5d1SDavid du Colombier 		default:
2243e12c5d1SDavid du Colombier 			break;
2253e12c5d1SDavid du Colombier 		}
2263e12c5d1SDavid du Colombier 	switch(sysmode){
2273e12c5d1SDavid du Colombier 	case OREAD:
2283e12c5d1SDavid du Colombier 	case OWRITE:
2293e12c5d1SDavid du Colombier 	case ORDWR:
2303e12c5d1SDavid du Colombier 		break;
2313e12c5d1SDavid du Colombier 	default:
2323e12c5d1SDavid du Colombier 		if(sysperm&CHAPPEND)
2333e12c5d1SDavid du Colombier 			sysmode = OWRITE;
2343e12c5d1SDavid du Colombier 		else
2353e12c5d1SDavid du Colombier 			sysmode = OREAD;
2363e12c5d1SDavid du Colombier 		break;
2373e12c5d1SDavid du Colombier 	}
2383e12c5d1SDavid du Colombier 
2393e12c5d1SDavid du Colombier 	/*
2403e12c5d1SDavid du Colombier 	 *  create file if we need to
2413e12c5d1SDavid du Colombier 	 */
2423e12c5d1SDavid du Colombier 	fd = open(path, sysmode);
2433e12c5d1SDavid du Colombier 	if(fd < 0){
2443e12c5d1SDavid du Colombier 		if(dirstat(path, &d) < 0){
2453e12c5d1SDavid du Colombier 			if(docreate == 0)
2463e12c5d1SDavid du Colombier 				return 0;
2473e12c5d1SDavid du Colombier 
2483e12c5d1SDavid du Colombier 			fd = create(path, sysmode, sysperm|perm);
2493e12c5d1SDavid du Colombier 			if(fd < 0)
2503e12c5d1SDavid du Colombier 				return 0;
2513e12c5d1SDavid du Colombier 			if(dirfstat(fd, &d) >= 0){
2523e12c5d1SDavid du Colombier 				d.mode |= sysperm|perm;
2533e12c5d1SDavid du Colombier 				dirfwstat(fd, &d);
2543e12c5d1SDavid du Colombier 			}
2553e12c5d1SDavid du Colombier 		} else
2563e12c5d1SDavid du Colombier 			return 0;
2573e12c5d1SDavid du Colombier 	}
2583e12c5d1SDavid du Colombier 
2593e12c5d1SDavid du Colombier 	bp = (Biobuf*)malloc(sizeof(Biobuf));
2603e12c5d1SDavid du Colombier 	if(bp == 0){
2613e12c5d1SDavid du Colombier 		close(fd);
2623e12c5d1SDavid du Colombier 		return 0;
2633e12c5d1SDavid du Colombier 	}
2643e12c5d1SDavid du Colombier 	Binit(bp, fd, sysmode);
2653e12c5d1SDavid du Colombier 
2663e12c5d1SDavid du Colombier 	/*
2673e12c5d1SDavid du Colombier 	 *  try opening
2683e12c5d1SDavid du Colombier 	 */
2693e12c5d1SDavid du Colombier 	if(append)
2703e12c5d1SDavid du Colombier 		Bseek(bp, 0, 2);
2713e12c5d1SDavid du Colombier 	return bp;
2723e12c5d1SDavid du Colombier }
2733e12c5d1SDavid du Colombier 
2743e12c5d1SDavid du Colombier /*
2753e12c5d1SDavid du Colombier  *  close the file, etc.
2763e12c5d1SDavid du Colombier  */
2773e12c5d1SDavid du Colombier int
2783e12c5d1SDavid du Colombier sysclose(Biobuf *bp)
2793e12c5d1SDavid du Colombier {
2803e12c5d1SDavid du Colombier 	int rv;
2813e12c5d1SDavid du Colombier 
282*219b2ee8SDavid du Colombier 	rv = Bterm(bp);
2833e12c5d1SDavid du Colombier 	close(Bfildes(bp));
2843e12c5d1SDavid du Colombier 	free(bp);
2853e12c5d1SDavid du Colombier 	return rv;
2863e12c5d1SDavid du Colombier }
2873e12c5d1SDavid du Colombier 
2883e12c5d1SDavid du Colombier /*
2893e12c5d1SDavid du Colombier  *  create a file
2903e12c5d1SDavid du Colombier  */
2913e12c5d1SDavid du Colombier int
2923e12c5d1SDavid du Colombier syscreate(char *file, int mode)
2933e12c5d1SDavid du Colombier {
2943e12c5d1SDavid du Colombier 	return create(file, ORDWR, mode);
2953e12c5d1SDavid du Colombier }
2963e12c5d1SDavid du Colombier 
2973e12c5d1SDavid du Colombier /*
2983e12c5d1SDavid du Colombier  *  make a directory
2993e12c5d1SDavid du Colombier  */
3003e12c5d1SDavid du Colombier int
3013e12c5d1SDavid du Colombier sysmkdir(char *file, ulong perm)
3023e12c5d1SDavid du Colombier {
3033e12c5d1SDavid du Colombier 	int fd;
3043e12c5d1SDavid du Colombier 
3053e12c5d1SDavid du Colombier 	if((fd = create(file, OREAD, 0x80000000L + perm)) < 0)
3063e12c5d1SDavid du Colombier 		return -1;
3073e12c5d1SDavid du Colombier 	close(fd);
3083e12c5d1SDavid du Colombier 	return 0;
3093e12c5d1SDavid du Colombier }
3103e12c5d1SDavid du Colombier 
3113e12c5d1SDavid du Colombier /*
3123e12c5d1SDavid du Colombier  *  change the group of a file
3133e12c5d1SDavid du Colombier  */
3143e12c5d1SDavid du Colombier int
3153e12c5d1SDavid du Colombier syschgrp(char *file, char *group)
3163e12c5d1SDavid du Colombier {
3173e12c5d1SDavid du Colombier 	Dir d;
3183e12c5d1SDavid du Colombier 
3193e12c5d1SDavid du Colombier 	if(dirstat(file, &d) < 0)
3203e12c5d1SDavid du Colombier 		return -1;
3213e12c5d1SDavid du Colombier 	strncpy(d.gid, group, sizeof(d.gid));
3223e12c5d1SDavid du Colombier 	return dirwstat(file, &d);
3233e12c5d1SDavid du Colombier }
3243e12c5d1SDavid du Colombier 
3253e12c5d1SDavid du Colombier /*
3263e12c5d1SDavid du Colombier  *  read in the system name
3273e12c5d1SDavid du Colombier  */
3283e12c5d1SDavid du Colombier extern char *
3293e12c5d1SDavid du Colombier sysname_read(void)
3303e12c5d1SDavid du Colombier {
3313e12c5d1SDavid du Colombier 	static char name[128];
3323e12c5d1SDavid du Colombier 	char *cp;
3333e12c5d1SDavid du Colombier 
3343e12c5d1SDavid du Colombier 	cp = getenv("site");
3353e12c5d1SDavid du Colombier 	if(cp == 0)
336*219b2ee8SDavid du Colombier 		cp = alt_sysname_read();
337*219b2ee8SDavid du Colombier 	if(cp == 0)
3383e12c5d1SDavid du Colombier 		cp = "kremvax";
3393e12c5d1SDavid du Colombier 	strcpy(name, cp);
3403e12c5d1SDavid du Colombier 	return name;
3413e12c5d1SDavid du Colombier }
342*219b2ee8SDavid du Colombier extern char *
343*219b2ee8SDavid du Colombier alt_sysname_read(void)
344*219b2ee8SDavid du Colombier {
345*219b2ee8SDavid du Colombier 	static char name[128];
346*219b2ee8SDavid du Colombier 	int n, fd;
347*219b2ee8SDavid du Colombier 
348*219b2ee8SDavid du Colombier 	fd = open("/dev/sysname", OREAD);
349*219b2ee8SDavid du Colombier 	if(fd < 0)
350*219b2ee8SDavid du Colombier 		return 0;
351*219b2ee8SDavid du Colombier 	n = read(fd, name, sizeof(name)-1);
352*219b2ee8SDavid du Colombier 	close(fd);
353*219b2ee8SDavid du Colombier 	if(n <= 0)
354*219b2ee8SDavid du Colombier 		return 0;
355*219b2ee8SDavid du Colombier 	name[n] = 0;
356*219b2ee8SDavid du Colombier 	return name;
357*219b2ee8SDavid du Colombier }
358*219b2ee8SDavid du Colombier 
359*219b2ee8SDavid du Colombier /*
360*219b2ee8SDavid du Colombier  *  get domain name
361*219b2ee8SDavid du Colombier  */
362*219b2ee8SDavid du Colombier extern char *
363*219b2ee8SDavid du Colombier domainname_read(void)
364*219b2ee8SDavid du Colombier {
365*219b2ee8SDavid du Colombier 	static char domain[Ndbvlen];
366*219b2ee8SDavid du Colombier 	Ndbtuple *t;
367*219b2ee8SDavid du Colombier 
368*219b2ee8SDavid du Colombier 	t = csgetval("sys", alt_sysname_read(), "dom", domain);
369*219b2ee8SDavid du Colombier 	if(t)
370*219b2ee8SDavid du Colombier 		ndbfree(t);
371*219b2ee8SDavid du Colombier 	return domain;
372*219b2ee8SDavid du Colombier }
3733e12c5d1SDavid du Colombier 
3743e12c5d1SDavid du Colombier /*
3753e12c5d1SDavid du Colombier  *  return true if the last error message meant file
3763e12c5d1SDavid du Colombier  *  did not exist.
3773e12c5d1SDavid du Colombier  */
3783e12c5d1SDavid du Colombier extern int
3793e12c5d1SDavid du Colombier e_nonexistant(void)
3803e12c5d1SDavid du Colombier {
3813e12c5d1SDavid du Colombier 	errstr(err);
3823e12c5d1SDavid du Colombier 	return strcmp(err, "file does not exist") == 0;
3833e12c5d1SDavid du Colombier }
3843e12c5d1SDavid du Colombier 
3853e12c5d1SDavid du Colombier /*
3863e12c5d1SDavid du Colombier  *  return true if the last error message meant file
3873e12c5d1SDavid du Colombier  *  was locked.
3883e12c5d1SDavid du Colombier  */
3893e12c5d1SDavid du Colombier extern int
3903e12c5d1SDavid du Colombier e_locked(void)
3913e12c5d1SDavid du Colombier {
3923e12c5d1SDavid du Colombier 	errstr(err);
3933e12c5d1SDavid du Colombier 	return strcmp(err, "open/create -- file is locked") == 0;
3943e12c5d1SDavid du Colombier }
3953e12c5d1SDavid du Colombier 
3963e12c5d1SDavid du Colombier /*
3973e12c5d1SDavid du Colombier  *  return the length of a file
3983e12c5d1SDavid du Colombier  */
3993e12c5d1SDavid du Colombier extern ulong
4003e12c5d1SDavid du Colombier sysfilelen(Biobuf *fp)
4013e12c5d1SDavid du Colombier {
4023e12c5d1SDavid du Colombier 	Dir	d;
4033e12c5d1SDavid du Colombier 
4043e12c5d1SDavid du Colombier 	if(dirfstat(Bfildes(fp), &d)<0)
4053e12c5d1SDavid du Colombier 		return -1;
4063e12c5d1SDavid du Colombier 	return d.length;
4073e12c5d1SDavid du Colombier }
4083e12c5d1SDavid du Colombier 
4093e12c5d1SDavid du Colombier /*
4103e12c5d1SDavid du Colombier  *  remove a file
4113e12c5d1SDavid du Colombier  */
4123e12c5d1SDavid du Colombier extern int
4133e12c5d1SDavid du Colombier sysremove(char *path)
4143e12c5d1SDavid du Colombier {
4153e12c5d1SDavid du Colombier 	return remove(path);
4163e12c5d1SDavid du Colombier }
4173e12c5d1SDavid du Colombier 
4183e12c5d1SDavid du Colombier /*
4193e12c5d1SDavid du Colombier  *  rename a file, fails unless both are in the same directory
4203e12c5d1SDavid du Colombier  */
4213e12c5d1SDavid du Colombier extern int
4223e12c5d1SDavid du Colombier sysrename(char *old, char *new)
4233e12c5d1SDavid du Colombier {
4243e12c5d1SDavid du Colombier 	Dir d;
4253e12c5d1SDavid du Colombier 	char *obase;
4263e12c5d1SDavid du Colombier 	char *nbase;
4273e12c5d1SDavid du Colombier 
4283e12c5d1SDavid du Colombier 	obase = strrchr(old, '/');
4293e12c5d1SDavid du Colombier 	nbase = strrchr(new, '/');
4303e12c5d1SDavid du Colombier 	if(obase){
4313e12c5d1SDavid du Colombier 		if(nbase == 0)
4323e12c5d1SDavid du Colombier 			return -1;
4333e12c5d1SDavid du Colombier 		if(strncmp(old, new, obase-old) != 0)
4343e12c5d1SDavid du Colombier 			return -1;
4353e12c5d1SDavid du Colombier 		nbase++;
4363e12c5d1SDavid du Colombier 	} else {
4373e12c5d1SDavid du Colombier 		if(nbase)
4383e12c5d1SDavid du Colombier 			return -1;
4393e12c5d1SDavid du Colombier 		nbase = new;
4403e12c5d1SDavid du Colombier 	}
4413e12c5d1SDavid du Colombier 	if(dirstat(old, &d) < 0)
4423e12c5d1SDavid du Colombier 		return -1;
4433e12c5d1SDavid du Colombier 	strcpy(d.name, nbase);
4443e12c5d1SDavid du Colombier 	return dirwstat(old, &d);
4453e12c5d1SDavid du Colombier }
4463e12c5d1SDavid du Colombier 
4473e12c5d1SDavid du Colombier /*
4483e12c5d1SDavid du Colombier  *  see if a file exists
4493e12c5d1SDavid du Colombier  */
4503e12c5d1SDavid du Colombier extern int
4513e12c5d1SDavid du Colombier sysexist(char *file)
4523e12c5d1SDavid du Colombier {
4533e12c5d1SDavid du Colombier 	Dir	d;
4543e12c5d1SDavid du Colombier 
4553e12c5d1SDavid du Colombier 	return dirstat(file, &d) == 0;
4563e12c5d1SDavid du Colombier }
4573e12c5d1SDavid du Colombier 
4583e12c5d1SDavid du Colombier /*
4593e12c5d1SDavid du Colombier  *  kill a process
4603e12c5d1SDavid du Colombier  */
4613e12c5d1SDavid du Colombier extern int
4623e12c5d1SDavid du Colombier syskill(int pid)
4633e12c5d1SDavid du Colombier {
4643e12c5d1SDavid du Colombier 	char name[64];
4653e12c5d1SDavid du Colombier 	int fd;
4663e12c5d1SDavid du Colombier 
4673e12c5d1SDavid du Colombier 	sprint(name, "/proc/%d/note", pid);
4683e12c5d1SDavid du Colombier 	fd = open(name, 1);
4693e12c5d1SDavid du Colombier 	if(fd < 0)
4703e12c5d1SDavid du Colombier 		return -1;
4713e12c5d1SDavid du Colombier 	if(write(fd, "die: yankee pig dog\n", sizeof("die: yankee pig dog\n") - 1) <= 0){
4723e12c5d1SDavid du Colombier 		close(fd);
4733e12c5d1SDavid du Colombier 		return -1;
4743e12c5d1SDavid du Colombier 	}
4753e12c5d1SDavid du Colombier 	close(fd);
4763e12c5d1SDavid du Colombier 	return 0;
4773e12c5d1SDavid du Colombier 
4783e12c5d1SDavid du Colombier }
4793e12c5d1SDavid du Colombier 
4803e12c5d1SDavid du Colombier /*
4813e12c5d1SDavid du Colombier  *  catch a write on a closed pipe
4823e12c5d1SDavid du Colombier  */
4833e12c5d1SDavid du Colombier static int *closedflag;
4843e12c5d1SDavid du Colombier static int
4853e12c5d1SDavid du Colombier catchpipe(void *a, char *msg)
4863e12c5d1SDavid du Colombier {
4873e12c5d1SDavid du Colombier 	static char *foo = "sys: write on closed pipe";
4883e12c5d1SDavid du Colombier 
4893e12c5d1SDavid du Colombier 	USED(a);
4903e12c5d1SDavid du Colombier 	if(strncmp(msg, foo, strlen(foo)) == 0){
4913e12c5d1SDavid du Colombier 		*closedflag = 1;
4923e12c5d1SDavid du Colombier 		return 1;
4933e12c5d1SDavid du Colombier 	}
4943e12c5d1SDavid du Colombier 	return 0;
4953e12c5d1SDavid du Colombier }
4963e12c5d1SDavid du Colombier void
4973e12c5d1SDavid du Colombier pipesig(int *flagp)
4983e12c5d1SDavid du Colombier {
4993e12c5d1SDavid du Colombier 	closedflag = flagp;
5003e12c5d1SDavid du Colombier 	atnotify(catchpipe, 1);
5013e12c5d1SDavid du Colombier }
5023e12c5d1SDavid du Colombier void
5033e12c5d1SDavid du Colombier pipesigoff(void)
5043e12c5d1SDavid du Colombier {
5053e12c5d1SDavid du Colombier 	atnotify(catchpipe, 0);
5063e12c5d1SDavid du Colombier }
5073e12c5d1SDavid du Colombier 
5083e12c5d1SDavid du Colombier void
5093e12c5d1SDavid du Colombier exit(int i)
5103e12c5d1SDavid du Colombier {
5113e12c5d1SDavid du Colombier 	char buf[32];
5123e12c5d1SDavid du Colombier 
5133e12c5d1SDavid du Colombier 	if(i == 0)
5143e12c5d1SDavid du Colombier 		exits(0);
5153e12c5d1SDavid du Colombier 	sprint(buf, "%d", i);
5163e12c5d1SDavid du Colombier 	exits(buf);
5173e12c5d1SDavid du Colombier }
5183e12c5d1SDavid du Colombier 
5193e12c5d1SDavid du Colombier /*
5203e12c5d1SDavid du Colombier  *  New process group.  Divest this process of at least signals associated
5213e12c5d1SDavid du Colombier  *  with other processes.  On Plan 9 fork the name space and environment
5223e12c5d1SDavid du Colombier  *  variables also.
5233e12c5d1SDavid du Colombier  */
5243e12c5d1SDavid du Colombier void
5253e12c5d1SDavid du Colombier newprocgroup(void)
5263e12c5d1SDavid du Colombier {
5273e12c5d1SDavid du Colombier 	rfork(RFENVG|RFNAMEG|RFNOTEG);
5283e12c5d1SDavid du Colombier }
529bd389b36SDavid du Colombier 
530bd389b36SDavid du Colombier /*
531bd389b36SDavid du Colombier  *  become a powerless user
532bd389b36SDavid du Colombier  */
533bd389b36SDavid du Colombier void
534bd389b36SDavid du Colombier becomenone(void)
535bd389b36SDavid du Colombier {
536bd389b36SDavid du Colombier 	int fd;
537bd389b36SDavid du Colombier 
538bd389b36SDavid du Colombier 	fd = open("#c/user", OWRITE);
539bd389b36SDavid du Colombier 	if(fd < 0 || write(fd, "none", strlen("none")) < 0)
540bd389b36SDavid du Colombier 		fprint(2, "can't become none\n");
541bd389b36SDavid du Colombier 	close(fd);
542bd389b36SDavid du Colombier 	if(newns("none", 0))
543bd389b36SDavid du Colombier 		fprint(2, "can't set new namespace\n");
544bd389b36SDavid du Colombier }
545*219b2ee8SDavid du Colombier 
546*219b2ee8SDavid du Colombier /*
547*219b2ee8SDavid du Colombier  *  query the connection server
548*219b2ee8SDavid du Colombier  */
549*219b2ee8SDavid du Colombier char*
550*219b2ee8SDavid du Colombier csquery(char *attr, char *val, char *rattr)
551*219b2ee8SDavid du Colombier {
552*219b2ee8SDavid du Colombier 	char token[Ndbvlen+4];
553*219b2ee8SDavid du Colombier 	char buf[256], *p, *sp;
554*219b2ee8SDavid du Colombier 	int fd, n;
555*219b2ee8SDavid du Colombier 
556*219b2ee8SDavid du Colombier 	fd = open("/net/cs", ORDWR);
557*219b2ee8SDavid du Colombier 	if(fd < 0)
558*219b2ee8SDavid du Colombier 		return 0;
559*219b2ee8SDavid du Colombier 	fprint(fd, "!%s=%s", attr, val);
560*219b2ee8SDavid du Colombier 	seek(fd, 0, 0);
561*219b2ee8SDavid du Colombier 	snprint(token, sizeof(token), "%s=", rattr);
562*219b2ee8SDavid du Colombier 	for(;;){
563*219b2ee8SDavid du Colombier 		n = read(fd, buf, sizeof(buf)-1);
564*219b2ee8SDavid du Colombier 		if(n <= 0)
565*219b2ee8SDavid du Colombier 			break;
566*219b2ee8SDavid du Colombier 		buf[n] = 0;
567*219b2ee8SDavid du Colombier 		p = strstr(buf, token);
568*219b2ee8SDavid du Colombier 		if(p && (p == buf || *(p-1) == 0)){
569*219b2ee8SDavid du Colombier 			close(fd);
570*219b2ee8SDavid du Colombier 			sp = strchr(p, ' ');
571*219b2ee8SDavid du Colombier 			if(sp)
572*219b2ee8SDavid du Colombier 				*sp = 0;
573*219b2ee8SDavid du Colombier 			p = strchr(p, '=');
574*219b2ee8SDavid du Colombier 			if(p == 0)
575*219b2ee8SDavid du Colombier 				return 0;
576*219b2ee8SDavid du Colombier 			return strdup(p+1);
577*219b2ee8SDavid du Colombier 		}
578*219b2ee8SDavid du Colombier 	}
579*219b2ee8SDavid du Colombier 	close(fd);
580*219b2ee8SDavid du Colombier 	return 0;
581*219b2ee8SDavid du Colombier }
582*219b2ee8SDavid du Colombier 
583*219b2ee8SDavid du Colombier extern int
584*219b2ee8SDavid du Colombier islikeatty(int fd)
585*219b2ee8SDavid du Colombier {
586*219b2ee8SDavid du Colombier 	Dir d;
587*219b2ee8SDavid du Colombier 
588*219b2ee8SDavid du Colombier 	if(dirfstat(fd, &d) < 0)
589*219b2ee8SDavid du Colombier 		return 0;
590*219b2ee8SDavid du Colombier 	return strcmp(d.name, "cons") == 0;
591*219b2ee8SDavid du Colombier }
592*219b2ee8SDavid du Colombier 
593*219b2ee8SDavid du Colombier extern int
594*219b2ee8SDavid du Colombier holdon(void)
595*219b2ee8SDavid du Colombier {
596*219b2ee8SDavid du Colombier 	int fd;
597*219b2ee8SDavid du Colombier 
598*219b2ee8SDavid du Colombier 	if(!islikeatty(0))
599*219b2ee8SDavid du Colombier 		return -1;
600*219b2ee8SDavid du Colombier 
601*219b2ee8SDavid du Colombier 	fd = open("/dev/consctl", OWRITE);
602*219b2ee8SDavid du Colombier 	write(fd, "holdon", 6);
603*219b2ee8SDavid du Colombier 
604*219b2ee8SDavid du Colombier 	return fd;
605*219b2ee8SDavid du Colombier }
606*219b2ee8SDavid du Colombier 
607*219b2ee8SDavid du Colombier extern void
608*219b2ee8SDavid du Colombier holdoff(int fd)
609*219b2ee8SDavid du Colombier {
610*219b2ee8SDavid du Colombier 	write(fd, "holdoff", 7);
611*219b2ee8SDavid du Colombier 	close(fd);
612*219b2ee8SDavid du Colombier }
613