| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 | --- 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); } 
 |