xref: /plan9/sys/src/libc/9sys/syslog.c (revision 679a83a8d7e0f9e893634d11f642af4ee1846fd5)
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;
89a747e4fSDavid du Colombier 	char	*name;
99a747e4fSDavid du Colombier 	Dir	*d;
109a747e4fSDavid 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
_syslogopen(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 
287e9ae060SDavid du Colombier static int
eqdirdev(Dir * a,Dir * b)297e9ae060SDavid du Colombier eqdirdev(Dir *a, Dir *b)
307e9ae060SDavid du Colombier {
317e9ae060SDavid du Colombier 	return a != nil && b != nil &&
327e9ae060SDavid du Colombier 		a->dev == b->dev && a->type == b->type &&
337e9ae060SDavid du Colombier 		a->qid.path == b->qid.path;
347e9ae060SDavid du Colombier }
357e9ae060SDavid du Colombier 
363e12c5d1SDavid du Colombier /*
373e12c5d1SDavid du Colombier  * Print
38219b2ee8SDavid du Colombier  *  sysname: time: mesg
39219b2ee8SDavid du Colombier  * on /sys/log/logname.
403e12c5d1SDavid du Colombier  * If cons or log file can't be opened, print on the system console, too.
413e12c5d1SDavid du Colombier  */
423e12c5d1SDavid du Colombier void
syslog(int cons,char * logname,char * fmt,...)433e12c5d1SDavid du Colombier syslog(int cons, char *logname, char *fmt, ...)
443e12c5d1SDavid du Colombier {
453e12c5d1SDavid du Colombier 	char buf[1024];
467dd7cddfSDavid du Colombier 	char *ctim, *p;
477dd7cddfSDavid du Colombier 	va_list arg;
487dd7cddfSDavid du Colombier 	int n;
499a747e4fSDavid du Colombier 	Dir *d;
509a747e4fSDavid du Colombier 	char err[ERRMAX];
513e12c5d1SDavid du Colombier 
529a747e4fSDavid du Colombier 	err[0] = '\0';
539a747e4fSDavid du Colombier 	errstr(err, sizeof err);
547dd7cddfSDavid du Colombier 	lock(&sl);
557dd7cddfSDavid du Colombier 
567dd7cddfSDavid du Colombier 	/*
577dd7cddfSDavid du Colombier 	 *  paranoia makes us stat to make sure a fork+close
587dd7cddfSDavid du Colombier 	 *  hasn't broken our fd's
597dd7cddfSDavid du Colombier 	 */
609a747e4fSDavid du Colombier 	d = dirfstat(sl.fd);
617e9ae060SDavid du Colombier 	if(sl.fd < 0 || sl.name == nil || strcmp(sl.name, logname) != 0 ||
627e9ae060SDavid du Colombier 	   !eqdirdev(d, sl.d)){
639a747e4fSDavid du Colombier 		free(sl.name);
649a747e4fSDavid du Colombier 		sl.name = strdup(logname);
659a747e4fSDavid du Colombier 		if(sl.name == nil)
669a747e4fSDavid du Colombier 			cons = 1;
679a747e4fSDavid du Colombier 		else{
687e9ae060SDavid du Colombier 			free(sl.d);
697e9ae060SDavid du Colombier 			sl.d = nil;
707dd7cddfSDavid du Colombier 			_syslogopen();
717dd7cddfSDavid du Colombier 			if(sl.fd < 0)
723e12c5d1SDavid du Colombier 				cons = 1;
737e9ae060SDavid du Colombier 			else
747e9ae060SDavid du Colombier 				sl.d = dirfstat(sl.fd);
753e12c5d1SDavid du Colombier 		}
769a747e4fSDavid du Colombier 	}
779a747e4fSDavid du Colombier 	free(d);
789a747e4fSDavid du Colombier 	if(cons){
799a747e4fSDavid du Colombier 		d = dirfstat(sl.consfd);
807e9ae060SDavid du Colombier 		if(sl.consfd < 0 || !eqdirdev(d, sl.consd)){
819a747e4fSDavid du Colombier 			free(sl.consd);
827e9ae060SDavid du Colombier 			sl.consd = nil;
837e9ae060SDavid du Colombier 			sl.consfd = open("#c/cons", OWRITE|OCEXEC);
847e9ae060SDavid du Colombier 			if(sl.consfd >= 0)
857e9ae060SDavid du Colombier 				sl.consd = dirfstat(sl.consfd);
869a747e4fSDavid du Colombier 		}
879a747e4fSDavid du Colombier 		free(d);
883e12c5d1SDavid du Colombier 	}
897dd7cddfSDavid du Colombier 
907dd7cddfSDavid du Colombier 	if(fmt == nil){
917dd7cddfSDavid du Colombier 		unlock(&sl);
927dd7cddfSDavid du Colombier 		return;
933e12c5d1SDavid du Colombier 	}
947dd7cddfSDavid du Colombier 
953e12c5d1SDavid du Colombier 	ctim = ctime(time(0));
967dd7cddfSDavid du Colombier 	p = buf + snprint(buf, sizeof(buf)-1, "%s ", sysname());
977dd7cddfSDavid du Colombier 	strncpy(p, ctim+4, 15);
987dd7cddfSDavid du Colombier 	p += 15;
99219b2ee8SDavid du Colombier 	*p++ = ' ';
100*679a83a8SDavid du Colombier 	errstr(err, sizeof err);
1017dd7cddfSDavid du Colombier 	va_start(arg, fmt);
1029a747e4fSDavid du Colombier 	p = vseprint(p, buf+sizeof(buf)-1, fmt, arg);
1037dd7cddfSDavid du Colombier 	va_end(arg);
1043e12c5d1SDavid du Colombier 	*p++ = '\n';
1053e12c5d1SDavid du Colombier 	n = p - buf;
1067dd7cddfSDavid du Colombier 
1077dd7cddfSDavid du Colombier 	if(sl.fd >= 0){
1087dd7cddfSDavid du Colombier 		seek(sl.fd, 0, 2);
1097dd7cddfSDavid du Colombier 		write(sl.fd, buf, n);
1103e12c5d1SDavid du Colombier 	}
1117dd7cddfSDavid du Colombier 
1127dd7cddfSDavid du Colombier 	if(cons && sl.consfd >=0)
1137dd7cddfSDavid du Colombier 		write(sl.consfd, buf, n);
1147dd7cddfSDavid du Colombier 
1157dd7cddfSDavid du Colombier 	unlock(&sl);
1163e12c5d1SDavid du Colombier }
117