[comp.protocols.appletalk] New step-by-step CAP60 install guide for SunOS + ASCII to PostScript filterNew step-by-step CAP60 install guide for SunOS + ASCII to PostScript converter

dank@jpl.nasa.gov (Dan Kegel) (04/23/91)

I wanted to install CAP such that (a) it could be trivially uninstalled,
(b) could be trivially mounted from an NFS fileserver, and (c) allows you
to print ASCII files to LocalTalk Laserwriters without having a copy of TranScript.
(a) and (b) require that CAP live as much as possible in a single directory, and
that this directory be mountable read-only. 
The following procedure satisfies these desires, and provides a simple program
to convert ASCII to PostScript.

Procedure to install CAP/UAB into /usr/local/cap on a Sun4 running SunOS 4.1.1
such that ALL read-only files live in /usr/local/cap, and all read-write files
live in /etc/cap.  This makes for easy deinstallation and copying to new 
systems.
In the following, #% indicates the shell prompt for super-user, 
% indicates the shell prompt for user cap, and ~ indicates /usr/local/cap.

INSTALLATION
0) Become superuser, create area for cap to save data in, add user 
   'cap' to /etc/passwd with home directory /usr/local/cap, and give
   the account a password.
   No program will execute as user cap; if you don't want to add this
   pseudouser, you can install the files with owner bin.
   /usr/local can be mounted read-only after installation is complete.
   $ su
   #% /usr/etc/install/add_user cap 59999 10 "Columbia Appletalk Package" \
     /usr/local/cap /bin/csh
   #% passwd cap

1) Become user cap, and Create subdirectories in ~cap:
   #% su cap
   #% mkdir /etc/cap
   #% chown cap /etc/cap			# for convenience later in setup
   % cd ~
   % mkdir bin include lib
   % ln -s /etc/cap etc

2) Grab and unpack tarfile:
   % cd /usr/local/cap
   % ftp munnari.oz.au
   FTP> binary
   FTP> cd mac
   FTP> get cap60.tar.Z
   FTP> quit
   % zcat cap60.tar.Z | tar xvf -		# creates subdirectory cap60.

3) CAP's Makefiles aren't smart enough to deal with include files or libraries
   in nonstandard places yet, so build a wrapper around the C compiler like so:
   Create cc in ~cap/bin, and add ~cap/bin to the path:
    % cat > ~/bin/cc
    #!/bin/csh -f
    /usr/ucb/cc -I/usr/local/cap/include -L/usr/local/cap/lib $*
    ^D
    % chmod +x ~/bin/cc
    % set path = (~/bin $path)

4) Let cap autoconfigure itself.  Answer 'yes' to the question about
   using UAB, and about slowing down output for Kinetics boxes, but
   otherwise just use the default answers:
    % cd ~/cap60
    % ./Configure

5) Edit m4.setup to restict all CAP files to live in /usr/local/cap.
   (Note that the 'debug' flag in m4.setup provides almost this
   functionality, but the etc, bin, and lib directories are mixed
   in with the source directories.  This way keeps them separate.)

    % cd ~/cap60
    % vi m4.setup

	line	old			new
	90	/usr/include		/usr/local/cap/include
	94	/etc			/usr/local/cap/etc
	97,99	/usr/local/cap		/usr/local/cap/bin
	101	/usr/local/lib/cap	/usr/local/cap/lib
	103	/usr/local/lib		/usr/local/cap/lib
	158	/etc/cap.auth		/usr/local/cap/etc/cap.auth

	Uncomment line 215 to define capprinters.

6) Create all the makefiles according to the new configuration files:
    % cd ~/cap60
    % ./gen.makes

7) Steps 5 and 6 should have been enough, but there are hardcoded paths
   in several source files.  Fix these by patching makefiles:

7a) Patch ~/cap60/support/uab/makefile to keep its database in 
   /usr/local/cap/etc instead of /etc by changing the line
	CFLAGS=-DDEBUG  -O
   to read
	CFLAGS=-DDEBUG  -O -DMTAB=\"/usr/local/cap/etc/etalk.local\"
   near the top.

7b) Patch ~/cap60/lib/cap/makefile to keep its database in 
   /usr/local/cap/etc instead of /etc by changing the line
	CFLAGS= -O
   to read
	CFLAGS= -O -DETAB=\"/usr/local/cap/etc/etalk.local\"
   near the top.

8) Patch cap60/man/makefile to install man pages for SunOS by adding following
   lines after the rule for 'all:'.  Be careful to start each line after
   'install' with a tab, and not with spaces, or Make will choke.
   % cd ~/cap60/man
   % vi makefile			# and add following lines:

 # Added 4/91 by Dan Kegel (dank@blacks.jpl.nasa.gov)
 # to install man pages into a private area suitable for
 # use with man, catman, and apropos via the MANPATH environment variable.
 DESTDIR = /usr/local/cap/man
 install:
	mkdir $(DESTDIR)
	mkdir $(DESTDIR)/man1 $(DESTDIR)/man3 $(DESTDIR)/man5 $(DESTDIR)/man8 
	mkdir $(DESTDIR)/cat1 $(DESTDIR)/cat3 $(DESTDIR)/cat5 $(DESTDIR)/cat8
	cp *.1 $(DESTDIR)/man1
	cp *.3 $(DESTDIR)/man3
	cp *.5 $(DESTDIR)/man5
	cp *.8 $(DESTDIR)/man8
	ln -s papif.8 $(DESTDIR)/man8/papof.8
	ln -s atprint.1 $(DESTDIR)/man1/tlw.1
	ln -s atprint.1 $(DESTDIR)/man1/lwpr.1
	cp    atprint.1 $(DESTDIR)/man8/isrv.8
	ln -s atprint.1 $(DESTDIR)/man1/iwpr.1
	ln -s CAP.3 $(DESTDIR)/man3/libcap.3
	ln -s CAP.3 $(DESTDIR)/man3/libafpc.3
	ln -s CAP.3 $(DESTDIR)/man3/libafp.3
	ln -s cvt2apple.1 $(DESTDIR)/man1/cvt2cap.1
	ln -s atlook.1 $(DESTDIR)/man1/atpinger.1
	ln -s atlook.1 $(DESTDIR)/man1/atlooklws.1
	/usr/etc/catman -M $(DESTDIR)
	sort -u $(DESTDIR)/whatis > /tmp/whatis
	mv /tmp/whatis $(DESTDIR)
	# Now add $(DESTDIR) to your MANPATH environment variable.
# Caution: above lines start with TAB, not blanks

8) Install cap's man pages (ignore errors from opendir):
    % cd ~/cap60/man
    % make install

9) Install cap's include files:
    % cd ~
    % mkdir include/netat
    % cp cap60/netat/*.h include/netat

10) Compile the programs and install them in ~/bin:
    % cd ~/cap60
    % make install

11) Create script that lets users access CAP if needed:
    % cat > ~/bin/setup_env
    # C-shell users add the line 'source /usr/local/cap/bin/setup_env'
    # to their .cshrc to use CAP programs, manpages, or libraries directly.
    set path = (/usr/local/cap/bin $path)
    setenv MANPATH ${MANPATH}:/usr/local/cap/man
    ^D

12) Create ~/etc/bridge_desc.
    Replace 'blacks' in the following examples with your hostname.
    For Sun4/470's and all others using the Intel ethernet chip (ie0):
    % cat > ~/etc/bridge_desc
    blacks  [elap,ie:0]     mkip    [0]
    blacks  [async,as:0]    none    [127.127,fakeZone]
    ^D

    For Sparcstation 2's and all others using the AMD Lance ethernet chip (le0):
    % cat > ~/etc/bridge_desc
    blacks  [elap,le:0]     mkip    [0]
    blacks  [async,as:0]    none    [127.127,fakeZone]
    ^D

13) Create read-write and read-only folders available to all Mac users.
    % mkdir ~/macpub ~/macpub/.finderinfo ~/macpub/.resource
    % chmod -R 755 ~/macpub
    % mkdir /usr/tmp/mactmp 
    % mkdir /usr/tmp/mactmp/.finderinfo /usr/tmp/mactmp/.resource
    % chmod -R 777 /usr/tmp/mactmp

    You might want to create a crontab entry for root that deletes 
    and recreates /usr/tmp/mactmp at midnight, to keep old files from choking
    your system.

14) Create a file describing the public folders.  Replace 'blacks' with 
    your hostname:
    % cat > ~/etc/afpvols
	/usr/local/cap/macpub:macpub
	/usr/tmp/mactmp:mactmp
	^D

15) Create a shell script to start CAP, and invoke it in /etc/rc.local:

    % su
    #% cat > /etc/cap/rc.cap
	#!/bin/sh
	### sample start servers file; start from '/etc/rc.local'
	LOGd=/usr/tmp
	LOGf=/dev/null
	CAP=/usr/local/cap/bin
	ETC=/usr/local/cap/etc
	LIB=/usr/local/cap/lib
	#LWARGS="-a ${LIB}/procsets -f ${LIB}/LW+Fonts"
	#
	# Start UAB first.
	# Assumes you've created /usr/local/cap/etc/bridge_desc.
	# If you run into problems, try adding the option -l /dev/console
	# to display log messages to the console.
	${CAP}/uab -f ${ETC}/bridge_desc
	sleep 10
	#
	# allow atis to startup before other CAP programs
	${CAP}/atis
	sleep 5
	#
	${CAP}/snitch -S -f "SUN 4 SunOS 4.1.1 UNIX" -l lwsrv
	# Start up fileserver. Assumes you've created /usr/local/cap/etc/afpvols
	${CAP}/aufs -U 20 -V ${ETC}/afpvols -l ${LOGf} -n `hostname`
	# Start up print server.
	# Assumes there's a printer called lw.`hostname` in /etc/printcap.
	#${CAP}/lwsrv -n "Laserwriter on "`hostname` -p lw.`hostname` ${LWARGS}
	^D
    #% chmod +x /etc/cap/rc.cap
    #% vi /etc/rc.local		# Add the following lines at the bottom:
	#
	# Start up Appletalk fileserver & print server.
	#
	if [ -f /etc/cap/rc.cap ]; then
	    /etc/cap/rc.cap; echo "Appletalk fileserver"
	fi
    ^D

16) Bring up CAP by rebooting or by executing /etc/cap/rc.cap by hand as root.
    #% /etc/cap/rc.cap

17) Test the installation by seeing if your fileserver is visible, and by
    logging in to it with ash (replace blacks with your hostname):
    % source ~cap/bin/setup_env
    % man atlook
    % man ash
    % atlook
    % ash "blacks:AFPServer@*"

PRINTER INSTALLATION
1)  In order to be able to print ASCII files rather than just PostScript files:

    a) Find an ASCII-to-Postscript filter.
       If your computer has Adobe TranScript, use /usr/local/lib/ps/pstext.
       If your computer doesn't have Adobe TranScript, you'll have to get
       a filter.  The source code for a simple one, ascii2ps, is given
       at the end of this document.  Compile and install it as follows:
	% cd ~cap
	% cc ascii2ps.c -o bin/ascii2ps

       A fancier one called 'text2ps' is available via ftp from 
       wuarchive.wustl.edu in usenet/comp.binaries.ibm.pc/volume01/text2ps
       as file text2ps.uue.Z.  You'll need to 'uncompress', 'uudecode', and 'arc'
       this file, then compile it and install it in ~cap/bin as above.
       I haven't tried it, but it looks very flexible.

    b) Modify papif to know about the program that converts ASCII to PostScript.
	% cd ~cap/cap60/applications/papif
	% vi makefile
	    Uncomment line 31:
		WPSTEXT="-DPSTEXT=\"/usr/local/lib/ps/pstext\"
	    If you are not using Adobe TranScript, replace the reference to
	    /usr/local/lib/ps/pstext with a path to your ASCII-to-Postscript 
	    filter, e.g.
		WPSTEXT="-DPSTEXT=\"/usr/local/cap/bin/ascii2ps\"
	% rm -f papif.o papif
	% make install

2) Arrange for your Unix system to be able to talk to a Laserwriter
    on your Localtalk network.  These instructions assume your computer
    uses a BSD-style lpr print spooler.

    a) Run 'atlook' to determine the LocalTalk name of the printer in question:
        % atlook | grep LaserWriter
	 19 - AIR Laser :LaserWriter@*        [Net: 22.136 Node:252 Skt:202]
       Choose an abbreviation of this name for use under Unix, e.g. "airlaser".
       The abbreviation should be short, and contain no punctuation or spaces.

    b) Become root and use vi to create an entry in /etc/printcap for the 
       printer.  This tells Unix how to access the printer.
       (Note: replace "airlaser" everywhere it occurs in the following examples
       with the abbreviated name chosen above.)
	#% vi /etc/printcap
	    # LocalTalk laserwriter.
	    # See ~cap/etc/cap.printers for LocalTalk name of this printer.
	    airlaser:\
		:lp=/var/spool/airlaser/fakedev:\
		:sd=/var/spool/airlaser:\
		:pl#72:pw#85:\
		:sf:\
		:lf=/var/adm/airlaser-lpd-errs:\
		:af=/var/adm/airlaser-lpd.acct:\
		:if=/usr/local/cap/bin/airlaser:\
		:of=/usr/local/cap/bin/papof:

    c) Create the spool directory, fake printer device, and log file
       mentioned in the above printcap entry:
	#% cd /var/spool
	#% mkdir airlaser; touch airlaser/fakedev; chmod 666 airlaser/fakedev
	#% chown -R daemon airlaser
	#% touch /var/adm/airlaser-lpd-errs
    
    d) The input filter mentioned in the above printcap entry should
       actually be a shell script that sets up a few environment variables and
       invokes the printer interface program ~cap/bin/papif.
       The shell script name should be the same as the abbreviated printer name
       (this is how the shell script knows which printer it is talking to).
	% cd ~cap/bin
	% cat > airlaser
	    #!/bin/csh -f
	    # Printer input filter for use with CAP.
	    # Invoked by lpd as a result of a if=pathname entry in /etc/printcap.
	    # Tell papif which printer to look up in ~cap/etc/cap.printers.
	    set arg0 = $0; setenv PRINTER $arg0:t
	    # Run papif to copy stdin to printer.
	    /usr/local/cap/bin/papif
	    ^D

    e) Create an entry in /usr/local/cap/etc/cap.printers so papif can look
       up the Appletalk name of your printer.
       The entry consists of the abbreviated name, an equals sign, and the
       full LocalTalk name, exactly as shown by atlook, with no extra spaces:
        % cat > ~cap/etc/cap.printers
	    airlaser=AIR Laser :LaserWriter@*
	    ^D

    You should now be able to print Postscript and ASCII files to your printer.

DEINSTALLATION

Delete any Localtalk LaserWriters you added in /etc/printcap and /var/spool.
Delete lines invoking /etc/cap/rc.cap from /etc/rc.local.
Delete /usr/tmp/mactmp.
Delete /etc/cap.
Delete or umount /usr/local/cap.
Delete user cap from /etc/passwd.

- Dan Kegel (dank@blacks.jpl.nasa.gov)

SOURCE FOR ASCII2PS
/*--------------------------------------------------------------------------
 Program to convert ASCII to PostScript.
--------------------------------------------------------------------------*/

#include <stdio.h>
#include <string.h>

#define IBUFLEN 1024

#define LINES 66
#define COLS 80

main()
{
    int page;
    int line;
    int ibuffull = 0;	/* kludge to handle ^L and long lines */
    char ibuf[IBUFLEN];

    /* Document header */
    fputs("\
%!PS-Adobe-1.0\n\
%%Creator: ascii2ps\n\
%%DocumentFonts: Courier\n\
/ld -11.4 def\n\
/E{ count { gsave show grestore } repeat 0 ld rmoveto } def\n\
/Courier findfont 11 scalefont setfont\n\
%%EndProlog\n\
", stdout);

    for (page=1; !feof(stdin); page++) {

	/* Page header */
	printf("%%%%Page: %d %d\n", page, page);
	printf("/sv save def 48 760 moveto\n");

	for (line=1; line<=LINES && !feof(stdin); line++) {
	    char obuf[IBUFLEN*2];
	    char *p, *q;
	    int c;
	    int col;

	    if (!ibuffull) {
		int len;
		if (fgets(ibuf, IBUFLEN, stdin) == NULL)
		    break;

		/* Strip trailing newline, if any */
		len = strlen(ibuf);
		if (ibuf[len-1] == '\n')
		    ibuf[len-1] = 0;
	    }

	    /* Expand tabs, escape backslashes and parens */
	    col = 0;
	    ibuffull = 0;	/* unless otherwise noted, eat all of ibuf */
	    for (p = ibuf, q=obuf; (c = *p++) != 0; ) {
		if (c == '(' || c == ')' || c == '\\')
		    *q++ = '\\';
		if (c == '\t') {
		    do {
			*q++ = ' ';
			col++;
		    } while (col % 8);
		} else if (c == '\014') {
		    /* Form feed- stop reading input line, go to next page */
		    line = LINES+1;
		    col = COLS+1;
		} else {
		    *q++ = c;
		    col++;
		}
		/* Wrap long lines onto next line.  Assumes last tabstop
		 * is at COLS+1.
		 */
		if (col >= COLS) {
		    bcopy(p, ibuf, strlen(p)+1);
		    ibuffull = 1;
		    break;
		}
	    }
	    *q = 0;

	    /* Encapsulate and print */
	    printf("(%s)E\n", obuf);
	}

	/* Page trailer */
	printf("showpage sv restore\n");
    }

    /* Document trailer */
    printf("%%Trailer\n");

    exit(0);
}