hard code list of plan 9 services in case they are not in /etc/services
diff --git a/src/lib9/syslog.c b/src/lib9/syslog.c
new file mode 100644
index 0000000..8bb602e
--- /dev/null
+++ b/src/lib9/syslog.c
@@ -0,0 +1,119 @@
+#include <u.h>
+#include <libc.h>
+
+static struct
+{
+	int	fd;
+	int	consfd;
+	char	*name;
+	Dir	*d;
+	Dir	*consd;
+	Lock	lk;
+} sl =
+{
+	-1, -1,
+};
+
+static void
+_syslogopen(void)
+{
+	char buf[1024], *p;
+
+	if(sl.fd >= 0)
+		close(sl.fd);
+	snprint(buf, sizeof(buf), "#9/log/%s", sl.name);
+	p = unsharp(buf);
+	sl.fd = open(p, OWRITE|OCEXEC|OAPPEND);
+	free(p);
+}
+
+/*
+ * Print
+ *  sysname: time: mesg
+ * on /sys/log/logname.
+ * If cons or log file can't be opened, print on the system console, too.
+ */
+void
+syslog(int cons, char *logname, char *fmt, ...)
+{
+	char buf[1024];
+	char *ctim, *p;
+	va_list arg;
+	int n;
+	Dir *d;
+	char err[ERRMAX];
+
+	err[0] = '\0';
+	errstr(err, sizeof err);
+	lock(&sl.lk);
+
+	/*
+	 *  paranoia makes us stat to make sure a fork+close
+	 *  hasn't broken our fd's
+	 */
+	d = dirfstat(sl.fd);
+	if(sl.fd < 0
+	   || sl.name == nil
+	   || strcmp(sl.name, logname)!=0
+	   || sl.d == nil
+	   || d == nil
+	   || d->dev != sl.d->dev
+	   || d->type != sl.d->type
+	   || d->qid.path != sl.d->qid.path){
+		free(sl.name);
+		sl.name = strdup(logname);
+		if(sl.name == nil)
+			cons = 1;
+		else{
+			_syslogopen();
+			if(sl.fd < 0)
+				cons = 1;
+			free(sl.d);
+			sl.d = d;
+			d = nil;	/* don't free it */
+		}
+	}
+	free(d);
+	if(cons){
+		d = dirfstat(sl.consfd);
+		if(sl.consfd < 0
+		   || d == nil
+		   || sl.consd == nil
+		   || d->dev != sl.consd->dev
+		   || d->type != sl.consd->type
+		   || d->qid.path != sl.consd->qid.path){
+			sl.consfd = open("/dev/tty", OWRITE|OCEXEC);
+			free(sl.consd);
+			sl.consd = d;
+			d = nil;	/* don't free it */
+		}
+		free(d);
+	}
+
+	if(fmt == nil){
+		unlock(&sl.lk);
+		return;
+	}
+
+	ctim = ctime(time(0));
+	werrstr(err);
+	p = buf + snprint(buf, sizeof(buf)-1, "%s ", sysname());
+	strncpy(p, ctim+4, 15);
+	p += 15;
+	*p++ = ' ';
+	va_start(arg, fmt);
+	p = vseprint(p, buf+sizeof(buf)-1, fmt, arg);
+	va_end(arg);
+	*p++ = '\n';
+	n = p - buf;
+
+	if(sl.fd >= 0){
+		seek(sl.fd, 0, 2);
+		write(sl.fd, buf, n);
+	}
+
+	if(cons && sl.consfd >=0)
+		write(sl.consfd, buf, n);
+
+	unlock(&sl.lk);
+}