rsalz@bbn.com (Rich Salz) (09/15/88)
Submitted-by: papowell@julius.cs.umn.edu Posting-number: Volume 16, Issue 23 Archive-name: plp/part10 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 10 (of 16)." # Contents: src/chartable.c src/pac.c utilities/cpr/cpr.c PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'src/chartable.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/chartable.c'\" else echo shar: Extracting \"'src/chartable.c'\" \(14924 characters\) sed "s/^X//" >'src/chartable.c' <<'END_OF_FILE' X/*************************************************************************** X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell X *************************************************************************** X * MODULE: chartable.c X * raster character representations X * Fixed width, X *************************************************************************** X * Revision History: Created deep in the bowels of history. X * $Log: chartable.c,v $ X * Revision 3.1 88/06/18 09:33:53 papowell X * Version 3.0- Distributed Sat Jun 18 1988 X * X * Revision 2.1 88/05/09 10:07:37 papowell X * PLP: Released Version X * X * Revision 1.1 88/03/01 11:08:14 papowell X * Initial revision X * X * Stolen by everybody. X * Fri Jan 15 13:53:37 CST 1988 X ***************************************************************************/ X#ifndef lint static char id_str1[] = X "$Header: chartable.c,v 3.1 88/06/18 09:33:53 papowell Exp $ PLP Copyright 1988 Patrick Powell"; X#endif lint X X#define c_______ 0 X#define c______1 01 X#define c_____1_ 02 X#define c____1__ 04 X#define c____11_ 06 X#define c___1___ 010 X#define c___1__1 011 X#define c___1_1_ 012 X#define c___11__ 014 X#define c__1____ 020 X#define c__1__1_ 022 X#define c__1_1__ 024 X#define c__11___ 030 X#define c__111__ 034 X#define c__111_1 035 X#define c__1111_ 036 X#define c__11111 037 X#define c_1_____ 040 X#define c_1____1 041 X#define c_1___1_ 042 X#define c_1__1__ 044 X#define c_1_1___ 050 X#define c_1_1__1 051 X#define c_1_1_1_ 052 X#define c_11____ 060 X#define c_11_11_ 066 X#define c_111___ 070 X#define c_111__1 071 X#define c_111_1_ 072 X#define c_1111__ 074 X#define c_1111_1 075 X#define c_11111_ 076 X#define c_111111 077 X#define c1______ 0100 X#define c1_____1 0101 X#define c1____1_ 0102 X#define c1____11 0103 X#define c1___1__ 0104 X#define c1___1_1 0105 X#define c1___11_ 0106 X#define c1__1___ 0110 X#define c1__1__1 0111 X#define c1__11_1 0115 X#define c1__1111 0117 X#define c1_1____ 0120 X#define c1_1___1 0121 X#define c1_1_1_1 0125 X#define c1_1_11_ 0126 X#define c1_111__ 0134 X#define c1_1111_ 0136 X#define c11____1 0141 X#define c11___1_ 0142 X#define c11___11 0143 X#define c11_1___ 0150 X#define c11_1__1 0151 X#define c111_11_ 0166 X#define c1111___ 0170 X#define c11111__ 0174 X#define c111111_ 0176 X#define c1111111 0177 X char chartab[][HEIGHT] = /* this is relatively easy to modify */ X /* just look: */ X{ X { c_______, X c_______, X c_______, X c_______, X c_______, X c_______, X c_______, X c_______, X c_______ }, /* */ X X { c__11___, X c__11___, X c__11___, X c__11___, X c__11___, X c_______, X c_______, X c__11___, X c__11___ }, /* ! */ X X { c_1__1__, X c_1__1__, X c_______, X c_______, X c_______, X c_______, X c_______, X c_______, X c_______ }, /* " */ X X { c_______, X c__1_1__, X c__1_1__, X c1111111, X c__1_1__, X c1111111, X c__1_1__, X c__1_1__, X c_______ }, /* # */ X X { c___1___, X c_11111_, X c1__1__1, X c1__1___, X c_11111_, X c___1__1, X c1__1__1, X c_11111_, X c___1___ }, /* $ */ X X { c_1_____, X c1_1___1, X c_1___1_, X c____1__, X c___1___, X c__1____, X c_1___1_, X c1___1_1, X c_____1_ }, /* % */ X X { c_11____, X c1__1___, X c1___1__, X c_1_1___, X c__1____, X c_1_1__1, X c1___11_, X c1___11_, X c_111__1 }, /* & */ X X { c___11__, X c___11__, X c___1___, X c__1____, X c_______, X c_______, X c_______, X c_______, X c_______ }, /* ' */ X X { c____1__, X c___1___, X c__1____, X c__1____, X c__1____, X c__1____, X c__1____, X c___1___, X c____1__ }, /* ( */ X X { c__1____, X c___1___, X c____1__, X c____1__, X c____1__, X c____1__, X c____1__, X c___1___, X c__1____ }, /* ) */ X X { c_______, X c___1___, X c1__1__1, X c_1_1_1_, X c__111__, X c_1_1_1_, X c1__1__1, X c___1___, X c_______ }, /* * */ X X { c_______, X c___1___, X c___1___, X c___1___, X c1111111, X c___1___, X c___1___, X c___1___, X c_______ }, /* + */ X X { c_______, X c_______, X c_______, X c_______, X c__11___, X c__11___, X c__1____, X c_1_____, X c_______ }, /* , */ X X { c_______, X c_______, X c_______, X c_______, X c1111111, X c_______, X c_______, X c_______, X c_______ }, /* - */ X X { c_______, X c_______, X c_______, X c_______, X c_______, X c_______, X c_______, X c__11___, X c__11___ }, /* . */ X X { c_______, X c______1, X c_____1_, X c____1__, X c___1___, X c__1____, X c_1_____, X c1______, X c_______ }, /* / */ X X { c_11111_, X c1_____1, X c1____11, X c1___1_1, X c1__1__1, X c1_1___1, X c11____1, X c1_____1, X c_11111_ }, /* 0 */ X X { c___1___, X c__11___, X c_1_1___, X c___1___, X c___1___, X c___1___, X c___1___, X c___1___, X c_11111_ }, /* 1 */ X X { c_11111_, X c1_____1, X c______1, X c_____1_, X c__111__, X c_1_____, X c1______, X c1______, X c1111111 }, /* 2 */ X X { c_11111_, X c1_____1, X c______1, X c______1, X c__1111_, X c______1, X c______1, X c1_____1, X c_11111_ }, /* 3 */ X X { c_____1_, X c____11_, X c___1_1_, X c__1__1_, X c_1___1_, X c1____1_, X c1111111, X c_____1_, X c_____1_ }, /* 4 */ X X { c1111111, X c1______, X c1______, X c11111__, X c_____1_, X c______1, X c______1, X c1____1_, X c_1111__ }, /* 5 */ X X { c__1111_, X c_1_____, X c1______, X c1______, X c1_1111_, X c11____1, X c1_____1, X c1_____1, X c_11111_ }, /* 6 */ X X { c1111111, X c1_____1, X c_____1_, X c____1__, X c___1___, X c__1____, X c__1____, X c__1____, X c__1____ }, /* 7 */ X X { c_11111_, X c1_____1, X c1_____1, X c1_____1, X c_11111_, X c1_____1, X c1_____1, X c1_____1, X c_11111_ }, /* 8 */ X X { c_11111_, X c1_____1, X c1_____1, X c1_____1, X c_111111, X c______1, X c______1, X c1_____1, X c_1111__ }, /* 9 */ X X { c_______, X c_______, X c_______, X c__11___, X c__11___, X c_______, X c_______, X c__11___, X c__11___ }, /* : */ X X X { c__11___, X c__11___, X c_______, X c_______, X c__11___, X c__11___, X c__1____, X c_1_____, X c_______ }, /* ; */ X X { c____1__, X c___1___, X c__1____, X c_1_____, X c1______, X c_1_____, X c__1____, X c___1___, X c____1__ }, /* < */ X X { c_______, X c_______, X c_______, X c1111111, X c_______, X c1111111, X c_______, X c_______, X c_______ }, /* = */ X X { c__1____, X c___1___, X c____1__, X c_____1_, X c______1, X c_____1_, X c____1__, X c___1___, X c__1____ }, /* > */ X X { c__1111_, X c_1____1, X c_1____1, X c______1, X c____11_, X c___1___, X c___1___, X c_______, X c___1___ }, /* ? */ X X { c__1111_, X c_1____1, X c1__11_1, X c1_1_1_1, X c1_1_1_1, X c1_1111_, X c1______, X c_1____1, X c__1111_ }, /* @ */ X X { c__111__, X c_1___1_, X c1_____1, X c1_____1, X c1111111, X c1_____1, X c1_____1, X c1_____1, X c1_____1 }, /* A */ X X { c111111_, X c_1____1, X c_1____1, X c_1____1, X c_11111_, X c_1____1, X c_1____1, X c_1____1, X c111111_ }, /* B */ X X { c__1111_, X c_1____1, X c1______, X c1______, X c1______, X c1______, X c1______, X c_1____1, X c__1111_ }, /* C */ X X { c11111__, X c_1___1_, X c_1____1, X c_1____1, X c_1____1, X c_1____1, X c_1____1, X c_1___1_, X c11111__ }, /* D */ X X { c1111111, X c1______, X c1______, X c1______, X c111111_, X c1______, X c1______, X c1______, X c1111111 }, /* E */ X X { c1111111, X c1______, X c1______, X c1______, X c111111_, X c1______, X c1______, X c1______, X c1______ }, /* F */ X X { c__1111_, X c_1____1, X c1______, X c1______, X c1______, X c1__1111, X c1_____1, X c_1____1, X c__1111_ }, /* G */ X X { c1_____1, X c1_____1, X c1_____1, X c1_____1, X c1111111, X c1_____1, X c1_____1, X c1_____1, X c1_____1 }, /* H */ X X { c_11111_, X c___1___, X c___1___, X c___1___, X c___1___, X c___1___, X c___1___, X c___1___, X c_11111_ }, /* I */ X X { c__11111, X c____1__, X c____1__, X c____1__, X c____1__, X c____1__, X c____1__, X c1___1__, X c_111___ }, /* J */ X X { c1_____1, X c1____1_, X c1___1__, X c1__1___, X c1_1____, X c11_1___, X c1___1__, X c1____1_, X c1_____1 }, /* K */ X X { c1______, X c1______, X c1______, X c1______, X c1______, X c1______, X c1______, X c1______, X c1111111 }, /* L */ X X { c1_____1, X c11___11, X c1_1_1_1, X c1__1__1, X c1_____1, X c1_____1, X c1_____1, X c1_____1, X c1_____1 }, /* M */ X X { c1_____1, X c11____1, X c1_1___1, X c1__1__1, X c1___1_1, X c1____11, X c1_____1, X c1_____1, X c1_____1 }, /* N */ X X { c__111__, X c_1___1_, X c1_____1, X c1_____1, X c1_____1, X c1_____1, X c1_____1, X c_1___1_, X c__111__ }, /* O */ X X { c111111_, X c1_____1, X c1_____1, X c1_____1, X c111111_, X c1______, X c1______, X c1______, X c1______ }, /* P */ X X { c__111__, X c_1___1_, X c1_____1, X c1_____1, X c1_____1, X c1__1__1, X c1___1_1, X c_1___1_, X c__111_1 }, /* Q */ X X { c111111_, X c1_____1, X c1_____1, X c1_____1, X c111111_, X c1__1___, X c1___1__, X c1____1_, X c1_____1 }, /* R */ X X { c_11111_, X c1_____1, X c1______, X c1______, X c_11111_, X c______1, X c______1, X c1_____1, X c_11111_ }, /* S */ X X { c1111111, X c___1___, X c___1___, X c___1___, X c___1___, X c___1___, X c___1___, X c___1___, X c___1___ }, /* T */ X X { c1_____1, X c1_____1, X c1_____1, X c1_____1, X c1_____1, X c1_____1, X c1_____1, X c1_____1, X c_11111_ }, /* U */ X X { c1_____1, X c1_____1, X c1_____1, X c_1___1_, X c_1___1_, X c__1_1__, X c__1_1__, X c___1___, X c___1___ }, /* V */ X X { c1_____1, X c1_____1, X c1_____1, X c1_____1, X c1__1__1, X c1__1__1, X c1_1_1_1, X c11___11, X c1_____1 }, /* W */ X X { c1_____1, X c1_____1, X c_1___1_, X c__1_1__, X c___1___, X c__1_1__, X c_1___1_, X c1_____1, X c1_____1 }, /* X */ X X { c1_____1, X c1_____1, X c_1___1_, X c__1_1__, X c___1___, X c___1___, X c___1___, X c___1___, X c___1___ }, /* Y */ X X { c1111111, X c______1, X c_____1_, X c____1__, X c___1___, X c__1____, X c_1_____, X c1______, X c1111111 }, /* Z */ X X { c_1111__, X c_1_____, X c_1_____, X c_1_____, X c_1_____, X c_1_____, X c_1_____, X c_1_____, X c_1111__ }, /* [ */ X X { c_______, X c1______, X c_1_____, X c__1____, X c___1___, X c____1__, X c_____1_, X c______1, X c_______ }, /* \ */ X X { c__1111_, X c_____1_, X c_____1_, X c_____1_, X c_____1_, X c_____1_, X c_____1_, X c_____1_, X c__1111_ }, /* ] */ X X { c___1___, X c__1_1__, X c_1___1_, X c1_____1, X c_______, X c_______, X c_______, X c_______ }, /* ^ */ X X { c_______, X c_______, X c_______, X c_______, X c_______, X c_______, X c_______, X c1111111, X c_______ }, /* _ */ X X { c__11___, X c__11___, X c___1___, X c____1__, X c_______, X c_______, X c_______, X c_______, X c_______ }, /* ` */ X X { c_______, X c_______, X c_______, X c_1111__, X c_____1_, X c_11111_, X c1_____1, X c1____11, X c_1111_1 }, /* a */ X X { c1______, X c1______, X c1______, X c1_111__, X c11___1_, X c1_____1, X c1_____1, X c11___1_, X c1_111__ }, /* b */ X X { c_______, X c_______, X c_______, X c_1111__, X c1____1_, X c1______, X c1______, X c1____1_, X c_1111__ }, /* c */ X X { c_____1_, X c_____1_, X c_____1_, X c_111_1_, X c1___11_, X c1____1_, X c1____1_, X c1___11_, X c_111_1_ }, /* d */ X X { c_______, X c_______, X c_______, X c_1111__, X c1____1_, X c111111_, X c1______, X c1____1_, X c_1111__ }, /* e */ X X { c___11__, X c__1__1_, X c__1____, X c__1____, X c11111__, X c__1____, X c__1____, X c__1____, X c__1____ }, /* f */ X X { c_111_1_, X c1___11_, X c1____1_, X c1____1_, X c1___11_, X c_111_1_, X c_____1_, X c1____1_, X c_1111__ }, /* g */ X X { c1______, X c1______, X c1______, X c1_111__, X c11___1_, X c1____1_, X c1____1_, X c1____1_, X c1____1_ }, /* h */ X X { c_______, X c___1___, X c_______, X c__11___, X c___1___, X c___1___, X c___1___, X c___1___, X c__111__ }, /* i */ X X { c____11_, X c_____1_, X c_____1_, X c_____1_, X c_____1_, X c_____1_, X c_____1_, X c_1___1_, X c__111__ }, /* j */ X X { c1______, X c1______, X c1______, X c1___1__, X c1__1___, X c1_1____, X c11_1___, X c1___1__, X c1____1_ }, /* k */ X X { c__11___, X c___1___, X c___1___, X c___1___, X c___1___, X c___1___, X c___1___, X c___1___, X c__111__ }, /* l */ X X { c_______, X c_______, X c_______, X c1_1_11_, X c11_1__1, X c1__1__1, X c1__1__1, X c1__1__1, X c1__1__1 }, /* m */ X X { c_______, X c_______, X c_______, X c1_111__, X c11___1_, X c1____1_, X c1____1_, X c1____1_, X c1____1_ }, /* n */ X X { c_______, X c_______, X c_______, X c_1111__, X c1____1_, X c1____1_, X c1____1_, X c1____1_, X c_1111__ }, /* o */ X X { c1_111__, X c11___1_, X c1____1_, X c1____1_, X c11___1_, X c1_111__, X c1______, X c1______, X c1______ }, /* p */ X X { c_111_1_, X c1___11_, X c1____1_, X c1____1_, X c1___11_, X c_111_1_, X c_____1_, X c_____1_, X c_____1_ }, /* q */ X X { c_______, X c_______, X c_______, X c1_111__, X c11___1_, X c1______, X c1______, X c1______, X c1______ }, /* r */ X X { c_______, X c_______, X c_______, X c_1111__, X c1____1_, X c_11____, X c___11__, X c1____1_, X c_1111__ }, /* s */ X X { c_______, X c__1____, X c__1____, X c11111__, X c__1____, X c__1____, X c__1____, X c__1__1_, X c___11__ }, /* t */ X X { c_______, X c_______, X c_______, X c1____1_, X c1____1_, X c1____1_, X c1____1_, X c1___11_, X c_111_1_ }, /* u */ X X { c_______, X c_______, X c_______, X c1_____1, X c1_____1, X c1_____1, X c_1___1_, X c__1_1__, X c___1___ }, /* v */ X X { c_______, X c_______, X c_______, X c1_____1, X c1__1__1, X c1__1__1, X c1__1__1, X c1__1__1, X c_11_11_ }, /* w */ X X { c_______, X c_______, X c_______, X c1____1_, X c_1__1__, X c__11___, X c__11___, X c_1__1__, X c1____1_ }, /* x */ X X { c1____1_, X c1____1_, X c1____1_, X c1____1_, X c1___11_, X c_111_1_, X c_____1_, X c1____1_, X c_1111__ }, /* y */ X X { c_______, X c_______, X c_______, X c111111_, X c____1__, X c___1___, X c__1____, X c_1_____, X c111111_ }, /* z */ X X { c___11__, X c__1____, X c__1____, X c__1____, X c_1_____, X c__1____, X c__1____, X c__1____, X c___11__ }, /* } */ X X { c___1___, X c___1___, X c___1___, X c___1___, X c___1___, X c___1___, X c___1___, X c___1___, X c___1___ }, /* | */ X X { c__11___, X c____1__, X c____1__, X c____1__, X c_____1_, X c____1__, X c____1__, X c____1__, X c__11___ }, /* } */ X X { c_11____, X c1__1__1, X c____11_, X c_______, X c_______, X c_______, X c_______, X c_______, X c_______ }, /* ~ */ X X { c_1__1__, X c1__1__1, X c__1__1_, X c_1__1__, X c1__1__1, X c__1__1_, X c_1__1__, X c1__1__1, X c__1__1_ } /* rub-out */ X}; END_OF_FILE if test 14924 -ne `wc -c <'src/chartable.c'`; then echo shar: \"'src/chartable.c'\" unpacked with wrong size! fi # end of 'src/chartable.c' fi if test -f 'src/pac.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/pac.c'\" else echo shar: Extracting \"'src/pac.c'\" \(15473 characters\) sed "s/^X//" >'src/pac.c' <<'END_OF_FILE' X/*************************************************************************** X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell X *************************************************************************** X * MODULE: pac.c X * Accounting Summary X *************************************************************************** X * Revision History: Created Thu Feb 4 15:39:38 CST 1988 X * $Log: pac.c,v $ X * Revision 3.1 88/06/18 09:35:14 papowell X * Version 3.0- Distributed Sat Jun 18 1988 X * X * Revision 2.2 88/05/14 10:20:47 papowell X * Modified -X flag handling X * X * Revision 2.1 88/05/09 10:09:39 papowell X * PLP: Released Version X * X * Revision 1.6 88/05/05 20:07:32 papowell X * Minor changes to shut up lint. X * X * Revision 1.5 88/04/15 13:06:00 papowell X * Std_environ() call added, to ensure that fd 0 (stdin), 1 (stdout), 2(stderr) X * have valid file descriptors; if not open, then /dev/null is used. X * X * Revision 1.4 88/04/07 09:11:50 papowell X * Removed redundant break; strangely, lint did not pick this up X * X * Revision 1.3 88/03/25 15:00:57 papowell X * Debugged Version: X * 1. Added the PLP control file first transfer X * 2. Checks for MX during file transfers X * 3. Found and fixed a mysterious bug involving the SYSLOG facilities; X * apparently they open files and then assume that they will stay X * open. X * 4. Made sure that stdin, stdout, stderr was available at all times. X * X * Revision 1.2 88/03/11 19:28:52 papowell X * Minor Changes, Updates X * X * Revision 1.1 88/03/01 11:08:58 papowell X * Initial revision X * X ***************************************************************************/ X X#ifndef lint static char id_str1[] = X "$Header: pac.c,v 3.1 88/06/18 09:35:14 papowell Exp $ PLP Copyright 1988 Patrick Powell"; X#endif lint X#include "lp.h" X/*************************************************************************** X * pac - printer/ploter accounting information X * SYNOPSIS X * pac [ -Pprinter ] [ -pprice ] [ -a ] [ -e ] [ -s ] X * DESCRIPTION X * Pac reads the printer/plotter accounting files, accumulating X * the number of pages (the usual case) or feet (for raster X * devices) of paper consumed by each user, and printing out X * how much each user consumed in pages or feet and dollars. X * -Pprinter X * Selects the printer. If not specified, the value of X * the environment variable PRINTER is used, and if it is X * not defined, the default printer for the site. X * -pprice X * The price per page to be used, instead of the printcap X * co (cost) entry. If none is specified, the default X * price of $0.02 per page is used. X * -a Accounting is done for all printers. A cumulative sum- X * mary of usage of all the entries will be printed. X * -e Accounting is done for each printer entry in turn. X * -s Summarize the accounting information in the summary X * accounting file. Used with the -a or -e flag all the X * accounting information for each printer can be done at X * once. This option has the side effect of truncating X * the original file. It copies the original file to a X * backup before doing any action. X * The accounting file is specified in the printcap af entry. X * The summary accounting file has the .sum suffix added. X * FILES X * printcap af entry X * NOTES X * The accounting information is generated by the various X * filters used by the LPD daemon. For each user file they X * should write a line to the accounting file in the following X * format. X * user host printer pages format date X * papowell umn-cs 10 C April 13 1988 X * The summary file will produce entries of the form: X * user host printer pages format runs cost X * papowell umn-cs 1320 17 32.00 X ***************************************************************************/ int All; /* do for all printers */ int Each; /* do for each printer */ int Summary; /* do a summary for each printer */ int Xpert; int Page_price; /* cost per page to be used */ float pagecost = 0.0; /* cost per page (or what ever) */ X X/* X * Hash Table X * Each user has his own entry X */ X X#define HASHSIZE 97 /* Number of hash buckets */ X struct entry { X struct entry *next; /* Forward hash link */ X char user[32]; /* user name */ X char host[32]; /* host name */ X char printer[32]; /* host name */ X long pages; /* Feet or pages of paper */ X char format[32]; /* format */ X long runs; /* Number of runs */ X float price; /* cost for this */ X struct entry *chain; /* list link */ X}; X struct entry *Hash_table[HASHSIZE]; /* Hash table proper */ struct entry *All_user, *Sum_user, *Raw_user; X X main( argc, argv ) X int argc; X char **argv; X{ X char **list; X X /* X * set umask to avoid problems with user umask X */ X (void)umask(0); X /* X * Set fd 0, 1, 2 to /dev/null if not open X */ X Std_environ(); X# ifdef XPERIMENT X Setup_test(); X# endif XPERIMENT X /* X * set up the pathnames for information files X */ X Tailor_names(); X X /* X * process the parameters X */ X Get_parms(argc, argv); X X if( All | Each ){ X for( list = All_printers(); *list; ++list ){ X Printer = *list; X Process(); X } X } else { X Process(); X } X if( All ){ X Sort_file( &All_user ); X Dump_info(All_user, "All"); X } X} X X/*************************************************************************** X * Get_parms() X * get the parameters X ***************************************************************************/ static char *optstr = "D:P:Xaep:s"; Get_parms( argc, argv ) X int argc; X char **argv; X{ X int option; X X while( (option = Getopt(argc,argv,optstr)) != EOF ){ X switch( option ){ X case 'p': X Check_int_dup( option, &Page_price, Optarg ); X break; X case 'D': X Check_int_dup( option, &Debug, Optarg ); X break; X case 'P': X if( Printer ){ X Check_str_dup( option, Printer, Optarg ); X } X Printer = Optarg; X break; X case 'X': X Check_dup( option, &Xpert ); X# ifdef DEBUG X Setup_test(); X Tailor_names(); X# else X Diemsg( "-X not allowed" ); X# endif DEBUG X break; X case 'e': X Check_dup( option, &Each ); X break; X case 'a': X Check_dup( option, &All ); X break; X case 's': X Check_dup( option, &Summary ); X break; X case '?': X break; X default: X fatal(XLOG_INFO, "Get_parms: badparm %c", option ); X } X } X X /* X * set up the Parms[] array X */ X for( ; Optind < argc; ++Optind ){ X if( Parmcount < MAXPARMS ){ X Parms[Parmcount].str = argv[Optind]; X ++Parmcount; X } else { X Diemsg( "too many files to print; break job up" ); X } X } X Get_Printer(0); X /* X * set default format X */ X if( FROMHOST[0] == 0 ){ X (void)strcpy(FROMHOST, Host); X } X if(Debug>4){ X (void)fprintf( stdout, "Printer %s, All %s, Each %s, Summary %s", X Printer, All, Each, Summary ); X } X} X X/*************************************************************************** X * Check_int_dup( int option, int *value, char *arg ) X * 1. check to see if value has been set X * 2. if not, then get integer value from arg X ***************************************************************************/ X Check_int_dup( option, value, arg ) X int option; X int *value; X char *arg; X{ X if( *value ){ X Diemsg( "duplicate option %c", option ); X } X if( sscanf( arg, "%d", value ) != 1 || *value <= 0){ X Diemsg( "option %c parameter (%s) is not positive integer", X option, arg); X } X} X/*************************************************************************** X * Check_str_dup( int option, char *value, char *arg ) X * 1. check to see if value has been set X * 2. if not, then set it X ***************************************************************************/ Check_str_dup( option, value, arg ) X int option; X char *value; X char *arg; X{ X if( *value ){ X Diemsg( "duplicate option %c", option ); X } X if( strlen( arg ) > MAXPARMLEN ){ X Diemsg( "option %c arguement too long (%s)", option, arg ); X } X (void)strcpy(value, arg ); X} X/*************************************************************************** X * Check_dup( int option, int *value ) X * 1. check to see if value has been set X * 2. if not, then set it X ***************************************************************************/ Check_dup( option, value ) X int option; X int *value; X{ X if( *value ){ X Diemsg( "duplicate option %c", option ); X } X *value = 1; X} X X X/*************************************************************************** X * Process X * Get the accounting file. X * 1. Read printcap entry. X * 2. Get the accounting file information X * 3. If we are to summarize, read the summyary X * 4. Combine the summary and other file information. X * 5. if we are to summarize, copy the information to the output summary file X * save the original file, and truncate it. X ***************************************************************************/ Process() X{ X char buf[BUFSIZ]; X FILE *fp, *bp, *sp; /* Accounting and summary file */ X X fp = bp = sp = 0; X if(Get_pc_entry(Printer, Status_pc_vars, Status_pc_len) == 0){ X Warnmsg("Printer %s does not exist\n", Printer ); X return; X } X if( SD == 0 || *SD == 0 ){ X if(Debug>2)log(XLOG_DEBUG,"not a Printer"); X return; X } X /* chdir to spool directory */ X if (chdir(SD) < 0) { X logerr_die( XLOG_NOTICE,"cannot chdir to %s", SD); X } X if( AF == 0 || *AF == 0 ){ X Warnmsg("Printer %s does not have accounting file", Printer ); X return; X } X if( (fp = fopen( AF, "r+" )) == 0 ){ X Warnmsg("Printer %s does not have accounting file", Printer ); X return; X } X (void)strcpy(buf, AF ); X (void)strcat(buf, ".bac" ); X if( (bp = fopen( buf, "w" )) == NULL ){ X logerr_die( XLOG_NOTICE,"cannot open backup file %s", buf); X } X if( Summary ){ X (void)strcpy(buf, AF ); X (void)strcat(buf, ".sum" ); X if( (sp = fopen( buf, "r+" )) == NULL ){ X logerr_die( XLOG_NOTICE,"cannot open summary file %s", buf); X } X } X Get_raw_file(fp,bp); X if( Summary ){ X Get_summary(sp); X Merge_raw_sum(); X Sort_file( &Sum_user ); X Update_sum(sp); X if( Each ){ X Dump_info( Sum_user, Printer ); X } X } else if( !All ){ X Dump_info( Raw_user, Printer ); X } X if( All ){ X Merge_raw_all(); X } X if( Sum_user ){ X Free_entry( Sum_user ); X Sum_user = 0; X } X Free_entry( Raw_user ); X Raw_user = 0; X if( sp ){ X (void)fclose(sp); X } X if( bp ){ X (void)fclose(bp); X } X if( fp ){ X (void)fclose(fp); X } X} X cleanup() X{ X exit(1); X} X/* X * Get_raw_file() X * read and copy the raw accounting file into the backup, X * set up the Raw information X */ X Get_raw_file(f, b) X FILE *f, *b; X{ X char buf[BUFSIZ]; X char user[BUFSIZ]; X char host[BUFSIZ]; X char printer[BUFSIZ]; X char format[BUFSIZ]; X int pages; X int i; X struct entry *p, *Add_entry(); X Raw_user = 0; X X Clean_hash(); X X while( fgets(buf, sizeof(buf), f ) ){ X (void)fputs(buf, b); X /* break out the fields */ X i = sscanf(buf,"%s %s %s %d %s\n",user,host,printer,&pages,format); X if( i < 4 || strlen(user) > 32 || strlen(host)>32 X || pages < 0 || strlen(format)>32){ X Warnmsg( "bad format of accounting information: %s\n", buf ); X } X p = Add_entry( &Raw_user, user, host, printer, format ); X p->pages += pages; X p->runs += 1; X } X} X/* X * Get_summary() X * read and copy the raw accounting file into the backup, X * set up the Raw information X */ X Get_summary(f) X FILE *f; X{ X char buf[BUFSIZ]; X char user[BUFSIZ]; X char host[BUFSIZ]; X char printer[BUFSIZ]; X char format[BUFSIZ]; X int pages; X int jobs; X int i; X struct entry *p, *Add_entry(); X X Sum_user = 0; X X Clean_hash(); X X while( fgets(buf, sizeof(buf), f ) ){ X /* break out the fields */ X i = sscanf(buf,"%s %s %s %d %s %d\n", X user,host,printer,&pages,format,&jobs); X if( i < 4 || strlen(user) > 32 || strlen(host)>32 X || pages < 0 || strlen(format)>32){ X Warnmsg( "bad format of accounting information: %s\n", buf ); X } X p = Add_entry( &Sum_user, user, host, printer, format ); X p->pages += pages; X p->runs += jobs; X } X} X Clean_hash() X{ X int i; X for(i = 0; i < HASHSIZE; ++i ){ X Hash_table[i] = 0; X } X} X int Hash( s ) X char *s; X{ X int i; X X i = s[1]*3 + s[0] + s[strlen(s) -1 ]*7; X return( i % HASHSIZE ); X} X struct entry * XFind_entry( user, host, printer, format ) X char *user, *host, *printer, *format; X{ X struct entry *p; X int i; X X i = Hash( user ); X X p = Hash_table[i]; X X while( p ){ X if( strcmp(user, p->user ) == 0 X && strcmp(host, p->host ) == 0 X && strcmp(printer, p->printer ) == 0 X && strcmp(format, p->format ) == 0 ){ X return(p); X } X p = p->next; X } X return( p ); X} X static struct entry *entry_list; X#define NENTRY 25 X struct entry * Make_entry( list, user, host, printer, format ) X struct entry **list; X char *user, *host, *printer, *format; X{ X struct entry *p; X static struct entry blank; /* all zeros */ X int i; X X if( entry_list == 0 ){ X p = entry_list = X (struct entry *)malloc( sizeof(struct entry) * NENTRY ); X for( i = 0; i < (NENTRY - 1); ++i ){ X p[i].next = &p[i+1]; X } X p[i].next = 0; X } X p = entry_list; X entry_list = p->next; X X *p = blank; X p->next = 0; X p->chain = 0; X X i = Hash( user ); X p->next = Hash_table[i]; X Hash_table[i] = p; X (void)strcpy( p->user, user ); X (void)strcpy( p->host, host ); X (void)strcpy( p->printer, printer ); X (void)strcpy( p->format, format ); X p->chain = *list; X *list = p; X return( p ); X} X XFree_entry( p ) X struct entry *p; X{ X struct entry *q; X while( p ){ X q = p->chain; X p->next = entry_list; X entry_list = p; X p = q; X } X} X struct entry * Add_entry( list, user, host, printer, format ) X struct entry **list; X char *user, *host, *printer; X char *format; X{ X struct entry *p; X p = Find_entry( user, host, printer, format ); X if( p == 0 ){ X p = Make_entry( list, user, host, printer, format ); X } X return( p ); X} X Merge_raw_sum() X{ X Merge_raw(&Sum_user); X} Merge_raw_all() X{ X Merge_raw(&All_user); X} Merge_raw(s) X struct entry **s; X{ X struct entry *p, *q; X X /* X * assume that you have just read in the summary file X */ X p = *s; X while( p ){ X q = Make_entry( s, p->user, p->host, p->printer, p->format); X q->runs += p->runs; X q->pages += p->pages; X p = p->chain; X } X} X Update_sum( fp ) X FILE *fp; X{ X struct entry *p; X X /* X * next, truncate the file X */ X if( ftruncate( fileno(fp), 0 ) < 0 ){ X logerr_die( XLOG_INFO, "cannot truncate summary file" ); X } X for( p = Sum_user; p; p = p->chain ){ X (void)fprintf( fp, "%s %s %s %d %s %d\n", p->user, p->host, p->printer, X p->pages, p->format, p->runs ); X } X} X cmpx( l, r ) X struct entry **l, **r; X{ X int c; X struct entry *sl, *sr; X sl = *l; X sr = *r; X if( (c = strcmp( sl->user, sr->user )) == 0 X && (c = strcmp( sl->host, sr->host )) == 0 ){ X c = strcmp( sl->printer, sr->printer ); X } X return( c ); X} Sort_file(st) X struct entry **st; X{ X int i, n; X struct entry *p, **q; X X /* count the number of entries */ X X for( i = 0, p = *st; p; p = p->chain, ++i ); X n = i; X if( n > 0 ){ X q = (struct entry **)malloc( (unsigned)n*sizeof(struct entry *)); X if( q == 0 ){ X logerr_die( XLOG_INFO, "malloc failed" ); X } X for( i = 0, p = *st; i < n; p = p->chain, ++i ){ X q[i] = p; X } X qsort( (char *)q, i, sizeof(struct entry *), cmpx ); X for( i = 0; i < n-1; ++i ){ X q[i]->chain = q[i+1]; X } X q[i]->chain = 0; X } X X} X Dump_info( p, header ) X struct entry *p; X char *header; X{ X (void)fprintf( stdout, "%s\n", header ); X for( ; p; p = p->chain ){ X (void)fprintf( stdout, "%s %s %s %d %s %d\n", p->user, p->host, p->printer, X p->pages, p->format, p->runs ); X } X} END_OF_FILE if test 15473 -ne `wc -c <'src/pac.c'`; then echo shar: \"'src/pac.c'\" unpacked with wrong size! fi # end of 'src/pac.c' fi if test -f 'utilities/cpr/cpr.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'utilities/cpr/cpr.c'\" else echo shar: Extracting \"'utilities/cpr/cpr.c'\" \(14860 characters\) sed "s/^X//" >'utilities/cpr/cpr.c' <<'END_OF_FILE' X/* X * This program prints the files named in its argument list, preceding X * the output with a table of contents. Each file is assumed to be C X * source code (but doesn't have to be) in that the program searches X * for the beginning and end of functions. Function names are added to X * the table of contents, provided the name starts at the beginning of X * a line. The function name in the output is double striken. X * X * By default blank space is inserted after every closing '}' X * character. Thus functions and structure declarations are nicely X * isolated in the output. The only drawback to this is that structure X * initialization tables sometimes produce lots of white space. X * The "-r" option removes this space, or changes it to the indicated X * length. X * X * The option "-l" indicates that the following argument is to be X * the page length used for output (changing the page length hasn't been X * tested much). X * X * The option "-s" indicates that the table of contents should be sorted X * by function name within each file. X * X * The option "-n" indicates that output lines should be numbered with X * the corresponding line number from the input file. X * X * The option "-p" indicates what proportion of the page in steps of 16 X * should be used for deciding if a new function needs a new page. X * That is -p12 (the default) indicates that if a function starts X * within the top 12/16 (3/4) of the page then do it, otherwise put it X * on a new page. Thus the higher the number (upto 16) the closer to X * the bottom of the page will functions be started. -p0 says put each X * func on a new page. X * X * Try it! You'll like it. (I call it cpr.c) X * X * Written by: X * Paul Breslin X * Human Computing Resources Corp. X * 10 St. Mary St. X * Toronto, Ontario X * Canada, M4Y 1P9 X * X * -- ...!decvax!utcsrgv!hcr!phb X * X * Sorting and standard input reading from: X * Rick Wise, CALCULON Corp., Rockville, MD. X * -- ...!decvax!harpo!seismo!rlgvax!cvl!umcp-cs!cal-unix!wise X * X * File modified time, X * numbered output, X * optional white space, X * improved function start tests from: X * David Wasley, U.C.Berkeley X * -- ...!ucbvax!topaz.dlw X * Modified the -r to leave variable amounts of space X * Patrick Powell, U. Waterloo X * X * Changed handling of form feeds to start a new page AND print heading: X * Terry Doner, U of Waterloo X * X * Fixed up to locate more functions, and added -p option X * Dennis Vadura, U of Waterloo X * X * It will find things like struct foo *f()... X * but not things like int X * f X * ()... X * ie. the constraint is that the () must appear on the same line X * as the function name. X * X * Clean up a bit for 80286 machines (lints a bit cleaner, too) X * Dan Frank, Prairie Computing X */ X#include <sys/types.h> X#include <sys/stat.h> X#include <stdio.h> X#include <ctype.h> X#include <signal.h> X#include <string.h> extern int errno; /* system error number */ extern char *sys_errlist[]; /* error message */ extern char *malloc() ; /* important for 8086-like systems */ X X#define BP 0xC /* Form feed */ X X#define TOC_SIZE 4096 X X#define NEWFILE 1 X#define NEWFUNCTION 2 X XFILE *File; X int Braces; /* Keeps track of brace depth */ int LineNumber; /* Count output lines */ int PageNumber = 0; /* You figure this one out */ int PageLength = 66; /* -l <len> Normal paper length */ int PagePart = 12; /* Decision on paging for new fn*/ int PageEnd; /* Accounts for space at bottom */ int SawFunction; int InComment; int InString; X long FileLineNumber; /* Input file line number */ X char *ProgName; char Today[30]; char *Name; /* Current file name */ X char FunctionName[80]; char FileDate[24]; /* Last modified time of file */ X char SortFlag; /* -s == sort table of contents */ char NumberFlag; /* -n == output line numbers */ int Space_to_leave = 5; /* -r<number> space to leave */ int TabWidth = 0; /* -t <number> width of tabs */ X main(argc, argv) char **argv; X { X register int i; X char *ctime(); X time_t thetime, time(); X char *parm; X int c; X X ProgName = argv[0]; X thetime = time((time_t *)0); X strcpy(Today,ctime(&thetime)); X X for( i=1; argc > i; ++i ) X { X if( argv[i][0] != '-' X || argv[i][1] == '\0' ) break; X X parm = argv[i]; X while( c = *++parm ) switch( c ){ X case 't': X if( argc < 3 ) Usage(); X TabWidth = atoi(argv[++i]); X if( TabWidth < 0 ) X TabWidth = 0; X break; X X case 'l': X if( argc < 3 ) Usage(); X PageLength = atoi(argv[++i]); X break; X X case 's': X ++SortFlag; X break; X X case 'n': X ++NumberFlag; X break; X X case 'r': X if( (c = parm[1]) && isdigit( c ) X &&( c = atoi( parm+1 )) > 0 ){ X Space_to_leave = c; X } else { X Space_to_leave = 0; X } X while( *parm ){ X ++parm; X } X --parm; X break; X X case 'p': X if( (c = parm[1]) && isdigit( c ) X &&( c = atoi( parm+1 )) >= 0 ){ X PagePart = (c <= 16) ? c: 16; X } X while( *parm ){ X ++parm; X } X --parm; X break; X X default: X Usage(); X break; X } X } X PageEnd = PageLength - ((PageLength > 30) ? 2 : 1); X X StartTempFile(); X X if( i == argc ) X { /* no file names */ X File = stdin; X Name = "Standard Input"; X List(); X } X X for(; i < argc; ++i ) X { X if( strcmp(argv[i], "-") == 0 ) X { X File = stdin; X Name = "Standard Input"; X } X else X { X if( (File = fopen( Name = argv[i], "r" )) == NULL ) X { X fprintf(stderr,"%s: Can't open file '%s': %s\n", X ProgName, Name, sys_errlist[errno] ); X continue; X } X } X List(); X if( File != stdin ) fclose(File); X } X X if( PageNumber > 1 || LineNumber > 0 ) X putchar(BP); X EndTempFile(); X X DumpTableOfContents(); X DumpTempFiles(); X Done(); X } X Usage() X { X fprintf(stderr, "Usage: %s [-n] [-t tabwidth] [-p[num]] [-r[num]] [-s] [-l pagelength] [files] [-]\n", X ProgName); X exit(1); X } X int SaveOut; char *TempName; char *Temp2Name; X StartTempFile() X { X int Done(); X extern char *mktemp(); X X CatchSignalsPlease(Done); X X SaveOut = dup(1); X TempName = mktemp("/tmp/cprXXXXXX"); X if( freopen(TempName, "w", stdout) == NULL ) X { X fprintf(stderr, "%s: Can't open temp file '%s': %s\n", ProgName, X TempName, sys_errlist[errno]); X exit(1); X } X } X XEndTempFile() X { X Temp2Name = mktemp("/tmp/CPRXXXXXX"); X if( freopen(Temp2Name, "w", stdout) == NULL ) X { X fprintf(stderr, "%s: Can't open temp file '%s': %s\n", ProgName, X Temp2Name, sys_errlist[errno]); X exit(1); X } X } X DumpTempFiles() X { X register int pid, w; X X fclose(stdout); X dup(SaveOut); X X while( (pid = fork()) < 0 ) sleep(1); X if( pid ) X while ((w = wait((int *)0)) != pid && w != -1); X else X { X CatchSignalsPlease(SIG_DFL); X X execl( "/bin/cat", "cat", Temp2Name, TempName, (char *)0 ); X fprintf(stderr, "%s: exec of /bin/cat failed: %s\n", ProgName, X sys_errlist[errno]); X exit(0); X } X } X Done() X { X CatchSignalsPlease(SIG_IGN); X X if( TempName ) unlink( TempName ); X if( Temp2Name ) unlink( Temp2Name ); X X exit(0); X } X CatchSignalsPlease(action) int (*action)(); X { X if( signal(SIGINT, SIG_IGN) != SIG_IGN ) signal(SIGINT, action); X if( signal(SIGQUIT, SIG_IGN) != SIG_IGN ) signal(SIGQUIT, action); X if( signal(SIGHUP, SIG_IGN) != SIG_IGN ) signal(SIGHUP, action); X } X List() X { X register int bp; X register char *bufp; X char buffer[256]; X X NewFile(); X bp = Braces = 0; X InString = InComment = 0; /* reset for new file -DV */ X SawFunction = 0; X bufp = buffer; X while( fgets(bufp, sizeof(buffer), File) != NULL ) X { X ++FileLineNumber; X if( bp ) NewFunction(); X X if( ++LineNumber >= PageEnd ) NewPage(); X X if( bufp[0] == '\f' X && bufp[1] == '\n' X && bufp[2] == '\0' ) NewPage(); /* was strcpy(bufp, "^L\n");*/ X X if( NumberFlag ) X { X if( *bufp == '\n' ) X printf(" "); X else X printf("%6ld ", FileLineNumber); X } X if( (Braces == 0) && LooksLikeFunction(bufp) ) X AddToTableOfContents(NEWFUNCTION); X X bp = PutLine(buffer); X } X } X PutLine(l) register char *l; X { X extern char *EndComment(); X extern char *EndString(); X register char c; X int bp; X char *save; X X bp = 0; X for( save = l; c = *l; ++l ) X if( InComment ) X l = EndComment(l); X else if( InString ) X l = EndString(l); X else X switch(c) X { X case '{': X ++Braces; X break; X X case '}': X if( --Braces == 0 ) X bp = 1; X break; X X case '\'': X for( ++l; *l && *l != '\''; ++l ) X if( *l == '\\' && *(l+1) ) ++l; X break; X X case '"': X InString = 1; X break; X X case '/': X if( *(l+1) == '*' ) X { X InComment = 1; X ++l; X } X break; X } X printf("%s", save); X return(bp); X } X char * XEndComment(p) register char *p; X { X register char c; X X /* X * Always return pointer to last non-null char looked at. X */ X while( c = *p++ ) X if( c == '*' && *p == '/' ) X { X InComment = 0; X return(p); X } X return(p-2); X } X char * XEndString(p) register char *p; X { X register char c; X X /* X * Always return pointer to last non-null char looked at. X */ X while( c = *p++ ) X if( c == '\\' && *p ) X { X ++p; X continue; X } X else if( c == '"' ) X { X InString = 0; X return(p-1); X } X return(p-2); X } X NewFunction() X { X register int i; X X if( Space_to_leave <= 0 || !SawFunction ) return; X if( LineNumber + Space_to_leave > (PageLength * PagePart / 16) ) X NewPage(); X else X { X for( i=0; i < (Space_to_leave); ++i ) putchar('\n'); X LineNumber += Space_to_leave; X } X X SawFunction = 0; X } X X#define HEADER_SIZE 3 X NewPage() X { X if( PageNumber >= 0 ) ++PageNumber; X putchar(BP); X LineNumber = 0; X X PutHeader(); X } X PutHeader() X { X register int i, l, j; X X putchar('\n'); X ++LineNumber; X l = strlen(Name); X for( j=0; j < l; ++j ) X printf("%c\b%c\b%c", Name[j], Name[j], Name[j]); X X if( PageNumber > 0 ) X { X printf(" %.17s", FileDate); X GoToColumn(l+19, 70); X printf("Page:%4d\n\n", PageNumber); X ++LineNumber; X ++LineNumber; X } X else X { X GoToColumn(l, 55); X printf("%s\n\n", Today); X ++LineNumber; X ++LineNumber; X } X } X GoToColumn(from, to) register int from, to; X { X if( from < to) X { X if( TabWidth > 0 ){ X from &= ~(TabWidth-1); X for( ; (from + TabWidth) <= to; from += TabWidth ) X putchar('\t'); X } X for( ; from < to; from++ ) X putchar(' '); X } X } X X#define isidchr(c) (isalnum(c) || (c == '_')) X X/* This used to incorrectly identify a declaration such as X * int (*name[])() = { initializers ... } X * as a function. It also picked up this in an assembler file: X * #define MACRO(x) stuff X * MACRO(x): X * Fixed both of these. -IAN! X */ LooksLikeFunction(s) register char *s; X { X register char *p; X register int i; X char *save; X X if( InComment || InString ) return(0); X X save = s; X X i = 0; X do X { X p = FunctionName; X X while( *s && (*s == ' ') || (*s == '\t') ) ++s; X if( *s == '*' ) ++s; X if( !*s || ((*s != '_') && !isalpha(*s)) ) return(0); X X while( isidchr(*s) ) X *p++ = *s++; X *p = '\0'; X X while( *s && (*s == ' ') || (*s == '\t') ) ++s; X i++; X } X while ( *s && *s != '(' && i < 4 ); X X if( *s != '(' || *(s+1) == '*' ) return(0); X X for (i = 0; *s; s++) X { X switch( *s ) X { X case '(': X ++i; X continue; X X case ')': X --i; X break; X X default: X break; X } X if( i == 0 ) break; X } X if( !*s ) return(0); X X while( *s ) X { X if( *s == '{') break; X if( *s == ';' || *s == ':' ) return(0); X ++s; X } X X /* X * This will cause the function name part of the line to X * be double striken. Note that this assumes the name and the opening X * parentheses are on the same line... X */ X X if( p = strchr( save, '(' ) ) X { X p--; X while( p != save && isidchr( *(p-1) ) ) p--; X for( i=0; save != p; save++, i++ ) putchar(' '); X for( ; *p != '('; p++, i++ ) putchar( *p ); X } X else X for( i=0; *save && (*save == '*' || isidchr(*save)); ++i, ++save) X if( *save == '*' ) X putchar(' '); X else X putchar(*save); X X while( i --> 0 ) putchar('\b'); X X SawFunction = 1; X return(1); X } X static char *Toc[TOC_SIZE]; static int TocPages[TOC_SIZE]; static int TocCount; X AddToTableOfContents(type) X { X if( TocCount > TOC_SIZE ) X return; X if( TocCount == TOC_SIZE ) X { X fprintf(stderr, "%s: More than %d Table of contents entries; others ignored.\n", X ProgName, TOC_SIZE); X ++TocCount; X return; X } X X if( type == NEWFILE ) X AddFile(); X else X AddFunction(); X } X AddFunction() X { X register int l; X register char *p; X X /* This heuristic stops multiple occurrences of a function, X * selected by #ifdefs, to all end up many times over in the X * Table of Contents. One only needs to see it once. -IAN! X */ X if( TocCount > 0 && TocPages[TocCount-1] == PageNumber X && strcmp(Toc[TocCount-1],FunctionName) == 0 ) X return; X l = strlen(FunctionName); X p = Toc[TocCount] = (char *)malloc(l+1); X strcpy(p, FunctionName); X TocPages[TocCount] = PageNumber; X ++TocCount; X } X AddFile() X { X register int i, l; X register int len; X char temp[20]; X X len = strlen(Name) + 20; X len = (len < 130) ? 130 : len; X Toc[TocCount] = (char *)malloc(len); X sprintf(Toc[TocCount], "\n File: %s ", Name); X l = strlen(Toc[TocCount]); X if( l < 64 ) X { X if( TabWidth > 0 ){ X i = ((64 - l) / TabWidth) + 1; X while( i-- > 0 ) X Toc[TocCount][l++] = '\t'; X } X else{ X while( l < 64 ) X Toc[TocCount][l++] = ' '; X } X Toc[TocCount][l++] = '\0'; X } X sprintf(temp, " Page %4d\n", PageNumber); X strcat(Toc[TocCount], temp); X ++TocCount; X } X NewFile() X { X GetFileTime(); X NewPage(); X AddToTableOfContents(NEWFILE); X FileLineNumber = 0; X } X GetFileTime() X { X struct stat st; X X if( File == stdin ) X strncpy(FileDate, &Today[4], 20); X else X { X fstat(fileno(File), &st); X strncpy(FileDate, ctime(&st.st_mtime) + 4, 20); X } X strncpy(&FileDate[12], &FileDate[15], 5); X FileDate[18] = '\0'; X } X DumpTableOfContents() X { X register int i, j; X int index[TOC_SIZE]; X X if( TocCount == 0 ) return; X X for (i = 0; i < TocCount; i++) index[i] = i; X if( SortFlag ) X SortTable(index); X X Name = "Table of Contents"; X X PageNumber = -1; X LineNumber = 0; X NewPage(); X X for( i=0; i < TocCount; ++i ) X { X if( Toc[index[i]][0] == '\n' ) X { X if( (LineNumber + 5) >= PageEnd ) NewPage(); X X printf("%s", Toc[index[i]]); X LineNumber += 2; X continue; X } X if( ++LineNumber >= PageEnd ) NewPage(); X X printf(" %s ", Toc[index[i]]); X for( j=strlen(Toc[index[i]]); j < 48; ++j ) putchar('.'); X printf(" %4d\n", TocPages[index[i]]); X } X } X SortTable(index) register int *index; X { X register int i, temp, flag; X X do { X flag = 0; X for (i = 0; i < TocCount - 1; i++) X { X if( Toc[index[i]][0] == '\n' || Toc[index[i+1]][0] == '\n' ) X continue; /* don't sort across file names */ X if( strcmp(Toc[index[i]], Toc[index[i+1]]) > 0) X { X temp = index[i]; X index[i] = index[i+1]; X index[i+1] = temp; X flag = 1; X } X } X } while( flag ); X } X X END_OF_FILE if test 14860 -ne `wc -c <'utilities/cpr/cpr.c'`; then echo shar: \"'utilities/cpr/cpr.c'\" unpacked with wrong size! fi # end of 'utilities/cpr/cpr.c' fi echo shar: End of archive 10 \(of 16\). cp /dev/null ark10isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 16 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.