add p910nd (thanks to Oliver Ertl)

SVN-Revision: 1993
This commit is contained in:
Nicolas Thill 2005-09-26 02:09:28 +00:00
parent d85480af2c
commit ff7251cf95
10 changed files with 426 additions and 0 deletions

View File

@ -84,6 +84,7 @@ source "package/openntpd/Config.in"
source "package/openssh/Config.in"
source "package/openswan/Config.in"
source "package/openvpn/Config.in"
source "package/p910nd/Config.in"
source "package/parprouted/Config.in"
source "package/pmacct/Config.in"
source "package/portmap/Config.in"

View File

@ -122,6 +122,7 @@ package-$(BR2_PACKAGE_OPENSWAN) += openswan
package-$(BR2_PACKAGE_OPENVPN) += openvpn
package-$(BR2_PACKAGE_OSIRIS) += osiris
package-$(BR2_PACKAGE_PALANTIR) += palantir
package-$(BR2_PACKAGE_P910ND) += p910nd
package-$(BR2_PACKAGE_PARPROUTED) += parprouted
package-$(BR2_PACKAGE_PCRE) += pcre
package-$(BR2_COMPILE_PHP4) += php4

View File

@ -0,0 +1,14 @@
config BR2_PACKAGE_P910ND
tristate "p910nd - A small non-spooling printer server"
default m if CONFIG_DEVEL
help
p910nd is a small daemon that copies any data received on
the port it is listening on to the corresponding printer
port. It is primarily intended for diskless Linux hosts
running as printer drivers but there is no reason why it
could not be used on diskful hosts. Port 9100 is copied
to /dev/lp0, 9101 to /dev/lp1 and 9102 to /dev/lp2. The
default is port 9100 to /dev/lp0.
http://www.etherboot.org/p910nd/

View File

@ -0,0 +1,42 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=p910nd
PKG_VERSION:=0.7
PKG_RELEASE:=1
PKG_MD5SUM:=7bf752532d26c9106f8039db95df3a6b
PKG_SOURCE_URL:=http://www.etherboot.org/p910nd
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_CAT:=bzcat
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install
PKG_INIT_PRIO=70
include $(TOPDIR)/package/rules.mk
$(eval $(call PKG_template,P910ND,p910nd,$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH)))
$(PKG_BUILD_DIR)/.configured:
touch $@
$(PKG_BUILD_DIR)/.built:
$(MAKE) -C $(PKG_BUILD_DIR) \
$(TARGET_CONFIGURE_OPTS) \
CFLAGS="$(TARGET_CFLAGS) -DLOCKFILE_DIR=\"\\\"/tmp\\\"\""
touch $@
$(IPKG_P910ND):
install -d -m0755 $(IDIR_P910ND)/etc/default
install -m0644 ./files/p910nd.default $(IDIR_P910ND)/etc/default/p910nd
install -d -m0755 $(IDIR_P910ND)/etc/init.d
install -m0755 ./files/p910nd.init $(IDIR_P910ND)/etc/init.d/p910nd
install -d -m0755 $(IDIR_P910ND)/usr/sbin
ln -sf p910nd $(IDIR_P910ND)/etc/init.d/S$(PKG_INIT_PRIO)p910nd
cp -fpR $(PKG_BUILD_DIR)/p910nd $(IDIR_P910ND)/usr/sbin
$(RSTRIP) $(IDIR_P910ND)
$(IPKG_BUILD) $(IDIR_P910ND) $(PACKAGE_DIR)
mostlyclean:
-$(MAKE) -C $(PKG_BUILD_DIR) clean
rm -rf $(PKG_BUILD_DIR)/.built

View File

@ -0,0 +1,10 @@
# Port 9100 is copied to /dev/lp0, 9101 to /dev/lp1 and 9102
# to /dev/lp2. The default is port 9100 to /dev/lp0.
# Values are 0|1|2
#
#PORT="0"
# The -b option turns on bidirectional copying.
# The -f option can be used to specify a different printer device.
#
#OPTIONS="-b -f /dev/usblp0"

View File

@ -0,0 +1,20 @@
#!/bin/sh
DEFAULT=/etc/default/p910nd
[ -f $DEFAULT ] && . $DEFAULT
RUN_D=/var/run
PID_F=$RUN_D/p910${PORT-0}d.pid
case $1 in
start)
mkdir -p $RUN_D
p910nd $OPTIONS
;;
stop)
[ -f $PID_F ] && kill $(cat $PID_F)
;;
*)
echo "usage: $0 (start|stop)"
exit 1
esac
exit $?

View File

@ -0,0 +1 @@
/etc/default/p910nd

View File

@ -0,0 +1,13 @@
Package: p910nd
Priority: optional
Section: net
Maintainer: OpenWrt Developers Team <openwrt-devel@openwrt.org>
Source: http://openwrt.org/cgi-bin/viewcvs.cgi/openwrt/package/p910nd/
Description: A small non-spooling printer server.
p910nd is a small daemon that copies any data received on
the port it is listening on to the corresponding printer
port. It is primarily intended for diskless Linux hosts
running as printer drivers but there is no reason why it
could not be used on diskful hosts. Port 9100 is copied
to /dev/lp0, 9101 to /dev/lp1 and 9102 to /dev/lp2. The
default is port 9100 to /dev/lp0.

View File

@ -0,0 +1,15 @@
--- p910nd-0.7/Makefile.orig 2005-09-25 13:54:28.465506888 +0200
+++ p910nd-0.7/Makefile 2005-09-25 13:54:46.928700056 +0200
@@ -2,9 +2,9 @@
# below if you don't want to use libwrap (hosts.{allow,deny} access control)
# If you don't have it in /var/log/subsys, uncomment and define
-#CFLAGS+=-DLOCKFILE_DIR=\"/var/log\"
+CFLAGS+=-DLOCKFILE_DIR=\"/tmp\"
LIBWRAP=-lwrap
p910nd: p910nd.c
-# $(CC) -Wall $(CFLAGS) -o $@ p910nd.c
- $(CC) -Wall $(CFLAGS) -DUSE_LIBWRAP -o $@ p910nd.c $(LIBWRAP)
+ $(CC) -Wall $(CFLAGS) -o $@ p910nd.c
+# $(CC) -Wall $(CFLAGS) -DUSE_LIBWRAP -o $@ p910nd.c $(LIBWRAP)

View File

@ -0,0 +1,309 @@
Only in p910nd: p910nd
diff -u p910nd-0.7/p910nd.c p910nd/p910nd.c
--- p910nd-0.7/p910nd.c 2004-08-09 03:25:01.000000000 +0400
+++ p910nd/p910nd.c 2005-05-11 00:37:03.385284744 +0400
@@ -74,7 +74,6 @@
#define LOCKFILE "/var/lock/subsys/p910%cd"
#endif
#define PRINTERFILE "/dev/lp%c"
-#define LOGOPTS LOG_ERR
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);
}