File:  [MW Coherent from dump] / coherent / d / bin / nroff / fwtable.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:39 2019 UTC (7 years, 2 months ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/*
 * fwtable.c
 * 6/7/91
 * Usage: fwtable [ -cptv ] [ -ssymset ] [ infile [ outfile ] ]
 * Read HP PCL bitmap font, PostScript AFM file, or HP TFM file
 * from infile or stdin, write font width table to outfile or stdout.
 *
 * Requires floating point output, PostScript routines in fwt_PS.c,
 * TFM routines in fwt_TFM.c:
 *	cc fwtable.c fwt_PS.c fwt_TFM.c -f
 *
 * Options:
 *	-c		Write C instead of binary
 *	-p		Input is PostScript AFM file
 *	-ssymset	Specify desired symbol set with -t option
 *	-t		Input is HP TFM file
 *	-v		Write one-line font description to stderr
 *
 * Understands PCL bitmap fonts, PostScript AFM files, HP TFM files.
 * Does not understand Intellifont scalable fonts.
 *
 * The following had better agree about the binary FWT format:
 *	troff/fwtable.c/dump_chartab()	writes binary FWT from HP PCL
 *	troff/fwt_PS.c/outputPS()	writes binary FWT from PostScript AFM
 *	troff/fwt_TFM.c/outputTFM()	writes binary FWT from HP TFM
 *	troff/fonts.c/loadfont()	reads binary FWT for troff
 *
 * Modified 12/12/90-12/28/90 by steve from dag's original hptable.c source;
 * the coding could definitely be cleaner.
 */

#include <stdio.h>
#include <canon.h>
#include "fwtable.h"

/* PCL bitmap font descriptor format.  Cf. "HP LJ III Tech Ref Man", p. 10-7. */
typedef struct fnt_hdr {
	short	f_hsize;
	uchar	f_desc_format;
	uchar	f_font_type;
	uchar	f_style_msb;
	uchar	f_reserved1;
	short	f_baseline;
	short	f_cell_width;
	short	f_cell_height;
	uchar	f_orientation;
	uchar	f_spacing;
	short	f_symbol_set;
	short	f_pitch;
	short	f_height;
	short	f_xheight;
	uchar	f_width_type;
	uchar	f_style;
	char	f_weight;		/* specifically signed!	*/
	uchar	f_face;
	uchar	f_comment[0];		/* remainder in add_info */
} font_header;

typedef struct add_info {
	char	a_slant;		/* Slant information	*/
	uchar	a_serif;		/* Serif style (see serif table) */
	uchar	a_quality;		/* Quality level	*/
	uchar	a_placement;		/* Placement		*/
	char	a_underline;		/* Underline position	*/
	uchar	a_uheight;		/* Underline height in dots	*/
	short	a_lspacing;		/* Optimum line spacing in dots * 4 */
	short	a_nwidth;		/* Average lower-case char width * 4 */
	short	a_firstc;		/* First code		*/
	short	a_lastc;		/* Last code		*/
	uchar	a_piextend;		/* Extend for pitch	*/
	uchar	a_poextend;		/* Extend for height	*/
	short	a_cap_height;		/* Cap height		*/
	long	a_fontnum;		/* Font Number		*/
	char	a_fontname[16];		/* Font name		*/
} font_extra;

typedef struct chr_hdr {
	uchar	c_format;		/* Character format (4)	*/
	uchar	c_continuation;		/* Continuation flag	*/
	uchar	c_size;			/* Header size to follow*/
	uchar	c_class;		/* Format class 1=raster*/
	uchar	c_orientation;		/* Orientation		*/
	uchar	c_empty2;		/* more padding...	*/
	short	c_left_offset;		/* left offset		*/
	short	c_top_offset;		/* top offset		*/
	short	c_char_width;		/* character width	*/
	short	c_char_height;		/* character height	*/
	short	c_delta_x;		/* delta X		*/
	uchar	c_data[0];		/* character data	*/
} character_header;
character_header *char_def();

/* Global arrays. */
/*
 * Typefaces.
 * Cf. "HP LJ III Tech Ref Man", pp. 10-27ff.
 * The list given there gives all values 0-84 and some values 87-168.
 * This list is truncated in the name of sanity.
 */
char	*faces[] = {
	"LinePrinter",			/*  0 */
	"Pica",				/*  1 */
	"Elite",			/*  2 */
	"Courier",			/*  3 */
	"Helvetica",			/*  4 */
	"Times",			/*  5 */
	"LetterGothic",			/*  6 */
	"Script",			/*  7 */
	"Prestige",			/*  8 */
	"Caslon",			/*  9 */
	"Orator",			/* 10 */
	"Presentation",			/* 11 */
	"HelveticaCondensed",		/* 12 */
	"Serifa",			/* 13 */
	"Futura",			/* 14 */
	"Palatino",			/* 15 */
	"ITCSouvenir",			/* 16 */
	"Optima",			/* 17 */
	"ITCGaramond",			/* 18 */
	"CooperBlack",			/* 19 */
	"Coronet",			/* 20 */
	"Broadway",			/* 21 */
	"BauerBodoniBlack",		/* 22 */
	"NewCenturySchlbk",		/* 23 */
	"               "		/* >23 */
 };
#define	NFACES	((sizeof faces / sizeof faces[0]) - 1)

/* f_serif values */
char *serif_tab[] = {
	"sans serif square",		/* 0 */
	"sans serif round",		/* 1 */
	"serif line",			/* 2 */
	"serif triangle",		/* 3 */
	"serif swath",			/* 4 */
	"serif block",			/* 5 */
	"serif bracket",		/* 6 */
	"rounded bracket",		/* 7 */
	"flair serif",			/* 8 */
	"script nonconnecting",		/* 9 */
	"script joining",		/* 10 */
	"script calligraphic",		/* 11 */
	"script broken letter",		/* 12 */
	"serif value out-of-range"	/* >12 */
};
#define	NSERIFS	((sizeof serif_tab / sizeof serif_tab[0]) - 1)

/* Style posture values.  The width and structure info is ignored for now. */
char *posture_tab[] = {
	"upright",			/* 0 */
	"italic",			/* 1 */
	"alternate italic",		/* 2 */
	"reserved"			/* 3 */
};

/* Orientation. */
char *orient_tab[] = {
	"portrait",			/* 0 */
	"landscape",			/* 1 */
	"reverse portrait",		/* 2 */
	"reverse landscape"		/* 3 */
};

/* Globals. */
char		buf[NBUF];		/* String conversion	*/
int		cflag;			/* Write C not binary	*/
int		char_datasize[NWIDTH];	/* Character size	*/
int		char_movement[NWIDTH];	/* Character movement	*/
font_header	*fhp;			/* Font header pointer	*/
FILE		*ifp = stdin;		/* The input FILE	*/
int		ipointsz;		/* Integer point size	*/
FILE		*ofp = stdout;		/* The output FILE	*/
int		pflag;			/* PostScript input	*/
char		*symset;		/* Desired symbol set	*/
int		tflag;			/* TFM input		*/
int		this_char;		/* Current character	*/
int		vflag;			/* Verbose		*/

main(argc, argv) int argc; char *argv[];
{
	register char *s;

	/* Process command-line options. */
	while (argc > 1 && argv[1][0] == '-') {
		for (s = &argv[1][1]; *s; s++) {
			switch(*s) {
			case 'c':
				++cflag;
				break;
			case 'p':
				++pflag;
				break;
			case 's':
				symset = ++s;
				while (*s)
					++s;
				--s;
				break;
			case 't':
				++tflag;
				break;
			case 'v':
				++vflag;
				break;
			case 'V':
				fprintf(stderr, "fwtable: V%s\n", VERSION);
				break;
			default:
				usage();
			}
		}
		--argc;
		++argv;
	}
	if (pflag && tflag)
		fatal("options -p and -t are mutually exclusive");
	if (symset != NULL && !tflag)
		fatal("-s option requires -t option");

	/* Set up input and output FILEs. */
	if (argc > 1 && (ifp = fopen(argv[1], "rb")) == NULL)
		fatal("cannot open input file \"%s\"", argv[1]);
	else if (argc > 2 && (ofp = fopen(argv[2], "w")) == NULL)
		fatal("cannot open output file \"%s\"", argv[2]);
	else if (argc > 3)
		usage();

	/* Do the work. */
	if (pflag) {
		/* PostScript. */
		inputPS();
		outputPS();
	} else if (tflag) {
		/* TFM. */
		inputTFM();
		outputTFM();
	} else {
		/* PCL. */
		if (argc > 1 && cflag)
			fprintf(ofp,"/* File %s */\n", argv[1]);
		base();
	}

	/* Close FILEs and exit. */
	if (ifp != stdin && fclose(ifp) == EOF)
		fatal("cannot close input file \"%s\"", argv[1]);
	else if (ofp != stdout && fclose(ofp) == EOF)
		fatal("cannot close output file \"%s\"", argv[2]);
	exit(0);
}

/*
 * Allocate size bytes.
 */
char *
alloc(size) register unsigned int size;
{
	register char *s;

	if ((s = malloc(size)) == NULL)
		fatal("out of space");
	return s;
}

void
base()
{
	register int c;

	/* Initialize. */
	for (c = 0 ; c < NWIDTH; c++) {
		char_movement[c] = -1;
		char_datasize[c] = 0;
	}

	/* Read the font description. */
	while ((c = fgetc(ifp)) != EOF) {
		if (c == '\033')
			escape();
		else
			if (c)
				nonfatal("unexpected char (0x%02x)", c);
	}

	/* Dump character table. */
	dump_chartab();
	if (fhp != NULL)
		free(fhp);
}

int
char_code(code) int code;
{
#ifdef	VERBOSE
	if (cflag)
		fprintf(ofp,"Character Code 0x%02x\n", code);
#endif
	this_char = code;
	return code;
}

character_header *
char_def(size) int size;
{
	register character_header *ch;

	ch = alloc(size);
	ch->c_format = getuchar();
	ch->c_continuation = getuchar();
	ch->c_size = getuchar();
	ch->c_class = getuchar();
	ch->c_orientation = getuchar();
	ch->c_empty2 = getuchar();
	ch->c_left_offset = getshort();
	ch->c_top_offset = getshort();
	ch->c_char_width = getshort();
	ch->c_char_height = getshort();
	ch->c_delta_x = getshort();
	if (size > 16)
		getextra(ch->c_data, size-16);
	return ch;
}

/*
 * Dump the character width table.
 */
void
dump_chartab()
{
	register int c, first, last, max, w;
	register long dsize;
	int mult, div, scale;

	/* Find first, last, max values in char_movement[]. */
	for (c = first = last = max = 0; c < NWIDTH; c++) {
		if (char_movement[c] >= 0) {
			if (first == 0)
				first = c;
			if (max < char_movement[c])
				max = char_movement[c];
			last = c;
		} else
			char_movement[c] = 0;
	}

	/*
	 * Calculate multiplier and divisor to convert entries to troff units.
	 * Character deltax is in quarter dots, so movement in troff units is
	 *	deltax * 720 / 1200.
	 * and 720/1200 == 3/5.
	 * troff multiplies by pointsize, this predivides accordingly;
	 * this simplifies scaling.
	 */
	mult = 3;
	div = ipointsz * 5;
	if (max > 255) {
		/* Max deltax is too big to fit in char, scale accordingly. */
		scale = (max / 256) + 1;
		mult *= scale;
		for (c = 0; c < NWIDTH; c++)
			if (char_movement[c] > 0)
				char_movement[c] /= scale;
	}
	/* Reduce if possible. */
	for (w = mult; w > 1; w--) {
		if ((mult % w) == 0 && (div % w) == 0) {
			div /= w;
			mult /= w;
		}
	}
	putshort(mult);				/* short f_num		*/
	putshort(div);				/* short f_den		*/

	/* Dump the movement table. */
	if (cflag) {
		fprintf(ofp,"\t\t/* Movement table: first = %d, last = %d */\n",
			first, last);
		fprintf(ofp,"\t\t{\n");
	}
	dsize = 0L;
	for (w = c = 0; c < NWIDTH; c++) {
		dsize += char_datasize[c];
		if (cflag) {
			if (w == 0)
				fprintf(ofp,"\t\t\t");
			fprintf(ofp,"%3d", char_movement[c]);
			fputc((c < NWIDTH-1) ? ',' : ' ', ofp);
			if (++w > 7) {
				w = 0;
				fprintf(ofp,"\t/* 0x%02x-0x%02x */\n", c-7, c);
			}
		} else
			fputc(char_movement[c], ofp);
	}
	if (cflag) {
		fprintf(ofp,"\t\t}\n");
		fprintf(ofp,"\t/* Size of font data (in bytes): %ld */\n", dsize);
		fprintf(ofp,"\t}\n");
	}
}

#ifdef	VERBOSE
#ifdef	GLYPH
void
dump_glyph(width, height, data) register uchar *data;
{
	register int c, d, f, g;

	width += 7;
	width >>= 3;
	fprintf(ofp,"-----------------------------------\n");
	for (c=0; c<height; c++) {
		for (d=0; d<width; d++) {
			f = *data++;
			for (g = 0; g < 8; g++) {
				if (f & 0x80)
					fprintf(ofp,"*");
				else
					fprintf(ofp,".");
				f <<= 1;
			}
		}
		fprintf(ofp,"\n");
	}
	fprintf(ofp,"-----------------------------------\n");
}
#endif
#endif

/*
 * Process an escape sequence.
 * The <Esc> has already been read.
 */
void
escape()
{
	register int c;

	c = getuchar();
	switch (c) {
	case '*':	escape_star();
			break;
	case '(':	escape_oparen();
			break;
	case ')':	escape_cparen();
			break;
	default:	nonfatal("unknown escape sequence (0x1B 0x%02x ...)", c);
			break;
	}
}

/*
 * Process a font defintition:
 *	<Esc> ) s <#> W	<font header>
 */
void
escape_cparen()
{
	register int c, q;
	register font_extra *fe;
	char *cp;
	double pointsz;

	if ((c = getuchar()) != 's') {
		nonfatal("unknown sequence \\033)%c", c);
		return;
	}
	q = getparm();
	if ((c = getuchar()) != 'W') {
		nonfatal("unknown sequence \\033)s%d%c", q, c);
		return;
	}
	read_header(q);
	/* pointsz is height*72/1200, 72/1200 == 3/50 */
	pointsz = ((double)(3.0*fhp->f_height))/50.0;
	if (cflag) {
		fprintf(ofp, "/*\n * Font Definition:\n");
		fprintf(ofp, " * Header size: %d\n", fhp->f_hsize);
		fprintf(ofp, " * %s bits\n", ((fhp->f_font_type) ? "Eight" : "Seven"));
		fprintf(ofp, " * Orientation: %s\n", orient_tab[fhp->f_orientation]);
		fprintf(ofp, " * Spacing: %s\n", ((fhp->f_spacing) ? "variable" : "fixed"));
		fprintf(ofp, " * Baseline: %d\n", fhp->f_baseline);
		fprintf(ofp, " * Cell width: %d\n", fhp->f_cell_width);
		fprintf(ofp, " * Cell height: %d\n", fhp->f_cell_height);
		fprintf(ofp, " * Pitch: %d\n", fhp->f_pitch);
		fprintf(ofp, " * Height: %d\n", fhp->f_height);
		fprintf(ofp, " * Weight: %d\n", fhp->f_weight);
		fprintf(ofp, " * Style: %s\n", posture_tab[(fhp->f_style)%4]);
		fprintf(ofp, " * Typeface: %s\n", faces[fhp->f_face]);
		fprintf(ofp, " * Designator: %d%c\n",
			fhp->f_symbol_set / 32,
			fhp->f_symbol_set % 32 + 64);
	}
	if (fhp->f_hsize > 26) {
		fe = fhp->f_comment;
		pointsz += ((double) fe->a_poextend)/4275.0;
		if (fe->a_serif > NSERIFS)
			fe->a_serif = NSERIFS;
		if (cflag) {
			fprintf(ofp, " * Slant: %d\n", fe->a_slant);
			fprintf(ofp, " * %s\n", serif_tab[fe->a_serif]);
			fprintf(ofp, " * Quality: %d\n", fe->a_quality);
			fprintf(ofp, " * First: 0x%02x\n", fe->a_firstc);
			fprintf(ofp, " * Last: 0x%02x\n", fe->a_lastc);
			fprintf(ofp, " * Underline pos: %d\n", fe->a_underline);
			fprintf(ofp, " * Height: %d\n", fe->a_uheight);
			fprintf(ofp, " * Line spacing: %u\n", fe->a_lspacing);
			fprintf(ofp, " * Nominal width: %u\n", fe->a_nwidth);
			fprintf(ofp, " * Pitch extend: %d\n", fe->a_piextend);
			fprintf(ofp, " * Height extend: %d\n", fe->a_poextend);
			fprintf(ofp, " * Font number: %ld\n", fe->a_fontnum);
			fprintf(ofp, " * Font name: %16s\n", fe->a_fontname);
		}
	}
	if (cflag && q > fhp->f_hsize) {
		register uchar *sp, *ep;
		register int c;

		c = 0;
		sp = (char *)fhp;
		ep = sp + q;
		sp += fhp->f_hsize;
		while (sp < ep) {
			if (c == 0)
				fprintf(ofp," # ");
			if (*sp >= 0x20 && *sp < 0x7F)
				fprintf(ofp,"%c", *sp++);
			else {
				fprintf(ofp,"\\x%02x", *sp++);
				c += 3;
			}
			if (++c > 72) {
				c = 0;
				fprintf(ofp," #\n");
			}
		}
	}
	ipointsz = (int)(pointsz*10+.5);	/* integer pointsize */
	if (cflag)
		fprintf(ofp,"\n */\n");

	/* Build a descriptive name. */
	sprintf(buf, "%s %.2f point ", faces[fhp->f_face], pointsz);
	cp = &buf[strlen(buf)];
	if (fhp->f_weight == 3)
		strcpy(cp, "bold ");
	else if (fhp->f_weight != 0)
		sprintf(cp, "%d weight ", fhp->f_weight);
	cp = &buf[strlen(buf)];
	if (fhp->f_style%4 != 0)
		sprintf(cp, "%s ", posture_tab[(fhp->f_style)%4]);
	if (fhp->f_orientation != 0)
		strcat(cp, orient_tab[fhp->f_orientation]);
	if (vflag)
		fprintf(stderr,"\t%s\n", buf);
	if (cflag)
		fprintf(ofp, "\t{\n\t\t\"%s\",\n", buf);
	else
		putstring(buf);			/* char *f_descr	*/

	if (cflag)
		fprintf(ofp, "\t\t\"\",\t/* PostScript name */\n");
	else
		putstring("");			/* char *f_PSname	*/

	/* Font parameters. */
	putshort(FLAG_PCL);			/* flags */
	putshort(fhp->f_font_type);
	putshort(fhp->f_orientation);
	putshort(fhp->f_spacing);
	putshort(fhp->f_symbol_set);
	putshort(fhp->f_pitch);
	putshort(ipointsz);
	putshort(fhp->f_style);
	putshort(fhp->f_weight);
	putshort(fhp->f_face);
}

/*
 * Process a character definition:
 *	<Esc> ( s <#> W <char data>
 */
void
escape_oparen()
{
	register int c;
	register int q;
	register character_header *ch;

	if ((c = getuchar()) != 's') {
		nonfatal("unknown sequence \\033(%c", c);
		return;
	}
	q = getparm();
	if ((c = getuchar()) != 'W') {
		nonfatal("unknown sequence \\033(s%d%c", q, c);
		return;
	}
	ch = char_def(q);

#ifdef	VERBOSE
	fprintf(ofp,"** %s, left off=%d, top off=%d char width=%d, char height=%d\n",
		orient_tab[ch->c_orientation],
		ch->c_left_offset, ch->c_top_offset,
		ch->c_char_width, ch->c_char_height);
	fprintf(ofp,"**  movement=%d (%d), data length = %d\n",
		ch->c_delta_x, ch->c_delta_x/4, q-16);
#ifdef	GLYPH
	dump_glyph(ch->c_char_width, ch->c_char_height, ch->c_data);
#endif
#endif
	char_movement[this_char] = ch->c_delta_x;
	char_datasize[this_char] = q-16;

	free(ch);
}

/*
 * Process a font id:
 *	<Esc> * c <#> D
 * or a character code:
 *	<Esc> * c <#> E
 */
void
escape_star()
{
	register int c, q;

	c = getuchar();
	if (c != 'c') {
		nonfatal("unknown escape sequence (0x1B 0x%02x 0x%02x ...)",
			'*', c);
		return;
	}
	q = getparm();
	c = getuchar();
	if (c == 'D')
		nonfatal("Font ID %d", q);
	else if (c == 'E')
		char_code(q);
	else
		nonfatal("unknown sequence \\033*c%d%c", q, c);
}

/* VARARGS */
void
fatal(args) char *args;
{
	fprintf(stderr, "fwtable: ");
	if (lineno != 0)
		fprintf(stderr, "%d: ", lineno);
	fprintf(stderr, "%r\n", &args);
	exit(1);
}

/*
 * Read size bytes into the supplied buffer.
 */
void
getextra(bp, size) register uchar *bp; register int size;
{
	while (size-- > 0)
		*bp++ = getuchar();
}

/*
 * Read a numeric parameter and return it.
 */
int
getparm()
{
	register int a, c;

	for (a = 0; (c = getuchar()) >= '0' && c <= '9'; ) {
		a *= 10;
		a += c - '0';
	}
	ungetc(c, ifp);
	return a;
}

/*
 * Read a short and return it.
 * The byte order is the opposite of the in-memory i8086 order.
 */
short
getshort()
{
	register int s;

	s = getuchar() << 8;
	return s | getuchar();
}

/*
 * Read an unsigned char and return it.
 */
unsigned int
getuchar()
{
	register int c;

	if ((c = fgetc(ifp)) == EOF)
		fatal("unexpected end of file");
	return (c & 0xFF);
}

/* VARARGS */
void
nonfatal(args) char *args;
{
	fprintf(stderr, "fwtable: %ld: %r\n", ftell(ifp), &args);
}

/*
 * Write count bytes from buf.
 */
void
ofpwrite(buf, count) register char *buf; register unsigned int count;
{
	if (fwrite(buf, count, 1, ofp) != 1)
		fatal("write error");
}

/*
 * Write a canonical short.
 */
void
putshort(i) int i;
{
	short s;

	if (cflag)
		fprintf(ofp, "\t\t%d,\n", i);
	else {
		s = (short)i;
		canshort(s);
		ofpwrite(&s, sizeof s);
	}
}

/*
 * Write a NUL-terminated string.
 */
void
putstring(s) register char *s;
{
	fputs(s, ofp);
	fputc('\0', ofp);
}

/*
 * Read a PCL font header.
 */
void
read_header(size) register int size;
{
	register int c;

	if (fhp != NULL)
		fatal("multiple font headers");
	fhp = alloc(size);
	fhp->f_hsize = getshort();
	fhp->f_desc_format = getuchar();
	if (fhp->f_desc_format == 10)
		fatal("Intellifont scalable fonts not yet supported");
	fhp->f_font_type = getuchar();
	fhp->f_style_msb = getuchar();
	fhp->f_reserved1 = getuchar();
	fhp->f_baseline = getshort();
	fhp->f_cell_width = getshort();
	fhp->f_cell_height = getshort();
	fhp->f_orientation = getuchar();
	fhp->f_spacing = getuchar();
	fhp->f_symbol_set = getshort();
	fhp->f_pitch = getshort();
	fhp->f_height = getshort();
	fhp->f_xheight = getshort();
	fhp->f_width_type = getuchar();
	fhp->f_style = getuchar();
	fhp->f_weight = getuchar();
	fhp->f_face = getuchar();
	if (fhp->f_face > NFACES) {
		/* Use extra entry at end of table. */
		sprintf(faces[NFACES], "[Typeface %3d]", fhp->f_face);
		fhp->f_face = NFACES;
	}
	if (size > 26)
		getextra(fhp->f_comment, size-26);
	/*
	 * Many of the fonts at MWC have a bogus extra ' ' after the font header.
	 * Eat the space silently rather than complaining about unexpected char.
	 */
	if ((c = fgetc(ifp)) != ' ')
		ungetc(c, ifp);
}

void
usage()
{
	fprintf(stderr,
		"Usage: fwtable [ -cptv ] [ -ssymset ] [ infile [ outfile ] ]\n"
		"Options:\n"
		"\t-c\t\tWrite C instead of binary\n"
		"\t-p\t\tInput is PostScript AFM file\n"
		"\t-ssymset\tSpecify desired symbol set with -t option\n"
		"\t-t\t\tInput is HP TFM file\n"
		"\t-v\t\tWrite one-line font description to stderr\n"
		);
	exit(1);
}

/* end of fwtable.c */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.