--- p910nd-0.7/p910nd.c.orig	2005-09-29 11:31:02.442914400 +0200
+++ p910nd-0.7/p910nd.c	2005-09-29 11:31:49.236800648 +0200
@@ -73,8 +73,7 @@
 #else
 #define		LOCKFILE	"/var/lock/subsys/p910%cd"
 #endif
-#define		PRINTERFILE	"/dev/lp%c"
-#define		LOGOPTS		LOG_ERR
+#define		PRINTERFILE	"/dev/printers/%c"
 
 static char	*progname;
 static char	version[] = "p910nd Version 0.7";
@@ -93,9 +92,9 @@
 	fprintf(stdout, "%s \n", version);
 }
 
-FILE *open_printer(int lpnumber)
+int open_printer(int lpnumber)
 {
-	FILE		*f;
+	int		lp;
 	char		lpname[sizeof(PRINTERFILE)];
 
 #ifdef	TESTING
@@ -105,12 +104,16 @@
 #endif
 	if (device == 0)
 		device = lpname;
-	if ((f = fopen(device, bidir ? "w+" : "w")) == NULL)
+	if ((lp = open(device, bidir ? O_RDWR : O_WRONLY)) == -1)
 	{
-		syslog(LOGOPTS, "%s: %m\n", device);
-		exit(1);
+		syslog(LOG_ERR, "%s: %m\n", device);
+
+		/* fallback to /dev/null if device is not available 
+		 * otherwise windows spooler will screw up
+		 */
+		lp = open("/dev/null", bidir ? O_RDWR : O_WRONLY);
 	}
-	return (f);
+	return (lp);
 }
 
 int get_lock(int lpnumber)
@@ -121,7 +124,7 @@
 	(void)snprintf(lockname, sizeof(lockname), LOCKFILE, lpnumber);
 	if ((lockfd = open(lockname, O_CREAT|O_RDWR)) < 0)
 	{
-		syslog(LOGOPTS, "%s: %m\n", lockname);
+		syslog(LOG_ERR, "%s: %m\n", lockname);
 		return (0);
 	}
 	memset(&lplock, 0, sizeof(lplock));
@@ -129,7 +132,7 @@
 	lplock.l_pid = getpid();
 	if (fcntl(lockfd, F_SETLKW, &lplock) < 0)
 	{
-		syslog(LOGOPTS, "%s: %m\n", lockname);
+		syslog(LOG_ERR, "%s: %m\n", lockname);
 		return (0);
 	}
 	return (1);
@@ -141,24 +144,36 @@
 		(void)close(lockfd);
 }
 
+ssize_t safe_write(int fd, char *buf, size_t count)
+{
+	size_t offset = 0;
+	
+	while (offset < count) {
+		ssize_t n = write(fd, buf + offset, count - offset);
+		
+		if (n < 0 && errno != EINTR)
+			return n;
+			
+		if (n > 0)
+			offset += n;
+	}
+
+	return offset;
+}
+
 /* Copy network socket to FILE f until EOS */
-int copy_stream(int fd, FILE *f)
+int copy_stream(int fd, int lp)
 {
-	int		nread;
+	int		nread, rcvd = 0, sent = 0;
 	char		buffer[8192];
 
 	if (bidir) {
-		FILE	*nf;
-
-		if ((nf = fdopen(fd, "w")) == NULL) {
-			syslog(LOGOPTS, "fdopen: %m\n");
-		}
 		for (;;) {
 			fd_set	readfds;
 			int result;
-			int maxfd = fileno(f) > fd ? fileno(f) : fd;
+			int maxfd = lp > fd ? lp : fd;
 			FD_ZERO(&readfds);
-			FD_SET(fileno(f), &readfds);
+			FD_SET(lp, &readfds);
 			FD_SET(fd, &readfds);
 			result = select(maxfd + 1, &readfds, 0, 0, 0);
 			if (result < 0)
@@ -169,43 +184,54 @@
 				nread = read(fd, buffer, sizeof(buffer));
 				if (nread <= 0)
 					break;
-				(void)fwrite(buffer, sizeof(char), nread, f);
+				if (safe_write(lp, buffer, nread) < 0) {
+					syslog(LOG_ERR, "write: %m\n");
+					break;
+				}
+				rcvd += nread;
 			}
-			if (FD_ISSET(fileno(f), &readfds)) {
-				nread = read(fileno(f), buffer, sizeof(buffer));
-				if (nread > 0 && nf != NULL) {
-					(void)fwrite(buffer, sizeof(char), nread, nf);
-					(void)fflush(nf);
+			if (FD_ISSET(lp, &readfds)) {
+				nread = read(lp, buffer, sizeof(buffer));
+				if (nread > 0) {
+					safe_write(fd, buffer, nread);
+					sent += nread;
 				}
 			}
 		}
-		(void)fflush(f);
-		(void)fclose(nf);
+		syslog(LOG_NOTICE, "Finished job: %d bytes received, %d bytes sent\n",
+			rcvd, sent);
 		return (0);
 	} else {
-		while ((nread = read(fd, buffer, sizeof(buffer))) > 0)
-			(void)fwrite(buffer, sizeof(char), nread, f);
-		(void)fflush(f);
+		while ((nread = read(fd, buffer, sizeof(buffer))) > 0) {
+			if (safe_write(lp, buffer, nread) < 0) {
+				syslog(LOG_ERR, "write: %m\n");
+				break;
+			}
+			rcvd += nread;
+		}
+		syslog(LOG_NOTICE, "Finished job: %d bytes received\n",	rcvd);
 		return (nread);
 	}
 }
 
 void one_job(int lpnumber)
 {
-	FILE		*f;
+	int		lp;
 	struct sockaddr_in	client;
 	socklen_t	clientlen = sizeof(client);
 
 	if (getpeername(0, (struct sockaddr*) &client, &clientlen) >= 0)
-		syslog(LOGOPTS, "Connection from %s port %hu\n",
+		syslog(LOG_NOTICE, "Connection from %s port %hu\n",
 			inet_ntoa(client.sin_addr),
 			ntohs(client.sin_port));
 	if (get_lock(lpnumber) == 0)
 		return;
-	f = open_printer(lpnumber);
-	if (copy_stream(0, f) < 0)
-		syslog(LOGOPTS, "copy_stream: %m\n");
-	fclose(f);
+	if ((lp = open_printer(lpnumber)) != -1)
+	{
+    		if (copy_stream(0, lp) < 0)
+			syslog(LOG_ERR, "copy_stream: %m\n");
+		close(lp);
+	}
 	free_lock();
 }
 
@@ -215,7 +241,7 @@
 #ifdef	USE_GETPROTOBYNAME
 	struct protoent	*proto;
 #endif
-	int		netfd, fd, one = 1;
+	int		netfd, fd, lp, one = 1;
 	socklen_t	clientlen;
 	struct sockaddr_in	netaddr, client;
 	char		pidfilename[sizeof(PIDFILE)];
@@ -225,7 +251,7 @@
 	switch (fork())
 	{
 	case -1:
-		syslog(LOGOPTS, "fork: %m\n");
+		syslog(LOG_ERR, "fork: %m\n");
 		exit (1);
 	case 0:		/* child */
 		break;
@@ -236,14 +262,14 @@
 	resourcelimit.rlim_max = 0;
 	if (getrlimit(RLIMIT_NOFILE, &resourcelimit) < 0)
 	{
-		syslog(LOGOPTS, "getrlimit: %m\n");
+		syslog(LOG_ERR, "getrlimit: %m\n");
 		exit(1);
 	}
 	for (fd = 0; fd < resourcelimit.rlim_max; ++fd)
 		(void)close(fd);
 	if (setsid() < 0)
 	{
-		syslog(LOGOPTS, "setsid: %m\n");
+		syslog(LOG_ERR, "setsid: %m\n");
 		exit(1);
 	}
 	(void)chdir("/");
@@ -254,7 +280,7 @@
 	(void)snprintf(pidfilename, sizeof(pidfilename), PIDFILE, lpnumber);
 	if ((f = fopen(pidfilename, "w")) == NULL)
 	{
-		syslog(LOGOPTS, "%s: %m\n", pidfilename);
+		syslog(LOG_ERR, "%s: %m\n", pidfilename);
 		exit(1);
 	}
 	(void)fprintf(f, "%d\n", getpid());
@@ -262,11 +288,10 @@
 	if (get_lock(lpnumber) == 0)
 		exit(1);
 #endif
-	f = open_printer(lpnumber);
 #ifdef	USE_GETPROTOBYNAME
 	if ((proto = getprotobyname("tcp")) == NULL)
 	{
-		syslog(LOGOPTS, "Cannot find protocol for TCP!\n");
+		syslog(LOG_ERR, "Cannot find protocol for TCP!\n");
 		exit(1);
 	}
 	if ((netfd = socket(AF_INET, SOCK_STREAM, proto->p_proto)) < 0)
@@ -274,12 +299,12 @@
 	if ((netfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0)
 #endif
 	{
-		syslog(LOGOPTS, "socket: %m\n");
+		syslog(LOG_ERR, "socket: %m\n");
 		exit(1);
 	}
 	if (setsockopt(netfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0)
 	{
-		syslog(LOGOPTS, "setsocketopt: %m\n");
+		syslog(LOG_ERR, "setsocketopt: %m\n");
 		exit(1);
 	}
 	netaddr.sin_port = htons(BASEPORT + lpnumber - '0');
@@ -287,12 +312,12 @@
 	memset(netaddr.sin_zero, 0, sizeof(netaddr.sin_zero));
 	if (bind(netfd, (struct sockaddr*) &netaddr, sizeof(netaddr)) < 0)
 	{
-		syslog(LOGOPTS, "bind: %m\n");
+		syslog(LOG_ERR, "bind: %m\n");
 		exit(1);
 	}
 	if (listen(netfd, 5) < 0)
 	{
-		syslog(LOGOPTS, "listen: %m\n");
+		syslog(LOG_ERR, "listen: %m\n");
 		exit(1);
 	}
 	clientlen = sizeof(client);
@@ -302,22 +327,26 @@
 #ifdef	USE_LIBWRAP
 		if (hosts_ctl("p910nd", STRING_UNKNOWN,
 			inet_ntoa(client.sin_addr), STRING_UNKNOWN) == 0) {
-			syslog(LOGOPTS, "Connection from %s port %hd rejected\n",
+			syslog(LOG_ERR, "Connection from %s port %hu rejected\n",
 				inet_ntoa(client.sin_addr),
 				ntohs(client.sin_port));
 			close(fd);
 			continue;
 		}
 #endif
-		syslog(LOGOPTS, "Connection from %s port %hd accepted\n",
+		syslog(LOG_NOTICE, "Connection from %s port %hu accepted\n",
 			inet_ntoa(client.sin_addr),
 			ntohs(client.sin_port));
 		/*write(fd, "Printing", 8);*/
-		if (copy_stream(fd, f) < 0)
-			syslog(LOGOPTS, "copy_stream: %m\n");
+		if ((lp = open_printer(lpnumber)) != -1)
+		{
+		        if (copy_stream(fd, lp) < 0)
+				syslog(LOG_ERR, "copy_stream: %m\n");
+			close(lp);
+		}
 		(void)close(fd);
 	}
-	syslog(LOGOPTS, "accept: %m\n");
+	syslog(LOG_ERR, "accept: %m\n");
 	free_lock();
 	exit(1);
 }
@@ -338,7 +367,7 @@
 	if (getsockname(0, (struct sockaddr*) &bind_addr, &ba_len) == 0)
 		return (0);		/* under inetd */
 	if (errno != ENOTSOCK)		/* strange... */
-		syslog(LOGOPTS, "getsockname: %m\n");
+		syslog(LOG_ERR, "getsockname: %m\n");
 	return (1);
 }
 
