/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#pragma ident "%Z%%M% %I% %E% SMI"
/*
*
* download - host resident font downloader
*
* Prepends host resident fonts to PostScript input files. The program assumes
* the input files are part of a single PostScript job and that requested fonts
* can be downloaded at the start of each input file. Downloaded fonts are the
* ones named in a %%DocumentFonts: comment and listed in a special map table.
* Map table pathnames (supplied using the -m option) that begin with a / are
* taken as is. Otherwise the final pathname is built using *hostfontdir (-H
* option), *mapname (-m option), and *suffix.
*
* The map table consists of fontname-filename pairs, separated by white space.
* Comments are introduced by % (as in PostScript) and extend to the end of the
* current line. The only fonts that can be downloaded are the ones listed in
* the active map table that point the program to a readable Unix file. A request
* for an unlisted font or inaccessible file is ignored. All font requests are
* ignored if the map table can't be read. In that case the program simply copies
* the input files to stdout.
*
* An example (but not one to follow) of what can be in a map table is,
*
* %
* % Map requests for Bookman-Light to file *hostfontdir/KR
* %
*
* Bookman-Light KR % Keeping everything (including the map
* % table) in *hostfontdir seems like the
* % cleanest approach.
*
* %
* % Map Palatino-Roman to file *hostfontdir/palatino/Roman
* %
*
*
*
* Once again, file names that begin with a / are taken as is. All others have
* *hostfontdir/ prepended to the file string associated with a particular font.
*
* Map table can be associated with a printer model (e.g. a LaserWriter), a
* printer destination, or whatever - the choice is up to an administrator.
* By destination may be best if your spooler is running several private
* printers. Host resident fonts are usually purchased under a license that
* restricts their use to a limited number of printers. A font licensed for
* a single printer should only be used on that printer.
*
* Was written quickly, so there's much room for improvement. Undoubtedly should
* be a more general program (e.g. scan for other comments).
*
*/
#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include "comments.h" /* PostScript file structuring comments */
#include "gen.h" /* general purpose definitions */
#include "path.h" /* for temporary directory */
#include "ext.h" /* external variable declarations */
#include "download.h" /* a few special definitions */
static void arguments(void);
static void copyfonts(char *);
static void copyinput(void);
static void done(void);
static void download(void);
static void init_signals(void);
static int lookup(char *);
static void options(void);
static void readmap(void);
static void readresident(void);
/*****************************************************************************/
int
{
/*
*
* Host resident font download. The input files are assumed to be part of a
* single PostScript job.
*
*/
init_signals(); /* sets up interrupt handling */
options(); /* first get command line options */
readmap(); /* read the font map table */
readresident(); /* and the optional resident font list */
arguments(); /* then process non-option arguments */
done(); /* and clean things up */
return (x_stat); /* not much could be wrong */
} /* End of main */
/*****************************************************************************/
static void
init_signals(void)
{
void interrupt(); /* handles signals if we catching them */
/*
*
* Makes sure we handle interrupts properly.
*
*/
} else {
} /* End else */
} /* End of init_signals */
/*****************************************************************************/
static void
options(void)
{
extern char *optarg; /* used by getopt() */
extern int optind;
/*
*
* Reads and processes the command line options.
*
*/
switch ( ch ) {
case 'c': /* look for this comment */
break;
case 'f': /* force a complete input file scan */
break;
case 'm': /* printer map table name */
break;
case 'p': /* printer name - for Unix 4.0 lp */
break;
case 'r': /* resident font list */
break;
case 'H': /* host resident font directory */
break;
case 'T': /* temporary file directory */
break;
case 'D': /* debug flag */
break;
case 'I': /* ignore FATAL errors */
break;
case '?': /* don't understand the option */
break;
default: /* don't know what to do for ch */
break;
} /* End switch */
} /* End while */
} /* End of options */
/*****************************************************************************/
static void
readmap(void)
{
char *path;
char *ptr;
int fd;
/*
*
* Initializes the map table by reading an ASCII mapping file. If mapname begins
* with a / it's the map table. Otherwise hostfontdir, mapname, and suffix are
* combined to build the final pathname. If we can open the file we read it all
* into memory, erase comments, and separate the font and file name pairs. When
* we leave next points to the next free slot in the map[] array. If it's zero
* nothing was in the file or we couldn't open it.
*
*/
return;
if ( *mapname != '/' ) {
if ( *ptr == '%' )
*ptr = ' ';
if ( (next % 50) == 0 )
break;
} /* End for */
} /* End if */
} /* End of readmap */
/*****************************************************************************/
static void
readresident(void)
{
char *path;
int ch;
int n;
/*
*
* Reads a file that lists the resident fonts for a particular printer and marks
* each font as already downloaded. Nothing's done if the file can't be read or
* there's no mapping file. Comments, as in the map file, begin with a % and
* extend to the end of the line. Added for Unix 4.0 lp.
*
*/
return;
} else path = residentfonts;
if ( buf[0] == '%' )
} /* End if */
} /* End of readresident */
/*****************************************************************************/
static void
arguments(void)
{
/*
*
* Makes sure all the non-option command line arguments are processed. If we get
* here and there aren't any arguments left, or if '-' is one of the input files
* we'll translate stdin. Assumes input files are part of a single PostScript
* job and fonts can be downloaded at the start of each file.
*
*/
if ( argc < 1 )
download();
else {
while ( argc > 0 ) {
download();
argc--;
argv++;
} /* End while */
} /* End else */
} /* End of arguments */
/*****************************************************************************/
static void
done(void)
{
/*
*
* Clean things up before we quit.
*
*/
} /* End of done */
/*****************************************************************************/
static void
download(void)
{
/*
*
* If next is zero the map table is empty and all we do is copy the input file
* to stdout. Otherwise we read the input file looking for %%DocumentFonts: or
* continuation comments, add any accessible fonts to the output file, and then
* append the input file. When reading stdin we append lines to fp_temp and
* recover them when we're ready to copy the input file. fp_temp will often
* only contain part of stdin - if there's no %%DocumentFonts: (atend) comment
* we stop reading fp_in after the header.
*
*/
if ( next > 0 ) {
} /* End if */
break;
infontlist = FALSE;
infontlist = TRUE;
else infontlist = FALSE;
} /* End while */
} /* End if */
copyinput();
} /* End of download */
/*****************************************************************************/
static void
{
char *font;
char *path;
int n;
/*
*
* list points to a %%DocumentFonts: or continuation comment. What follows the
* the keyword will be a list of fonts separated by white space (or (atend)).
* Look for each font in the map table and if it's found copy the font file to
* stdout (once only).
*
*/
break;
} /* End if */
} /* End if */
} /* End while */
} /* End of copyfonts */
/*****************************************************************************/
static void
copyinput(void)
{
/*
*
* Copies the input file to stdout. If fp_temp isn't NULL seek to the start and
* add it to the output file - it's a partial (or complete) copy of stdin made
* by download(). Then copy fp_in, but only seek to the start if it's not stdin.
*
*/
} /* End if */
} /* End of copyinput */
/*****************************************************************************/
static int
{
int i;
/*
*
* Looks for *font in the map table. Return the map table index if found and
* not yet downloaded - otherwise return next.
*
*/
for ( i = 0; i < next; i++ )
i = next;
break;
} /* End if */
return(i);
} /* End of lookup */
/*****************************************************************************/
static Map *
{
/*
*
* Allocates space for num Map elements. Calls malloc() if ptr is NULL and
* realloc() otherwise.
*
*/
return(ptr);
} /* End of allocate */