9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: G. David Butler gdb@dbSystems.com
Subject: Setting up lp for PC
Date: Mon,  8 Jan 1996 09:31:37 -0500	[thread overview]
Message-ID: <19960108143137.pXC8H5ZMlO03DeoYjenrirkcWe4dSyYolsZlP_Nw6BM@z> (raw)

This is how I added a postscript printer on serial port
eia1 on a PC cpu server named cpu1.

To drive a printer on the parallel port, a different
approach is required since tcpostio requires feedback
from the printer and the parallel interface is one way.
Basically a lptsrv needs to be written that opens
/dev/lpt1data write only and emulates the responses
from tcpostio.  A simpler approach would be to change
the daemon side alltogether so it doesn't chat with
the printer.

Since I have a file server that does *NOT* have a WORM,
I have all the cpus and terminals share the /sys/lib/lp
directory and use the queue and tmp directories there.
(In other words, no bootes "other" file system.)

After these changes, one can print from the cpu console
and any terminal or cpu window.

I would like to have some feedback to the code in eiasrv.c.
Did I do all the "proper" Plan 9 things?

Enjoy.

David Butler
gdb@dbSystems.com


==================================================
add to /sys/lib/lp/devices: (line broken for readability)
ps	Office	cpu1	/srv/eia1	512	post+nohead	generic
generic	generic	generic	tcppost	FIFO

==================================================
/sys/lib/lp/bin/lpsend.rc (/sys/src/cmd/lp/lpsend.rc):
diff -e lpsend.rc.cdrom lpsend.rc
24,32c
#if (test -e /net/dk/clone || import helix /net/dk) {
# 	dialstring=`{ndb/query sys $1 dk}
#	network=dk
#	if (! ~ $dialstring '') {
#		if(lpsend $dialstring $network printer) exit ''
#	}
#	rv=$rv^', dk failed'
#}
#if not rv=$rv^', no dk'
.
5c
if (test -e /net/tcp/clone || import cpu1 /net/tcp) {
.

==================================================
/rc/bin/lp (/sys/src/cmd/lp/lp.rc):
diff -e lp.rc.cdrom lp.rc
17,21c
#if (! test -r /srv/bootes) srv -m bootes
#if (! mount -c /srv/bootes /n/bootesother other || ! bind -a /n/bootesother/lp /sys/lib/lp) {
#	echo 'could not properly setup LPSPOOL' >[1=2]
#	exit 'LPSPOOL setup'
#}
.

==================================================
/386/bin/aux/lpdaemon (/sys/src/cmd/lp/lpdaemon.c):
diff -e lpdaemon.c.cdrom lpdaemon.c
423a
		ACK();
.
153c
	return(fd);
.
151d
146c
	close(fd);
	if((fd=open(tmpf, 2)) < 0) {
.
141c
	if((fd=creat(tmpf, 0666)) < 0) {
.
137,138c
	char tmpf[100];
	int fd;
.
92a
#else
	fputs(s1, fp);
#endif
.
91a
#ifndef PLAN9
.
90a
#else
	vfprintf(fp, s1, ap);
#endif
.
89a
#ifndef PLAN9
.
79a
#endif
.
77a
#ifndef PLAN9
.

==================================================
/386/bin/aux/tcpostio (/sys/src/cmd/postscript/tcpostio.l):
diff -e tcpostio.l.cdrom tcpostio.l
412c
				fprint(2, ". %5.2f%% sent, %.100s\n", bytes_sent*100.0/bytes_to_send, statusbuf);
.
283c
				blocksize = atoi(av);
.
197c
byte statusbuf[PRBUFSIZ];
.
177c
			if (write(printerfd, "\004", 1) != 1) {
.
162c
					if (write(printerfd, "\004", 1) != 1) {
.
149c
			if (write(printerfd, "\024", 1) != 1) {
.
123,124c
				if (*(ke = find(ks, ":")) == '\0') {
					return(PR_UNKNOWN);
				}
				kl = ke - ks;
.
120a
				return(statuslist[i].val);
.
117,118c
						break;
.
103c
			vl = ve - vs;
.
91,92c
		if (*(ke = find(ks, ":")) == '\0') {
			return(PR_UNKNOWN);
		}
		kl = ke - ks;
.
59c
	{ nil, PR_UNKNOWN }
.

==================================================
/386/bin/aux/eiasrv (/sys/src/cmd/aux/eiasrv.c):
cat eiasrv.c
/*
 * Copyright (c) 1996 G. David Butler
 * All Rights Reserved.
 *
 * Unrestricted use of this source is granted as long as
 * the above copyright remains.
 */

#include <u.h>
#include <libc.h>

#define PRBUFSIZ 8192	/* from /sys/src/cmd/postscript/tcpostio/tcpostio.h */

char Srvfilename[256];
int Childpid;

/* remove the /srv entry and kill the child at exit */
void
cleanup(void)
{
	remove(Srvfilename);
	postnote(PNPROC, Childpid, "kill");
}

/* on interrupt, if in the child writing to pipe, OK */
/* else, cleanup and exit */
int
notehandler(void *, char *note) {
	static char *pipenote = "sys: write on closed pipe";

	if (strncmp(note, pipenote, sizeof(pipenote) - 1) == 0) {
		return 1;
	}
	cleanup();
	return 0;
}

void
main(int argc, char *argv[])
{
	int blocksize;	/* see tcpostio.l about this */
	int baud;		/* rate of the serial device */
	int outputfd;	/* fd to serial device */
	int inputfd;	/* fd from pipe on /srv */
	int pipefd[2];
	char buf[PRBUFSIZ];

	blocksize = PRBUFSIZ;
	baud = 9600;	/* default rate */

	ARGBEGIN {
	case 'B':
		blocksize = atoi(ARGF());
		break;
	case 'b':
		baud = atoi(ARGF());
		break;
	default:
		fprint(2, "%s: badflag('%c')\n", argv0, ARGC());
		break;
	} ARGEND

	if (argc != 1 || baud == 0) {
		fprint(2, "Usage: %s [-B blocksize] [-b baud] device\n", argv0);
		exits("fatal");
	}

	if (blocksize < 1 || blocksize > PRBUFSIZ) {
		blocksize = PRBUFSIZ;
	}

	if ((outputfd = open(*argv, ORDWR)) < 0) {
		fprint(2, "%s: open of (%s) failed: %r\n", argv0, *argv);
		exits("fatal");
	}

	/* set the port up correctly for I/O */
	sprint(Srvfilename, "%sctl", *argv);
	if ((inputfd = open(Srvfilename, OWRITE)) < 0) {
		fprint(2, "%s: open of (%s) failed: %r\n", argv0, Srvfilename);
		exits("fatal");
	}

	sprint(buf, "b%d", baud);
	if (write(inputfd, buf, strlen(buf)) < 0 ||
	    write(inputfd, "d1", 2) < 0 ||
	    write(inputfd, "r1", 2) < 0 ||
	    write(inputfd, "m1", 2) < 0 ||
	    write(inputfd, "pn", 2) < 0 ||
	    write(inputfd, "s1", 2) < 0 ||
	    write(inputfd, "l8", 2) < 0) {
		fprint(2, "%s: write to (%s) failed: %r\n", argv0, Srvfilename);
		exits("fatal");
	}
	close(inputfd);

	/* this is the name of our "named pipe" */
	sprint(Srvfilename, "/srv%s", strrchr(*argv, '/'));
	if ((inputfd = create(Srvfilename, OWRITE, 0666)) < 0) {
		fprint(2, "%s: create of (%s) failed: %r\n", argv0, Srvfilename);
		exits("fatal");
	}

	atexit(cleanup);

	if (pipe(pipefd) < 0) {
		fprint(2, "%s: pipe failed: %r\n", argv0);
		exits("fatal");
	}

	sprint(buf, "%d", pipefd[0]);
	if (write (inputfd, buf, strlen(buf)) < 0) {
		fprint(2, "%s: write to (%s) failed: %r\n", argv0, Srvfilename);
		exits("fatal");
	}

	close(inputfd);
	close(pipefd[0]);
	inputfd = pipefd[1];

	atnotify(notehandler, 1);

	/* the parent and child can share */
	if (Childpid = rfork(RFPROC)) {

		while ((pipefd[0] = read(inputfd, buf, blocksize)) >= 0) {
			pipefd[1] = 0;
			while (pipefd[1] < pipefd[0]) {
				if ((baud = write(outputfd, buf, pipefd[0])) < 0) {
					fprint(2, "%s: parent write failed: %r\n", argv0);
					exits("fatal");
				}
				pipefd[1] += baud;
			}
		}

		if (pipefd[0] < 0) {
			fprint(2, "%s: parent read failed: %r\n", argv0);
			exits("fatal");
		} else {
			exits("");
		}

	} else {

		while ((pipefd[0] = read(outputfd, buf, blocksize)) >= 0) {
			pipefd[1] = 0;
			while (pipefd[1] < pipefd[0]) {
				if ((baud = write(inputfd, buf, pipefd[0])) < 0) {
					buf[0] = '\0';
					errstr(buf);
					if (strcmp(buf, "interrupted") == 0) {
						pipefd[1] = pipefd[0];
						continue;
					} else {
						fprint(2, "%s: child write failed: %s\n", argv0, buf);
						exits("fatal");
					}
				}
				pipefd[1] += baud;
			}
		}

		if (pipefd[0] < 0) {
			fprint(2, "%s: child read failed: %r\n", argv0);
			exits("fatal");
		} else {
			exits("");
		}
	}
}


==================================================
/sys/src/cmd/aux/mkfile:
diff -e mkfile.cdrom mkfile
10a
	eiasrv\
.


==================================================
/rc/bin/cpurc:
	add a line to your cpu server bootup like:
		aux/eiasrv -b 38400 /dev/eia1 &






             reply	other threads:[~1996-01-08 14:31 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1996-01-08 14:31 G.David [this message]
  -- strict thread matches above, loose matches on Subject: below --
1996-01-08 20:17 Luther
1996-01-07  4:00 Luther

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=19960108143137.pXC8H5ZMlO03DeoYjenrirkcWe4dSyYolsZlP_Nw6BM@z \
    --to=9fans@9fans.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).