[comp.sources.mac] macps & prepfix - print Macintosh files from Unix

edmoy@violet.Berkeley.EDU (Edward Moy) (05/14/89)

[macps & prepfix - print Macintosh files from Unix]

Macps is a Unix program that takes an uploaded PostScript file created
on a Macintosh (by typing Command-F at the LaserWriter dialog box) and
includes an appropriately modified LaserPrep file so that the result
can be sent to a PostScript printer from Unix.  Since the Apple
LaserPrep files are copyrighted, I've included a program, prepfix, that
reads version 4.0 and up LaserPrep files, and edits them so that they
are compatible with Unix, and are even electronically mailable.

CHANGES IN VERSION 2.1

Version 2.1 of prepfix uses a safer method for turning on bit-smoothing
for non-Apple printers.  This should get around some of the problems
people have been having with specialized macros in the LaserPreps that
are Apple printer specific.  The -l and -p options in version 1.1 have
been replaced with the single -l option, and the limit on the number
of printers you can specify has been removed.

Also, prepfix removes some other various macros that cause
unpredictable problems, and a problem with Apple LaserWriter II/NTs
(but not other Apple printers).

Version 2.1 macps has several new options.  The -c option allow you to
specify the number of copies to generate (overriding any multiple copy
option that was specified on the Macintosh).  The -d option allows an
alternate directory to look for the macps.config file.  Finally, the -r
(raw) option suppresses the conversion of 8-bit binary into ASCII, and
is useful for some graphics programs that manipulate gray-scale images,
and produce 8-bit binary PostScript output.

Macps will even work with a NeXT laser printer, but (at least the 0.8
version of the operating system) will not do bit smoothing.  Beware,
though, that if you print Macintosh patterns at 400 dpi, they will
look funny.

Edward Moy				Principal Programmer - Macintosh & Unix
Workstation Support Services		Workstation Software Support Group
University of California
Berkeley, CA  94720

edmoy@violet.Berkeley.EDU
ucbvax!violet!edmoy

---
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#
#	ReadMe
#	Installation
#	Makefile
#	macaux.c
#	macps.c
#	prepfix.c
#	str.h
#	ucbwhich.c
#	ucbwhich.h
#	macps.config
#	macps.1
#	prepfix.1
#
# This archive created: Sat May 13 08:25:46 1989
# By:	Roger L. Long (bytebug@dhw68k.cts.com)
export PATH; PATH=/bin:$PATH
echo shar: extracting "'ReadMe'" '(4367 characters)'
if test -f 'ReadMe'
then
	echo shar: will not over-write existing file "'ReadMe'"
else
sed 's/^X//' << \SHAR_EOF > 'ReadMe'
XCOPYRIGHT NOTICE (SCCSid = "@(#)ReadMe	2.1 3/29/89")
X
XCopyright (c) 1988, The Regents of the University of California.
XEdward Moy, Workstation Software Support Group, Workstation Support
XSerices, Information Systems and Technology.
X
XPermission is granted to any individual or institution to use, copy, or
Xredistribute this software so long as it is not sold for profit,
Xprovided that this notice and the original copyright notices are
Xretained.  The University of California makes no representations about
Xthe suitability of this software for any purpose.  It is provided "as
Xis" without express or implied warranty.
X
XWHAT IS MACPS?
X
XMacps is a Unix program that takes an uploaded PostScript file created
Xon a Macintosh (by typing Command-F at the LaserWriter dialog box; see
Xmacps.1 for more details) and includes an appropriately modified
XLaserPrep file so that the result can be sent to a PostScript printer
Xfrom Unix.  The LaserPrep file contains macros used by the PostScript
Xgenerator on the Macintosh.
X
XWHY IS MACPS NEEDED?
X
XThis is how Mac printing works.  When a Mac talks to a LaserWriter, it
Xasks if the LaserWriter has had a LaserPrep file downloaded to it.  A
XLaserWriter that is first powered up, has no such LaserPrep file, and
Xso the Mac downloads it and makes the LaserPrep file resident in
Xmemory.  Then the actual print file is sent to the LaserWriter.
XSubsequent print requests need not download the LaserPrep file, unless
Xit is a different version.
X
XSince a LaserWriter connected to a Unix system usually does things
Xother than Mac printing, it is unwise to make LaserPrep files resident
Xin memory so that other PostScript jobs have less memory to work with.
XWhat prepfix does is to modify a LaserPrep file so that, among other
Xthings, it does not make itself resident in memory.  Thus, the
XLaserPrep file must be downloaded for each Mac print job.  This is the
Xfunction of macps, to automatically append the appropriate LaserPrep
Xfile.
X
XWHICH VERSION OF THE LASERPREP WILL BE USED?
X
XMacps interprets the %%IncludeProcSet directive found in the PostScript
Xgenerated by LaserWriter driver 4.0 and greater.  It takes the ProcSet
Xid and looks it up in a file "macps.config", to get the pathname of the
Xprep file, and thus macps can convert PostScript generated by different
Xversions of the LaserWriter driver.
X
XHOW ARE THE LASERPREP FILES GENERATED?
X
XSince the Apple LaserPrep files are copyrighted, I've included a
Xprogram, prepfix, that reads version 4.0 and up LaserPrep files, and
Xedits them so that they are compatible with Unix, and are even
Xelectronically mailable (See prepfix.1 for more details).
X
XWHERE IS THE MACPS.CONFIG FILE LOCATED?
X
XMacps has some special code that is able to figure out from which
Xdirectory it was called from.  It will then look in a "lib" subdiretory
Xfor the macps.config file.
X
XWHAT ABOUT BIT-SMOOTHING ON NON-LASERWRITER PRINTERS?
X
XFor PostScript printers using Motorola 680x0 processors and Adobe
XPostScript firmware other than LaserWriters, there is an option that
Xwill allow these printers to do bit-smoothing, just like LaserWriters.
X
XCHANGES IN VERSION 2.1
X
XVersion 2.1 of prepfix uses a safer method for turning on bit-smoothing
Xfor non-Apple printers.  This should get around some of the problems
Xpeople have been having with specialized macros in the LaserPreps that
Xare Apple printer specific.  The -l and -p options in version 1.1 have
Xbeen replaced with the single -l option, and the limit on the number
Xof printers you can specify has been removed.
X
XAlso, prepfix removes some other various macros that cause
Xunpredictable problems, and a problem with Apple LaserWriter II/NTs
X(but not other Apple printers).
X
XVersion 2.1 macps has several new options.  The -c option allow you to
Xspecify the number of copies to generate (overriding any multiple copy
Xoption that was specified on the Macintosh).  The -d option allows an
Xalternate directory to look for the macps.config file.  Finally, the -r
X(raw) option suppresses the conversion of 8-bit binary into ASCII, and
Xis useful for some graphics programs that manipulate gray-scale images,
Xand produce 8-bit binary PostScript output.
X
XMacps will even work with a NeXT laser printer, but (at least the 0.8
Xversion of the operating system) will not do bit smoothing.  Beware,
Xthough, that if you print Macintosh patterns at 400 dpi, they will
Xlook funny.
SHAR_EOF
if test 4367 -ne "`wc -c < 'ReadMe'`"
then
	echo shar: error transmitting "'ReadMe'" '(should have been 4367 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'Installation'" '(3000 characters)'
if test -f 'Installation'
then
	echo shar: will not over-write existing file "'Installation'"
else
sed 's/^X//' << \SHAR_EOF > 'Installation'
XInstallation Instructions (SCCSid = "@(#)Installation	2.1 3/29/89")
X
X1) Look at the Makefile.  There are two CFLAGS options that you can
Xuse.  Setting SYSV should allow macps and prepfix to compile on System
XV machines (I've only tried it under A/UX).  Setting CONFIGDIR will
Xcause macps to look for macps.config in that directory.  The options
Xwill look something like:
X
XCFLAGS = -O -DSYSV -DCONFIGDIR=\"/usr/new/lib\"
X
X2) Type "make".  If all goes well, macps and prepfix will be created.
X
X3) To create the unprocessed LaserPrep file on the Mac, as well as
Xcreating the raw PostScript files that you want to print, make sure
Xthat either you're not running MultiFinder, or if you are, go to the
XChooser under the Apple menu, click on the LaserWriter icon and then
Xturn off Background Printing.
X
X4) For each version of LaserPrep on the Mac that you want to include,
Xinstall that version in the System Folder.  Then, open an empty
Xdocument in some simple application (one that doesn't have its
Xown ProcSet to download).  Choose Print from the File menu and the
XLaserWriter print dialog will appear.  Click on the OK button and
XIMMEDIATELY press and hold Command-K.  When a dialog box appears
Xtelling you that it is creating a PostScript file, you can release
XCommand-K.  The unprocessed LaserPrep file will usually be found in one
Xof three places, in the System Folder, in the same folder as the
Xapplication or at the top level of the disk.
X
X5) Upload the PostScript file(s) to Unix, using some file transfer
Xprogram like MacTerminal, Versaterm, Red Ryder, MacKermit or NCSA
XTelnet (if your file transfer program feels left out, feel free to add
Xit to your list).
X
X6) Run prepfix on each unprocessed file, diverting the standard output
Xto an appropriataly named file (like LaserPrep5.2).  If you want to
Xallow bit smoothing on a non-Apple PostScript printer, specify the -l
Xoption to prepfix (you can specify as many printer names as you want,
Xeach with a separate -l flag).  If you aren't sure the your printer can
Xdo smoothing, you can try it and see if it works (if it doesn't, you
Xcan always re-run prepfix on the unprocessed file(s), leaving off the
Xprinter that doesn't work).  If you don't know the product name for you
Xprinter, you can use the following PostScript code to print it:
X
X%!
X/in {72 mul} def
X/Courier findfont 18 scalefont setfont
X1 in 8 in moveto
Xstatusdict /product get show
Xshowpage
X
X7) Put the modified LaserPrep file(s) in some directory and modify the
Xmacps.config file to point to these LaserPrep files.  Then put the
Xmacps.config file in a "lib" subdirectory to where you install macps
X(or in the directory CONFIGDIR if you used that option).
X
X8) Now when you want to print something, do the same thing as in step 4
Xabove with the LaserWriter print dialog, except press and hold
XCommand-F (this cause LaserPrep not to be included in the PostScript
Xfile).
X
X9) Upload the PostScript file and run macps on it, sending the output
Xto your printer, as in:
X
X	% macps psfile | lpr
SHAR_EOF
if test 3000 -ne "`wc -c < 'Installation'`"
then
	echo shar: error transmitting "'Installation'" '(should have been 3000 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'Makefile'" '(1056 characters)'
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile'
X# Copyright (c) 1988, The Regents of the University of California.
X# Edward Moy, Workstation Software Support Group, Workstation Support Serices,
X# Information Systems and Technology.
X#
X# Permission is granted to any individual or institution to use, copy,
X# or redistribute this software so long as it is not sold for profit,
X# provided that this notice and the original copyright notices are
X# retained.  The University of California makes no representations about the
X# suitability of this software for any purpose.  It is provided "as is"
X# without express or implied warranty.
X#
X# SCCSid = "@(#)Makefile	2.1 3/29/89"
X#
X# For System V, include -DSYSV in CFLAGS below.
X# To specify a fixed path for macps.config, include -DCONFIGDIR=\"path\"
X# in CFLAGS below (path is the full pathname of the directory).
X#
XCFLAGS = -O
XMACPS = macps.o macaux.o ucbwhich.o
XPREPFIX = prepfix.o macaux.o
X
Xall : macps prepfix
X
Xmacps : $(MACPS)
X	cc -o macps $(CFLAGS) $(MACPS)
X
Xprepfix : $(PREPFIX)
X	cc -o prepfix $(CFLAGS) $(PREPFIX)
X
Xclean :
X	/bin/rm -f *.o macps prepfix
SHAR_EOF
if test 1056 -ne "`wc -c < 'Makefile'`"
then
	echo shar: error transmitting "'Makefile'" '(should have been 1056 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'macaux.c'" '(3584 characters)'
if test -f 'macaux.c'
then
	echo shar: will not over-write existing file "'macaux.c'"
else
sed 's/^X//' << \SHAR_EOF > 'macaux.c'
X/*
X * Copyright (c) 1988, The Regents of the University of California.
X * Edward Moy, Workstation Software Support Group, Workstation Support Serices,
X * Information Systems and Technology.
X *
X * Permission is granted to any individual or institution to use, copy,
X * or redistribute this software so long as it is not sold for profit,
X * provided that this notice and the original copyright notices are
X * retained.  The University of California makes no representations about the
X * suitability of this software for any purpose.  It is provided "as is"
X * without express or implied warranty.
X */
X
X#ifndef lint
Xstatic char *SCCSid = "@(#)macaux.c	2.1 3/29/89";
X#endif lint
X
X#include <ctype.h>
X#include <stdio.h>
X#include "str.h"
X
X#define	FALSE		0
X#define	TRUE		1
X
Xextern char *myname;
Xint rawmode = FALSE;
X
XSTR *
XSTRalloc()
X{
X	register STR *str;
X	char *malloc();
X
X	if((str = (STR *)malloc(sizeof(STR))) == NULL ||
X	 (str->bufptr = (unsigned char *)malloc(STRSIZE)) == NULL) {
X		fprintf(stderr, "%s: STRalloc: Out of memory\n", myname);
X		exit(1);
X	}
X	str->curendptr = str->bufptr;
X	str->realendptr = str->bufptr + STRSIZE;
X	return(str);
X}
X
XSTRfree(str)
XSTR *str;
X{
X	free((char *)str->bufptr);
X	free((char *)str);
X}
X
XSTRexpand(str)
Xregister STR *str;
X{
X	register int curend, realend;
X	char *realloc();
X
X	curend = str->curendptr - str->bufptr;
X	realend = (str->realendptr - str->bufptr) + STRSIZEDELTA;
X	if((str->bufptr = (unsigned char *)realloc((char *)str->bufptr,
X	 realend)) == NULL) {
X		fprintf(stderr, "%s: STRexpand: Out of memory\n", myname);
X		exit(1);
X	}
X	str->curendptr = str->bufptr + curend;
X	str->realendptr = str->bufptr + realend;
X}
X
XSTRgets(str, fp)
Xregister STR *str;
Xregister FILE *fp;
X{
X	register int c;
X
X	str->curendptr = str->bufptr;
X	for( ; ; ) {
X		if((c = getc(fp)) == EOF)
X			return(str->curendptr > str->bufptr);
X		if(str->curendptr >= str->realendptr)
X			STRexpand(str);
X		*str->curendptr++ = c;
X		if(c == '\n' || c == '\r')
X			return(TRUE);
X	}
X}
X
XSTRputsptr(str, cp, fp)
Xregister STR *str;
Xregister unsigned char *cp;
Xregister FILE *fp;
X{
X	if(rawmode) {
X		for( ; cp < str->curendptr ; cp++)
X			putc(*cp, fp);
X		return;
X	}
X	for( ; cp < str->curendptr ; cp++) {
X		if(!isascii(*cp))
X			fprintf(fp, "\\%03o", *cp);
X		else if(isprint(*cp))
X			putc(*cp, fp);
X		else {
X			switch(*cp) {
X			 case '\n':
X			 case '\r':
X				putc('\n', fp);
X				continue;
X			 case '\t':
X				putc('\t', fp);
X				continue;
X			 default:
X				fprintf(fp, "\\%03o", *str);
X				continue;
X			}
X		}
X	}
X}
X
XSTRcompareptr(str, cp, sp)
Xregister STR *str;
Xregister unsigned char *cp, *sp;
X{
X	register int comp;
X
X	for( ; ; ) {
X		if(*sp == 0)
X			return(cp >= str->curendptr ? 0 : 1);
X		if(cp >= str->curendptr)
X			return(-1);
X		if(*sp == '\n') {
X			if(*cp != '\n' && *cp != '\r')
X				return((int)*cp - (int)*sp);
X		} else if((comp = (int)*cp - (int)*sp) != 0)
X			return(comp);
X		cp++;
X		sp++;
X	}
X}
X
XSTRheadcmpptr(str, cp, sp)
Xregister STR *str;
Xregister unsigned char *cp, *sp;
X{
X	register int comp;
X
X	for( ; ; ) {
X		if(*sp == 0)
X			return(0);
X		if(cp >= str->curendptr)
X			return(-1);
X		if(*sp == '\n') {
X			if(*cp != '\n' && *cp != '\r')
X				return((int)*cp - (int)*sp);
X		} else if((comp = (int)*cp - (int)*sp) != 0)
X			return(comp);
X		cp++;
X		sp++;
X	}
X}
X
Xunsigned char *
XSTRmatch(str, sp)
Xregister STR *str;
Xregister unsigned char *sp;
X{
X	register unsigned char *mp, *last;
X	register int firstchar;
X
X	firstchar = *sp;
X	last = str->curendptr - strlen(sp);
X	mp = str->bufptr;
X	while(mp <= last) {
X		if(*mp == firstchar && STRheadcmpptr(str, mp, sp) == 0)
X			return(mp);
X		mp++;
X	}
X	return(NULL);
X}
SHAR_EOF
if test 3584 -ne "`wc -c < 'macaux.c'`"
then
	echo shar: error transmitting "'macaux.c'" '(should have been 3584 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'macps.c'" '(4880 characters)'
if test -f 'macps.c'
then
	echo shar: will not over-write existing file "'macps.c'"
else
sed 's/^X//' << \SHAR_EOF > 'macps.c'
X/*
X * Copyright (c) 1988, The Regents of the University of California.
X * Edward Moy, Workstation Software Support Group, Workstation Support Serices,
X * Information Systems and Technology.
X *
X * Permission is granted to any individual or institution to use, copy,
X * or redistribute this software so long as it is not sold for profit,
X * provided that this notice and the original copyright notices are
X * retained.  The University of California makes no representations about the
X * suitability of this software for any purpose.  It is provided "as is"
X * without express or implied warranty.
X */
X
X#ifndef lint
Xstatic char *SCCSid = "@(#)macps.c	2.1 3/29/89";
X#endif lint
X
X#include <ctype.h>
X#include <stdio.h>
X#ifdef SYSV
X#include <string.h>
X#else SYSV
X#include <strings.h>
X#endif SYSV
X#include <sys/types.h>
X#include <sys/file.h>
X#include "str.h"
X#include "ucbwhich.h"
X
X#define	CONFIG		"macps.config"
X#ifdef SYSV
X#define	index		strchr
X#define	rindex		strrchr
X#endif SYSV
X
Xchar *finale = "macps restore\n";
Xchar intro[] = "\
X%%! *** Created by macps: %s\
X/macps save def\n\
X";
Xchar *myname;
Xint ncopies = 0;
X#ifdef CONFIGDIR
Xchar ucblib[UCBMAXPATHLEN] = CONFIGDIR;
X#else CONFIGDIR
Xint ucbalternate;
Xchar ucbpath[UCBMAXPATHLEN];
Xchar ucblib[UCBMAXPATHLEN];
X#endif CONFIGDIR
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	register STR* str;
X	register char *cp, *pp;
X	register FILE *fp;
X	register int i, fd;
X	char line[BUFSIZ];
X	char path[UCBMAXPATHLEN];
X	long ltime;
X	char *ctime();
X
X#ifndef CONFIGDIR
X	ucbwhich(*argv);
X#endif CONFIGDIR
X	if(myname = rindex(*argv, '/'))
X		myname++;
X	else
X		myname = *argv;
X	cp = NULL;
X	for(argc--, argv++ ; argc > 0 && **argv == '-' ; argc--, argv++) {
X		switch((*argv)[1]) {
X		 case 'c':	/* multiple copies */
X			if((*argv)[2])
X				ncopies = atoi(&(*argv[2]));
X			else {
X				if(argc < 2)
X					Usage();	/* never returns */
X				argc--;
X				ncopies = atoi(*++argv);
X			}
X			if(ncopies <= 0)
X				Usage();	/* never returns */
X			break;
X		 case 'd':	/* alternate directory for config file */
X			if((*argv)[2])
X				cp = &(*argv[2]);
X			else {
X				if(argc < 2)
X					Usage();	/* never returns */
X				argc--;
X				cp = *++argv;
X			}
X			strcpy(ucblib, cp);
X			break;
X		 case 'r':	/* raw mode */
X			rawmode++;
X			break;
X		 default:
X			Usage();	/* never returns */
X		}
X	}
X	if(argc > 1)
X		Usage();	/* never returns */
X	if(argc == 1 && freopen(*argv, "r", stdin) == NULL) {
X		fprintf(stderr, "%s: can't open %s\n", myname, *argv);
X		exit(1);
X	}
X	str = STRalloc();
X	if(!STRgets(str, stdin)) {
X		fprintf(stderr, "%s: Null input\n", myname);
X		exit(1);
X	}
X	strcat(ucblib, "/");
X	strcpy(path, ucblib);
X	strcat(path, CONFIG);
X	if((fp = fopen(path, "r")) == NULL) {
X		fprintf(stderr, "%s: Can't open %s\n", myname, path);
X		exit(1);
X	}
X	time(&ltime);
X	printf(intro, ctime(&ltime));
X	do {
X		if(ncopies != 0 && STRheadcompare(str, "userdict /#copies ")
X		 == 0)
X			continue;
X		if(STRcompare(str, "%%EOF\n") == 0) {
X			if(finale) {
X				fputs(finale, stdout);
X				finale = NULL;
X			}
X			STRputs(str, stdout);
X			continue;
X		}
X		if(STRheadcompare(str, "%%IncludeProcSet:") == 0) {
X			for(cp = (char *)&str->bufptr[17] ; ; cp++) {
X				if(!*cp) {
X					fprintf(stderr,
X				 "%s: Syntax error on IncludeProcSet line\n",
X					 myname);
X					exit(1);
X				}
X				if(!isascii(*cp) || !isspace(*cp))
X					break;
X			}
X			pp = (char *)str->curendptr;
X			while(--pp >= cp) {
X				if(!isascii(*pp) || !isspace(*pp))
X					break;
X				*pp = 0;
X			}
X			str->curendptr = (unsigned char *)(pp + 1);
X			fseek(fp, 0L, 0);
X			for( ; ; ) {
X				if(!fgets(line, BUFSIZ, fp)) {
X					fprintf(stderr,
X					 "%s: Unknown IncludeProcSet %s\n",
X					 myname, cp);
X					exit(1);
X				}
X				if(*line == '#')
X					continue;
X				if(pp = index(line, '\n')) {
X					if(pp == line)
X						continue;
X					*pp = 0;
X				}
X				if(!(pp = index(line, '\t'))) {
X					fprintf(stderr,
X					 "%s: Syntax error in macps.config\n",
X					 myname);
X					exit(1);
X				}
X				*pp++ = 0;
X				if(STRcompareptr(str, cp, line) == 0)
X					break;
X			}
X			if(*pp == '/')
X				strcpy(path, pp);
X			else {
X				strcpy(path, ucblib);
X				strcat(path, pp);
X			}
X			fflush(stdout);
X			if((fd = open(path, O_RDONLY, 0)) < 0) {
X				fprintf(stderr, "%s: Can't open %s\n", myname,
X				 path);
X				exit(1);
X			}
X			while((i = read(fd, line, BUFSIZ)) > 0)
X				write(1, line, i);
X			close(fd);
X			continue;
X		}
X		STRputs(str, stdout);
X		if(ncopies > 1 && isascii(*str->bufptr) &&
X		 isdigit(*str->bufptr)) {
X			cp = (char *)str->bufptr;
X			while(cp < (char *)str->curendptr && isascii(*cp)
X			 && isdigit(*cp))
X				cp++;
X			if((char *)str->curendptr - cp == 4 &&
X			 STRcompareptr(str, cp, " mf\n") == 0) {
X				printf("userdict /#copies %d put\n", ncopies);
X				ncopies = -1;
X			}
X		}
X	} while(STRgets(str, stdin));
X	if(finale)
X		fputs(finale, stdout);
X	exit(0);
X}
X
XUsage()
X{
X	fputs("Usage: macps [-c #] [-d directory] [-r] [file]\n", stderr);
X	exit(1);
X}
SHAR_EOF
if test 4880 -ne "`wc -c < 'macps.c'`"
then
	echo shar: error transmitting "'macps.c'" '(should have been 4880 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'prepfix.c'" '(5474 characters)'
if test -f 'prepfix.c'
then
	echo shar: will not over-write existing file "'prepfix.c'"
else
sed 's/^X//' << \SHAR_EOF > 'prepfix.c'
X/*
X * Copyright (c) 1988, The Regents of the University of California.
X * Edward Moy, Workstation Software Support Group, Workstation Support Serices,
X * Information Systems and Technology.
X *
X * Permission is granted to any individual or institution to use, copy,
X * or redistribute this software so long as it is not sold for profit,
X * provided that this notice and the original copyright notices are
X * retained.  The University of California makes no representations about the
X * suitability of this software for any purpose.  It is provided "as is"
X * without express or implied warranty.
X */
X
X#ifndef lint
Xstatic char *SCCSid = "@(#)prepfix.c	2.1 3/29/89";
X#endif lint
X
X#include <ctype.h>
X#include <stdio.h>
X#ifdef SYSV
X#include <string.h>
X#else SYSV
X#include <strings.h>
X#endif SYSV
X#include "str.h"
X
X#define	CLEARTOMARK	12
X#define EEXECLEN	80
X#define EXTRA		(NZEROLINE * ZEROLINE + CLEARTOMARK)
X#define LINELEN		256
X#define	NPRODUCTS	32
X#define NZEROLINE	7
X#define ZEROLINE	65
X#ifdef SYSV
X#define	index		strchr
X#define	rindex		strrchr
X#endif SYSV
X
Xchar exstr[] = "\
X%ck userdict/%s known not and{currentfile eexec}{%d{currentfile read\n\
Xpop pop}repeat}ifelse\n\
X";
Xchar *match();
Xchar *myname;
Xint maxproducts = NPRODUCTS;
Xint nproducts = 0;
Xchar Ok[] = "\
X/Ok{ok dup not{save /Pd statusdict /product get def false 0 1 ProdArr length\n\
X1 sub{Pd exch ProdArr exch get anchorsearch exch pop{pop pop true exit}if}for\n\
Xexch restore}if}bind def\n\
X";
Xchar ProdArr0[] = "/ProdArr [\n";
Xchar ProdArr1[] = "] def\n";
Xchar **products;
Xchar tempname[] = "/tmp/prepfixXXXXXX";
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	register STR *str;
X	register FILE *tp;
X	register int i;
X	register unsigned char *lp;
X	char buf[BUFSIZ];
X	char *malloc(), *realloc();
X
X	if(myname = rindex(*argv, '/'))
X		myname++;
X	else
X		myname = *argv;
X	for(argc--, argv++ ; argc > 0 && **argv == '-' ; argc--, argv++) {
X		switch((*argv)[1]) {
X		 case 'h':
X			usage();
X		 case 'l':
X			if(nproducts <= 0 && (products =
X			 (char **)malloc(maxproducts*sizeof(char *))) == NULL) {
X				fprintf(stderr,
X				 "%s: Out of memory creating products array\n",
X				 myname);
X				exit(1);
X			} else if(nproducts >= maxproducts - 1 && (products =
X			 (char **)realloc(products, (maxproducts += NPRODUCTS)
X			 * sizeof(char *))) == NULL) {
X				fprintf(stderr,
X				 "%s: Out of memory expanding products array\n",
X				 myname);
X				exit(1);
X			}
X			if((*argv)[2])
X				products[nproducts++] = &(*argv)[2];
X			else {
X				if(argc < 2) {
X					fprintf(stderr,
X					 "%s: No argument for -l\n", myname);
X					exit(1);
X				}
X				argc--;
X				argv++;
X				products[nproducts++] = *argv;
X			}
X			break;
X		}
X	}
X	if(argc > 1)
X		usage();
X	if(argc > 0 && freopen(*argv, "r", stdin) == NULL) {
X		fprintf(stderr, "%s: Can't open %s\n", myname, *argv);
X		exit(1);
X	}
X	mktemp(tempname);
X	if((tp = fopen(tempname, "w+")) == NULL) {
X		fprintf(stderr, "%s: Can't create temp file %s\n",
X		 myname, tempname);
X		exit(1);
X	}
X	unlink(tempname);
X	str = STRalloc();
X	if(!STRgets(str, stdin)) {
X		fprintf(stderr, "%s: Null input\n", myname);
X		exit(1);
X	}
X	for( ; ; ) {
X		if(STRheadcompare(str, "% \251") == 0) {
X			fputs("% ", tp);
X			str->bufptr[0] = '(';
X			str->bufptr[1] = 'C';
X			str->bufptr[2] = ')';
X		} else if(STRheadcompare(str, "%%BeginProcSet:") == 0) {
X			STRputs(str, stdout);
X			fseek(tp, 0L, 0);
X			while((i = fread(buf, 1, BUFSIZ, tp)) > 0)
X				fwrite(buf, 1, i, stdout);
X			fclose(tp);
X			break;
X		}
X		STRputs(str, tp);
X		if(!STRgets(str, stdin)) {
X			fprintf(stderr, "%s: No BeginProcSet\n", myname);
X			exit(1);
X		}
X	}
X	while(STRgets(str, stdin)) {
X		if(nproducts > 0 && STRheadcompare(str, "/ok{") == 0) {
X			STRputs(str, stdout);
X			fputs(ProdArr0, stdout);
X			for(i = 0 ; i < nproducts ; i++)
X				printf("(%s)\n", products[i]);
X			fputs(ProdArr1, stdout);
X			fputs(Ok, stdout);
X			continue;
X		} else if(STRmatch(str, "setdefaulttimeouts")
X		 || STRmatch(str, "setsccinteractive"))
X			continue;
X		else if(STRmatch(str, "eexec")) {
X			if(STRmatch(str, "/stretch")) {
X				eexec("stretch", str);
X				continue;
X			} else if(STRmatch(str, "/smooth4")) {
X				eexec("smooth4", str);
X				continue;
X			}
X		} else if(STRmatch(str, "(LaserWriter II NT)")) {
X			STRgets(str, stdin);	/* skip next line */
X			while(STRgets(str, stdin) && isxdigit(*str->bufptr))
X				{}
X		} else if(lp = STRmatch(str, "scaleby96{ppr")) {
X			STRputsptr(str, lp, stdout);
X			continue;
X		} else if(STRheadcompare(str, "%%EndProcSet") == 0) {
X			STRputs(str, stdout);
X			break;
X		}
X		STRputs(str, stdout);
X	}
X	exit(0);
X}
X
Xeexec(name, str)
Xchar *name;
Xregister STR *str;
X{
X	register int len;
X	register unsigned char *bp;
X
X	if(!STRgets(str, stdin)) {
X		fprintf(stderr, "%s: EOF during reading eexec\n", myname);
X		exit(1);
X	}
X	bp = str->bufptr;
X	len = (str->curendptr - bp) - 1;
X	printf(exstr, nproducts > 0 ? 'O' : 'o', name, len + (len / EEXECLEN)
X	 + (len % EEXECLEN ? 1 : 0) + EXTRA);
X	while(len >= 80) {
X		fwrite(bp, 80, 1, stdout);
X		putchar('\n');
X		bp += 80;
X		len -= 80;
X	}
X	if(len > 0) {
X		fwrite(bp, len, 1, stdout);
X		putchar('\n');
X	}
X	for( ; ; ) {
X		if(!STRgets(str, stdin)) {
X			fprintf(stderr, "%s: EOF reached before cleartomark\n",
X			 myname);
X			exit(1);
X		}
X		if(STRheadcompare(str, "cleartomark") == 0) {
X			STRputs(str, stdout);
X			return;
X		}
X		STRputs(str, stdout);
X	}
X}
X
Xusage()
X{
X	fprintf(stderr,
X	 "Usage: %s [-l product_name1 [-l product_name2]...] [file]\n",
X	 myname);
X	fprintf(stderr, "       %s -help\n", myname);
X	exit(1);
X}
SHAR_EOF
if test 5474 -ne "`wc -c < 'prepfix.c'`"
then
	echo shar: error transmitting "'prepfix.c'" '(should have been 5474 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'str.h'" '(1159 characters)'
if test -f 'str.h'
then
	echo shar: will not over-write existing file "'str.h'"
else
sed 's/^X//' << \SHAR_EOF > 'str.h'
X/*
X * Copyright (c) 1988, The Regents of the University of California.
X * Edward Moy, Workstation Software Support Group, Workstation Support Serices,
X * Information Systems and Technology.
X *
X * Permission is granted to any individual or institution to use, copy,
X * or redistribute this software so long as it is not sold for profit,
X * provided that this notice and the original copyright notices are
X * retained.  The University of California makes no representations about the
X * suitability of this software for any purpose.  It is provided "as is"
X * without express or implied warranty.
X */
X
X/*
X * SCCSid = "@(#)str.h	2.1 3/29/89"
X */
X
X#define	STRSIZEDELTA	1024
X#define	STRSIZE		1024
X
X#define	STRcompare(str,fp)	STRcompareptr((str), (str)->bufptr, (fp))
X#define	STRheadcompare(str,fp)	STRheadcmpptr((str), (str)->bufptr, (fp))
X#define	STRputs(str,fp)		STRputsptr((str), (str)->bufptr, (fp))
X
Xtypedef struct {
X	unsigned char *bufptr;
X	unsigned char *curendptr;
X	unsigned char *realendptr;
X} STR;
X
Xextern int rawmode;
X
XSTR *STRalloc();
Xint STRcompareptr();
Xint STRfree();
Xint STRgets();
Xint STRheadcmpptr();
Xunsigned char *STRmatch();
Xint STRputsptr();
SHAR_EOF
if test 1159 -ne "`wc -c < 'str.h'`"
then
	echo shar: error transmitting "'str.h'" '(should have been 1159 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'ucbwhich.c'" '(3272 characters)'
if test -f 'ucbwhich.c'
then
	echo shar: will not over-write existing file "'ucbwhich.c'"
else
sed 's/^X//' << \SHAR_EOF > 'ucbwhich.c'
X/*
X * Copyright (c) 1988, The Regents of the University of California.
X * Edward Moy, Workstation Software Support Group, Workstation Support Serices,
X * Information Systems and Technology.
X *
X * Permission is granted to any individual or institution to use, copy,
X * or redistribute this software so long as it is not sold for profit,
X * provided that this notice and the original copyright notices are
X * retained.  The University of California makes no representations about the
X * suitability of this software for any purpose.  It is provided "as is"
X * without express or implied warranty.
X */
X
X#ifndef CONFIGDIR
X#ifndef lint
Xstatic char *SCCSid = "@(#)ucbwhich.c	2.1 3/29/89";
X#endif lint
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include "ucbwhich.h"
X
X#define	F_OK		0	/* does file exist */
X#define	X_OK		1	/* is it executable by caller */
X#define	W_OK		2	/* writable by caller */
X#define	R_OK		4	/* readable by caller */
X
X#define	LIBLEN		4
X#ifdef SYSV
X#define	index		strchr
X#define	rindex		strrchr
X#endif SYSV
X
Xstatic char lib[] = "/lib";
X
Xchar ucblib[UCBMAXPATHLEN];
Xint ucbalternate = 0;
Xchar ucbpath[UCBMAXPATHLEN];
X
Xucbwhich(str)
Xchar *str;
X{
X	register char *dir, *name, *cp, *tp;
X	register int len;
X	char dirbuf[UCBMAXPATHLEN], namebuf[UCBMAXPATHLEN];
X	struct stat sbuf;
X	char *index(), *rindex(), *getwd(), *getenv();
X
X	strcpy(name = namebuf, str);
X	if(*name == '/')	/* absolute pathname */
X		*(rindex(dir = name, '/')) = 0 ; /* remove tail */
X	else {
X		if(cp = index(name, '/')) { /* relative pathname */
X			if((dir = getwd(dirbuf)) == NULL)
X				return(0);
X			 /* if any errors occurs assume standard version */
X			*cp++ = 0;
X			for( ; ; ) {
X				if(*name != 0) { /* multiple slashes */
X					if(strcmp(name, "..") == 0) {
X						/* parent directory */
X						if((tp = rindex(dir, '/')) ==
X						 NULL)
X						 	return(0);
X						if(tp == dir)
X							tp++;
X						 /* root directory */
X						*tp = 0;
X						 /* remove last component */
X					} else if(strcmp(name, ".") != 0) {
X						/* subdirectory */
X						strcat(dir, "/");
X						strcat(dir, name);
X					}
X				}
X				name = cp;
X				if((cp = index(name, '/')) == NULL) break;
X				/* ignore last component */
X				*cp++ = 0;
X			}
X		} else { /* look through $PATH variable */
X			if((tp = getenv("PATH")) == NULL)
X				return(0);
X			for(name = namebuf ; ; ) {
X				if(*tp == 0)
X					return(0);
X				else if(*tp == ':')
X					tp++;
X				if((cp = index(tp, ':')) == NULL)
X					cp = tp + strlen(tp);
X				 /* positioned on null */
X				for(dir = dirbuf ; tp < cp ; )
X					*dir++ = *tp++;
X				*dir = 0;
X				strcpy(name, dir = dirbuf);
X				strcat(name, "/");
X				strcat(name, str);
X				if(stat(name, &sbuf) < 0 || (sbuf.st_mode &
X				 S_IFMT) != S_IFREG)
X					continue;
X				if(access(name, X_OK) == 0) {
X					if(strcmp(dir, ".") == 0 &&
X					 (dir = getwd(dirbuf)) == NULL)
X						return(0);
X					break;
X				}
X			}
X		}
X	}
X	strcpy(ucbpath, dir);
X	strcpy(ucblib, dir);
X	if((len = strlen(dir)) < LIBLEN || strcmp(&dir[len - LIBLEN], lib)
X	 != 0)
X		strcat(ucblib, lib);
X	else
X		ucbpath[len - LIBLEN] = 0;
X	ucbalternate = (strcmp(ucbpath, UCBSTANDARD) != 0);
X#ifdef EBUG
X	fprintf(stderr, "ucbwhich: alt=%d path=%s lib=%s\n", ucbalternate,
X	 ucbpath, ucblib);
X#endif EBUG
X	return(ucbalternate);
X}
X#endif CONFIGDIR
SHAR_EOF
if test 3272 -ne "`wc -c < 'ucbwhich.c'`"
then
	echo shar: error transmitting "'ucbwhich.c'" '(should have been 3272 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'ucbwhich.h'" '(777 characters)'
if test -f 'ucbwhich.h'
then
	echo shar: will not over-write existing file "'ucbwhich.h'"
else
sed 's/^X//' << \SHAR_EOF > 'ucbwhich.h'
X/*
X * Copyright (c) 1988, The Regents of the University of California.
X * Edward Moy, Workstation Software Support Group, Workstation Support Serices,
X * Information Systems and Technology.
X *
X * Permission is granted to any individual or institution to use, copy,
X * or redistribute this software so long as it is not sold for profit,
X * provided that this notice and the original copyright notices are
X * retained.  The University of California makes no representations about the
X * suitability of this software for any purpose.  It is provided "as is"
X * without express or implied warranty.
X */
X
X/*
X * SCCSid = "@(#)ucbwhich.h	2.1 3/29/89"
X */
X
X#define	UCBMAXPATHLEN	128
X#define	UCBSTANDARD	"/usr/ucb"
X
Xextern char ucblib[];
Xextern int ucbalternate;
Xextern char ucbpath[];
SHAR_EOF
if test 777 -ne "`wc -c < 'ucbwhich.h'`"
then
	echo shar: error transmitting "'ucbwhich.h'" '(should have been 777 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'macps.config'" '(491 characters)'
if test -f 'macps.config'
then
	echo shar: will not over-write existing file "'macps.config'"
else
sed 's/^X//' << \SHAR_EOF > 'macps.config'
X# This is the config file read by macps.
X# SCCSid = "@(#)macps.config	2.1 3/29/89"
X#
X# Each line is composed of the %%IncludeProcSet id, a tab and the file
X# containing the ProcSet.  If the file doesn't begin with a slash, the
X# the name is taken to be relative to the directory in which this config file
X# resides.
X
X"(AppleDict md)" 65 0	ProcSets/LaserPrep4.0
X"(AppleDict md)" 66	ProcSets/LaserPrep5.0
X"(AppleDict md)" 67 0	ProcSets/LaserPrep5.1
X"(AppleDict md)" 68 0	ProcSets/LaserPrep5.2
SHAR_EOF
if test 491 -ne "`wc -c < 'macps.config'`"
then
	echo shar: error transmitting "'macps.config'" '(should have been 491 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'macps.1'" '(2593 characters)'
if test -f 'macps.1'
then
	echo shar: will not over-write existing file "'macps.1'"
else
sed 's/^X//' << \SHAR_EOF > 'macps.1'
X.\" SCCSid = "@(#)macps.1	2.1 3/29/89"
X.TH MACPS 1 "29 March 1989"
X.UC 4
X.SH NAME
Xmacps \- print Macintosh-created PostScript file on Unix
X.SH SYNOPSIS
X.B macps
X[
X\-c copies
X]
X[
X\-d directory
X]
X[
X\-r
X]
X[
Xfile
X]
X.SH DESCRIPTION
X.I Macps
Xtakes the command-line file (or the standard input if no filename is given),
Xand prepends the appropriate Macintosh LaserPrep file (e.g., those generated
Xby
X.IR prepfix (1)).
XThe standard output can then be directed to a PostScript printer, via
X.IR lpr (1),
Xfor example.
X.PP
XThe input PostScript file is generated on a Macintosh by typing (and holding)
XCommand-F immediately after clicking the OK button of the LaserWriter printer
Xdialog box.
XAnother dialog will appear, confirming that a file named ``PostScript'' is
Xbeing created (the Command-F keys can be released now).
X.PP
XDepending on the application, the created PostScript file can be found in the
XSystem Folder, the application folder or the top level of the disk.
XThis file can then be uploaded via some file transfer program, such as
XMacTerminal/VersaTerm and
X.IR macget (1)
Xor MacKermit/Red Ryder and
X.IR kermit (1).
X.PP
XNormally, you would specify the number of copies in the LaserWriter
Xprint dialog box on the Macintosh.
XHowever, you can override that after uploading the PostScript file by
Xspecifying the
X.B \-c
Xoption, followed by the number of copies.
X.PP
XThe file
X.B macps.config
Xspecifies the mapping between the internal LaserPrep name and the actual
Xfile it resides in.
XThis file is normally located in the lib subdirectory from which
X.I macps
Xwas called from.
XThe
X.B \-d
Xoption allow you to specify an alternate directory in which the
X.B macps.config
Xfile can be found.
X.PP
XMost Macintosh applications produce normal ASCII PostScript files.
XHowever, some graphics programs that manipulate gray-scale images will
Xproduce PostScript files that contain 8-bit binary data.
XSince
X.I macps
Xnormally converts this binary data, these PostScript file will not work
Xproperly.
XThe
X.B \-r
X(raw) option suppresses this binary conversion.
X(Note: Depending on how the printer is physically connected, it may not be
Xable to handle 8-bit binary data properly, and results may be disappointing.)
X.SH FILES
X.TP "\w'lib/macps.config   'u"
Xlib/macps.config
Xmaps ProcSet ids to LaserPrep filenames
X.SH "SEE ALSO"
Xlpr(1), macget(1), kermit(1), prepfix(1)
X.SH BUGS
X.I Macps
Xonly works with version 4.0 and up of the Macintosh LaserPrep files.
XBecause of the way bit smoothing is implimented by the LaserWriter driver,
Xsome PostScript printers other than the Apple LaserWriters may not be able to
Xbit smooth.
SHAR_EOF
if test 2593 -ne "`wc -c < 'macps.1'`"
then
	echo shar: error transmitting "'macps.1'" '(should have been 2593 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'prepfix.1'" '(2100 characters)'
if test -f 'prepfix.1'
then
	echo shar: will not over-write existing file "'prepfix.1'"
else
sed 's/^X//' << \SHAR_EOF > 'prepfix.1'
X.\" SCCSid = "@(#)prepfix.1	2.1 3/29/89"
X.TH PREPFIX 1 "29 March 1989"
X.UC 4
X.SH NAME
Xprepfix \- converts Apple LaserPrep files to form useable on Unix
X.SH SYNOPSIS
X.B prepfix
X[
X\-l
Xprinter_name1
X[
X\-l
Xprinter_name2
X]...
X]
X[
Xfile
X]
X.SH DESCRIPTION
X.I Prepfix
Xtakes the command-line LaserPrep file (or the standard input if no filename is
Xgiven), and converts it into a form that is useable on Unix with the
X.IR macps (1),
Xand is even electronically mailable.
X.PP
XTo use
X.IR prepfix ,
Xcreate the input LaserPrep file on a Macintosh by opening an empty
Xdocument in some application, selecting
X.B Print
Xfrom the
X.B File
Xmenu and then typing (and holding) Command-K immediately after clicking the
X.B OK
Xbutton in the LaserWriter print dialog box.
XAnother dialog will appear, confirming that a file named ``PostScript'' is
Xbeing created (the Command-K keys can be released now).
X.PP
XDepending on the application, the created PostScript file can be found in the
XSystem Folder, the application folder or the top level of the disk.
XThis file can then be uploaded via some file transfer program, such as
XMacTerminal/VersaTerm and
X.IR macget (1)
Xor MacKermit/Red Ryder and
X.IR kermit (1).
X.PP
XNormally, only Apple LaserWriters can take advantage of the bit smoothing
Xfeature of the LaserPrep file.
XHowever, other PostScript laser printer using the Motorola 680x0 processor
Xand the Adobe PostScript firmware can be made to do bit smoothing by
Xspecifying for each printer the
X.B \-l
Xoption and the printer's name, as returned by the PostScript
X.B product
Xcommand in
X.B statusdict
X(remember to quote the printer name if it contains blanks).
XThe resulting LaserPrep file will be modified so that for LaserWriters and for
Xprinters specified in the
X.B \-l
Xoption, bit smoothing will be allowed (smoothing must still be selected in the
XPrint Dialog box when saving the PostScript to disk).
XMore than one printer name can be specified using additional
X.B \-l
Xand printer name pairs.
X.SH "SEE ALSO"
Xmacps(1), macget(1), kermit(1)
X.SH BUGS
X.I Prepfix
Xonly works with version 4.0 and up of the Macintosh LaserPrep files.
SHAR_EOF
if test 2100 -ne "`wc -c < 'prepfix.1'`"
then
	echo shar: error transmitting "'prepfix.1'" '(should have been 2100 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0
---