17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
23*f928ce67Sceastha  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
287c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate  *
327c478bd9Sstevel@tonic-gate  * download - host resident font downloader
337c478bd9Sstevel@tonic-gate  *
347c478bd9Sstevel@tonic-gate  * Prepends host resident fonts to PostScript input files. The program assumes
357c478bd9Sstevel@tonic-gate  * the input files are part of a single PostScript job and that requested fonts
367c478bd9Sstevel@tonic-gate  * can be downloaded at the start of each input file. Downloaded fonts are the
377c478bd9Sstevel@tonic-gate  * ones named in a %%DocumentFonts: comment and listed in a special map table.
387c478bd9Sstevel@tonic-gate  * Map table pathnames (supplied using the -m option) that begin with a / are
397c478bd9Sstevel@tonic-gate  * taken as is. Otherwise the final pathname is built using *hostfontdir (-H
407c478bd9Sstevel@tonic-gate  * option), *mapname (-m option), and *suffix.
417c478bd9Sstevel@tonic-gate  *
427c478bd9Sstevel@tonic-gate  * The map table consists of fontname-filename pairs, separated by white space.
437c478bd9Sstevel@tonic-gate  * Comments are introduced by % (as in PostScript) and extend to the end of the
447c478bd9Sstevel@tonic-gate  * current line. The only fonts that can be downloaded are the ones listed in
457c478bd9Sstevel@tonic-gate  * the active map table that point the program to a readable Unix file. A request
467c478bd9Sstevel@tonic-gate  * for an unlisted font or inaccessible file is ignored. All font requests are
477c478bd9Sstevel@tonic-gate  * ignored if the map table can't be read. In that case the program simply copies
487c478bd9Sstevel@tonic-gate  * the input files to stdout.
497c478bd9Sstevel@tonic-gate  *
507c478bd9Sstevel@tonic-gate  * An example (but not one to follow) of what can be in a map table is,
517c478bd9Sstevel@tonic-gate  *
527c478bd9Sstevel@tonic-gate  *	%
537c478bd9Sstevel@tonic-gate  *	% Map requests for Bookman-Light to file *hostfontdir/KR
547c478bd9Sstevel@tonic-gate  *	%
557c478bd9Sstevel@tonic-gate  *
567c478bd9Sstevel@tonic-gate  *	  Bookman-Light		KR	% Keeping everything (including the map
577c478bd9Sstevel@tonic-gate  *					% table) in *hostfontdir seems like the
587c478bd9Sstevel@tonic-gate  *					% cleanest approach.
597c478bd9Sstevel@tonic-gate  *
607c478bd9Sstevel@tonic-gate  *	%
617c478bd9Sstevel@tonic-gate  *	% Map Palatino-Roman to file *hostfontdir/palatino/Roman
627c478bd9Sstevel@tonic-gate  *	%
637c478bd9Sstevel@tonic-gate  *	  Palatino-Roman	palatino/Roman
647c478bd9Sstevel@tonic-gate  *
657c478bd9Sstevel@tonic-gate  *	% Map ZapfDingbats to file /usr/lib/host/dingbats
667c478bd9Sstevel@tonic-gate  *
677c478bd9Sstevel@tonic-gate  *	  ZapfDingbats		/usr/lib/host/dingbats
687c478bd9Sstevel@tonic-gate  *
697c478bd9Sstevel@tonic-gate  * Once again, file names that begin with a / are taken as is. All others have
707c478bd9Sstevel@tonic-gate  * *hostfontdir/ prepended to the file string associated with a particular font.
717c478bd9Sstevel@tonic-gate  *
727c478bd9Sstevel@tonic-gate  * Map table can be associated with a printer model (e.g. a LaserWriter), a
737c478bd9Sstevel@tonic-gate  * printer destination, or whatever - the choice is up to an administrator.
747c478bd9Sstevel@tonic-gate  * By destination may be best if your spooler is running several private
757c478bd9Sstevel@tonic-gate  * printers. Host resident fonts are usually purchased under a license that
767c478bd9Sstevel@tonic-gate  * restricts their use to a limited number of printers. A font licensed for
777c478bd9Sstevel@tonic-gate  * a single printer should only be used on that printer.
787c478bd9Sstevel@tonic-gate  *
797c478bd9Sstevel@tonic-gate  * Was written quickly, so there's much room for improvement. Undoubtedly should
807c478bd9Sstevel@tonic-gate  * be a more general program (e.g. scan for other comments).
817c478bd9Sstevel@tonic-gate  *
827c478bd9Sstevel@tonic-gate  */
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate #include <stdio.h>
857c478bd9Sstevel@tonic-gate #include <signal.h>
867c478bd9Sstevel@tonic-gate #include <fcntl.h>
877c478bd9Sstevel@tonic-gate #include <sys/types.h>
887c478bd9Sstevel@tonic-gate #include <sys/stat.h>
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate #include "comments.h"			/* PostScript file structuring comments */
917c478bd9Sstevel@tonic-gate #include "gen.h"			/* general purpose definitions */
927c478bd9Sstevel@tonic-gate #include "path.h"			/* for temporary directory */
937c478bd9Sstevel@tonic-gate #include "ext.h"			/* external variable declarations */
947c478bd9Sstevel@tonic-gate #include "download.h"			/* a few special definitions */
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate char	*temp_dir = TEMPDIR;		/* temp directory - for copying stdin */
977c478bd9Sstevel@tonic-gate char	*hostfontdir = HOSTFONTDIR;	/* host resident directory */
987c478bd9Sstevel@tonic-gate char	*mapname = "map";		/* map table - usually in *hostfontdir */
997c478bd9Sstevel@tonic-gate char	*suffix = "";			/* appended to the map table pathname */
1007c478bd9Sstevel@tonic-gate Map	*map = NULL;			/* device font map table */
1017c478bd9Sstevel@tonic-gate char	*stringspace = NULL;		/* for storing font and file strings */
1027c478bd9Sstevel@tonic-gate int	next = 0;			/* next free slot in map[] */
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate char	*residentfonts = NULL;		/* list of printer resident fonts */
1057c478bd9Sstevel@tonic-gate char	*printer = NULL;		/* printer name - only for Unix 4.0 lp */
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate char	buf[2048];			/* input file line buffer */
1087c478bd9Sstevel@tonic-gate char	*comment = DOCUMENTFONTS;	/* look for this comment */
1097c478bd9Sstevel@tonic-gate int	atend = FALSE;			/* TRUE only if a comment says so */
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate FILE	*fp_in = stdin;			/* next input file */
1127c478bd9Sstevel@tonic-gate FILE	*fp_temp = NULL;		/* for copying stdin */
1137c478bd9Sstevel@tonic-gate 
114*f928ce67Sceastha static Map *allocate(Map *, int);
115*f928ce67Sceastha static void arguments(void);
116*f928ce67Sceastha static void copyfonts(char *);
117*f928ce67Sceastha static void copyinput(void);
118*f928ce67Sceastha static void done(void);
119*f928ce67Sceastha static void download(void);
120*f928ce67Sceastha static void init_signals(void);
121*f928ce67Sceastha static int lookup(char *);
122*f928ce67Sceastha static void options(void);
123*f928ce67Sceastha static void readmap(void);
124*f928ce67Sceastha static void readresident(void);
1257c478bd9Sstevel@tonic-gate 
126*f928ce67Sceastha /*****************************************************************************/
1277c478bd9Sstevel@tonic-gate 
128*f928ce67Sceastha int
main(int agc,char * agv[])129*f928ce67Sceastha main(int agc, char *agv[])
1307c478bd9Sstevel@tonic-gate {
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate /*
1337c478bd9Sstevel@tonic-gate  *
1347c478bd9Sstevel@tonic-gate  * Host resident font download. The input files are assumed to be part of a
1357c478bd9Sstevel@tonic-gate  * single PostScript job.
1367c478bd9Sstevel@tonic-gate  *
1377c478bd9Sstevel@tonic-gate  */
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate     argc = agc;				/* other routines may want them */
1407c478bd9Sstevel@tonic-gate     argv = agv;
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate     prog_name = argv[0];		/* just for error messages */
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate     init_signals();			/* sets up interrupt handling */
1457c478bd9Sstevel@tonic-gate     options();				/* first get command line options */
1467c478bd9Sstevel@tonic-gate     readmap();				/* read the font map table */
1477c478bd9Sstevel@tonic-gate     readresident();			/* and the optional resident font list */
1487c478bd9Sstevel@tonic-gate     arguments();			/* then process non-option arguments */
1497c478bd9Sstevel@tonic-gate     done();				/* and clean things up */
1507c478bd9Sstevel@tonic-gate 
151*f928ce67Sceastha     return (x_stat);			/* not much could be wrong */
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate }   /* End of main */
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate /*****************************************************************************/
1567c478bd9Sstevel@tonic-gate 
157*f928ce67Sceastha static void
init_signals(void)158*f928ce67Sceastha init_signals(void)
1597c478bd9Sstevel@tonic-gate {
1607c478bd9Sstevel@tonic-gate     void	interrupt();		/* handles signals if we catching them */
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate /*
1637c478bd9Sstevel@tonic-gate  *
1647c478bd9Sstevel@tonic-gate  * Makes sure we handle interrupts properly.
1657c478bd9Sstevel@tonic-gate  *
1667c478bd9Sstevel@tonic-gate  */
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate     if ( signal(SIGINT, interrupt) == SIG_IGN )  {
1697c478bd9Sstevel@tonic-gate 	signal(SIGINT, SIG_IGN);
1707c478bd9Sstevel@tonic-gate 	signal(SIGQUIT, SIG_IGN);
1717c478bd9Sstevel@tonic-gate 	signal(SIGHUP, SIG_IGN);
1727c478bd9Sstevel@tonic-gate     } else {
1737c478bd9Sstevel@tonic-gate 	signal(SIGHUP, interrupt);
1747c478bd9Sstevel@tonic-gate 	signal(SIGQUIT, interrupt);
1757c478bd9Sstevel@tonic-gate     }   /* End else */
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate     signal(SIGTERM, interrupt);
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate }   /* End of init_signals */
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate /*****************************************************************************/
1827c478bd9Sstevel@tonic-gate 
183*f928ce67Sceastha static void
options(void)184*f928ce67Sceastha options(void)
1857c478bd9Sstevel@tonic-gate {
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate     int		ch;			/* return value from getopt() */
1887c478bd9Sstevel@tonic-gate     char	*optnames = "c:fm:p:r:H:T:DI";
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate     extern char	*optarg;		/* used by getopt() */
1917c478bd9Sstevel@tonic-gate     extern int	optind;
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate /*
1947c478bd9Sstevel@tonic-gate  *
1957c478bd9Sstevel@tonic-gate  * Reads and processes the command line options.
1967c478bd9Sstevel@tonic-gate  *
1977c478bd9Sstevel@tonic-gate  */
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate     while ( (ch = getopt(argc, argv, optnames)) != EOF )  {
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate 	switch ( ch )  {
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	    case 'c':			/* look for this comment */
2047c478bd9Sstevel@tonic-gate 		    comment = optarg;
2057c478bd9Sstevel@tonic-gate 		    break;
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	    case 'f':			/* force a complete input file scan */
2087c478bd9Sstevel@tonic-gate 		    atend = TRUE;
2097c478bd9Sstevel@tonic-gate 		    break;
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate 	    case 'm':			/* printer map table name */
2127c478bd9Sstevel@tonic-gate 		    mapname = optarg;
2137c478bd9Sstevel@tonic-gate 		    break;
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 	    case 'p':			/* printer name - for Unix 4.0 lp */
2167c478bd9Sstevel@tonic-gate 		    printer = optarg;
2177c478bd9Sstevel@tonic-gate 		    break;
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate 	    case 'r':			/* resident font list */
2207c478bd9Sstevel@tonic-gate 		    residentfonts = optarg;
2217c478bd9Sstevel@tonic-gate 		    break;
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate 	    case 'H':			/* host resident font directory */
2247c478bd9Sstevel@tonic-gate 		    hostfontdir = optarg;
2257c478bd9Sstevel@tonic-gate 		    break;
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate 	    case 'T':			/* temporary file directory */
2287c478bd9Sstevel@tonic-gate 		    temp_dir = optarg;
2297c478bd9Sstevel@tonic-gate 		    break;
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 	    case 'D':			/* debug flag */
2327c478bd9Sstevel@tonic-gate 		    debug = ON;
2337c478bd9Sstevel@tonic-gate 		    break;
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate 	    case 'I':			/* ignore FATAL errors */
2367c478bd9Sstevel@tonic-gate 		    ignore = ON;
2377c478bd9Sstevel@tonic-gate 		    break;
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate 	    case '?':			/* don't understand the option */
2407c478bd9Sstevel@tonic-gate 		    error(FATAL, "");
2417c478bd9Sstevel@tonic-gate 		    break;
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 	    default:			/* don't know what to do for ch */
2447c478bd9Sstevel@tonic-gate 		    error(FATAL, "missing case for option %c\n", ch);
2457c478bd9Sstevel@tonic-gate 		    break;
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 	}   /* End switch */
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate     }   /* End while */
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate     argc -= optind;			/* get ready for non-option args */
2527c478bd9Sstevel@tonic-gate     argv += optind;
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate }   /* End of options */
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate /*****************************************************************************/
2577c478bd9Sstevel@tonic-gate 
258*f928ce67Sceastha static void
readmap(void)259*f928ce67Sceastha readmap(void)
2607c478bd9Sstevel@tonic-gate {
2617c478bd9Sstevel@tonic-gate     char	*path;
2627c478bd9Sstevel@tonic-gate     char	*ptr;
2637c478bd9Sstevel@tonic-gate     int		fd;
2647c478bd9Sstevel@tonic-gate     struct stat	sbuf;
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate /*
2677c478bd9Sstevel@tonic-gate  *
2687c478bd9Sstevel@tonic-gate  * Initializes the map table by reading an ASCII mapping file. If mapname begins
2697c478bd9Sstevel@tonic-gate  * with a / it's the map table. Otherwise hostfontdir, mapname, and suffix are
2707c478bd9Sstevel@tonic-gate  * combined to build the final pathname. If we can open the file we read it all
2717c478bd9Sstevel@tonic-gate  * into memory, erase comments, and separate the font and file name pairs. When
2727c478bd9Sstevel@tonic-gate  * we leave next points to the next free slot in the map[] array. If it's zero
2737c478bd9Sstevel@tonic-gate  * nothing was in the file or we couldn't open it.
2747c478bd9Sstevel@tonic-gate  *
2757c478bd9Sstevel@tonic-gate  */
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate     if ( hostfontdir == NULL || mapname == NULL )
2787c478bd9Sstevel@tonic-gate 	return;
2797c478bd9Sstevel@tonic-gate 
2807c478bd9Sstevel@tonic-gate     if ( *mapname != '/' ) {
2817c478bd9Sstevel@tonic-gate 	if ( (path = malloc(strlen(hostfontdir) + strlen(mapname) +
2827c478bd9Sstevel@tonic-gate 						strlen(suffix) + 2)) == NULL )
2837c478bd9Sstevel@tonic-gate 	    error(FATAL, "no memory");
2847c478bd9Sstevel@tonic-gate 	sprintf(path, "%s/%s%s", hostfontdir, mapname, suffix);
2857c478bd9Sstevel@tonic-gate     } else path = mapname;
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate     if ( (fd = open(path, 0)) != -1 ) {
2887c478bd9Sstevel@tonic-gate 	if ( fstat(fd, &sbuf) == -1 )
2897c478bd9Sstevel@tonic-gate 	    error(FATAL, "can't fstat %s", path);
2907c478bd9Sstevel@tonic-gate 	if ( (stringspace = malloc(sbuf.st_size + 2)) == NULL )
2917c478bd9Sstevel@tonic-gate 	    error(FATAL, "no memory");
2927c478bd9Sstevel@tonic-gate 	if ( read(fd, stringspace, sbuf.st_size) == -1 )
2937c478bd9Sstevel@tonic-gate 	    error(FATAL, "can't read %s", path);
2947c478bd9Sstevel@tonic-gate 	close(fd);
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 	stringspace[sbuf.st_size] = '\n';	/* just to be safe */
2977c478bd9Sstevel@tonic-gate 	stringspace[sbuf.st_size+1] = '\0';
2987c478bd9Sstevel@tonic-gate 	for ( ptr = stringspace; *ptr != '\0'; ptr++ )	/* erase comments */
2997c478bd9Sstevel@tonic-gate 	    if ( *ptr == '%' )
3007c478bd9Sstevel@tonic-gate 		for ( ; *ptr != '\n' ; ptr++ )
3017c478bd9Sstevel@tonic-gate 		    *ptr = ' ';
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate 	for ( ptr = stringspace; ; next++ ) {
3047c478bd9Sstevel@tonic-gate 	    if ( (next % 50) == 0 )
3057c478bd9Sstevel@tonic-gate 		map = allocate(map, next+50);
3067c478bd9Sstevel@tonic-gate 	    map[next].downloaded = FALSE;
3077c478bd9Sstevel@tonic-gate 	    map[next].font = strtok(ptr, " \t\n");
3087c478bd9Sstevel@tonic-gate 	    map[next].file = strtok(ptr = NULL, " \t\n");
3097c478bd9Sstevel@tonic-gate 	    if ( map[next].font == NULL )
3107c478bd9Sstevel@tonic-gate 		break;
3117c478bd9Sstevel@tonic-gate 	    if ( map[next].file == NULL )
3127c478bd9Sstevel@tonic-gate 		error(FATAL, "map table format error - check %s", path);
3137c478bd9Sstevel@tonic-gate 	}   /* End for */
3147c478bd9Sstevel@tonic-gate     }	/* End if */
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate }   /* End of readmap */
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate /*****************************************************************************/
3197c478bd9Sstevel@tonic-gate 
320*f928ce67Sceastha static void
readresident(void)321*f928ce67Sceastha readresident(void)
3227c478bd9Sstevel@tonic-gate {
3237c478bd9Sstevel@tonic-gate     FILE	*fp;
3247c478bd9Sstevel@tonic-gate     char	*path;
3257c478bd9Sstevel@tonic-gate     int		ch;
3267c478bd9Sstevel@tonic-gate     int		n;
3277c478bd9Sstevel@tonic-gate 
3287c478bd9Sstevel@tonic-gate /*
3297c478bd9Sstevel@tonic-gate  *
3307c478bd9Sstevel@tonic-gate  * Reads a file that lists the resident fonts for a particular printer and marks
3317c478bd9Sstevel@tonic-gate  * each font as already downloaded. Nothing's done if the file can't be read or
3327c478bd9Sstevel@tonic-gate  * there's no mapping file. Comments, as in the map file, begin with a % and
3337c478bd9Sstevel@tonic-gate  * extend to the end of the line. Added for Unix 4.0 lp.
3347c478bd9Sstevel@tonic-gate  *
3357c478bd9Sstevel@tonic-gate  */
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate     if ( next == 0 || (printer == NULL && residentfonts == NULL) )
3387c478bd9Sstevel@tonic-gate 	return;
3397c478bd9Sstevel@tonic-gate 
3407c478bd9Sstevel@tonic-gate     if ( printer != NULL ) {		/* use Unix 4.0 lp pathnames */
3417c478bd9Sstevel@tonic-gate 	sprintf(buf, "/etc/lp/printers/%s/residentfonts", printer);
3427c478bd9Sstevel@tonic-gate 	path = buf;
3437c478bd9Sstevel@tonic-gate     } else path = residentfonts;
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate     if ( (fp = fopen(path, "r")) != NULL ) {
3467c478bd9Sstevel@tonic-gate 	while ( fscanf(fp, "%s", buf) != EOF )
3477c478bd9Sstevel@tonic-gate 	    if ( buf[0] == '%' )
3487c478bd9Sstevel@tonic-gate 		while ( (ch = getc(fp)) != EOF && ch != '\n' ) ;
3497c478bd9Sstevel@tonic-gate 	    else if ( (n = lookup(buf)) < next )
3507c478bd9Sstevel@tonic-gate 		map[n].downloaded = TRUE;
3517c478bd9Sstevel@tonic-gate 	fclose(fp);
3527c478bd9Sstevel@tonic-gate     }	/* End if */
3537c478bd9Sstevel@tonic-gate 
3547c478bd9Sstevel@tonic-gate }   /* End of readresident */
3557c478bd9Sstevel@tonic-gate 
3567c478bd9Sstevel@tonic-gate /*****************************************************************************/
3577c478bd9Sstevel@tonic-gate 
358*f928ce67Sceastha static void
arguments(void)359*f928ce67Sceastha arguments(void)
3607c478bd9Sstevel@tonic-gate {
3617c478bd9Sstevel@tonic-gate 
3627c478bd9Sstevel@tonic-gate /*
3637c478bd9Sstevel@tonic-gate  *
3647c478bd9Sstevel@tonic-gate  * Makes sure all the non-option command line arguments are processed. If we get
3657c478bd9Sstevel@tonic-gate  * here and there aren't any arguments left, or if '-' is one of the input files
3667c478bd9Sstevel@tonic-gate  * we'll translate stdin. Assumes input files are part of a single PostScript
3677c478bd9Sstevel@tonic-gate  * job and fonts can be downloaded at the start of each file.
3687c478bd9Sstevel@tonic-gate  *
3697c478bd9Sstevel@tonic-gate  */
3707c478bd9Sstevel@tonic-gate 
3717c478bd9Sstevel@tonic-gate     if ( argc < 1 )
3727c478bd9Sstevel@tonic-gate 	download();
3737c478bd9Sstevel@tonic-gate     else {
3747c478bd9Sstevel@tonic-gate 	while ( argc > 0 ) {
3757c478bd9Sstevel@tonic-gate 	    fp_temp = NULL;
3767c478bd9Sstevel@tonic-gate 	    if ( strcmp(*argv, "-") == 0 )
3777c478bd9Sstevel@tonic-gate 		fp_in = stdin;
3787c478bd9Sstevel@tonic-gate 	    else if ( (fp_in = fopen(*argv, "r")) == NULL )
3797c478bd9Sstevel@tonic-gate 		error(FATAL, "can't open %s", *argv);
3807c478bd9Sstevel@tonic-gate 	    download();
3817c478bd9Sstevel@tonic-gate 	    if ( fp_in != stdin )
3827c478bd9Sstevel@tonic-gate 		fclose(fp_in);
3837c478bd9Sstevel@tonic-gate 	    if ( fp_temp != NULL )
3847c478bd9Sstevel@tonic-gate 		fclose(fp_temp);
3857c478bd9Sstevel@tonic-gate 	    argc--;
3867c478bd9Sstevel@tonic-gate 	    argv++;
3877c478bd9Sstevel@tonic-gate 	}   /* End while */
3887c478bd9Sstevel@tonic-gate     }	/* End else */
3897c478bd9Sstevel@tonic-gate 
3907c478bd9Sstevel@tonic-gate }   /* End of arguments */
3917c478bd9Sstevel@tonic-gate 
3927c478bd9Sstevel@tonic-gate /*****************************************************************************/
3937c478bd9Sstevel@tonic-gate 
394*f928ce67Sceastha static void
done(void)395*f928ce67Sceastha done(void)
3967c478bd9Sstevel@tonic-gate {
3977c478bd9Sstevel@tonic-gate 
3987c478bd9Sstevel@tonic-gate /*
3997c478bd9Sstevel@tonic-gate  *
4007c478bd9Sstevel@tonic-gate  * Clean things up before we quit.
4017c478bd9Sstevel@tonic-gate  *
4027c478bd9Sstevel@tonic-gate  */
4037c478bd9Sstevel@tonic-gate 
4047c478bd9Sstevel@tonic-gate     if ( temp_file != NULL )
4057c478bd9Sstevel@tonic-gate 	unlink(temp_file);
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate }   /* End of done */
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate /*****************************************************************************/
4107c478bd9Sstevel@tonic-gate 
411*f928ce67Sceastha static void
download(void)412*f928ce67Sceastha download(void)
4137c478bd9Sstevel@tonic-gate {
4147c478bd9Sstevel@tonic-gate     int		infontlist = FALSE;
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate /*
4177c478bd9Sstevel@tonic-gate  *
4187c478bd9Sstevel@tonic-gate  * If next is zero the map table is empty and all we do is copy the input file
4197c478bd9Sstevel@tonic-gate  * to stdout. Otherwise we read the input file looking for %%DocumentFonts: or
4207c478bd9Sstevel@tonic-gate  * continuation comments, add any accessible fonts to the output file, and then
4217c478bd9Sstevel@tonic-gate  * append the input file. When reading stdin we append lines to fp_temp and
4227c478bd9Sstevel@tonic-gate  * recover them when we're ready to copy the input file. fp_temp will often
4237c478bd9Sstevel@tonic-gate  * only contain part of stdin - if there's no %%DocumentFonts: (atend) comment
4247c478bd9Sstevel@tonic-gate  * we stop reading fp_in after the header.
4257c478bd9Sstevel@tonic-gate  *
4267c478bd9Sstevel@tonic-gate  */
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate     if ( next > 0 ) {
4297c478bd9Sstevel@tonic-gate 	if ( fp_in == stdin ) {
4307c478bd9Sstevel@tonic-gate 	    if ( (temp_file = tempnam(temp_dir, "post")) == NULL )
4317c478bd9Sstevel@tonic-gate 		error(FATAL, "can't generate temp file name");
4327c478bd9Sstevel@tonic-gate 	    if ( (fp_temp = fopen(temp_file, "w+")) == NULL )
4337c478bd9Sstevel@tonic-gate 		error(FATAL, "can't open %s", temp_file);
4347c478bd9Sstevel@tonic-gate 	    unlink(temp_file);
4357c478bd9Sstevel@tonic-gate 	    temp_file = NULL;
4367c478bd9Sstevel@tonic-gate 	}   /* End if */
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate 	while ( fgets(buf, sizeof(buf), fp_in) != NULL ) {
4397c478bd9Sstevel@tonic-gate 	    if ( fp_temp != NULL )
4407c478bd9Sstevel@tonic-gate 		fprintf(fp_temp, "%s", buf);
4417c478bd9Sstevel@tonic-gate 	    if ( buf[0] != '%' || buf[1] != '%' ) {
4427c478bd9Sstevel@tonic-gate 		if ( (buf[0] != '%' || buf[1] != '!') && atend == FALSE )
4437c478bd9Sstevel@tonic-gate 		    break;
4447c478bd9Sstevel@tonic-gate 		infontlist = FALSE;
4457c478bd9Sstevel@tonic-gate 	    } else if ( strncmp(buf, comment, strlen(comment)) == 0 ) {
4467c478bd9Sstevel@tonic-gate 		copyfonts(buf);
4477c478bd9Sstevel@tonic-gate 		infontlist = TRUE;
4487c478bd9Sstevel@tonic-gate 	    } else if ( buf[2] == '+' && infontlist == TRUE )
4497c478bd9Sstevel@tonic-gate 		copyfonts(buf);
4507c478bd9Sstevel@tonic-gate 	    else infontlist = FALSE;
4517c478bd9Sstevel@tonic-gate 	}   /* End while */
4527c478bd9Sstevel@tonic-gate     }	/* End if */
4537c478bd9Sstevel@tonic-gate 
4547c478bd9Sstevel@tonic-gate     copyinput();
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate }   /* End of download */
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate /*****************************************************************************/
4597c478bd9Sstevel@tonic-gate 
460*f928ce67Sceastha static void
copyfonts(char * list)461*f928ce67Sceastha copyfonts(char *list)
4627c478bd9Sstevel@tonic-gate {
4637c478bd9Sstevel@tonic-gate     char	*font;
4647c478bd9Sstevel@tonic-gate     char	*path;
4657c478bd9Sstevel@tonic-gate     int		n;
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate /*
4687c478bd9Sstevel@tonic-gate  *
4697c478bd9Sstevel@tonic-gate  * list points to a %%DocumentFonts: or continuation comment. What follows the
4707c478bd9Sstevel@tonic-gate  * the keyword will be a list of fonts separated by white space (or (atend)).
4717c478bd9Sstevel@tonic-gate  * Look for each font in the map table and if it's found copy the font file to
4727c478bd9Sstevel@tonic-gate  * stdout (once only).
4737c478bd9Sstevel@tonic-gate  *
4747c478bd9Sstevel@tonic-gate  */
4757c478bd9Sstevel@tonic-gate 
4767c478bd9Sstevel@tonic-gate     strtok(list, " \n");		/* skip to the font list */
4777c478bd9Sstevel@tonic-gate 
4787c478bd9Sstevel@tonic-gate     while ( (font = strtok(NULL, " \t\n")) != NULL ) {
4797c478bd9Sstevel@tonic-gate 	if ( strcmp(font, ATEND) == 0 ) {
4807c478bd9Sstevel@tonic-gate 	    atend = TRUE;
4817c478bd9Sstevel@tonic-gate 	    break;
4827c478bd9Sstevel@tonic-gate 	}   /* End if */
4837c478bd9Sstevel@tonic-gate 	if ( (n = lookup(font)) < next ) {
4847c478bd9Sstevel@tonic-gate 	    if ( *map[n].file != '/' ) {
4857c478bd9Sstevel@tonic-gate 		if ( (path = malloc(strlen(hostfontdir)+strlen(map[n].file)+2)) == NULL )
4867c478bd9Sstevel@tonic-gate 		    error(FATAL, "no memory");
4877c478bd9Sstevel@tonic-gate 		sprintf(path, "%s/%s", hostfontdir, map[n].file);
4887c478bd9Sstevel@tonic-gate 		cat(path);
4897c478bd9Sstevel@tonic-gate 		free(path);
4907c478bd9Sstevel@tonic-gate 	    } else cat(map[n].file);
4917c478bd9Sstevel@tonic-gate 	    map[n].downloaded = TRUE;
4927c478bd9Sstevel@tonic-gate 	}   /* End if */
4937c478bd9Sstevel@tonic-gate     }	/* End while */
4947c478bd9Sstevel@tonic-gate 
4957c478bd9Sstevel@tonic-gate }   /* End of copyfonts */
4967c478bd9Sstevel@tonic-gate 
4977c478bd9Sstevel@tonic-gate /*****************************************************************************/
4987c478bd9Sstevel@tonic-gate 
499*f928ce67Sceastha static void
copyinput(void)500*f928ce67Sceastha copyinput(void)
5017c478bd9Sstevel@tonic-gate {
5027c478bd9Sstevel@tonic-gate 
5037c478bd9Sstevel@tonic-gate /*
5047c478bd9Sstevel@tonic-gate  *
5057c478bd9Sstevel@tonic-gate  * Copies the input file to stdout. If fp_temp isn't NULL seek to the start and
5067c478bd9Sstevel@tonic-gate  * add it to the output file - it's a partial (or complete) copy of stdin made
5077c478bd9Sstevel@tonic-gate  * by download(). Then copy fp_in, but only seek to the start if it's not stdin.
5087c478bd9Sstevel@tonic-gate  *
5097c478bd9Sstevel@tonic-gate  */
5107c478bd9Sstevel@tonic-gate 
5117c478bd9Sstevel@tonic-gate     if ( fp_temp != NULL ) {
5127c478bd9Sstevel@tonic-gate 	fseek(fp_temp, 0L, 0);
5137c478bd9Sstevel@tonic-gate 	while ( fgets(buf, sizeof(buf), fp_temp) != NULL )
5147c478bd9Sstevel@tonic-gate 	    printf("%s", buf);
5157c478bd9Sstevel@tonic-gate     }	/* End if */
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate     if ( fp_in != stdin )
5187c478bd9Sstevel@tonic-gate 	fseek(fp_in, 0L, 0);
5197c478bd9Sstevel@tonic-gate 
5207c478bd9Sstevel@tonic-gate     while ( fgets(buf, sizeof(buf), fp_in) != NULL )
5217c478bd9Sstevel@tonic-gate 	printf("%s", buf);
5227c478bd9Sstevel@tonic-gate 
5237c478bd9Sstevel@tonic-gate }   /* End of copyinput */
5247c478bd9Sstevel@tonic-gate 
5257c478bd9Sstevel@tonic-gate /*****************************************************************************/
5267c478bd9Sstevel@tonic-gate 
527*f928ce67Sceastha static int
lookup(char * font)528*f928ce67Sceastha lookup(char *font)
5297c478bd9Sstevel@tonic-gate {
5307c478bd9Sstevel@tonic-gate     int		i;
5317c478bd9Sstevel@tonic-gate 
5327c478bd9Sstevel@tonic-gate /*
5337c478bd9Sstevel@tonic-gate  *
5347c478bd9Sstevel@tonic-gate  * Looks for *font in the map table. Return the map table index if found and
5357c478bd9Sstevel@tonic-gate  * not yet downloaded - otherwise return next.
5367c478bd9Sstevel@tonic-gate  *
5377c478bd9Sstevel@tonic-gate  */
5387c478bd9Sstevel@tonic-gate 
5397c478bd9Sstevel@tonic-gate     for ( i = 0; i < next; i++ )
5407c478bd9Sstevel@tonic-gate 	if ( strcmp(font, map[i].font) == 0 ) {
5417c478bd9Sstevel@tonic-gate 	    if ( map[i].downloaded == TRUE )
5427c478bd9Sstevel@tonic-gate 		i = next;
5437c478bd9Sstevel@tonic-gate 	    break;
5447c478bd9Sstevel@tonic-gate 	}   /* End if */
5457c478bd9Sstevel@tonic-gate 
5467c478bd9Sstevel@tonic-gate     return(i);
5477c478bd9Sstevel@tonic-gate 
5487c478bd9Sstevel@tonic-gate }   /* End of lookup */
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate /*****************************************************************************/
5517c478bd9Sstevel@tonic-gate 
552*f928ce67Sceastha static Map *
allocate(Map * ptr,int num)553*f928ce67Sceastha allocate(Map *ptr, int num)
5547c478bd9Sstevel@tonic-gate {
5557c478bd9Sstevel@tonic-gate 
5567c478bd9Sstevel@tonic-gate /*
5577c478bd9Sstevel@tonic-gate  *
5587c478bd9Sstevel@tonic-gate  * Allocates space for num Map elements. Calls malloc() if ptr is NULL and
5597c478bd9Sstevel@tonic-gate  * realloc() otherwise.
5607c478bd9Sstevel@tonic-gate  *
5617c478bd9Sstevel@tonic-gate  */
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate     if ( ptr == NULL )
5647c478bd9Sstevel@tonic-gate 	ptr = (Map *)malloc(num * sizeof(Map));
5657c478bd9Sstevel@tonic-gate     else ptr = (Map *)realloc(ptr, num * sizeof(Map));
5667c478bd9Sstevel@tonic-gate 
5677c478bd9Sstevel@tonic-gate     if ( ptr == NULL )
5687c478bd9Sstevel@tonic-gate 	error(FATAL, "no map memory");
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate     return(ptr);
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate }   /* End of allocate */
573