[comp.dcom.lans] Connecting a printer to an Ethernet

wsmith@umn-cs.UUCP (03/12/87)

Assuming you are using printcap with a :rm=bridge: or some such thing,
the problem is that this causes your Gould to look for a print daemon
to send the file to on the Bridge box (which isn't running such a thing).

There is no need to change the line printer daemon.  What you need to do
is set up a printcap entry as below:

bridge|lp2:\
	:lp=/dev/null:sd=/usr/spool/bridge-lp:lf=/usr/adm/bridge-errs:\
	:af=/usr/adm/bridge-acct:if=/usr/local/bin/bridge-filter:tr=\f:

(Make sure the files are writeable by daemon, otherwise the daemon may
go into an infinite loop trying to write them).

Next you write the program /usr/local/bin/bridge-filter to prepend a banner 
to the output (there may be an easier way) - the arguments lpd sends to
this program are $5=user, $7=host (for the others, see its documentation).
Then you have this program start a "telnet" session to the bridge
box and send the banner and file along.  Bridges only speak telnet,
so you must use that (assuming you are using the TCP software, not the
XNS stuff).

I've never done this exact application, but I have used a similar setup
for remote printing to non-BSD machines.  Good Luck!

Randy Smith
wsmith@umn-cs.arpa
..!ihnp4!umn-cs!wsmith

mcdermot@merlin.UUCP (03/12/87)

I have connected a printer to a Bridge using lpr.  Here is the printcap entry:

office:for printed mail:\
	:lp=/dev/null:sd=/usr/spool/bpd:\
	:lf=/usr/adm/lpd-errs:\
	:if=/etc/lproffice:\
	:rf=/usr/ucb/fpr:

Here is the source for lproffice: The clue is to use telnet which the bridge
understands.  The name of this file should be '/etc/lproffice' because
it users the trailing part of the filename to do the printer selection.

I'm sorry there are not more comments.  This was a quick hack and I had no
intent of distributing it.  Also, please forgive me for including source
here (that is flame /dev/null for all such complaints!).

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <signal.h>
#include <netdb.h>

main(ac,av)
int ac;
char *av[];
{
	int c;
	struct sockaddr_in server;
	struct servent *sp;
	struct hostent *hp;
	FILE *printer;
	int s;

loop:
	sp = getservbyname("telnet","tcp");
	/* running code named lprxxxx where xxxx is printer Bridge name*/
	hp = gethostbyname(av[0]+3);
	if(hp == NULL){
		fprintf(stderr,"lpfilter: unknown printer: %s\n",av[0]+3);
		exit(2);
	}
	bzero((char *)&server,sizeof(server));
	bcopy(hp -> h_addr,(char *)&server.sin_addr,hp->h_length);
	server.sin_family = hp->h_addrtype;
	server.sin_port = sp->s_port;
	s = socket (AF_INET, SOCK_STREAM,0);
	if(connect(s,(char *)&server,sizeof(server))<0){
		perror("lpfilter: cannot connect");
		exit (2);
	}
	printer = fdopen(s,"w");
	/* boy, lpd is a mess! */
	while ( (c = getchar()) != EOF){
	    if(c == '\n') fprintf(printer,"\n\r        ");
	    else if(c == '\031') {
		if (( c = getchar()) == '\01'){
			fflush(printer);
			kill(getpid(),SIGSTOP);
			continue;
		}
		else {
			ungetc(c,stdin);
			c = '\031';
		}
	    }
	    putc(c,printer);
	}
	exit(0);
}
John McDermott			{gatech|ucbvax|lanl}!unmvax!mcdermot
Univ of NM			W (505) 277-4650 
Albuquerque, NM 87131		H (505) 255-7796

uusgta@sw1e.UUCP (03/13/87)

In article <57700001@umn-cs.UUCP>, wsmith@umn-cs.UUCP writes:
> is set up a printcap entry as below:
> 
> bridge|lp2:\
> 	:lp=/dev/null:sd=/usr/spool/bridge-lp:lf=/usr/adm/bridge-errs:\
> 	:af=/usr/adm/bridge-acct:if=/usr/local/bin/bridge-filter:tr=\f:

I have done this, running into problems with the above when for other reasons
I had to add another (besides acctng) filter entry.  Since there is no filter
that *All* data will go through when more than one filter is defined filters
are "stopped" and started by lpd.  This is rough when the filter is your only
com path.
Fortunately the hack to lpd is straightforward. In the lpd code (common.c I
think) find the place where either a dev or a socket (to another lpd) is opened
& add a third choice.  Whole hack fits in couple dozen lines (but I obfuscated
that into several hundred & a daemon :-) ) There are a couple changes to lpq
also.  I found it helpful to add an address entry to printcap & put a bridge
address in internet form there. You don't want the address in /etc/hosts cause
then users can open telnet connections & screw with the printer. Being able to
specify the address simplifies testing since you can sit at a terminal & watch
what happens.  I would send you the code except I've changed jobs & management
at my old job is braindamaged.  (You can reach them only by phone and have them
start uucp for one q run.  Paranoia at a University?)

  There was a continuing problem that confuses the hell out of me. Occasionally
the Bridge would say it's connected when it wasn't. Netstat showed the socket
in FIN_WAIT_2.  Listening the Bridge port out corrected the problem.  Also the
Bridge discards buffered data after socket shutdown.  A workaround is a kludgey
one second sleep after data is finished before closing the socket.
I sure would like to know what caused the FIN_WAIT_2 problem.  If ANYONE
knows of shutdown problems twixt a Bridge (CS100 for us) & BSD please let 
me know.  Also if convenient for you, send me mail and I'll send for voice #'s
to my old job.  They are supposed to be on NSFnet soon but have heads in sand
till then.  _DEITY knows if they are willing to share code.   Hope all this
is still true.  I'm now the BSD bigot in a SV shop :-).
-- 
#			---Tom Adams---
# {bellcore,ihnp4}!sw1e!uusgta	St. Louis MO	314-235-4237
# Opinions expressed here are mine, not those of Southwestern Bell Telephone