📄 ln03of.c
字号:
#ifndef lintstatic char *sccsid = "@(#)ln03of.c 4.1 (ULTRIX) 7/2/90";#endif lint/************************************************************************ * * * Copyright (c) 1987 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* * ln03of.c 4.12 07/16/83 * * Modification history * * 23-Nov-88 - Dave Gray (gray) * * Fixed bad pointer reference in strncmp * * LN03(S) Laser Printer filter * * 5-May-88 Pradeep Chetal (chetal) * - made 8-bit clean * * 23-Jan-88 David Gray (gray) * * Modified the escape handler to embed Nroff escape sequences * in the buffer to allow appropriate actions to take place, ie., * super and subscripting. * * 7-Dec-87 Pradeep Chetal (chetal) * * Added code to handle literal option and some optimizations. * * 9-Sep-87 - Ricky Palmer (rsp) * * Added some additional comments. * * 21-Aug-87 - David Gray (gray) * * To determine file type the first 4096 characters of the file * are buffered in "filestorage". When the file is actually printed * an attempt was made to access the 4097 element which resulted in an * extra character being inserted into the final output. This has been * corrected. The correction made was to change the test * globi <= in to globi < in * in function ln03of(). * * * 25-Apr-87 - Ricky Palmer (rsp) * * Berkeley ln03 filter code put into source maintenance format. * * Letter Quality Printers filter for ln03 looking like lqp * * filter which reads the output of nroff and converts lines * with ^H's to overwritten lines. Thus this works like 'ul' * but is much better: it can handle more than 2 overwrites * and it is written with some style. * modified by kls to use register references instead of arrays * to try to gain a little speed. * * Passes through escape and control sequences. * * Sends control chars to change to landscape mode for pages wider * than 80 columns. Also changes font and pitch for this case in * order to get 66 lines per page in landscape mode. * * Special logic for nroff ESC9 (partial line feed): this is * converted to ln03 sequence for partial line feed. Eventually * this kluge should be replaced by an output package for nroff * which knows about ln03 output. * * 25-Apr-87 - Ricky Palmer (rsp) * * Added code to original Berkeley filter based on * LCG01 and LJ250 filters. This filter supports * normal text output as well as sixels for output of * sixel graphics. * */#include <stdio.h>#include <signal.h>#include <errno.h>#include <syslog.h>#include <ctype.h>#include <a.out.h>#include <imghdr.h>#include <strings.h>#include <sys/ioctl.h>#include <locale.h>#define MAXWIDTH 132 /* maximum char. width */#define BUFWIDTH 182 /* maximum buf. width */#define MAXREP 10 /* buffer depth */#define DEFWIDTH 80 /* width char. count */#define DEFHEIGHT 66 /* length char. count */#define MAXP_PIX_WIDTH 800 /* portrait pixel width */#define MAXP_PIX_HEIGHT 1040 /* portrait pix. height */#define MAXL_PIX_WIDTH 1040 /* landscape p. width */#define MAXL_PIX_HEIGHT 800 /* landscape p. length */#define MAXCOPIES 1 /* default # of copies */#define HOW_MUCH_TO_CHECK 4096 /* input buffer amount */#define EMPTY_FILE 0 /* 0-10,77 file types */#define EXECUTABLE_FILE 1#define ARCHIVE_FILE 2#define DATA_FILE 3#define TEXT_FILE 4#define CTEXT_FILE 5#define ATEXT_FILE 6#define RTEXT_FILE 7#define FTEXT_FILE 8#define CAT_FILE 9#define XIMAGE_FILE 10#define ITS 77#define SOFF '\077' /* sixel element offset */#define MAX(a,b) (a < b ? b : a) /* useful macros */#define MAXIMUM(a,b,c) (MAX(MAX(a,b),c))#define MIN(a,b) (a > b ? b : a)#define MINIMUM(a,b,c) (MIN(MIN(a,b),c))#define ESC '\033' /* escape sequence introducer */#define BSLH '\134' /* back slash */#define UCP '\120' /* upper case P */#define PLD '\113' /* upper case K = ln03of partial line down */#define PLU '\114' /* upper case L = ln03of partial line up */#define FLU '\115' /* upper case M = ln03of full line up */#define E_NINE '\071' /* 9: nroff ESC9 = partial line down */#define E_EIGHT '\070' /* 8: nroff ESC8 = partial line up */#define E_SEVEN '\067' /* 7: nroff ESC7 = full line up */#define escend(x) ((x!='\120')&&(x!='\133')&&(x>='\100')&&(x<='\176'))/* Added a few macros for 8bit support */#define is_7bit_cntrl(ch) ((unsigned char)ch < 040 || (unsigned char)ch == 0177)FILE *input = stdin, *output = stdout; /* input and output */char filestorage[HOW_MUCH_TO_CHECK]; /* first chunk of pipe */char buf[MAXREP][BUFWIDTH]; /* buffer for output */int maxcol[MAXREP] = {-1}; /* maximum columns */int lineno; /* line number */int width = DEFWIDTH; /* default line length */int length = DEFHEIGHT; /* page length */int indent; /* indentation length */int npages = MAXCOPIES; /* number of copies */int literal; /* print control chars. */int error; /* error return status */int esclen; /* num escape chars */int maxrep; /* current depth in buf */int col; /* column position */char *name; /* user's login name */char *host; /* user's machine name */char *acctfile; /* accounting info. file*/int globi = 0, in = 0; /* global i and in vars.*/int kindofile = EMPTY_FILE; /* initial kind of file */int tmppagecount = 0, tmplinecount = 0; /* tmp counters */char *imgptr; /* image data pointers */short *cmpptr; /* color map pointer */struct imghdr im; /* image file header */char *malloc(); /* malloc pointer */char *setlocale(); /* Intl. function */unsigned size; /* the usual */int escflg = 0; /* escape sequence flag, 1 = in progress */int lstchr; /* last character */int rotated = 0; /* image rotated */char *fort[] = { "function","subroutine","common", "dimension","block","integer", "real","data","double",0 };char *asc[] = { "chmk","mov","tst","clr","jmp",0 };char *c[] = { "int","char","float","double", "struct","extern",0 };char *as[] = { "globl","byte","align","text", "data","comm",0 };void exit(), bcopy(), syslog();unsigned sleep();/* sixmap is the dither pattern used to create sixel output bytes */struct sixmap { char s0,s1,s2;} base_sixmap[] = { { 0+SOFF, 0+SOFF, 0+SOFF } , { 4+SOFF, 0+SOFF, 0+SOFF } , { 4+SOFF, 0+SOFF, 1+SOFF } , { 4+SOFF, 4+SOFF, 1+SOFF } , { 6+SOFF, 4+SOFF, 1+SOFF } , { 6+SOFF, 6+SOFF, 1+SOFF } , { 6+SOFF, 6+SOFF, 6+SOFF } , { 7+SOFF, 6+SOFF, 6+SOFF } , { 7+SOFF, 6+SOFF, 7+SOFF } , { 7+SOFF, 7+SOFF, 7+SOFF }};struct sixmap offset_sixmap[] = { { 0+SOFF, 0+SOFF, 0+SOFF }, { 32+SOFF, 0+SOFF, 0+SOFF }, { 32+SOFF, 0+SOFF, 8+SOFF }, { 32+SOFF, 32+SOFF, 8+SOFF }, { 48+SOFF, 32+SOFF, 8+SOFF }, { 48+SOFF, 48+SOFF, 8+SOFF }, { 48+SOFF, 48+SOFF, 48+SOFF }, { 56+SOFF, 48+SOFF, 48+SOFF }, { 56+SOFF, 48+SOFF, 56+SOFF }, { 56+SOFF, 56+SOFF, 56+SOFF }};/* The general strategy here is to reset the printer to initial state, sleep for five seconds for stability, process the command line arguments, open the syslog file for log information, determine the input stream "file type", call the filter code, and then optionally process accounting information upon completion. Informational and failure conditions are logged to syslog.*/main(argc, argv) int argc; char *argv[];{ register int i; register char *cp; setlocale(LC_CTYPE,"ENG_GB.MCS"); fprintf(output, "\033c"); /* reset to initial state */ sleep(5); while (--argc) { if (*(cp = *++argv) == '-') { switch (cp[1]) { case 'n': /* collect login name */ argc--; name = *++argv; break; case 'h': /* collect host name */ argc--; host = *++argv; break; case 'w': /* collect page width */ if ((i = atoi(&cp[2])) > 0 && i <= MAXWIDTH) width = i; if (width > 80) { /* switch to landscape mode */ fprintf(output,"\033[15m"); /* change font */ fprintf(output,"\033[7 J"); /* A4 page format */ fprintf(output,"\033[66t"); /* 66 lines/page */ fprintf(output,"\033[8 L"); /* vp = 12 lines/30mm */ } break; case 'l': /* collect page length */ length = atoi(&cp[2]); break; case 'i': /* collect indent */ indent = atoi(&cp[2]); break; case 'c': /* print control chars */ literal++; break; } } else acctfile = cp; } openlog("ln03of",LOG_PID); kindofile = determinefile(); error = ln03of(); if(error) { syslog(LOG_INFO,"Failed to output data"); exit(2); } if (name && acctfile && access(acctfile, 02) >= 0 && freopen(acctfile, "a", output) != NULL) { printf("%7.2f\t%s:%s\n", (float)npages, host, name); } exit(0);}/* The general strategy here is to "sniff" the incoming data to determine how to process output characters to the printer. Not all possible data streams are reflected here but a wide enough variety is covered to handle printing of just about all kinds of data streams. This code is derived originally from the "file" command code and modified to reflect its current usage. Note that currently only the first HOW_MUCH_TO_CHECK bytes are used so that if multiple files are concatenated together and then sent through the filter the first file will determine how the filter will act.*/determinefile(){ register int j = 0, nl = 0; register char ch, *chptr; in = read(fileno(input), &filestorage[0], HOW_MUCH_TO_CHECK); if((chptr = index(&filestorage[0],'\014')) != NULL) globi = chptr + 1 - &filestorage[0]; if(in == 0 && globi == 0){ return(EMPTY_FILE); } switch(*(int *)&filestorage[globi]) { case 0413: case 0410: case 0411: case 0407: return(EXECUTABLE_FILE); break; case 0177555: case 0177545: case 070707: case 027456: return(ARCHIVE_FILE); break; case 04553207: return(XIMAGE_FILE); break; default: break; } if((strncmp(filestorage+globi, "!<arch>\n__.SYMDEF", 17) == 0) || (strncmp(filestorage+globi, "!<arch>\n", 8) == 0)) { return(ARCHIVE_FILE); } if(ccom() == 0) goto notc; while(filestorage[globi] == '#'){ j = globi;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -