/**
*
* print
*
* CLI PRINT command
* Version 1.2
*
* (c) 1988 by John F. Zacharias, All rights reserved
*
* Permission granted for use by non-profit, non-commercial user
* provided above copyright notice and these restrictions are
* included with any copy.  Any for profit use or use by a commericial
* enterprise is strictly forbidden unless proper arrangements are
* made with the author.
*
* This program is intended to run only under CLI.  The CLI command line
* syntax is:
*
* print {-i} file-name {...file-name} {rp=n} {OPT H | N | S}
*
* parameters:
*
*       -i         perform printer initialization (sets printer to Preferences
*		   specifications).
*
*	file-name  the name of the file or directory to print.
*
*	rp=	   start printing at page number n.  This allows you to skip
*		   over a portion of a printout they may have previously
*		   been printed.  The "rp=" applies ONLY to the filename that
*		   precedes it.
*
*	OPT H	   Printout is in hexadecimal.
*
*	OPT N	   Sequence number each line of the printout.
*
*	OPT S	   Show all control characters and printer ESC sequences.
*
* NOTE: multiple OPT operands can be given - any one option operand will
*       apply to all files that preceed that option operand.  As an example:
*
*       print file-1 opt h file-2 opt n file 3
*
*       will print file-1 in hex, file-2 with sequence numbers, and file-3
*       without sequence numbers.
*
* MODIFIED FOR WORKBENCH 1.3
*
* NOTICE: This program can not be used as a 'resident' command.  It is not
*         re-entrant.
*
* THIS FILE IS WRITTEN FOR LATTICE V. 4.01
*
**/

#include <time.h>
#include <stdio.h>
#include <intuition/intuition.h>
#include <dos.h>
#include <ctype.h>

#define	MAXFILES  25		     /* change if different # files wanted */
#define TOP_MARGIN 4                 /* number lines at top of page */
#define DIRLNSZ 76		     /* size of full directory line */
#define DIRHD_LINES 14               /* body = page size minus this (files) */
#define FILHD_LINES 12               /* body = page size minus this (dir) */
#define EJECT -1		     /* Eject code returned by GET_LINE() */
#define PARLINE -2		     /* Partial line code rtrnd by GET_LINE() */

 
struct Dir_Entry {
	struct Dir_Entry *de_left;
	struct Dir_Entry *de_right;
	struct Dir_Entry *de_root;
	long de_Type;
	long de_Protect;
	long de_Size;
	long de_Blocks;
	struct DateStamp de_Date;
	char de_Name[32];
	};			     /* structure used to define each 
				        directory entry */

extern long IntuitionBase;           /* global intuition base variable */
extern char *_ProgramName;           /* Program Name */
extern int (*_ONBREAK)();	     /* ONBREAK routine */

struct Preferences Prefs;            /* for looking at preferences */
struct InfoData DiskInfo;            /* for looking at disk volume info */
struct FileInfoBlock Fib;            /* for looking at File Information Block */
struct DateStamp FileDate;	     /* for looking at file date/time */	
struct DateStamp SysDate;	     /* for looking at system date/time */

static struct IntuiText Text1 = {-1,-1,
			0,
			16,14,
			NULL,
			"** Abort Current Print-Out? **",
			NULL};

static struct IntuiText Text2 = {-1,-1,
			0,
			16,14,
			NULL,
			"** Go on to next File? **",
			NULL};

static struct IntuiText NameText = {-1,-1,
			0,
			6,4,
			NULL,
			NULL,
			NULL};

static struct IntuiText NoText = {-1,-1,
			0,
			8,4,
			NULL,
			"NO",
			NULL};

static struct IntuiText YesText = {-1,-1,
			0,
			8,4,
			NULL,
			"YES",
			NULL};


/* Global Variables - accessed by more than one function */

long FileProtect, FileSize, FileBlocks;

FILE *Prt;
FILE *Inp;

unsigned int SeqNo;
int lmargn, lnsz, pgsz, lncnt, Abort_Print, nfiles;
int nmbrfiles = 0;
int page_no = 0;
int init_prtr = 0;
char heading_buf[132];

char FullPath[160];
char FileComments[80];
char FileName[MAXFILES][160];
char Option[MAXFILES];

#define HEX       'h'
#define LINENOS   'n'
#define SHOW	  's'

int StartPage[MAXFILES];
int ResetPage[MAXFILES];
int PrintType[MAXFILES];

#define HAVE_FILE   -1
#define HAVE_DIR    1

 
void main(argc, argv)      

int argc;
char *argv[];

{
	int PRTBRK();

	printf("PRINT v 1.2\n");
	printf("Copyright (c) 1988 by John F. Zacharias, All Rights Reserved\n");

	IntuitionBase = OpenLibrary("intuition.library",0);
	if (IntuitionBase == NULL) {
		printf("Can't open Intuition Library\n");
		exit(1);
		}
 
	GetPrefs(&Prefs,sizeof(Prefs));
	
	lmargn = Prefs.PrintLeftMargin;
	lnsz = Prefs.PrintRightMargin-Prefs.PrintLeftMargin+1;
	pgsz = Prefs.PaperLength;

	getargs(argc,argv);
/*	showargs();             /* TEMPORARY for testing */

	if ((Prt = fopen("PRT:","w")) == NULL) {
		printf(">> Printer can't be opened <<\n");
		exit(1);
		}

	if (init_prtr) fputs("\x1b#1",Prt);

	_ONBREAK = PRTBRK;	/* Set up break processing routine */

	for(nfiles=1; nfiles <= nmbrfiles; nfiles++){
		Abort_Print = 0;
		if (PrintType[nfiles] == HAVE_FILE) print_files(nfiles);
		if (PrintType[nfiles] == HAVE_DIR) print_directory(nfiles);
		}

	fclose(Prt);
	rbrk();
	exit(0);
}
getargs(argc,argv)

int argc;
char *argv[];

{
	int ftype;
	int argn = 0;
	int n = 1;
	char opt;

	if (argc < 2)
		printf("ERROR: no arguements given\n");

	while(argc-- > 1) {	
		argn++;
		if (stricmp(argv[argn],"-i") == 0) {
			init_prtr = 1;
			continue;
			}
		if (strnicmp(argv[argn],"rp=",3) == 0) {
			if (nmbrfiles == 0) {
				printf("ERROR: Starting page must follow filename\n");
				exit(1);
				}
			if (sscanf(argv[argn],"rp=%d",
				&StartPage[nmbrfiles]) != 1) {
				printf("ERROR: Incorrect starting page number\n");
				exit(1);
				}
			continue;
			}
		if (stricmp(argv[argn],"opt") == 0) {
			if (--argc < 1) {
				printf("ERROR: No option given\n");
				exit(1);
				}
			if (strlen(argv[++argn]) > 1) {
				printf("ERROR: Option '%c' invalid combination\n",
					argv[argn]);
				exit(1);
				}
			strlwr(argv[argn]);
			opt = *argv[argn];
			if (((opt == HEX) || (opt == LINENOS) || (opt == SHOW))
					== 0) {
				printf("ERROR: '%c' is an invalid option\n",
					opt);
				exit(1);
				}
			for(;n <= nmbrfiles; n++)
				Option[n] = opt;
			continue;
			}

 		ftype = getfa(argv[argn]);

		if (ftype != NULL) {
			nmbrfiles++;
			strcpy(FileName[nmbrfiles],argv[argn]);
			PrintType[nmbrfiles] = ftype;
			StartPage[nmbrfiles] = 0;
			}
		else printf("%s does not exist\n",argv[argn]);
		}
	return(0);
}


print_files(fileno)

int fileno;

{
	int lnend, newline, textsz, mode;

/*
*	mode = 0 (text display), 1 (hex display)
*	newline = 0 (continuation line), 1 (start of line)
*	lnend = 0 (end of file)
*		+ (size of line if line feed encountered)
*		-1 (EJECT encountered - TEXT only!)
*		-2 (line size reached, no line feed - TEXT only!)
*
*/

	char inbuf[182], date[50];

	page_no = 1;
	set_header(heading_buf,fileno);
	lncnt = pgsz - FILHD_LINES;
	if (page_no >= StartPage[fileno]) {
		skip_lines(TOP_MARGIN);
		fprintf(Prt,heading_buf,page_no);
		ConvertDate(&FileDate,date,1);
		fprintf(Prt,"\nThe file was last updated on %s\n",date);
		fprintf(Prt,"The file size is %d bytes (%d blocks)\n",FileSize,FileBlocks);
		fprintf(Prt,"File protection status: ");
		Set_Protect(FileProtect);
		fputs(" allowed\n",Prt);
		fprintf(Prt,"File comments are: %s\n",FileComments);
		DateStamp(&SysDate);
		ConvertDate(&SysDate,date,1);
		fprintf(Prt,"\nThis file is being printed on %s\n",date);
		line_across();
		skip_lines(2);
		}

	lncnt = lncnt - 8;

	if ((Inp = fopen(FileName[fileno],"r")) == NULL) {
		printf("Cannot open file %s\n",FileName[fileno]);
		fprintf(Prt,"CANNOT OPEN FILE TO PRINT\n\f");
		return(0);
		}

	mode = 0;
	newline = 1;		/* indicate start of new line */
	SeqNo = 0;
	textsz = lnsz;

	if (Option[fileno] == LINENOS) textsz = lnsz-7;

	if (Option[fileno] == HEX) {
		textsz = 16;
		mode = 1;
		}

	while ((lnend = get_line(inbuf,textsz,mode,Option[fileno]))) {
		if (Abort_Print) {
			fprintf(Prt,"\n>>> PRINTOUT ABORTED WITH CONTROL C <<<\n");
			break;
			}
		if ((lnend == EJECT) && (*inbuf == 0)) {
			newline = 1;
			lncnt = 0;
			continue;
			}
		if (newline || (lncnt < -3)) {
			if (lncnt <= 0) {
				if (page_no >= StartPage[fileno])
					putc('\f',Prt);
				if (++page_no >= StartPage[fileno]) {
					skip_lines(TOP_MARGIN);
					fprintf(Prt,heading_buf,page_no);
					line_across();
					skip_lines(2);
					}
				lncnt = pgsz - FILHD_LINES;
				}
			}
		if (mode) newline = lnend-1;
		print_line(inbuf,newline,fileno);
		lncnt--;
		newline = 1;	/* indicate start of line for next line */ 
		if (lnend == PARLINE) newline = 0;	/* next not start */
		if (lnend == EJECT) lncnt = 0;
		}

	putc('\f',Prt);
	fclose(Inp);
	return(0);
}

Set_Protect(fp)

long fp;

{
	if (fp & 128) putc('-',Prt);
		 else putc('-',Prt);
	if (fp & 64) putc('s',Prt);
		 else putc('-',Prt);
	if (fp & 32) putc('p',Prt);
		 else putc('-',Prt);
	if (fp & 16) putc('a',Prt);
		 else putc('-',Prt);
	if (fp & 8) putc('-',Prt);
		 else putc('r',Prt);
	if (fp & 4) putc('-',Prt);
		 else putc('w',Prt);
	if (fp & 2) putc('-',Prt);
		 else putc('e',Prt);
	if (fp & 1) putc('-',Prt);
		 else putc('d',Prt);
	return(0);
}

set_header(buf,fileno)

char *buf;
int fileno;

{
	char l,*p;

	get_path(fileno);
	p = stpcpy(buf,"FILE: ");
	if (PrintType[fileno] == HAVE_DIR) {
		p = stpcpy(buf,"DIRECTORY: ");
		}
	l = strlen(FullPath);
	p = p + stccpy(p,FullPath,lnsz-15) - 1;
	while(p < buf+lnsz-8)
		*p++=' ';
	stpcpy(p,"Page %3d\n");
	return(0);
}

get_path(fileno)

int fileno;

{
	long file_lock,new_lock;
	char *p;

	file_lock = Lock(FileName[fileno],ACCESS_READ);

	if (file_lock == NULL) {
		printf("Can't get File Lock for %s\n",FileName[fileno]);
		exit(1);
		}

	if (Info(file_lock,&DiskInfo) == NULL) {
		printf("Cannot get volume information for %s\n",
			FileName[fileno]);
		exit(1);
		}

	if (Examine(file_lock,&Fib) == NULL) {
		printf("Cannot get FIB for %s\n",FileName[fileno]);
		exit(1);
		}

	strcpy(FullPath,Fib.fib_FileName);
	FileProtect = Fib.fib_Protection;
	FileSize = Fib.fib_Size;
	FileBlocks = Fib.fib_NumBlocks;

	FileDate.ds_Days = Fib.fib_Date.ds_Days;
	FileDate.ds_Minute = Fib.fib_Date.ds_Minute;
	FileDate.ds_Tick = Fib.fib_Date.ds_Tick;

	strcpy(FileComments,Fib.fib_Comment);

	while(new_lock = ParentDir(file_lock)) {

		if (Examine(new_lock,&Fib) == NULL) {
			printf("Cannot get parent FIB for %s\n",FullPath);
			return(0);
			}

		strins(FullPath,"/");
		strins(FullPath,Fib.fib_FileName);

		UnLock(file_lock);
		file_lock = new_lock;
		}

	p = strchr(FullPath,'/');
	if (p) {
		*p = ':';
		return(0);
		}

	strcat(FullPath,":");
	return(0);
}

ConvertDate(Date,datebuf,mode)

struct DateStamp *Date;
int mode;
char *datebuf;

{

	long t;
	int i, weekday, day, month, year, dmode;
	int tmode = 6;

	static int month_day[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};

	char date_table[3];
	char time_table[4];
	char *p;

	static char *day_week[] = {
		"Sunday, ",
		"Monday, ",
		"Tuesday, ",
		"Wednesday, ",
		"Thursday, ",
		"Friday, ",
		"Saturday, "
	};

	i = 2;
	t = Date->ds_Days;
	year = 0;
	month_day[2] = 29;
	weekday = t % 7;

	while(1) {
		while (i<4) {
			if (t<365) {
				month_day[2] = 28;
				break;
				}
			t = t - 365;
			year++;
			i++;
			if (year == 2100) i = 0;
			}

		if (t<366) break;
		t = t - 366;
		year++;
		i = 1;
		}
	 
	i = 0;
	month = 0;

	while (t >= 0) {
		day = t + 1;
		t = t - month_day[++month];
		}

	date_table[0] = year;
	date_table[1] = month;
	date_table[2] = day;
	
	time_table[0] = Date->ds_Minute / 60;
	time_table[1] = Date->ds_Minute % 60;
	time_table[2] = Date->ds_Tick / TICKS_PER_SECOND;
	time_table[3] = 0;

	p = datebuf;
/*	dmode = 2;
	if (mode) dmode = 5;	* this was required for stpdate */
	dmode = mode;
	if (mode) p = stpcpy(p,day_week[weekday]);
	p = astpdate(p,dmode,date_table);	/* replaces stpdate */
	if (mode) p = stpcpy(p," at ");
	else p = stpcpy(p," ");
	stptime(p,tmode,time_table);
	return(0);
}

skip_lines(nolines)

int nolines;

{
	while (nolines--) putc('\n',Prt);
	return(0);
}

print_line(inbuf,lnstrt,fn)

int fn, lnstrt;
char *inbuf;

{

	if (Option[fn] == LINENOS) {
		if (lnstrt) {
			SeqNo++;
			if (page_no >= StartPage[fn])
				fprintf(Prt,"%5d: %s\n",SeqNo,inbuf);
			return(1);
			}
		else {
 			if (page_no >= StartPage[fn])
				fprintf(Prt,"       %s\n",inbuf);
			return(1);
			}
		}
	if (page_no < StartPage[fn]) return(1);

	if (Option[fn] == HEX) {
		print_hexline(inbuf,lnstrt);
		return(1);
		}

	fprintf(Prt,"%s\n",inbuf);
	return(1);
}
	
line_across()

{
	int i;

	i = 10;
	while (i--) fputc(' ',Prt);
	i = lnsz - 20;
	while (i--) fputc('-',Prt);
	i = 10;
	while (i--) fputc(' ',Prt);
	fputc('\n',Prt);
	return(0);
}
get_line(buf,sz,mode,opt)

char *buf;
int sz, mode;
char opt;

/*	Mode is 0 for text display and 1 for hex display.
*
*	Normally, this routine returns the size of the text placed in
*	the buffer.  On text displays this occurs only when a line
*	feed ($0A) is encountered.
*
*	If the "end of file" occurs a zero is returned.
*
*	The following applies to text displays only:
*
*	This routine returns EJECT (-1) if a line form ($0C) appears
*	in the text even if the buffer has data in it.
*
*	This routine returns PARLINE (-2) if the line size passed as
*	"sz" is reached before a line feed is encountered.
*
*	Binary zeros in text are ignored.
*
*	If a carriage return ($0D) is encountered it is ignored if a
*	line feed is in the same sequence, otherwise the carriage
*	return is treated as a line feed.
*
*	All other control sequences (ASCII 0 through 31) are displayed
*	with a ^ followed with a capitol character representing the
*	ASCII position.
*
*/
   
{
	int l = 0;
	int cr = 0;
	int c;

	while (l < sz) {
		if ((c = fgetc(Inp)) == EOF) {
			*buf = 0;
			if (l == 0) return(0);
			ungetc(c,Inp);
			return(l+1);
			}
		if (mode == 0) {
			if (c > 127) c = c-128;
			if (c == '\n') {
				*buf = 0;
				return(l+1);
				}
			if (opt == SHOW) {
				if (c < 32) {
					if (l > sz-3) break;
					*buf++ = '^';
					l++;
					c = c + 64;
					}
				}
			if (c == '\f') {
				*buf = 0;
				if ((c = fgetc(Inp)) != '\n')
					ungetc(c,Inp);
				return(EJECT);
				}
			if (c == 13) {
				cr = 1;
				continue;
				}
			if (cr && l) {
				*buf = 0;
				ungetc(c,Inp);
				return(l+1);
				}
			cr = 0;
			if (c == 8) {
				if (l == 0) continue;
				l--;
				*buf-- = 0;
				continue;
				}
			if (c == 27) {
				if (byp_esc() == 0) {
					*buf = 0;
					if (l == 0) return(0);
					ungetc(c,Inp);
					return(l+1);
					}
				}
			if (c == '\t') {
				while (++l %8) *buf++ = ' ';
				*buf++ = ' ';
				continue;
				}
			if (c < 32) continue;
			}
		l++;
		*buf++ = c;
		}
	if (mode == 1) return(l+1);
	*buf = 0;
	if ((c = fgetc(Inp)) == '\n') return(l+1);
	ungetc(c,Inp);
	return(PARLINE);
}

print_hexline(inbuf,ln)

int ln;
unsigned char *inbuf;

{
	unsigned int hexbuf[8], i;
	unsigned char c;

	for(i = 0; i < ln; i+=2) 
		hexbuf[i/2] = (*(inbuf+i))*256 + (*(inbuf+i+1));

	fprintf(Prt,"  %06X:  ",SeqNo);
	for (i=0; i < ln/2; i++)
		fprintf(Prt,"%04X ",hexbuf[i]);

	if (ln%2)
		fprintf(Prt,"%02X   ",hexbuf[ln/2]/256);

	for (i = (ln/2)+(ln%2); i < 8; i++)
		fprintf(Prt,"     ");

	fprintf(Prt, "  ");
	for (i=0; i < ln; i++) {
		c = *inbuf++;
		c = toascii(c);			/* removes 2-7 high zone */
		if (c == '\x7f') c = '.';
		if (c == '\n') c = '>';
		if (c < 32) c = '.';
		fputc(c,Prt);
		}
	fputc('\n',Prt);
	SeqNo = SeqNo + ln;
	return(0);
}

print_directory(fn)

int fn;

{
	struct Dir_Entry *root, *get_dir_base();
	int dir_no = 0;
	int percent, free, fbytes;
	char date[50], vol_name[30];

	root = NULL;
	root = get_dir_base(FileName[fn],root);

	page_no = 1;
	set_header(heading_buf,fn);
	lncnt = pgsz - DIRHD_LINES;
	if (page_no >= StartPage[fn]) {
		skip_lines(TOP_MARGIN);
		fprintf(Prt,heading_buf,page_no);
		ConvertDate(&FileDate,date,1);
		fprintf(Prt,"\nThis directory was last updated on %s\n",date);
		stptok(FullPath,vol_name,sizeof(vol_name),":");
		fprintf(Prt,"The Volume containing the directory is: %s\n", vol_name);
  		fprintf(Prt,"The Volume contains %d blocks of %d bytes each.\n",
			DiskInfo.id_NumBlocks, DiskInfo.id_BytesPerBlock);
		percent = 100 * DiskInfo.id_NumBlocksUsed / DiskInfo.id_NumBlocks;
		fprintf(Prt,"The number of blocks currently is use are %d (%d%%).\n",
			DiskInfo.id_NumBlocksUsed, percent);
		free = DiskInfo.id_NumBlocks - DiskInfo.id_NumBlocksUsed;
		fbytes = free * DiskInfo.id_BytesPerBlock;
		fprintf(Prt,"The number of blocks available are %d (%d bytes).\n",
			free, fbytes);
		fprintf(Prt,"The number of soft errors are %d.\n\n",
			DiskInfo.id_NumSoftErrors);
		DateStamp(&SysDate);
		ConvertDate(&SysDate,date,1);
		fprintf(Prt,"\nThis directory is being printed on %s\n",date);
		print_dir_head_1();
		}
	lncnt = lncnt - 11;

	print_dir_line(root,dir_no,fn);

	putc('\f',Prt);

	return(0);
}

struct Dir_Entry *get_dir_base(name,root)

char *name;
struct Dir_Entry *root;

{
	struct Dir_Entry *get_file_info();
	struct FileInfoBlock *Dib;

	long dir_lock, old_lock;

	Dib = (struct FileInfoBlock *)malloc(sizeof(struct FileInfoBlock));
	if (!Dib) {
		printf("ERROR: Out of Memory allocating directory FIB\n");
		exit(1);
		}

	dir_lock = Lock(name,ACCESS_READ);

	if (dir_lock == NULL) {
		printf("Can't get file lock for directory %s\n",name);
		exit(1);
		}

	old_lock = CurrentDir(dir_lock);

	if (Examine(dir_lock,Dib) == NULL) {
		printf("Can't get FIB for directory %s\n",name);
		exit(1);
		}

	while(ExNext (dir_lock,Dib)) { 
		root = get_file_info(root,Dib);
		if (Abort_Print) break;
		}

	UnLock(dir_lock);
	CurrentDir(old_lock);
	return(root);
}

struct Dir_Entry *get_file_info(p,fb)

struct Dir_Entry *p;
struct FileInfoBlock *fb;

{
	struct Dir_Entry *get_dir_base();

	if (p == NULL) {
		p = (struct Dir_Entry *)malloc(sizeof(struct Dir_Entry));
		if (!p) {
			printf("ERROR: Out of Memory allocating Directories\n");
			exit(1);
			}
		p->de_Type = fb->fib_DirEntryType;
		p->de_Protect = fb->fib_Protection;
		p->de_Size = fb->fib_Size;
		p->de_Blocks = fb->fib_NumBlocks;
		p->de_Date.ds_Days = fb->fib_Date.ds_Days;
		p->de_Date.ds_Minute = fb->fib_Date.ds_Minute;
		p->de_Date.ds_Tick = fb->fib_Date.ds_Tick;
		stccpy(p->de_Name,fb->fib_FileName,30);
		p->de_left = p->de_right = p->de_root = NULL;

  		if (p->de_Type > 0) 
			p->de_root = get_dir_base(p->de_Name,p->de_root);

		return(p);
		}

	if (p->de_Type == fb->fib_DirEntryType) {
		if (stricmp (fb->fib_FileName, p->de_Name) < 0)
			p->de_left = get_file_info(p->de_left,fb);
		else
			p->de_right = get_file_info(p->de_right,fb);
		return(p);
		}

	if (fb->fib_DirEntryType < 0)
		p->de_left = get_file_info(p->de_left,fb);
	else
		p->de_right = get_file_info(p->de_right,fb);
	return(p);
}

print_dir_line(p,n,fileno)

struct Dir_Entry *p;
int n;
int fileno;

{
	int n1;
	char date[30];

	if (Abort_Print) {
		fprintf(Prt,"\n>>> PRINTOUT ABORTED WITH CONTROL C <<<\n");
		return(1);
		}

	if (p != NULL) {
		if (print_dir_line(p->de_left, n, fileno)) return(1);
		if (lncnt <= 0) {
			if (page_no >= StartPage[fileno]) putc('\f',Prt);
			if (++page_no >= StartPage[fileno]) {
				skip_lines(TOP_MARGIN);
				fprintf(Prt,heading_buf,page_no);
				print_dir_head_1();
				}
			lncnt = pgsz - 14;
			}
		else
			{
			if (p->de_Type > 0) {
				if (page_no >= StartPage[fileno]) line_across();
				lncnt--;
				}
			}
		if (page_no >= StartPage[fileno]) {
			fprintf(Prt,"%2d> ", n);
			if (p->de_Type > 0) 
				fprintf(Prt,"<DIR>");
			else
				fprintf(Prt,"     ");
			fprintf(Prt,"%30.30s %6d %4d ", p->de_Name, p->de_Size,
				p->de_Blocks);
			Set_Protect(p->de_Protect);
			ConvertDate(&p->de_Date,date,0);
			}
		if (lnsz < DIRLNSZ+1) {
			if (page_no >= StartPage[fileno]) 
				fprintf(Prt,"\n    Last Updated On ");
			lncnt--;
			}
		if (page_no >= StartPage[fileno]) fprintf(Prt," %s\n",date);
		lncnt--;
		if (p->de_Type > 0) {
			if (page_no >= StartPage[fileno]) skip_lines(1);
			lncnt--;
			n1 = n + 1;
			if (print_dir_line(p->de_root, n1, fileno)) return(1);
			}

		if (print_dir_line(p->de_right, n, fileno)) return(1);
		}
	return(0);
}

print_dir_head_1()

{
	line_across();
	skip_lines(2);
	fprintf(Prt,"Lvl %35.35s  Bytes Blks","NAME");
	if (lnsz > DIRLNSZ) fprintf(Prt,"      Last Updated On");
	skip_lines(2);
	return(0);
}

/*	the following routine is used to replace the Lattice "stpdate"
*	routine because of the incompatibility of base years (Amiga uses
*	1978 while Lattice uses 1980).  Since "print" only uses two of
*	the stpdate modes, these are the only two that are programmed.
*/

astpdate(p,m,dt)

char *p, *dt;
int m;

{
	int l, dy, yr, mo;
	static char *month[] = {
		"",
		"January",
		"February",
		"March",
		"April",
		"May",
		"June",
		"July",
		"August",
		"September",
		"October",
		"November",
		"December",
	};

	mo = dt[1];
	yr = dt[0];
	dy = dt[2];

	if (m) {
		p = stpcpy(p,month[mo]);
		yr = yr+1978;
		l = sprintf(p," %d, %4.4d",dy,yr);
		return (p+l);
		}
	else {
		yr = yr+78;
		l = sprintf(p,"%2.2d/%02.2d/%02.2d",mo,dy,yr);
		return (p+l);
		}

}

PRTBRK()

{
	NameText.IText = _ProgramName;
	NameText.NextText = &Text1;
	if (AutoRequest (NULL, &NameText, &NoText, &YesText, 0, 0, 296, 60)
		== TRUE) return(0);
	Abort_Print = 1;
	if (nfiles >= nmbrfiles) return(0);

	NameText.NextText = &Text2;
	if (AutoRequest (NULL, &NameText, &NoText, &YesText, 0, 0, 254, 60)
		== TRUE) nfiles = nmbrfiles+1;
	return(0);
}

byp_esc()

{
	int c;

	if ((c = fgetc(Inp)) == EOF) return(0);
	if ((c == '#') || (c == '(')) {
		if (fgetc(Inp) == EOF) return(0);
		return(1);
		}
	if (c != '[') return(1);
	while ((c = fgetc(Inp)) != EOF) {
		if (isalpha(c)) return(1);
		}
	return(0);
}

/*
*	The following routine is for testing purposes only.
*
*	It is used to display the arguments as they are parsed by
*	by the 'getargs()' routine. 
*
*/

showargs()

{
	int nfiles;

	printf("Initialize Printer = %d\n",init_prtr);
	for(nfiles=1; nfiles <= nmbrfiles; nfiles++) {
		printf("\nFile number %d:\n",nfiles);	
		printf("   FILE NAME: %s\n",FileName[nfiles]);
		printf("   PRINT OPTION: %c\n",Option[nfiles]);
		printf("   STARTING PAGE: %d\n",StartPage[nfiles]);
		printf("   RESET PAGE: %d\n",ResetPage[nfiles]);
		printf("   PRINT TYPE: ");
		if (PrintType[nfiles] == HAVE_FILE)
			printf("HAVE_FILE\n");
		if (PrintType[nfiles] == HAVE_DIR)
			printf("HAVE_DIR\n");
		}
	return(1);
}
