jim@mit-athena.UUCP (Jim Fulton) (02/26/85)
[Go ahead, make my day.] There is a slight problem in the line printer spooling software that will bite you if you use remote printers and accidently include an output filter (OF) in the /etc/printcap. Lpd will start up a filter even if it is sending the file to be printed on a remote machine (note that it doesn't even use the filter in sending). Thus, the filter ends up sitting around forever, preventing the local lpd from telling the remote lpd to look in its queues for jobs to print. Now, for those who would answer "don't be stupid and list an output filter if you are sending to a remote machine", think about what happens when someone makes a mistake. Perhaps, but it would be nice if "mistakes" like this (I argue that since the OF isn't used, it shouldn't matter). Besides, it would be nicer to list both remote and local info and have the printing software figure out what to use (see below). The problem is in the routine openpr() in printjob.c and the fix is fairly easy to make. Move the if block /* * Start up an output filter, if needed. */ if (OF) { ... } inside the "if (*LP) { ... }" block that does processing if the printer is attached to this machine so that it comes after the status ("%s is ready and printing", printer); line. Now, you only get filters started up if they are actually going to be used. While I'm at it, here is another useful thing. Having to keep different printcap files (or even entries) for machines with printers attached and machines without printers is a REAL pain in the neck. If you insert the following code into init() in printjob.c and displayq() in displayq.c after the line RM = pgetstr("rm", &bp); then you can include entries in the printcap for both local and remote hosts (i.e. lp= and rp=/rm=): /* * Figure out whether the local machine is the same as the remote * machine entry (if it exists). If not, then ignore the local * queue information. */ if (RM != (char *) NULL) { char name[255]; struct hostent *hp; /* get the name of the local host */ gethostname (name, sizeof(name) - 1); name[sizeof(name)-1] = '\0'; /* get the network standard name of the local host */ hp = gethostbyname (name); if (hp == (struct hostent *) NULL) { printf ("unable to get hostname for local machine %s\n", name); goto localcheck_done; } else strcpy (name, hp->h_name); /* get the network standard name of RM */ hp = gethostbyname (RM); if (hp == (struct hostent *) NULL) { printf ("unable to get hostname for remote machine %s\n", RM); goto localcheck_done; } /* if printer is not on local machine, ignore LP */ if (strcmp (name, hp->h_name) != 0) *LP = '\0'; } localcheck_done: I apologize if I've forgotten anything. This code has been running here at Athena for awhile on a network with almost 2 dozen printers and over 50 vaxen and has been incredibly useful. We now have one printcap file for all of our machines. For those who are interested, local aliases for printer names (i.e. lpr -Plaser where laser means the laser printer in the cluster nearest me) are provided using a cluster information database that I will probably post to the net after I've released it here. Jim Fulton arpa: jim%mit-athena@mit-mc.ARPA MIT Project Athena uucp: decvax!mit-athena!jim