xref: /plan9/sys/src/libc/9sys/syslog.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier 
47dd7cddfSDavid du Colombier static struct
57dd7cddfSDavid du Colombier {
67dd7cddfSDavid du Colombier 	int	fd;
77dd7cddfSDavid du Colombier 	int	consfd;
8*9a747e4fSDavid du Colombier 	char	*name;
9*9a747e4fSDavid du Colombier 	Dir	*d;
10*9a747e4fSDavid du Colombier 	Dir	*consd;
117dd7cddfSDavid du Colombier 	Lock;
127dd7cddfSDavid du Colombier } sl =
137dd7cddfSDavid du Colombier {
147dd7cddfSDavid du Colombier 	-1, -1,
157dd7cddfSDavid du Colombier };
167dd7cddfSDavid du Colombier 
177dd7cddfSDavid du Colombier static void
187dd7cddfSDavid du Colombier _syslogopen(void)
19219b2ee8SDavid du Colombier {
20219b2ee8SDavid du Colombier 	char buf[1024];
21219b2ee8SDavid du Colombier 
227dd7cddfSDavid du Colombier 	if(sl.fd >= 0)
237dd7cddfSDavid du Colombier 		close(sl.fd);
247dd7cddfSDavid du Colombier 	snprint(buf, sizeof(buf), "/sys/log/%s", sl.name);
257dd7cddfSDavid du Colombier 	sl.fd = open(buf, OWRITE|OCEXEC);
26219b2ee8SDavid du Colombier }
27219b2ee8SDavid du Colombier 
283e12c5d1SDavid du Colombier /*
293e12c5d1SDavid du Colombier  * Print
30219b2ee8SDavid du Colombier  *  sysname: time: mesg
31219b2ee8SDavid du Colombier  * on /sys/log/logname.
323e12c5d1SDavid du Colombier  * If cons or log file can't be opened, print on the system console, too.
333e12c5d1SDavid du Colombier  */
343e12c5d1SDavid du Colombier void
353e12c5d1SDavid du Colombier syslog(int cons, char *logname, char *fmt, ...)
363e12c5d1SDavid du Colombier {
373e12c5d1SDavid du Colombier 	char buf[1024];
387dd7cddfSDavid du Colombier 	char *ctim, *p;
397dd7cddfSDavid du Colombier 	va_list arg;
407dd7cddfSDavid du Colombier 	int n;
41*9a747e4fSDavid du Colombier 	Dir *d;
42*9a747e4fSDavid du Colombier 	char err[ERRMAX];
433e12c5d1SDavid du Colombier 
44*9a747e4fSDavid du Colombier 	err[0] = '\0';
45*9a747e4fSDavid du Colombier 	errstr(err, sizeof err);
467dd7cddfSDavid du Colombier 	lock(&sl);
477dd7cddfSDavid du Colombier 
487dd7cddfSDavid du Colombier 	/*
497dd7cddfSDavid du Colombier 	 *  paranoia makes us stat to make sure a fork+close
507dd7cddfSDavid du Colombier 	 *  hasn't broken our fd's
517dd7cddfSDavid du Colombier 	 */
52*9a747e4fSDavid du Colombier 	d = dirfstat(sl.fd);
537dd7cddfSDavid du Colombier 	if(sl.fd < 0
54*9a747e4fSDavid du Colombier 	   || sl.name == nil
557dd7cddfSDavid du Colombier 	   || strcmp(sl.name, logname)!=0
56*9a747e4fSDavid du Colombier 	   || sl.d == nil
57*9a747e4fSDavid du Colombier 	   || d == nil
58*9a747e4fSDavid du Colombier 	   || d->dev != sl.d->dev
59*9a747e4fSDavid du Colombier 	   || d->type != sl.d->type
60*9a747e4fSDavid du Colombier 	   || d->qid.path != sl.d->qid.path){
61*9a747e4fSDavid du Colombier 		free(sl.name);
62*9a747e4fSDavid du Colombier 		sl.name = strdup(logname);
63*9a747e4fSDavid du Colombier 		if(sl.name == nil)
64*9a747e4fSDavid du Colombier 			cons = 1;
65*9a747e4fSDavid du Colombier 		else{
667dd7cddfSDavid du Colombier 			_syslogopen();
677dd7cddfSDavid du Colombier 			if(sl.fd < 0)
683e12c5d1SDavid du Colombier 				cons = 1;
69*9a747e4fSDavid du Colombier 			free(sl.d);
707dd7cddfSDavid du Colombier 			sl.d = d;
71*9a747e4fSDavid du Colombier 			d = nil;	/* don't free it */
723e12c5d1SDavid du Colombier 		}
73*9a747e4fSDavid du Colombier 	}
74*9a747e4fSDavid du Colombier 	free(d);
75*9a747e4fSDavid du Colombier 	if(cons){
76*9a747e4fSDavid du Colombier 		d = dirfstat(sl.consfd);
777dd7cddfSDavid du Colombier 		if(sl.consfd < 0
78*9a747e4fSDavid du Colombier 		   || d == nil
79*9a747e4fSDavid du Colombier 		   || sl.consd == nil
80*9a747e4fSDavid du Colombier 		   || d->dev != sl.consd->dev
81*9a747e4fSDavid du Colombier 		   || d->type != sl.consd->type
82*9a747e4fSDavid du Colombier 		   || d->qid.path != sl.consd->qid.path){
837dd7cddfSDavid du Colombier 			sl.consfd = open("#c/cons", OWRITE|OCEXEC);
84*9a747e4fSDavid du Colombier 			free(sl.consd);
857dd7cddfSDavid du Colombier 			sl.consd = d;
86*9a747e4fSDavid du Colombier 			d = nil;	/* don't free it */
87*9a747e4fSDavid du Colombier 		}
88*9a747e4fSDavid du Colombier 		free(d);
893e12c5d1SDavid du Colombier 	}
907dd7cddfSDavid du Colombier 
917dd7cddfSDavid du Colombier 	if(fmt == nil){
927dd7cddfSDavid du Colombier 		unlock(&sl);
937dd7cddfSDavid du Colombier 		return;
943e12c5d1SDavid du Colombier 	}
957dd7cddfSDavid du Colombier 
963e12c5d1SDavid du Colombier 	ctim = ctime(time(0));
977dd7cddfSDavid du Colombier 	werrstr(err);
987dd7cddfSDavid du Colombier 	p = buf + snprint(buf, sizeof(buf)-1, "%s ", sysname());
997dd7cddfSDavid du Colombier 	strncpy(p, ctim+4, 15);
1007dd7cddfSDavid du Colombier 	p += 15;
101219b2ee8SDavid du Colombier 	*p++ = ' ';
1027dd7cddfSDavid du Colombier 	va_start(arg, fmt);
103*9a747e4fSDavid du Colombier 	p = vseprint(p, buf+sizeof(buf)-1, fmt, arg);
1047dd7cddfSDavid du Colombier 	va_end(arg);
1053e12c5d1SDavid du Colombier 	*p++ = '\n';
1063e12c5d1SDavid du Colombier 	n = p - buf;
1077dd7cddfSDavid du Colombier 
1087dd7cddfSDavid du Colombier 	if(sl.fd >= 0){
1097dd7cddfSDavid du Colombier 		seek(sl.fd, 0, 2);
1107dd7cddfSDavid du Colombier 		write(sl.fd, buf, n);
1113e12c5d1SDavid du Colombier 	}
1127dd7cddfSDavid du Colombier 
1137dd7cddfSDavid du Colombier 	if(cons && sl.consfd >=0)
1147dd7cddfSDavid du Colombier 		write(sl.consfd, buf, n);
1157dd7cddfSDavid du Colombier 
1167dd7cddfSDavid du Colombier 	unlock(&sl);
1173e12c5d1SDavid du Colombier }
118