home *** CD-ROM | disk | FTP | other *** search
- /**
- **
- ** LJ -- A printing utility for the HP LaserJet
- **
- **
- ** This program prints a series of files on the LaserJet printer. The
- ** files are printed in a "landscape" font at 17 characters to the inch.
- ** To take advantage of this density, two "pages" of information from
- ** the file are printed on each piece of paper (left and right halves).
- **
- ** Usage is: LJ file1 file2 file3 ...
- **
- ** Where file# is a valid MS-DOS filename, included on the command line.
- **
- ** Originally written by Joe Barnhart and subsequently modifed by:
- ** Ray Duncan and Chip Rabinowitz. This program has been placed in
- ** the public domain for use without profit.
- **
- ** Revised 9/86 for the Mark Williams C Programming System,
- ** Steven Stern, JMB Realty Corp.
- **
- ** Revised 11/86 for DOS wild card characters in the file name.
- **/
-
- #include "stdio.h"
- #include "dos.h"
-
- #define MAXLINE 66 /* maximum lines per page on LaserJet */
- #define TAB 5 /* width of one tab stop */
-
- FILE *lp, /* FILE pointer for lpt1 */
- *fp; /* FILE pointer for the file to be printed */
-
- /*
- * Structure of msdos date/time bit fields
- * These are defined on page C-5 of the IBM-PC DOS 2.0 manual
- */
- struct date {
- unsigned d_sec : 5; /* Time, 2 second intervals */
- unsigned d_min : 6; /* Time, minutes */
- unsigned d_hour : 5; /* Time, hours */
- unsigned d_day : 5; /* Date, day of month */
- unsigned d_month : 4; /* Date, month of year */
- unsigned d_year : 7; /* Date, year since 1980 */
- };
-
- /*
- * Structure filled in by msdos for FINDFIRST and FINDNEXT calls
- * This is defined of page D-49 of the IBM-PC DOS 2.0 manual
- *
- * The struct "dta" is here for use by DOS. DOS is instructed via
- * the SETDTA call to use this struct for it's storage of file information.
- */
-
- struct find {
- char fnd_dosinfo[21]; /* Reserved for dos */
- char fnd_attr; /* File attribute */
- struct date fnd_date; /* Date structure */
- long fnd_size; /* File size */
- char fnd_name[13]; /* File name less path */
- }dta;
-
- /*************************************************************************
-
- main
-
- *************************************************************************/
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int filenum;
- char fname[70];
- int fnamecnt;
- struct reg r;
-
- if (argc <= 1)
- {
- printf("I don't read minds.\n");
- exit(1);
- }
-
- r.r_ax = SETDTA; /* set up DOS disk transfer area */
- ptoreg(dsreg, r.r_dx, r.r_ds,&dta); /* address of global struct "dta" */
- intcall (&r, &r, DOSINT);
-
- /* initialize the LaserJet for landscape printing */
-
- lp = fopen("lpt1","w");
- fprintf( lp,"\033E\033&l1O\033(s17H\033&l5.14C\033&l70F\033&l7E" );
-
-
- for(filenum = 1; filenum < argc; filenum++ )
- {
- fnamecnt=0;
- while (next_file(&fnamecnt,argv[filenum])==0)
- {
- strcpy(fname,dta.fnd_name);
- expand_fname(fname);
- fp = fopen(fname ,"r");
- if( fp == NULL )
- {
- printf( "File %s doesn't exist.\n", fname );
- }
- else
- {
- printf( "Now printing %s\n", fname );
- printfile( fname );
- fclose( fp );
- }
- } /* of while wild-card expansion */
-
- if (fnamecnt == 0) /* wild-card produced no hits */
- {
- printf("No match found for %s\n",argv[filenum]);
- }
-
- } /* of loop through run-time args */
-
- fprintf( lp, "\r\033E" ); /* clear LaserJet */
- fclose(lp);
-
- }
-
- /*************************************************************************
-
- printfile (filename)
-
- *************************************************************************/
-
- printfile(filename)
- char *filename;
- {
- int pagenum = 1;
- int retval = 0;
-
- while( (feof(fp)==0) && (retval==0) )
- {
- fprintf(lp, "\033&a0r85m5L\r"); /* set LaserJet to left half */
- header(filename, pagenum++); /* title top of page */
- retval = printpage(); /* print one page */
- if(feof(fp)==0 && retval==0)
- { /* if more to print... */
- dovert();
- fprintf(lp, "\033&a0r171m91L\r"); /* LaserJet to right half */
- header(filename, pagenum++); /* title top of page */
- retval = printpage(); /* and print another page */
- }
- fputc('\f', lp); /* kick out paper */
- }
- return(0);
- }
-
- /*************************************************************************
-
- printpage
- print a logical page
-
- *************************************************************************/
-
- printpage()
- {
- char c;
- int line,col;
- static int cont = 0;
- static char *cont1 = "---->";
-
- line = col = 0;
- if(cont)
- {
- fprintf(lp,cont1);
- col = strlen(cont1);
- cont = 0;
- }
-
- while( line < MAXLINE )
- {
- c = fgetc(fp);
- if(col>=80)
- {
- line++;
- switch(c)
- {
- case '\n':
- case '\r':
- case '\f':
- case EOF:
- case '\377':
- case '\032':
- break;
- default:
- if(line >= MAXLINE)
- {
- cont = 1;
- ungetc(c,fp);
- return(0);
- }
- fprintf(lp,"\n%s",cont1);
- col = strlen(cont1);
- break;
- }
- }
- switch(c)
- {
- case '\n': /* newline found */
- col = 0; /* zero column and */
- line++; /* advance line count */
- if( line < MAXLINE )
- fprintf(lp,"\n");
- break;
- case '\r': /* CR found */
- break; /* discard it */
- case '\t': /* TAB found */
- do
- fputc(' ',lp);
- while ( (++col % TAB) != 0 );
- break;
- case '\f': /* Page break or */
- line = MAXLINE; /* force termination of loop */
- break;
- case EOF: /* EOF mark */
- case '\377': /* EOF mark */
- case '\032': /* EOF mark */
- return(-1);
- default: /* no special case */
- fputc(c,lp); /* print character */
- col++;
- break;
- }
- }
- return(0);
- }
-
- /*************************************************************************
-
- header
- print a page header
-
- *************************************************************************/
-
- header( filename, pagenum )
- char *filename;
- int pagenum;
- {
- char datestr[11], timestr[11];
-
- timestamp(timestr);
- datestamp(datestr);
- fprintf(lp, "File: %-40s%s %s -- Page: %03d\n\n",
- filename,datestr,timestr,pagenum);
- }
-
- timestamp( timestr )
- char *timestr;
- {
- int tod[7];
-
- gettime(tod);
-
- sprintf(timestr,"%02d:%02d",tod[3],tod[4]);
- return;
- }
-
- datestamp( datestr )
- char *datestr;
- {
- int tod[7];
-
- gettime(tod);
- sprintf(datestr,"%02d/%02d/%02d",tod[1],tod[2],tod[0]);
-
- return;
- }
-
- /*************************************************************************
-
- dovert()
- draw a vertical line down the center of the physical page
-
- *************************************************************************/
-
- dovert()
- {
- int line = 1;
-
- fprintf(lp,"\033&a0r90m88L\r|");
-
- while(line++ < MAXLINE+2) fprintf(lp,"\n|");
- }
-
- /*************************************************************************
-
- expand_fname
-
- fully expands a pc file name. I.e, given "ABC", will return
- <drive>:<\path\>ABC.
-
- usage:
- expand_fname(file)
-
- Note: The results are returned in the buffer "file", which must
- be long enough to accept the result (at least 65 bytes).
-
- This routine DOES NOT validate the contents of "file". If they do
- not form an acceptable DOS file name, the result is unpredicted.
- *************************************************************************/
-
- expand_fname(file)
-
- char *file;
-
- {
- struct reg r;
-
- char temp[100],
- drive,
- *tptr;
-
- int i;
-
- tptr = &temp[0];
-
- for (i=0; file[i]!='\0'; i++) /* copy w/o blanks */
- {
- if (file[i] != ' ')
- {
- *tptr = toupper(file[i]);
- tptr++;
- }
- }
- *tptr = '\0';
-
- tptr = &temp[0];
-
- if (*(tptr+1) == ':') /* drive specification */
- {
- drive = toupper(*tptr);
- tptr += 2;
- }
- else
- {
- r.r_ax = GETDISK; /* get the current drive */
- intcall (&r,&r,DOSINT);
- drive = r.r_ax + 'A';
- }
-
- if (*tptr == '\\') /* if start of path, we're done */
- {
- *file = drive;
- *(file+1) = ':';
- *(file+2) = '\0';
- strcat(file+2,tptr);
- return(0);
- }
-
- *file = drive;
- *(file+1) = ':';
- *(file+2) = '\\';
- *(file+3) = '\0';
- r.r_dx = drive + 1 - 'A';
- r.r_ax = GETCDIR;
- ptoreg (dsreg, r.r_si, r.r_ds, file+3);
- intcall (&r, &r, DOSINT);
-
- if (*(file+3) != '\0') strcat(file,"\\"); /* don't add slash if path */
- /* is null */
- strcat(file,tptr);
- return(0);
- }
- /*************************************************************************
-
- next_file
-
- get a file name from the user's input, processing wild cards, if any
-
- usage:
- i = next_file(&count,fname_as_supplied);
-
- parameters:
- count - a counter to track calls to this function. should be set to
- zero on the first call for a give fname_as_supplied.
- fname_- a null-terminated file name
-
- This function returns its matching file names in the global struct dta.
-
- The function value is set to zero if a file is found, and -1 otherwise.
-
- *************************************************************************/
-
- next_file(cnt,fstr)
- char *fstr;
- int *cnt;
-
- {
- struct reg r;
-
- if (*cnt==0)
- {
- r.r_ax = NFFIRST; /* Function code for FIND FIRST */
- r.r_cx = 0;
- ptoreg(dsreg, r.r_dx, r.r_ds, &fstr[0]); /* absolute address of str for DOS */
- intcall (&r, &r, DOSINT);
- if (r.r_ax == 2 || r.r_ax == 18) return(-1);
- }
-
- if (*cnt !=0)
- {
- r.r_ax = NFNEXT;
- intcall (&r, &r, DOSINT);
- if (r.r_ax==18)
- return(-1);
- }
-
- /* After a FINDFIRST service, DOS returns file information
- in the Disk Transfer Area. See Norton, function 0x4E, for
- layout of the DTA or FDIR.C, which came with the Mark
- Williams package */
-
- ++*cnt;
- return (0);
- }