200-p910nd-0.7.patch 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. --- p910nd-0.7/p910nd.c.orig 2005-09-29 11:31:02.442914400 +0200
  2. +++ p910nd-0.7/p910nd.c 2005-09-29 11:31:49.236800648 +0200
  3. @@ -73,8 +73,7 @@
  4. #else
  5. #define LOCKFILE "/var/lock/subsys/p910%cd"
  6. #endif
  7. -#define PRINTERFILE "/dev/lp%c"
  8. -#define LOGOPTS LOG_ERR
  9. +#define PRINTERFILE "/dev/printers/%c"
  10. static char *progname;
  11. static char version[] = "p910nd Version 0.7";
  12. @@ -93,9 +92,9 @@
  13. fprintf(stdout, "%s \n", version);
  14. }
  15. -FILE *open_printer(int lpnumber)
  16. +int open_printer(int lpnumber)
  17. {
  18. - FILE *f;
  19. + int lp;
  20. char lpname[sizeof(PRINTERFILE)];
  21. #ifdef TESTING
  22. @@ -105,12 +104,16 @@
  23. #endif
  24. if (device == 0)
  25. device = lpname;
  26. - if ((f = fopen(device, bidir ? "w+" : "w")) == NULL)
  27. + if ((lp = open(device, bidir ? O_RDWR : O_WRONLY)) == -1)
  28. {
  29. - syslog(LOGOPTS, "%s: %m\n", device);
  30. - exit(1);
  31. + syslog(LOG_ERR, "%s: %m\n", device);
  32. +
  33. + /* fallback to /dev/null if device is not available
  34. + * otherwise windows spooler will screw up
  35. + */
  36. + lp = open("/dev/null", bidir ? O_RDWR : O_WRONLY);
  37. }
  38. - return (f);
  39. + return (lp);
  40. }
  41. int get_lock(int lpnumber)
  42. @@ -121,7 +124,7 @@
  43. (void)snprintf(lockname, sizeof(lockname), LOCKFILE, lpnumber);
  44. if ((lockfd = open(lockname, O_CREAT|O_RDWR)) < 0)
  45. {
  46. - syslog(LOGOPTS, "%s: %m\n", lockname);
  47. + syslog(LOG_ERR, "%s: %m\n", lockname);
  48. return (0);
  49. }
  50. memset(&lplock, 0, sizeof(lplock));
  51. @@ -129,7 +132,7 @@
  52. lplock.l_pid = getpid();
  53. if (fcntl(lockfd, F_SETLKW, &lplock) < 0)
  54. {
  55. - syslog(LOGOPTS, "%s: %m\n", lockname);
  56. + syslog(LOG_ERR, "%s: %m\n", lockname);
  57. return (0);
  58. }
  59. return (1);
  60. @@ -141,24 +144,36 @@
  61. (void)close(lockfd);
  62. }
  63. +ssize_t safe_write(int fd, char *buf, size_t count)
  64. +{
  65. + size_t offset = 0;
  66. +
  67. + while (offset < count) {
  68. + ssize_t n = write(fd, buf + offset, count - offset);
  69. +
  70. + if (n < 0 && errno != EINTR)
  71. + return n;
  72. +
  73. + if (n > 0)
  74. + offset += n;
  75. + }
  76. +
  77. + return offset;
  78. +}
  79. +
  80. /* Copy network socket to FILE f until EOS */
  81. -int copy_stream(int fd, FILE *f)
  82. +int copy_stream(int fd, int lp)
  83. {
  84. - int nread;
  85. + int nread, rcvd = 0, sent = 0;
  86. char buffer[8192];
  87. if (bidir) {
  88. - FILE *nf;
  89. -
  90. - if ((nf = fdopen(fd, "w")) == NULL) {
  91. - syslog(LOGOPTS, "fdopen: %m\n");
  92. - }
  93. for (;;) {
  94. fd_set readfds;
  95. int result;
  96. - int maxfd = fileno(f) > fd ? fileno(f) : fd;
  97. + int maxfd = lp > fd ? lp : fd;
  98. FD_ZERO(&readfds);
  99. - FD_SET(fileno(f), &readfds);
  100. + FD_SET(lp, &readfds);
  101. FD_SET(fd, &readfds);
  102. result = select(maxfd + 1, &readfds, 0, 0, 0);
  103. if (result < 0)
  104. @@ -169,43 +184,54 @@
  105. nread = read(fd, buffer, sizeof(buffer));
  106. if (nread <= 0)
  107. break;
  108. - (void)fwrite(buffer, sizeof(char), nread, f);
  109. + if (safe_write(lp, buffer, nread) < 0) {
  110. + syslog(LOG_ERR, "write: %m\n");
  111. + break;
  112. + }
  113. + rcvd += nread;
  114. }
  115. - if (FD_ISSET(fileno(f), &readfds)) {
  116. - nread = read(fileno(f), buffer, sizeof(buffer));
  117. - if (nread > 0 && nf != NULL) {
  118. - (void)fwrite(buffer, sizeof(char), nread, nf);
  119. - (void)fflush(nf);
  120. + if (FD_ISSET(lp, &readfds)) {
  121. + nread = read(lp, buffer, sizeof(buffer));
  122. + if (nread > 0) {
  123. + safe_write(fd, buffer, nread);
  124. + sent += nread;
  125. }
  126. }
  127. }
  128. - (void)fflush(f);
  129. - (void)fclose(nf);
  130. + syslog(LOG_NOTICE, "Finished job: %d bytes received, %d bytes sent\n",
  131. + rcvd, sent);
  132. return (0);
  133. } else {
  134. - while ((nread = read(fd, buffer, sizeof(buffer))) > 0)
  135. - (void)fwrite(buffer, sizeof(char), nread, f);
  136. - (void)fflush(f);
  137. + while ((nread = read(fd, buffer, sizeof(buffer))) > 0) {
  138. + if (safe_write(lp, buffer, nread) < 0) {
  139. + syslog(LOG_ERR, "write: %m\n");
  140. + break;
  141. + }
  142. + rcvd += nread;
  143. + }
  144. + syslog(LOG_NOTICE, "Finished job: %d bytes received\n", rcvd);
  145. return (nread);
  146. }
  147. }
  148. void one_job(int lpnumber)
  149. {
  150. - FILE *f;
  151. + int lp;
  152. struct sockaddr_in client;
  153. socklen_t clientlen = sizeof(client);
  154. if (getpeername(0, (struct sockaddr*) &client, &clientlen) >= 0)
  155. - syslog(LOGOPTS, "Connection from %s port %hu\n",
  156. + syslog(LOG_NOTICE, "Connection from %s port %hu\n",
  157. inet_ntoa(client.sin_addr),
  158. ntohs(client.sin_port));
  159. if (get_lock(lpnumber) == 0)
  160. return;
  161. - f = open_printer(lpnumber);
  162. - if (copy_stream(0, f) < 0)
  163. - syslog(LOGOPTS, "copy_stream: %m\n");
  164. - fclose(f);
  165. + if ((lp = open_printer(lpnumber)) != -1)
  166. + {
  167. + if (copy_stream(0, lp) < 0)
  168. + syslog(LOG_ERR, "copy_stream: %m\n");
  169. + close(lp);
  170. + }
  171. free_lock();
  172. }
  173. @@ -215,7 +241,7 @@
  174. #ifdef USE_GETPROTOBYNAME
  175. struct protoent *proto;
  176. #endif
  177. - int netfd, fd, one = 1;
  178. + int netfd, fd, lp, one = 1;
  179. socklen_t clientlen;
  180. struct sockaddr_in netaddr, client;
  181. char pidfilename[sizeof(PIDFILE)];
  182. @@ -225,7 +251,7 @@
  183. switch (fork())
  184. {
  185. case -1:
  186. - syslog(LOGOPTS, "fork: %m\n");
  187. + syslog(LOG_ERR, "fork: %m\n");
  188. exit (1);
  189. case 0: /* child */
  190. break;
  191. @@ -236,14 +262,14 @@
  192. resourcelimit.rlim_max = 0;
  193. if (getrlimit(RLIMIT_NOFILE, &resourcelimit) < 0)
  194. {
  195. - syslog(LOGOPTS, "getrlimit: %m\n");
  196. + syslog(LOG_ERR, "getrlimit: %m\n");
  197. exit(1);
  198. }
  199. for (fd = 0; fd < resourcelimit.rlim_max; ++fd)
  200. (void)close(fd);
  201. if (setsid() < 0)
  202. {
  203. - syslog(LOGOPTS, "setsid: %m\n");
  204. + syslog(LOG_ERR, "setsid: %m\n");
  205. exit(1);
  206. }
  207. (void)chdir("/");
  208. @@ -254,7 +280,7 @@
  209. (void)snprintf(pidfilename, sizeof(pidfilename), PIDFILE, lpnumber);
  210. if ((f = fopen(pidfilename, "w")) == NULL)
  211. {
  212. - syslog(LOGOPTS, "%s: %m\n", pidfilename);
  213. + syslog(LOG_ERR, "%s: %m\n", pidfilename);
  214. exit(1);
  215. }
  216. (void)fprintf(f, "%d\n", getpid());
  217. @@ -262,11 +288,10 @@
  218. if (get_lock(lpnumber) == 0)
  219. exit(1);
  220. #endif
  221. - f = open_printer(lpnumber);
  222. #ifdef USE_GETPROTOBYNAME
  223. if ((proto = getprotobyname("tcp")) == NULL)
  224. {
  225. - syslog(LOGOPTS, "Cannot find protocol for TCP!\n");
  226. + syslog(LOG_ERR, "Cannot find protocol for TCP!\n");
  227. exit(1);
  228. }
  229. if ((netfd = socket(AF_INET, SOCK_STREAM, proto->p_proto)) < 0)
  230. @@ -274,12 +299,12 @@
  231. if ((netfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0)
  232. #endif
  233. {
  234. - syslog(LOGOPTS, "socket: %m\n");
  235. + syslog(LOG_ERR, "socket: %m\n");
  236. exit(1);
  237. }
  238. if (setsockopt(netfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0)
  239. {
  240. - syslog(LOGOPTS, "setsocketopt: %m\n");
  241. + syslog(LOG_ERR, "setsocketopt: %m\n");
  242. exit(1);
  243. }
  244. netaddr.sin_port = htons(BASEPORT + lpnumber - '0');
  245. @@ -287,12 +312,12 @@
  246. memset(netaddr.sin_zero, 0, sizeof(netaddr.sin_zero));
  247. if (bind(netfd, (struct sockaddr*) &netaddr, sizeof(netaddr)) < 0)
  248. {
  249. - syslog(LOGOPTS, "bind: %m\n");
  250. + syslog(LOG_ERR, "bind: %m\n");
  251. exit(1);
  252. }
  253. if (listen(netfd, 5) < 0)
  254. {
  255. - syslog(LOGOPTS, "listen: %m\n");
  256. + syslog(LOG_ERR, "listen: %m\n");
  257. exit(1);
  258. }
  259. clientlen = sizeof(client);
  260. @@ -302,22 +327,26 @@
  261. #ifdef USE_LIBWRAP
  262. if (hosts_ctl("p910nd", STRING_UNKNOWN,
  263. inet_ntoa(client.sin_addr), STRING_UNKNOWN) == 0) {
  264. - syslog(LOGOPTS, "Connection from %s port %hd rejected\n",
  265. + syslog(LOG_ERR, "Connection from %s port %hu rejected\n",
  266. inet_ntoa(client.sin_addr),
  267. ntohs(client.sin_port));
  268. close(fd);
  269. continue;
  270. }
  271. #endif
  272. - syslog(LOGOPTS, "Connection from %s port %hd accepted\n",
  273. + syslog(LOG_NOTICE, "Connection from %s port %hu accepted\n",
  274. inet_ntoa(client.sin_addr),
  275. ntohs(client.sin_port));
  276. /*write(fd, "Printing", 8);*/
  277. - if (copy_stream(fd, f) < 0)
  278. - syslog(LOGOPTS, "copy_stream: %m\n");
  279. + if ((lp = open_printer(lpnumber)) != -1)
  280. + {
  281. + if (copy_stream(fd, lp) < 0)
  282. + syslog(LOG_ERR, "copy_stream: %m\n");
  283. + close(lp);
  284. + }
  285. (void)close(fd);
  286. }
  287. - syslog(LOGOPTS, "accept: %m\n");
  288. + syslog(LOG_ERR, "accept: %m\n");
  289. free_lock();
  290. exit(1);
  291. }
  292. @@ -338,7 +367,7 @@
  293. if (getsockname(0, (struct sockaddr*) &bind_addr, &ba_len) == 0)
  294. return (0); /* under inetd */
  295. if (errno != ENOTSOCK) /* strange... */
  296. - syslog(LOGOPTS, "getsockname: %m\n");
  297. + syslog(LOG_ERR, "getsockname: %m\n");
  298. return (1);
  299. }