From:	MERC::"uunet!alcatel.co.@!Dietmar.Berg"  9-JUN-1992 07:46:53.82
To:	uucm000@uxa.ecn.bgu.edu, osyjm@schizo.coe.montana.edu,
	BEAR@nucvs7.anu.edu.au, martinea@ireq.hydro.qc.ca, ONASCH@ira.uka.de,
	klein@saturn.glassboro.edu, powers@elros.stg.trw.com, galaxy::gleeve
CC:	
Subj:	LPD for UCX Part04 of 6

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 6)."
# Contents:  lpdgw.c dlpd.tex build.com ilpd_start.com dlpd_start.com
#   dlpd.config
# Wrapped by berg@valide on Tue Jun  9 12:28:50 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'lpdgw.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lpdgw.c'\"
else
echo shar: Extracting \"'lpdgw.c'\" \(13220 characters\)
sed "s/^X//" >'lpdgw.c' <<'END_OF_FILE'
Xstatic char sccsid[] = "@(#)lpdgw.c 1.2 1/30/92 15:42:23";
X/*
X  lpdgw.c  --  Gateway for lpd(8) from Internet to DECnet
X
X  Dietmar Berg, BSH
X*/
X
X
X#include <stdio.h>
X#include <fcntl.h>
X#include <ctype.h>
X#include <time.h>
X#include <sys/file.h>
X#include <sys/time.h>
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <netinet/in.h>
X#include <netdnet/dn.h>
X#include <sys/wait.h>
X#include <sys/ioctl.h>
X#include <errno.h>
X#include <netdb.h>
X#include <signal.h>
X#include <syslog.h>
X#include <strings.h>
X
X
X#define USAGE "Usage: %s [-d] [-D debug-host] [-n node] [-l logfile] [port-#]\n"
X
X
X#define	SERVER_NAME	 "printer"	/* services(5) searched for tcp-port */
X
X#define DEFAULT_VMS_NODE "DVAX03"	/* when not specified somewhere else */
X#define NETWORK_OBJECT	 "DLPD"		/* NW object to connect to */
X
X#define EOF_CHAR	 '\032'		/* ^Z, sent by NETWORK_OBJECT to force exit */
X
X#define TIMEOUT		 180		/* timeout (s) for select() */
X
X#define BACKLOG		2		/* # of pending connections */
X#define BUFLEN		1024		/* network buffer length */
X
X
X
X/* ignore interrupts during system-call */
X#define no_eintr(x) 	while (((x) == -1) && (errno == EINTR))
X
X
X#define TRUE	1
X#define FALSE	0
X
X
Xstatic int sd_inet, nsd_inet;	/* internet sockets */
Xstatic int sd_dnet;		/* DECnet socket */
X
Xstatic int debug = FALSE;	/* debug-flag */
Xstatic char debug_host[32];	/* debugging for a single host only */
X
Xstatic char *program;		/* argv[0] */
Xstatic char *default_vms_node = DEFAULT_VMS_NODE; /* when not specified with printer */
X
Xextern int errno;		/* UNIX error codes */
X
X/* make it more readable */
X#define DBG(x)  if(debug) x
X
X
Xvoid
Xterminate (pid, exit_status)
Xlong pid;
X{
X    if (debug)
X    {
X    	time_t bintim; 
X	time (&bintim);
X	if (exit_status)
X	{
X	    char s[9];
X	    errno = exit_status;
X	    sprintf (s, "%5u:\t");
X	    perror (s);
X	} /*if*/
X        fprintf (stderr, "------ subprocess %u terminated at %24.24s -----\n\n",
X			 				pid, ctime (&bintim));
X    }
X    close (sd_dnet);
X    close (nsd_inet);
X    fflush (stderr);
X    exit (exit_status);
X} /* terminate() */
X
X
X
X
X/*
X  get exit status from child, discard it
X  (let it die in peace, not <exiting>)
X  called upon SIGCHLD-signal.
X*/
Xvoid
Xgetstat ()
X{
X    union wait status;
X    int pid;
X    while ((pid = wait3 (&status, WNOHANG | WUNTRACED, 0)) > 0)
X	;
X    return;
X} /* getstat() */
X
X
X/*
X  C H I L D  -  P R O C E S S
X  This one does the real work
X*/
Xvoid
Xsub_process (sa)
Xstruct sockaddr_in * sa;		/* peer address */
X{
X    static char i2d_buf[BUFLEN], d2i_buf[BUFLEN];
X    char *i2d_buf_p = i2d_buf,
X         *d2i_buf_p = d2i_buf;		/* index into buffers */
X    int i2d_len = 0, d2i_len = 0;	/* current buffer lengths */
X    int len;
X    fd_set rd_mask, wr_mask;		/* bit masks for status checks */
X    char d_eof = FALSE, i_eof = FALSE;	/* EOF-flags */
X    struct hostent * he;		/* host database entry */
X    static struct linger s_linger;	/* socket option structure */
X    long pid = getpid();		/* process id of child */
X    char s [64];			/* general purpose string */
X    char vms_node [10];			/* VMS partner */
X    register char * p;
X    static struct timeval timeout = {TIMEOUT, 0}; /* timeout for select() */
X
X
X    /* close old inet socket */
X    close (sd_inet);
X
X    /* format the address string for debug or error msg */
X    strcpy (s, inet_ntoa (sa->sin_addr));
X
X    if (debug)
X    {
X	time_t bintim;
X	time (&bintim);
X        fprintf (stderr, 
X		"\n\n------- subprocess %u started at %24.24s -------\n",
X		pid, ctime (&bintim));
X        fflush (stderr);
X    } /*if*/
X
X    if ((he = gethostbyaddr (&sa->sin_addr, 4, AF_INET)) == NULL)
X    {
X        if (!debug)
X	{	/* append to syslog */
X	    openlog (program, LOG_PID);		/* identify myself */
X	    syslog (LOG_CRIT, 
X			"Request from unknown host %s, check /etc/hosts", s);
X	} /*if*/
X	fprintf (stderr, "%5u:\t Unknown host %s\n", pid, s);
X	terminate (pid, ECONNREFUSED);
X    } /*if*/
X
X    /* reset debug-flag now if request from a host we should not trace */
X    if (debug && *debug_host)
X	debug = (strcmp (debug_host, he->h_name) == 0);
X
X    DBG (fprintf(stderr, "%5u:\t sd_inet=%u, addr=%s (%s)\n", 
X					pid, sd_inet, s, he->h_name));
X
X
X    /* receive the first msg from inet to parse it for desired vms-node */
X
X    if ((i2d_len = read (nsd_inet, i2d_buf, sizeof(i2d_buf)-1)) < 0)
X	terminate (pid, errno);
X    i2d_buf[i2d_len] = '\0';		/* terminate the string */
X
X    DBG (fprintf (stderr, "%5u:\t request=^%c, %s", pid, 
X					i2d_buf[0]+'@', &i2d_buf[1]));
X
X    if ((p = strchr (i2d_buf, '@')) != NULL)
X    {	    /* printer and node given */
X	sscanf (p+1, "%s", vms_node);
X        if (getnodebyname (vms_node) == NULL)
X	{	/* no such node */
X	    if (!debug)
X	    {	    /* append to syslog */
X		openlog (program, LOG_PID);		/* identify myself */
X	        syslog (LOG_CRIT, "%m, Request for unknown VMS node %s from %s", 
X								vms_node, he->h_name);
X	    } /*if*/
X	    terminate (pid, EHOSTUNREACH);
X	} /*if*/
X	while (*p && !isspace (*p))
X	    *p++ = ' ';		/* replace by spaces before sending on */
X    } /*if*/
X    else
X	strcpy (vms_node, default_vms_node);	/* insert default name */
X
X    DBG (fprintf (stderr, "%5u:\t vms_node=%s, msg=%s", 
X				pid, vms_node, &i2d_buf[1]));
X
X
X
X    /* initiate a DECnet connection */
X    /* 
X	the name of the originating UNIX-host is supplied
X	as 'optional data'
X    */
X    if ((sd_dnet = dnet_conn (vms_node, NETWORK_OBJECT,
X		0, he->h_name, strlen(he->h_name), 0, 0)) == -1)
X    {
X	if (!debug)
X	{	/* append to syslog */
X	    openlog (program, LOG_PID);		/* identify myself */
X	    syslog (LOG_CRIT, "%m, no connection to %s, object %s from %s",
X						vms_node, NETWORK_OBJECT, he->h_name);
X	} /*if*/
X	sprintf (s, "%5u:\t dnet_conn:", pid);
X	nerror (s);				/* print DECnet error msg */
X	terminate (pid, errno);
X    } /*if*/
X
X    DBG (fprintf (stderr, "%5u:\t %s connected to %s on sd_dnet=%u\n", 
X					     pid, he->h_name, vms_node, sd_dnet));
X
X
X/* the following section is somewhat experimental... */
X    s_linger.l_onoff = 0;		/* turn lingering on */
X    s_linger.l_linger = 10;		/* timeout */
X    if (setsockopt (sd_dnet, SOL_SOCKET, SO_LINGER, &s_linger, sizeof(s_linger)) == -1)
X        perror ("setsockopt/dnet");
X    if (setsockopt (nsd_inet, SOL_SOCKET, SO_LINGER, &s_linger, sizeof(s_linger)) == -1)
X    	perror ("setsockopt/inet");
X
X
X    /* start by writing current i2d-buffer */
X    FD_ZERO (&rd_mask);
X    FD_ZERO (&wr_mask);
X    FD_SET (sd_dnet,  &wr_mask);
X 
X    /* multiplex data between dnet and inet */
X    while (   FD_ISSET (sd_dnet,  &rd_mask)
X           || FD_ISSET (sd_dnet,  &wr_mask)
X           || FD_ISSET (nsd_inet, &rd_mask)
X           || FD_ISSET (nsd_inet, &wr_mask))
X    {
X
X	if (debug) 
X	    fprintf (stderr, "select: wr=%02X, rd=%02X\n", 
X			*(char*)wr_mask, *(char*)rd_mask);
X
X        if (select (FD_SETSIZE, &rd_mask, &wr_mask, NULL, &timeout) < 0)
X	{
X	    if (!debug)
X	    {	    /* append to syslog */
X	        openlog (program, LOG_PID);		/* identify myself */
X	        syslog (LOG_CRIT, "%m, connection between %s and %s timed out", 
X							vms_node, he->h_name);
X	    } /*if*/
X	    terminate (pid, ETIMEDOUT);		/* timeout expired */
X	} /*if*/
X
X        if (FD_ISSET (nsd_inet, &rd_mask))
X        {
X            if ((i2d_len = read (nsd_inet, i2d_buf, sizeof(i2d_buf))) < 0)
X                terminate (pid, errno);
X            else
X                i_eof = (i2d_len == 0);         /* EOF received */
X            i2d_buf_p = i2d_buf;                /* reset pointer */
X            DBG (fprintf (stderr, "\t INET ---> %d bytes\n", i2d_len));
X        } /*if*/
X 
X        if (FD_ISSET (sd_dnet, &rd_mask))
X        {
X	    if ((d2i_len = read (sd_dnet, d2i_buf, sizeof(d2i_buf))) < 0)
X	    	terminate (pid, errno);
X            else
X		if (d_eof = ((d2i_len == 1) && (d2i_buf[0] == EOF_CHAR)
X			   || (d2i_len == 0) && dnet_eof (sd_dnet)))
X		    d2i_len = 0;		/* don't send this one! */
X            d2i_buf_p = d2i_buf;                /* reset pointer */
X            DBG (fprintf (stderr, "\t DNET ---> %d bytes\n", d2i_len));
X        } /*if*/
X 
X        if (FD_ISSET (sd_dnet, &wr_mask))
X        {
X            if ((len = write (sd_dnet, i2d_buf_p, i2d_len)) < 0)
X		terminate (pid, errno);
X            i2d_len -= len;             /* reduce buffer bytecount */
X            i2d_buf_p += len;           /* advance pointer */
X            DBG (fprintf (stderr, "\t %d bytes ---> DNET\n", len));
X        } /*if*/
X  
X
X        if (FD_ISSET (nsd_inet, &wr_mask))
X        {
X            if ((len = write (nsd_inet, d2i_buf_p, d2i_len)) < 0)
X		terminate (pid, errno);
X            d2i_len -= len;             /* reduce buffer bytecount */
X            d2i_buf_p += len;           /* advance pointer */
X            DBG (fprintf (stderr, "\t %d bytes ---> INET\n", len));
X        } /*if*/
X
X	if (debug)
X	{
X            if (d_eof) fprintf (stderr, "%5u:\t DNET returned EOF\n", pid);
X            if (i_eof) fprintf (stderr, "%5u:\t INET returned EOF\n", pid);
X	    fflush (stderr);
X	} /*if*/
X
X	if (debug)
X	    fprintf (stderr, "i_eof=%d, d_eof=%d\n", i_eof, d_eof);
X
X        /* set descriptors for next run */
X        FD_ZERO (&rd_mask);
X        if ((i2d_len == 0) && ! (i_eof||d_eof))
X            FD_SET (nsd_inet, &rd_mask);	/* inet -> dnet */
X        if ((d2i_len == 0) && ! (d_eof||i_eof))
X            FD_SET (sd_dnet, &rd_mask);		/* dnet -> inet */
X              
X        FD_ZERO (&wr_mask);
X        if ((i2d_len > 0))
X            FD_SET (sd_dnet, &wr_mask);		/* inet -> dnet */
X        if ((d2i_len > 0))
X            FD_SET (nsd_inet, &wr_mask);	/* dnet -> inet */
X
X	if (debug)
X	    fprintf (stderr, "setup: wr=%02X, rd=%02X\n", 
X			*(char*)wr_mask, *(char*)rd_mask);
X    } /*while*/
X
X    close (nsd_inet);
X    close (sd_dnet);
X
X    terminate (pid, 0);			/* no RETURN ! */
X} /* sub_process() */
X
X
Xint
Xmain (argc, argv)
Xint argc;
Xchar *argv[];
X{
X    register int i;
X    unsigned int inet_port;		/* internet port number */
X    int fd = -1;			/* file descriptor for error output */
X    struct servent *se;			/* inet port name structure */
X    struct sockaddr_in sa_inet;		/* internet address structure */
X    int sa_inet_len = sizeof(sa_inet);	/* length of address field */
X    char optval = 1;			/* for setting socket option */
X    int opt;				/* option char */
X    extern char *optarg;		/* for use with getopt() */
X    extern int optind;
X
X
X    /* get last element from pathname to program */
X    if (program = (char*) rindex (argv[0], '/'))
X        program++;
X    else
X        program = argv[0];
X 
X    /* parse arguments */
X    while ((opt = getopt (argc, argv, "dD:l:n:")) != EOF)
X    {
X        switch (opt)
X	{
X	    case 'd' : 	/* debug */
X			debug = TRUE;
X			break;
X	    case 'D' :	/* debug, hostname follows */
X			debug = TRUE;
X			strcpy (debug_host, optarg); 
X			fprintf (stderr, "Debugging for host %s only\n", debug_host);
X			break;
X
X	    case 'l' :	/* logfile */
X			if ((fd = open (optarg, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
X			{
X			    perror (optarg);
X			    exit (errno);
X			} /*if*/
X			break;
X
X	    case 'n' :	/* VMS-node */
X			if (getnodebyname (default_vms_node = optarg) == NULL)
X			{
X			    errno = EHOSTUNREACH;
X			    perror (optarg);
X			    exit (errno);
X			} /*if*/
X			break;
X
X	    default  :  /* error */
X			fprintf (stderr, USAGE, program);
X			exit (2);
X	} /*switch*/
X    } /*while*/
X
X    /* port number could come along now */
X    if (optind < argc)
X	if (sscanf (argv[optind], "%d", &inet_port) != 1)
X	{
X	    fprintf (stderr, "expected internet port #, not '%s'\n", argv[optind]);
X	    fprintf (stderr, USAGE, program);
X	    exit (2);
X	} /*if*/
X
X
X    if (inet_port == 0)
X    {	    /* not defined yet */
X	if ((se = getservbyname (SERVER_NAME, "tcp")) == NULL)
X	{
X	    fprintf (stderr, "No server entry for %s\n", SERVER_NAME);
X	    exit (EINVAL);
X	} /*if*/
X	inet_port = se->s_port;
X    } /*if*/
X
X
X/*
X  Got all parameters now.
X  <stderr> will not be redirected until a socket has been
X  sucessfully bound to the desired port address, so you
X  see what you get (or don't get).
X*/
X
X    /* create (server) socket in INET address family */
X    if ((sd_inet = socket (AF_INET, SOCK_STREAM, 0)) == -1)
X    {
X	perror ("INET_Socket");
X	exit (errno);
X    } /*if*/
X
X    sa_inet.sin_family = AF_INET;
X    sa_inet.sin_port = htons (inet_port);
X    sa_inet.sin_addr.s_addr = 0;
X    if (bind (sd_inet, &sa_inet, sizeof(sa_inet)) == -1)
X    {
X	perror ("INET_bind");
X	exit (errno);
X    } /*if*/
X
X    if (listen (sd_inet, BACKLOG) == -1)
X    {
X	perror ("INET_listen");
X	exit (errno);
X    } /*if*/
X
X
X    /* stderr redirection ? */
X    if (fd != -1)
X    {
X	dup2 (fd, 2);
X	close (fd);
X    }
X
X
X    /* say goodbye to shell, control terminals, and all that stuff... */
X    if (fork())
X	exit (0);
X    close (0);
X    close (1);
X    fd = open ("/dev/tty");
X    ioctl (fd, TIOCNOTTY, 0);
X    close (fd);
X
X
X/*
X    from now on this process loops and spawns children on
X    incoming connection requests
X*/
X
X    signal (SIGCHLD, getstat);		/* let children die in peace */
X
X    while (1)
X    {
X	no_eintr (nsd_inet = accept (sd_inet, &sa_inet, &sa_inet_len));
X	if (nsd_inet < 0)
X	{
X	    perror ("accept");
X	    exit (errno);
X	}
X	if (fork() == 0)
X	    sub_process (&sa_inet);	/* child */
X
X        close (nsd_inet);
X    } /* while(forever) */
X
X    return (0);
X} /* main() */
END_OF_FILE
if test 13220 -ne `wc -c <'lpdgw.c'`; then
    echo shar: \"'lpdgw.c'\" unpacked with wrong size!
fi
# end of 'lpdgw.c'
fi
if test -f 'dlpd.tex' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dlpd.tex'\"
else
echo shar: Extracting \"'dlpd.tex'\" \(30339 characters\)
sed "s/^X//" >'dlpd.tex' <<'END_OF_FILE'
X% Integration of UNIX-printing under VMS
X% @(#)dlpd.tex 1.7 4/21/92 16:29:19
X\documentstyle{article}
X\pagestyle{plain}
X
X
X\textheight = 24cm
X\textwidth  = 17cm
X
X\setlength{\parskip}{0.7ex plus0.5ex minus0.2ex}
X\setlength{\parindent}{0pt}
X
X\begin{document}
X
X\title{Integration of UNIX printing under VMS \\ \vspace{3ex}\normalsize Edition 2}
X\author{Dietmar Berg}
X\maketitle
X
X
X\tableofcontents
X
X\begin{abstract}
X This manual describes an arrangement where queues connected to VAX/VMS hosts
X can transparently be used from UNIX machines via an ULTRIX gateway or
X directly if the ULTRIX-Connection software is installed. All existing UNIX
X programs to handle printer queues can be used without modification.
X
X \noindent
X Version 2.x of the software now also supports VMS batch queue access by
X the UNIX ``print'' mechanism.
X\end{abstract}
X
X
X
X\part{User Guide}
X
XThis part of the manual describes how the UNIX commands {\tt lpr}(1), {\tt
Xlprm}(1) and {\tt lpq}(1) can be used to access printer/batch jobs on a VMS
Xmachine which does remote printing/batch execution for a UNIX host. For the
Xsake of brevity, only the options relevant for use in the UNIX/VMS
Xenvironment described here are documented. More information can be found in the
Xonline manual.
X
X
X
X\section{Submission of Print-/Batch-Jobs}
X
XThe UNIX command {\tt lpr}(1) is supported as far as the capabilities of
XUNIX printing can be emulated under VMS. This does not apply to calling
Xappropriate filters when the files do not contain text, but binary data (e.g.
X{\tt troff}(1) output). When a file is sent to a VMS batch queue, it must
Xcontain DCL commands, which will be executed as a batch job executing in
Xthe user's login-directory.
X
XA problem arises with the different filename-syntax. While {\tt y.tab.c} is a
Xperfectly legal filename under UNIX, it violates VMS syntax. The software
Xrunning under VMS tries to conserve as much information as possible. In this
Xsense, it renames the temporary spool-filenames to what resembles most their
Xoriginal name (if it had not been standard input), sometimes suppressing
Xunsupported characters (or characters violating VMS syntax) before queueing
Xthe files. If the file was printed from standard input, but there is an
Xexplicit jobname defined, this one is used as a filename, to have something
Xreasonable printed on the flag page.
X
X
X\medskip\noindent
XSyntax:
X
X\noindent
X~~~~{\tt lpr} [{\tt -P}{\em printer}]
X              [{\tt -C}{\em classification}]
X              [{\tt -\#}{\em copies}]
X              [{\tt -J}{\em jobname}]
X              [{\tt -prmhs}]           {\em file(s) $\ldots$}
X
X
X\medskip
X\noindent
XThe supported options are:
X
X\noindent
X{ \centering
X\begin{tabular}{lp{135mm}}
X  \tt -P\em printer &
X    This option names the queue on which to print. It must be one of the queues
X    defined on the UNIX side (in {\tt printcap}(5)), not a VMS queue name!
X    Note that when this option is not specified, the value of the environment
X    variable {\tt PRINTER} (if set) is used instead.
X    \\
X  \tt -\#\em copies &
X    Print the specified number of {\em copies} of the job. This option is
X    applied to all files in the (print-) job. It is emulated by {\tt /COPIES}.
X    \\
X  \tt -C\em classification &
X    When sending a file to a print or batch queue, the (normally unused)
X    {\em classification} string can be used to supply information
X    (setups and parameters) to the job.
X
X    A setup-specification must start with \verb'+' (which is stripped);
X    it is added to the one associated with the queue (if there is one).
X
X    A parameter specification must start with \verb'/' (which is stripped).
X    Parameters which come from the general configuration info
X    for this queue are shifted "up" (and fall out at the top).
X    \\
X  \tt -J\em jobname &
X    Use this name as the name of the print/batch job instead of the name of
X    the first file. This name is also used as a filename when nothing else
X    is available (standard input).
X    \\
X  \tt -T\em title &
X    Use this name as the title for the {\tt -p} option. This name is also
X    used as the name of the temporary file when no filename is available
X    (standard input).
X    \\
X  \tt -m &
X    Send mail upon job completion. The job is queued with {\tt /NOTIFY} and
X    aditionally mail is sent when the job completes. When the job
X    terminates abnormally, mail is always sent to the user. Otherwise,
X    depending on how the system is set up, mail is sent to the user
X    or to an alias which causes a notification message to be written to the
X    users terminal.
X    It is particularly useful to set {\tt ~biff y~}
X    to get asynchronuous mail delivery and notification.
X    \\
X  \tt -h &
X    Suppress the printing of the flag page (job queued with {\tt NOFLAG}).
X    This option is mutually exclusive to {\tt -J}.
X    \\
X  \tt -p &
X    Format the file before printing. This option is emulated by {\tt /HEADER},
X    but is not supported (by VMS) on the PrintServer40 or the ScriptPrinter.
X    \\
X  \tt -l &
X    Print control characters and suppress page breaks. This option is emulated
X    by \mbox{\tt /PASSALL}.
X    \\
X  \tt -r &
X    Remove the file upon completion of spooling. This is equivalent to {\tt
X    /DELETE} under VMS, but it applies to the file on the UNIX machine (the
X    temporary spool files on the VMS machine are automatically deleted).
X    \\
X  \tt -s &
X    Use a symbolic link instead of copying the file to the (UNIX) spool
X    directory. Don't use this option unless you know what you are doing.
X\end{tabular} }
X
X
X
X\subsection*{Examples}
X
X\begin{verbatim}
X   setenv PRINTER lps40_ansi.1p
X   lpr -m myfile
X\end{verbatim}
X
XThe environment variable {\tt PRINTER} is set to {\tt lps40\_ansi.1p} to define
Xthe default printer name for all subsequent queue operations.
XThe file {\tt myfile} is then printed on this queue. The user will be notified
Xwhen the job completes (mail on abnormal termination, mail or terminal
Xnotification on success).
X
X\medskip
X\begin{verbatim}
X   pr y.tab.c | lpr -Plps40_ansi_1l -Jy.tab.c \
X                 '-C+lps$errorhandler/mess=print/output_tray=side'
X\end{verbatim}
X
XThe file {\tt y.tab.c} is formatted by {\tt pr}(1) and then piped to the
Xprinter {\tt lps40\_ansi\_1l} (landscape, slightly reduced). The filename is
X``restored'' by using the {\tt -J} (Jobname) option. Special sheet
Xand error handling is defined using the {\tt -C} option to supply two
Xparameters (additional to the ones defined for the queue).
XA setup module ({\tt lps\$errorhandler}) is also included in the job.
XNote the quotes to prevent the \verb'$' from being recognized by the
Xshell.
X
X
X
X\section{Removal of Jobs}
X
XThe UNIX command {\tt lprm}(1) is fully supported. Nevertheless, there are a
Xfew specialities as far as root privileges and deletion of jobs queued under
XVMS are concerned. The different possibilities are detailed in the examples
Xbelow. A hash sign ({\tt \#}) in front of the command means that the command is
Xissued by root, a percent sign ({\tt \%}) means that it is issued by any user
Xother than root.
X
XThe queue affected by the command is either specified explicitely with the {\tt
X-P} option or implicitely by the environment-variable {\tt PRINTER}. If the
X``remote printer'' entry in {\tt /etc/printcap} contains an additional wildcard
Xqueue specification, all queues matched by either the wildcard or the target
Xqueue specification are searched. Jobs found in other queues than the target
Xqueue are only deleted when they were queued from the target queue, except when
Xa user other than root deletes a job per {\em entry} number. Ownership
Xverification on VMS is based on the user identification code (UIC),
XUNIX users which map to the same UIC are considered equivalent.
X
X\medskip\noindent
XSyntax:
X
X{\tt lprm} [{\tt -P}{\em printer}] [{\tt -}]
X           [{\em entry $\ldots$}]
X           [{\em user $\ldots$}]
X
X
X\subsection*{Examples}
X
X\indent
X{\tt \# lprm -P}{\em printer} {\tt -}
X
XThis command clears the queue from all jobs which where queued under UNIX
Xfrom one of the hosts in the same equivalence group as the host from which the
Xcommand is issued.
X
X
X\medskip
X{\tt \# lprm -P}{\em printer user }[{\em user1}] [{\em user2...}] \\
X\indent
X{\tt \# lprm -P}{\em printer entry }[{\em entry1}] [{\em entry2...}]
X
XThis command clears the queue from jobs of one or more {\em users} or
Xfrom jobs with the specified {\em entries}. It only affects jobs which where
Xqueued under UNIX from one of the hosts in the same equivalence group as the
Xhost from which the command is issued.
X
X
X\medskip
X{\tt \% lprm -P}{\em printer} {\tt -}
X
XThis command clears the queue from all jobs of the user who issued the command.
XIt affects jobs which where queued under UNIX and which (on the VMS-side) have
Xthe same owner-UIC as the user who issues the command (even if the jobs were
Xqueued from other users on other hosts).
X
X
X
X\medskip
X{\tt \% lprm -P}{\em printer entry} [{\em entry1}] [{\em entry2...}]
X
XThis command clears the queue from one or more jobs with the specified {\em
Xentries}. It affects jobs which where queued under UNIX {\bf or VMS} and
Xwhich (on the VMS-side) have the same owner-UIC as the user who issued the
Xcommand (even if the jobs were queued from other users on other hosts).
XVerification of the submission queue in the case of wildcard queue search is
X{\em not} done.
X
X
X
X
X\section{Display of Jobs}
X
XThe UNIX command {\tt lpq}(1) is fully supported. Output is formatted
XVMS-like, with the username given as {\em user@host} when the job was queued
Xunder UNIX or the plain VMS-username when it was queued under VMS.
X
X\medskip\noindent
XSyntax:
X
X{\tt lpq} [{\tt -l}]
X          [{\tt -P\em printer}]
X          [{\tt entry $\ldots$}]
X          [{\tt user  $\ldots$}]
X
X\medskip
XThe {\-l} option requests listing in long format, showing filenames, the
X{\tt -P\em printer} option selects a particular queue (otherwise a default
Xone or the one specified by the environment variable {\tt PRINTER} is used).
X
X
X
X\section{Currently Configured Queues}
X\label{sec:AAA-queues}
X
XThe following shows how queues are configured in Alcatel Austria.
XOnly one set of entries per printer type (LPS40, LPS20, LN03R) is shown.
X
XTo find an up-to-date list of printer queues, execute the command \hfill \\
X\hbox{\verb"  % grep '^[a-z]' /etc/printcap"}
X
X\begin{tabular}{ll}
X\tt lps40\_ps &            LPS40\_PS, portrait\\
X\tt lps40\_ps\_2p &         LPS40\_PS, portrait, 2 pages/sheet\\
X\tt lps40\_ps\_l &         LPS40\_PS, landscape\\
X\tt lps40\_ps\_la3 &         LPS40\_PS, landscape, A3 format\\
X\tt lps40\_ps\_2l &         LPS40\_PS, landscape, 2 pages/sheet\\
X\tt lps40\_ansi &   LPS40\_ANSI, portrait\\
X\tt lps40\_ansi\_1p &     LPS40\_ANSI, portrait, singleholes\\
X\tt lps40\_ansi\_2p &         LPS40\_ANSI, portrait, 2 pages/sheet\\
X\tt lps40\_ansi\_l &         LPS40\_ANSI, landscape\\
X\tt lps40\_ansi\_1l &         LPS40\_ANSI, landscape, singleholes\\
X\tt lps40\_ansi\_2l &         LPS40\_ANSI, landscape, 2 pages/sheet\\
X\tt lps20\_ps &   LPS20\_PS, portrait\\
X\tt lps20\_ps\_1p\_2 &  LPS20\_PS, portrait, double-sided\\
X\tt lps20\_ps\_2p &         LPS20\_PS, portrait, 2 pages/sheet\\
X\tt lps20\_ps\_l &      LPS20\_PS, landscape\\
X\tt lps20\_ps\_l\_2 &  LPS20\_PS, landscape, double-sided\\
X\tt lps20\_ps\_2l &         LPS20\_PS, landscape, 2 pages/sheet\\
X\tt lps20\_ansi &   LPS20\_ANSI, portrait\\
X\tt lps20\_ansi\_1p &     LPS20\_ANSI, portrait, singleholes\\
X\tt lps20\_ansi\_1p\_2 &  LPS20\_ANSI, portrait, singleholes, double-sided\\
X\tt lps20\_ansi\_2p &     LPS20\_ANSI, portrait, 2 pages/sheet\\
X\tt lps20\_ansi\_l &      LPS20\_ANSI, landscape\\
X\tt lps20\_ansi\_1l &     LPS20\_ANSI, landscape, singleholes\\
X\tt lps20\_ansi\_1l\_2 &  LPS20\_ANSI, landscape, singleholes, double-sided\\
X\tt lps20\_ansi\_2l &      LPS20\_ANSI, landscape, 2 pages/sheet\\
X\tt ln03r\_146\_p &     LN03R\_146\$PRINT, portrait, A4\\
X\tt ln03r\_146\_l &        LN03R\_146\$PRINT, landscape, A4\\
X\tt ln03r\_146\_2p &        LN03R\_146\$PRINT, portrait, 2 pages/sheet A4\\
X\tt ln03r\_146\_2l &        LN03R\_146\$PRINT, landscape, 2 pages/sheet A4\\
X\tt ln03r\_146\_ps &        LN03R\_146\$PRINT, postscript, A4\\
X\end{tabular}
X
X
X\clearpage
X\part{Installation and Operation Guide}
X
X
XThere are two versions:
X\begin{description}
X  \item [DECnet --- DLPD]
X        This version operates on DECnet with a gateway process executing
X        on a VAX under ULTRIX for performing the protocol conversion.
X  \item [Internet --- ILPD]
X        This version uses the VMS/ULTRIX Connection Software (separate
X        license required)
X\end{description}
X
X
X
X\section{VMS-Software}
X
XThis section describes the process runing under VMS. All logical names,
Xfilenames, etc. shown here begin with {\tt DLPD}$\ldots$ for the DECnet version
Xand {\tt ILPD}$\ldots$ for the UCX version.
X
X\noindent
XThe process (DLPD shown as an example) must be started with the
Xfollowing privileges and quotas:
X
X\begin{verbatim}
X  $ run -
X      /process_name="DLPD Server" -
X      /detach -
X      /input=NL: -
X      /output=NL: -
X      /error=dlpd_'F$GETSYI ("NODENAME")'.log -
X      /priority=6 -
X      /privilege=(nosame,tmpmbx,netmbx,sysnam,sysprv,cmkrnl) -
X      /subprocess_limit=1 -
X      /page_file=8192 -
X      /ast_limit=128 -
X      /io_buffered=32 -
X      /io_direct=32 -
X      /buffer_limit=32768 -
X      /enqueue_limit=128 -
X      /file_limit=128 -
X      /uic=[...,...] -
X      /noauthorize -
X      dlpd.exe
X\end{verbatim}
X
X
XPrior to this, the logical name {\tt DLPD\$CONFIG}/{\tt ILPD\$CONFIG} must be
Xdefined in the system logical name table as the name of the configuration file
X(see section~\ref{sect:config-vms}).
X
XThe logical name {\tt DLPD\$SCRATCH}/{\tt ILPD\$SCRATCH} must also be defined
Xin the system logical name table as the name of a scratch directory which will
Xbe used for MAIL and for temporary storage (it is actually only used to {\em
Xrename} the files there, since RMS does not support renaming of a file which
Xdoes not reside in a directory). This directory must be writable by both the
Xserver process and through SYSPRV privilege.
X
X\noindent
XThe (high) AST-limit is necessary for notification of job-completion by MAIL.
X
X\medskip
XTo communicate with the process once it is running, commands can be written
X(SYSPRV privilege required) to {\tt DLPD\$CMD}/{\tt ILPD\$CMD}, which is a
XVMS mailbox. The commands currently recognized are:
X
X\noindent
X\begin{tabular}{lp{135mm}}
X\tt CONFIG &
X    Re-read the configuration file {\tt DLPD\$CONFIG}/{\tt ILPD\$CONFIG}
X    This command
X    must be issued to make any changes in the configuration file or the UAF
X    known to the process.
X    \\
X\tt EXIT &
X    Terminate gracefully, cleaning up logical names, subprocesses, etc.
X    \\
X\tt STAT &
X    Display statistics about how many files, jobs, etc. have been received
X    since last displayed and since startup.
X    \\
X\tt CLEAR &
X    Force abort (close) of all open network connections which have
X    timed out long ago. This is a real brute-force method which (in very rare
X    cases) might cause the process to crash with access violation.
X    \\
X\tt ABORT &
X    Raise an (unhandled) exception to get a dump of the process. For
X    debugging only.
X    \\
X\tt VERSION &
X    Show the version number of the currently running process as operator
X    message. Full version information (on a source-file basis) is written
X    to the logfile.
X    \\
X\tt SHOW\_Q &
X    Show the entries in the internal processing queue. Output is written
X    to the logfile.
X    \\
X\tt ACCOUNTING &
X    Write accounting information for this process to the logfile.
X    \\
X\tt DUMP\_USERS &
X    Dump the user-database to the logfile. The format is more for debugging
X    than for day-to-day use, showing hash-table, indices, etc.
X    \\
X\tt DUMP\_QUEUES &
X    Dump the VMS-queue-database to the logfile. The format is more for debugging
X    than for day-to-day use, showing indices into tables, etc.
X    \\
X\end{tabular}
X
X
X\noindent
XProblems are reported to the VMS operator class ``CENTRAL''.
X
X
XThe logical name {\tt DLPD\$MAXCONNS}/{\tt ILPD\$MAXCONNS} can be set to the
Xnumber of simultaneous connections (threads). If not set, the value defaults to
Xeigth.
X
XThe logical name {\tt DLPD\$MAIL\_FORMAT}  gives a string for formatting mail
Xaddresses for sending completion mail to the UNIX hosts. The format is similar
Xto a {\tt printf(3)} formatting string, with {\tt \%u} being replaced by the
Xusername, while {\tt \%h} is substituted by the hostname. The string is passed
Xto a CLI, therefore any `"' have to be byte-stuffed (doubled). If the character
X`{\tt \%}' itself is required in the mail-address, it must be doubled.
X
XExample: \hfill \\
X\verb'$ DEFINE /SYSTEM DLPD$MAIL_FORMAT WINS%%"""""""%u@%h"""""""' \hfill \\
XFor user {\tt berg} at host {\tt sunw17} this
Xresults in a mail-address of {\tt WINS\%"berg@sunw17"}
X
X
XThe logical name {\tt DLPD\$DEBUG}/{\tt ILPD\$DEBUG} can be set to a number
X(decimal or in another radix following C conventions) which is interpreted as a
Xbit-mask and used to control recording of information in different sections of
Xcode. These messages are written to the error output of the process.
X
X\noindent
XCurrently the appropriate bit-masks are:
X{
X\begin{verbatim}
X  #define DBG_JOB_HOLD      0x00000001   /* set /HOLD */
X  #define DBG_JBC_JOB       0x00000002   /* log job create/close/abort */
X  #define DBG_JBC_FILE      0x00000004   /* log add_file() */
X  #define DBG_RCV           0x00000008   /* log receiving of file(s) */
X  #define DBG_GETQUI        0x00000010   /* log $GETQUI ops */
X  #define DBG_DELJOB        0x00000020   /* log job-deletions */
X  #define DBG_NET           0x00000100   /* log network activity */
X  #define DBG_CONN_Q        0x00000200   /* print connection queue */
X  #define DBG_REQUEST       0x00000400   /* log incoming requests */
X  #define DBG_FN            0x00001000   /* log names of ctrl and data files */
X  #define DBG_CF            0x00002000   /* log control file */
X  #define DBG_MAIL          0x00010000   /* log mail */
X  #define DBG_MAILER_OUTPUT 0x00020000   /* log output of mailer process */
X  #define DBG_CONFIG        0x00100000   /* configuration database */
X  #define DBG_VMSQTYPES     0x00200000   /* VMS queue database */
X\end{verbatim}}
X
XThe most useful values are {\tt DBG\_REQUEST} to see what requests come, for
Xwhich queue, from which host (1 message line per entry) and, occasionally, {\tt
XDBG\_JOB\_HOLD} when debugging a configuration file to see what goes in the
Xqueue without actually printing/executing it.
X
X
X\subsection{Additional logical names for ILPD}
X
XThe internet version uses an additional logical name:
X
X\begin{tabular}{lp{120mm}}
X \tt ILPD\$INET\_PORT   & defines the internet port number (default: 515) \\
X\end{tabular}
X
X
X
X\subsection{Gateway-Software for DLPD}
X
XSyntax:
X
X{\tt lpdgw [-d] [-l}{\em\ logfile}{\tt ] [-n}{\em\ node\_name}{\tt ] [}{\em port-number}]
X
X
XThe gateway process on the ULTRIX-machine listens for {\tt lpd}-requests on the
Xinternet port specified on the commandline or in {\tt services}(5) under the
Xname {\tt printer}. When a request comes in, {\tt lpdgw} forks itself to handle
Xthe connection while the parent process continues listening on the internet
Xport.
X
XThe address of the sender is checked to be known (there must be an entry in
X{\tt hosts}(5) for it). If it is ok, the first line of internet data is
Xreceived and parsed. It holds the type of request and the printer for which it
Xis intended. This printer specification may carry a destination (DECnet)
Xhost-name in the form {\em printer@host}, in which case the {\em host} field is
Xextracted and a DECnet connection to this one for the network object {\tt DLPD}
Xis attempted. If no host name is present, the default node specified as
Xcommandline argument (with the {\tt -n} option) is used. If this has not been
Xspecified either, the built-in default {\tt DVAX03} is used.
X
XWhen the DECnet connection has been successully established, this first line of
Xdata is sent on to the DECnet process (with any {\em @host} specification
Xremoved). For the rest of its life, the subprocess performs multiplexing of
Xdata between internet and DECnet using the {\tt select}(2) system call. A
Xtimeout of 3~minutes is imposed on any read/write operation, after which the
Xconnections are closed and the subprocess terminates.
X
X\medskip
X
XThere is one important point when selecting an internet port number. The port
Xfor communication between {\tt lpd}s of the {\em remote} machines and {\tt
Xlpdgw} must be different from the one used by the {\tt lpd} running on the
Xgateway. {\em This implies that printing on VMS from the gateway machine
Xitself is not possible}.
X
X\medskip
X\noindent
XThe gateway process should be started as part of the site-specific boot
Xsequence ({\tt /etc/rc.local}).
X
X
X\section{Configuration}
X
XConfiguration is done mostly at two sites: The UNIX machine(s) from where
Xprinting/batch execution is to be allowed and the VMS machine(s) the queue
Xresides on. It is also possible to specify a few things on the gateway machine,
Xbut this is only in regard to TCP-port addresses and internet/DECnet host
Xnames.
X
X
X
X\subsection{Configuration at the VMS-machine}
X\label{sect:config-vms}
X
XThe configuration-file is accessed via the system-wide logical name {\tt
XDLPD\$CONFIG}/{\tt ILPD\$CONFIG}. It defines
X
X\begin{itemize}
X\item UNIX hosts considered equivalent (for checking root privilege)
X\item mapping from UNIX usernames and -machines to VMS usernames
X\item print/batch permissions for each VMS user
X\item abbreviations for setup strings
X\item abbreviations for parameter strings
X\end{itemize}
X
XA few general comments: All entries in this file are case-sensitive. Everything
Xfrom `\#' to the end of a line is treated as a comment. Lines completely blank
Xare ignored. Lines can be continued by writing `\verb"\"' or {\tt -} as the
Xlast character of the line.
X
X
X
X\subsubsection{Equivalent UNIX hosts}
X
XSyntax:
X
X{\em equivalence\_name} {\em host1} {\em host2}  $\ldots $
X
X\medskip
X{\em equivalence\_name} and {\em host} must be lowercase and up to
X16~characters in length. All hosts named in a single entry are considered
Xequivalent as far as root-privileges (for removing jobs) are concerned.
XEquivalence names also serve as a shorthand for mapping usernames.
XNote that when an equivalence name is the same as a hostname, the equivalence
Xname is matched first when determining access privileges for an incoming
Xrequest. This is {\em not } guaranteed to remain the same in future versions.
X
X
X\subsubsection{Mapping of usernames}
X
XSyntax:
X
X{\em VMS\_USERNAME}[{\tt /B}][{\tt /P}] {\em user1}@{\em host1}[{\tt /B}][{\tt /P}] {\em user2}@{\em host2}[{\tt /B}][{\tt /P}]  $\ldots $
X
X\medskip
X
X{\em VMS\_USERNAME} must be uppercase and up to 12~characters in length. {\em
Xuser} must be lowercase and up to 12~characters in length. {\em host} must be
Xlowercase and up to 16~characters in length. It can also refer to one of the
Xequivalence groups defined above. The VMS-user must be enabled
X(the flag {\tt UIC\$V\_NOACNT} must not be set) and have network access for at
Xleast a single hour per week. It does not seem to make sense to restrict
Xnetwork access to the times allowed in the user's UAF, since this only keeps
Xthe spooling system busy retrying (and thus consuming resources). For allowing
Xbatch access (see below), the user must also have batch access for at least
Xone hour per week.
X
XWhen the special {\em VMS\_USERNAME} {\tt \$NOTIFY} is specified, completion
Xmail on success is sent to the UNIX user given on the right side, provided
Xthere is one for the host from which the job was sent.
X
X\medskip\noindent
XThere are two ``qualifiers'' which specify access rights:
X\begin{itemize}
X \item {\tt /P} --- to allow PRINTing
X \item {\tt /B} --- to allow BATCH execution
X\end{itemize}
X
XThese can be attached to a {\em VMS\_USERNAME} (no intervening white space)
Xwhere they apply to all {\tt user@host} entries in this line, or to the
X{\tt user@host} entry itself, in which case they apply to requests from this
Xhost (or equivalence group).
X
XThe special {\em VMS\_USERNAME} {\tt \$DEFAULT} sets the default permissions
X(from that point on where it is encountered).
XBuilt-in default is PRINT.
X
XNote that when {\tt /B} is specified, the PRINT privilege is reset and
Xmust be enabled separately by {\tt /P}.
X
X\begin{quote}
X{\bf For security reasons, it is recommended not to allow batch execution for
Xprivileged accounts.}  There is a compile-time configuration option to enforce
Xthis (search for the string {\tt MAX\_PRIVS} in the file {\tt CONFIG.C}.)
X\end{quote}
X
XOnly the first character of a qualifier is checked. No errors  are reported
Xwhen another character is seen, to allow use of this configuration file for
Xanother software package (which needs another qualifier).
X
X
X\subsubsection{Abbreviations for setup strings}
X
XSyntax:
X
X{\tt =}{\em abbrev} {\em SETUP\_SPECIFICATION}
X
X
X
X
X\subsubsection{Abbreviations for parameter strings}
X
XSyntax:
X
X{\tt /}{\em abbrev} {\em PARAMETER\_SPECIFICATION}
X
X
X
X\subsubsection{Example}
X
X\begin{verbatim}
X valid_cae      valid1 valid2 valid3 valid4 valid5 valid6 \
X                valid7 valid8 valid9 valida
X sunyp1         suns01 \
X                sunw01 sunw01 sunw03 sunw04 \
X                sunw10 sunw11 sunw12 sunw13 sunw14 sunw15 \
X                sunw16 sunw17 sunw17 sunw18 sunw19 sunw20
X
X =ERR    LPS$ERRORHANDLER
X =MCS    LPS$DECMCSENCODING,LPS$FINDFONT_ISOLATIN1_DECMCS_V40
X
X /P      PAGE_ORIENTATION=PORTRAIT
X /L      PAGE_ORIENTATION=LANDSCAPE
X /SNGH   LAYUP=LPS$SINGLEHOLES
X /LU2    LAYUP=LPS$2UP
X /NU2    NUMBER_UP=2
X /NU4    NUMBER_UP=4
X
X $DEFAULT/P
X APL_BERG/B/P   berg@valid_cae      berg@dunx01/P
X AV_PCMS/B      cv_link@valid_cae
X CIM_WEIGENSA   weigen@valid_cae    root@valid_cae    weigen@sunyp1
X GT_HAHN        hahn@valid_cae
X ZEILER         zeiler@valid_cae    gz@dunx01         root@dunx01
X $NOTIFY        notify@valid_cae
X\end{verbatim}
X
XIn this example, hosts {\tt valid[1-9a]} form the equivalence-group {\tt
Xvalid\_cae}, while {\tt sunyp1} consists of {\tt suns01} and {\tt sunw*}.
XSetup- and parameter definitions allow to use the {\sc PostScript} error
Xhandler, turn pages or scale printed output. For print jobs queued from any of
Xthe hosts in {\tt valid\_cae}, completion mail is sent to the user {\tt notify}
X(probably a mail alias) when the job completes successfully, and the owner of
Xthe job otherwise. Completion mail for jobs queued from a host in {\tt sunyp1}
Xare always sent to the job-owner.
X
XThe default permissions are PRINT, user {\tt APL\_BERG} has PRINT- and BATCH
Xpermission when coming as user {\tt berg} from {\tt valid\_cae}, PRINT
Xpermission only when coming from host {\tt dunx01}.
XUuser {\tt AV\_PCMS} has BATCH permission only. All others have PRINT
Xpermission (set by {\tt \$DEFAULT})..
X
X
X
X\subsection{Configuration at the UNIX-machine}
X
XThe configuration file at the UNIX side is the well-known {\tt
Xprintcap}(5). Printer definitions for printers residing on a VMS-machine
Xmust be set up as ``remote printers''. The two relevant entries are ``remote
Xmachine'' ({\tt rm=}) which must name the {\em gateway} and ``remote
Xprinter'' ({\tt rp=}) which must name the VMS-queue along with a few
Xparameters. The complete syntax for this entry is (no blanks allowed!):
X
X\medskip
X{\tt rp=}{\em VMS\_q}{\tt [|}{\em wildcard\_VMS\_q}%
X{\tt ][=}{\em setup}%
X{\tt ][/}{\em param1}%
X{\tt ]}$\ldots ${\tt [/}{\em param8}%
X{\tt ][@}{\em VMS\_node}{\tt ]}
X
XNote that the name of the VMS-machine is as seen from the {\em
Xgateway}-machine, which might be different due to name length constraints (e.g.
Xcluster {\tt DVAX} is called {\tt D} in Alcatel Austria).
X
X\medskip
X
X{\em VMS\_q} is the full VMS queue name (usually a generic queue) the jobs
Xshould be directed to. If there is no {\em wildcard\_VMS\_q} specified (see
Xbelow) and the queue is a generic one, search for display and deletion is
Xextended to all queues defined as targets of this queue.
X
X
X\medskip
X
X{\em wildcard\_VMS\_q} is an optional VMS queue spec containing wildcard
Xcharacters. This specification (and the full name) is used for display and
Xdeletion of jobs. If present, {\em wildcard\_VMS\_q} must be preceded by~`{\tt
X|}'.
X
X
X
X\medskip
X
X{\em setup} is an optional shorthand code for a setup module specification
Xdefined at the VMS-side in the configuration file. If present, {\em setup} must
Xbe preceded by~`{\tt =}'.
X
X
X
X\medskip
X{\em param} is an optional shorthand code for a parameter specification
Xdefined at the VMS-side in the configuration file. There can be up to eight
Xsuch specifications. If present, either of them must be preceded by~`{\tt /}'.
X
X
X
X\medskip
X{\em VMS\_node} is the optional name of a VMS node to which the gateway process
Xshould direct the request. If present, {\em VMS\_node} must be preceded
Xby~`{\tt @}'.
X
X
XThe spool directories for all printers must be distinct (even if they differ in
Xonly a {\em setup}- or {\em param}-item, since there is no way for {\tt lpd}(8)
Xto distinguish queues other than by the spool-directory the requests reside in.
X
X
X
X\subsubsection{Example}
X
X\begin{verbatim}
X  lps40_ps.1p|             LPS40_PS, portrait, singleholes:\
X        :mx#0:\
X        :lp=:\
X        :rm=dunx01:\
X        :rp=LPS40_PS|LPS40$*=MCS/P/SNGH:\
X        :sd=/usr/spool/lps40_ps.1p.dvax:\
X        :lf=/usr/spool/lps40_ps.1p.dvax/errorlog:
X\end{verbatim}
X
X
XIn this example requests for UNIX printer {\tt lps40\_ps.1p}  are sent via
Xgateway {\tt dunx01} to VMS-queue {\tt LPS40\_PS}. When displaying or deleting
Xjobs, wildcard search spec is {\tt LPS40\$*} which matches all output execution
Xqueues fed from {\tt LPS40\_PS}. Setup-spec is {\tt MCS} (to select DEC
XMCS-encoding), parameters are {\tt P} (for portrait orientation) and {\tt SNGH}
X(for a layup-definition). Since no VMS-node is specified, the gateway process
Xuses its own default.
X
X
X\appendix
X\section{User-Notification at the UNIX side}
X
XWhen the dummy VMS-username {\tt \$NOTIFY} is specified and has a
XUNIX-username for the host from which the print job came, mail is sent on
Xsuccessful completion not to the owner of the job, but to that username. This
Xcan be an alias piping the mail to a script which {\em writes} to the terminal.
XThe original username can be restored from the fourth word of the ``Subject''
Xfield, e.g.
X
X{\tt Subject: Printer/Batch job from \em NN \tt completed successfully}
X
X%\section{}
X\end{document}
END_OF_FILE
if test 30339 -ne `wc -c <'dlpd.tex'`; then
    echo shar: \"'dlpd.tex'\" unpacked with wrong size!
fi
# end of 'dlpd.tex'
fi
if test -f 'build.com' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'build.com'\"
else
echo shar: Extracting \"'build.com'\" \(1343 characters\)
sed "s/^X//" >'build.com' <<'END_OF_FILE'
XCC /noopt /list /debug=all /define=(CRASH_MAILER="""SYSTEM""") LPD.C
XCC /noopt /list /debug=all /define=(CRASH_MAILER="""SYSTEM""") CONFIG.C
XCC /noopt /list /debug=all /define=(CRASH_MAILER="""SYSTEM""") UTIL.C
XCC /noopt /list /debug=all /define=(CRASH_MAILER="""SYSTEM""") CMD.C
XCC /noopt /list /debug=all /define=(CRASH_MAILER="""SYSTEM""") RCVJOB.C
XCC /noopt /list /debug=all /define=(CRASH_MAILER="""SYSTEM""") SHOWJOB.C
XCC /noopt /list /debug=all /define=(CRASH_MAILER="""SYSTEM""") DELJOB.C
XCC /noopt /list /debug=all /define=(CRASH_MAILER="""SYSTEM""") SNDJBC.C
XCC /noopt /list /debug=all /define=(CRASH_MAILER="""SYSTEM""") GETQUI.C
XCC /noopt /list /debug=all /define=(CRASH_MAILER="""SYSTEM""") LLIST.C
XCC /noopt /list /debug=all /define=(CRASH_MAILER="""SYSTEM""") BASELINE.C
XCC /noopt /list /debug=all /define=(CRASH_MAILER="""SYSTEM""") INET.C
Xlink /map=ilpd /full /trace /nodebug /exec=ILPD.EXE lpd.obj, config.obj, util.obj, cmd.obj, rcvjob.obj, showjob.obj, deljob.obj, sndjbc.obj, getqui.obj, llist.obj, baseline.obj, inet.obj, lpd/opt, sys$library:ucx$ipc/lib
XCC /noopt /list /debug=all /define=(CRASH_MAILER="""SYSTEM""") DNET.C
Xlink /map=dlpd /full /trace /nodebug /exec=DLPD.EXE lpd.obj, config.obj, util.obj, cmd.obj, rcvjob.obj, showjob.obj, deljob.obj, sndjbc.obj, getqui.obj, llist.obj, baseline.obj, dnet.obj, lpd/opt
END_OF_FILE
if test 1343 -ne `wc -c <'build.com'`; then
    echo shar: \"'build.com'\" unpacked with wrong size!
fi
# end of 'build.com'
fi
if test -f 'ilpd_start.com' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ilpd_start.com'\"
else
echo shar: Extracting \"'ilpd_start.com'\" \(1089 characters\)
sed "s/^X//" >'ilpd_start.com' <<'END_OF_FILE'
X$ SET NOON
X$ !
X$ ! Start Internet (UCX) LPD Server
X$ !
X$ DEFINE/SYSTEM/EXECUTIVE_MODE/NAME_ATTRIBUTE=NO_ALIAS ILPD$CONFIG  system_data:[decnet.objects]dlpd.config
X$ DEFINE/SYSTEM/EXECUTIVE_MODE/NAME_ATTRIBUTE=NO_ALIAS ILPD$SCRATCH system_data:[decnet.dlpd]
X$ DEFINE/SYSTEM/EXECUTIVE_MODE/NAME_ATTRIBUTE=NO_ALIAS ILPD$MAIL_FORMAT ALCSUN::"""""""%u@%h"""""""
X$ DEFINE/SYSTEM/EXECUTIVE_MODE                         ILPD$INET_PORT   515
X$ DEFINE/SYSTEM/EXECUTIVE_MODE                         ILPD$DEBUG       0x400
X$ check_image = "''F$SEARCH ("system_data:[decnet.objects]ilpd.exe")'"
X$ IF check_image .NES. "" THEN -
X$ RUN -
X  /DETACH -
X  /UIC=[NET_ILPD] -
X  /AST_LIMIT=128 -
X  /NOAUTHORIZE -
X  /BUFFER_LIMIT=32768 -
X  /DUMP -
X  /ENQUEUE_LIMIT=128 -
X  /ERROR=system_data:[decnet.dlpd]ilpd_'F$GETSYI ("NODENAME")'.log -
X  /FILE_LIMIT=128 -
X  /INPUT=NL: -
X  /IO_BUFFERED=32 -
X  /IO_DIRECT=32 -
X  /OUTPUT=NL: -
X  /PAGE_FILE=8192 -
X  /PRIORITY=6 -
X  /PRIVILEGES=(NOSAME,CMKRNL,NETMBX,SYSNAM,SYSPRV,TMPMBX) -
X  /PROCESS_NAME="ILPD Server" -
X  /SUBPROCESS_LIMIT=1 -
X  'check_image'
X$ !
X$ EXIT
X$ !
END_OF_FILE
if test 1089 -ne `wc -c <'ilpd_start.com'`; then
    echo shar: \"'ilpd_start.com'\" unpacked with wrong size!
fi
chmod +x 'ilpd_start.com'
# end of 'ilpd_start.com'
fi
if test -f 'dlpd_start.com' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dlpd_start.com'\"
else
echo shar: Extracting \"'dlpd_start.com'\" \(1001 characters\)
sed "s/^X//" >'dlpd_start.com' <<'END_OF_FILE'
X$ SET NOON
X$ !
X$ ! Start DECnet LPD Server
X$ !
X$ DEFINE/SYSTEM/EXECUTIVE_MODE/NAME_ATTRIBUTE=NO_ALIAS DLPD$CONFIG  system_data:[decnet.objects]dlpd.config
X$ DEFINE/SYSTEM/EXECUTIVE_MODE/NAME_ATTRIBUTE=NO_ALIAS DLPD$SCRATCH system_data:[decnet.dlpd]
X$ DEFINE/SYSTEM/EXECUTIVE_MODE/NAME_ATTRIBUTE=NO_ALIAS DLPD$MAIL_FORMAT ALCSUN::"""""""%u@%h"""""""
X$ DEFINE/SYSTEM/EXECUTIVE_MODE                         DLPD$DEBUG   0x400
X$ check_image = "''F$SEARCH ("system_data:[decnet.objects]dlpd.exe")'"
X$ IF check_image .NES. "" THEN -
X$ RUN -
X  /DETACH -
X  /UIC=[NET_DLPD] -
X  /AST_LIMIT=128 -
X  /NOAUTHORIZE -
X  /BUFFER_LIMIT=32768 -
X  /DUMP -
X  /ENQUEUE_LIMIT=128 -
X  /ERROR=system_data:[decnet.dlpd]dlpd_'F$GETSYI ("NODENAME")'.log -
X  /FILE_LIMIT=128 -
X  /INPUT=NL: -
X  /IO_BUFFERED=32 -
X  /IO_DIRECT=32 -
X  /OUTPUT=NL: -
X  /PAGE_FILE=8192 -
X  /PRIORITY=6 -
X  /PRIVILEGES=(NOSAME,CMKRNL,NETMBX,SYSNAM,SYSPRV,TMPMBX) -
X  /PROCESS_NAME="DLPD Server" -
X  /SUBPROCESS_LIMIT=1 -
X  'check_image'
X  !
X$ EXIT
X$ !
END_OF_FILE
if test 1001 -ne `wc -c <'dlpd_start.com'`; then
    echo shar: \"'dlpd_start.com'\" unpacked with wrong size!
fi
chmod +x 'dlpd_start.com'
# end of 'dlpd_start.com'
fi
if test -f 'dlpd.config' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dlpd.config'\"
else
echo shar: Extracting \"'dlpd.config'\" \(2306 characters\)
sed "s/^X//" >'dlpd.config' <<'END_OF_FILE'
X#
X# This file maps UNIX hosts and usernames to VMS usernames
X# for the submission of print-jobs ("Proxy access").
X#
X# It also specifies abbreviations for setup- and parameter-strings
X# which can then be used to configure printers at the UNIX side
X# via /etc/printcap.
X#
X# Dietmar Berg / Alcatel Austria,  89-02-21
X#
X
X# Definitions of printer setup-strings
X#
X# Syntax:
X#   =abbrev  SETUP_SPECIFICATION
X#
X# The abbreviation must be preceded by '=' and
X# less than 8 characters in length.
X
X=ERR	LPS$ERRORHANDLER
X=MCS 	LPS$DECMCSENCODING,LPS$FINDFONT_ISOLATIN1_DECMCS_V40
X=MCSERR	LPS$ERRORHANDLER,LPS$DECMCSENCODING,LPS$FINDFONT_ISOLATIN1_DECMCS_V40
X=L3	L
X=P3	P
X
X# Definition of printer parameter strings.
X#
X# Syntax:
X#   /abbrev  PARAMETER_SPECIFICATION
X#
X# The abbreviation must be preceded by '/' and
X# less than 8 characters in length.
X
X/P	PAGE_ORIENTATION=PORTRAIT
X/L	PAGE_ORIENTATION=LANDSCAPE
X/SNGH	LAYUP=LPS$SINGLEHOLES
X/LU2	LAYUP=LPS$2UP
X/NU2	NUMBER_UP=2
X/NU4	NUMBER_UP=4
X/A3	SHEET_SIZE=A3
X/PS	DATA_TYPE=POSTSCRIPT
X/ANSI   DATA_TYPE=ANSI
X
X
X# Definition of equivalent UNIX-machines.
X#
X# Syntax:
X#   equivalence_name   host1  host2  host3 ...
X#
X# All machine names *MUST* be lowercase and
X# at most 16 chars in length.
X#
X# This definition is done mainly for checking root-privilege,
X# but also to save typing work for specifying usernames.
X
Xvalid_cae	valid1 valid2\
Xvalid3 valid4 valid5 \
X		valid6 valid7 valid8 valid9 valida \
X		validd \
X		redac1 redac2
Xsunyp1          suns01 \
X		sunw01 sunw02 sunw03 sunw04 \
X		sunw10 sunw11 sunw12 sunw13 sunw14 sunw15 \
X		sunw16 sunw17 sunw18 sunw19 sunw20
X
X
X# Definition of usernames.
X#
X# Syntax:
X#    VMS_USERNAME  	user1@host1  user2@host2 ...
X#
X# The VMS usernames *MUST* be uppercase, everything else must
X# be lowercase. <host> may also be one of the <equivalence_names>
X# defined above. All names must be at most 12 chars in length.
X
X#ADS_SCHWENDE    schwen@valid_cae
XADS_TOMSU       tomsu@valid_cae		tomsu@sunyp1
XX100_BERG/B/P	berg@valid_cae		berg@dunx01	berg@sunyp1
XCIM_BERG	dberg@valid_cae		dberg@dunx01	dberg@sunyp1
XCIM_DZIEDZIO    dzie@valid_cae		dzie@sunyp1
XX100_SEILER	seiler@valid_cae	seiler@sunyp1
XX100_SOMMERB	sommerba@sunyp1
XZEILER          zeiler@valid_cae    	gz@dunx01  	\
Xroot@dunx01
X$NOTIFY         notify@valid_cae	notify@suns01
X#END_CONFIG
END_OF_FILE
if test 2306 -ne `wc -c <'dlpd.config'`; then
    echo shar: \"'dlpd.config'\" unpacked with wrong size!
fi
chmod +x 'dlpd.config'
# end of 'dlpd.config'
fi
echo shar: End of archive 4 \(of 6\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 6 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
