home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PROGRAMS / UTILS / LASER / LJ2.ZIP / LJ2.C < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-10  |  11.1 KB  |  423 lines

  1. /**
  2.  **
  3.  **   LJ -- A printing utility for the HP LaserJet
  4.  **
  5.  **
  6.  **   This program prints a series of files on the LaserJet printer.  The
  7.  **   files are printed in a "landscape" font at 17 characters to the inch.
  8.  **   To take advantage of this density, two "pages" of information from
  9.  **   the file are printed on each piece of paper (left and right halves).
  10.  **
  11.  **   Usage is:       LJ  file1 file2 file3 ...
  12.  **
  13.  **   Where file# is a valid MS-DOS filename, included on the command line.
  14.  **
  15.  **   Originally written by Joe Barnhart and subsequently modifed by:
  16.  **     Ray Duncan and Chip Rabinowitz.  This program has been placed in
  17.  **     the public domain for use without profit.
  18.  **     
  19.  **   Revised 9/86 for the Mark Williams C Programming System,
  20.  **     Steven Stern, JMB Realty Corp.
  21.  **
  22.  **   Revised 11/86 for DOS wild card characters in the file name.
  23.  **/
  24.  
  25. #include "stdio.h"
  26. #include "dos.h"
  27.  
  28. #define MAXLINE 66         /* maximum lines per page on LaserJet */
  29. #define TAB   5            /* width of one tab stop */
  30.  
  31. FILE *lp,              /* FILE pointer for lpt1 */
  32.      *fp;              /* FILE pointer for the file to be printed */
  33.  
  34. /*
  35.  * Structure of msdos date/time bit fields
  36.  * These are defined on page C-5 of the IBM-PC DOS 2.0 manual
  37.  */
  38. struct date {
  39.    unsigned d_sec   : 5;   /* Time, 2 second intervals */
  40.    unsigned d_min   : 6;   /* Time, minutes */
  41.    unsigned d_hour  : 5;   /* Time, hours */
  42.    unsigned d_day   : 5;   /* Date, day of month */
  43.    unsigned d_month : 4;   /* Date, month of year */
  44.    unsigned d_year  : 7;   /* Date, year since 1980 */
  45. };
  46.  
  47. /*
  48.  * Structure filled in by msdos for FINDFIRST and FINDNEXT calls
  49.  * This is defined of page D-49 of the IBM-PC DOS 2.0 manual
  50.  *
  51.  * The struct "dta" is here for use by DOS.  DOS is instructed via
  52.  * the SETDTA call to use this struct for it's storage of file information.
  53.  */
  54.  
  55. struct find {
  56.    char   fnd_dosinfo[21];  /* Reserved for dos */
  57.    char   fnd_attr;         /* File attribute */
  58.    struct date fnd_date;    /* Date structure */
  59.    long   fnd_size;         /* File size */
  60.    char   fnd_name[13];     /* File name less path */
  61. }dta;
  62.  
  63. /*************************************************************************
  64.  
  65. main
  66.  
  67. *************************************************************************/
  68.  
  69. main(argc, argv)
  70. int argc;
  71. char *argv[];
  72. {
  73. int filenum;
  74. char fname[70];
  75. int fnamecnt;
  76. struct reg r;
  77.    
  78.    if (argc <= 1)
  79.       {
  80.       printf("I don't read minds.\n");
  81.       exit(1);
  82.       }
  83.       
  84.    r.r_ax = SETDTA;                     /* set up DOS disk transfer area */
  85.    ptoreg(dsreg, r.r_dx, r.r_ds,&dta); /* address of global struct "dta" */
  86.    intcall (&r, &r, DOSINT);
  87.  
  88. /* initialize the LaserJet for landscape printing */
  89.  
  90.    lp = fopen("lpt1","w");
  91.    fprintf( lp,"\033E\033&l1O\033(s17H\033&l5.14C\033&l70F\033&l7E" );
  92.  
  93.  
  94.    for(filenum = 1; filenum < argc; filenum++ )
  95.       {
  96.       fnamecnt=0;
  97.       while (next_file(&fnamecnt,argv[filenum])==0)
  98.          {
  99.          strcpy(fname,dta.fnd_name);
  100.          expand_fname(fname);
  101.          fp = fopen(fname ,"r");
  102.          if( fp == NULL )
  103.             {
  104.             printf( "File %s doesn't exist.\n", fname );
  105.             }
  106.          else 
  107.             {
  108.             printf( "Now printing %s\n", fname );
  109.             printfile( fname );
  110.             fclose( fp );
  111.             }
  112.          } /* of while wild-card expansion */
  113.       
  114.       if (fnamecnt == 0)              /* wild-card produced no hits */
  115.          {
  116.          printf("No match found for %s\n",argv[filenum]);
  117.          }
  118.          
  119.       }    /* of loop through run-time args */
  120.       
  121.    fprintf( lp, "\r\033E" );      /* clear LaserJet */
  122.    fclose(lp);
  123.  
  124. }
  125.  
  126. /*************************************************************************
  127.  
  128. printfile (filename)
  129.  
  130. *************************************************************************/
  131.  
  132. printfile(filename)
  133. char *filename;
  134. {
  135.    int pagenum = 1;
  136.    int retval = 0;
  137.  
  138.    while( (feof(fp)==0) && (retval==0) )
  139.       {
  140.       fprintf(lp, "\033&a0r85m5L\r");     /* set LaserJet to left half */
  141.       header(filename, pagenum++);          /* title top of page */
  142.       retval = printpage();                 /* print one page */
  143.       if(feof(fp)==0 && retval==0)
  144.          {                                  /* if more to print... */
  145.          dovert();
  146.          fprintf(lp, "\033&a0r171m91L\r");    /* LaserJet to right half */
  147.          header(filename, pagenum++);             /* title top of page */
  148.          retval = printpage();                  /* and print another page */
  149.          }
  150.       fputc('\f', lp);                          /* kick out paper */
  151.       }
  152.    return(0);
  153. }
  154.  
  155. /*************************************************************************
  156.  
  157. printpage
  158.    print a logical page
  159.    
  160. *************************************************************************/
  161.  
  162. printpage()
  163. {
  164.    char c;
  165.    int line,col;
  166.    static int cont = 0;
  167.    static char *cont1 = "---->";
  168.  
  169.    line = col = 0;
  170.    if(cont)
  171.       {
  172.       fprintf(lp,cont1);
  173.       col = strlen(cont1);
  174.       cont = 0;
  175.       }
  176.  
  177.    while( line < MAXLINE )
  178.       {
  179.       c = fgetc(fp);
  180.       if(col>=80)
  181.          {
  182.          line++;
  183.          switch(c)
  184.             {
  185.             case '\n':
  186.             case '\r':
  187.             case '\f':
  188.             case EOF:
  189.             case '\377':
  190.             case '\032':
  191.                break;
  192.             default:
  193.                if(line >= MAXLINE)
  194.                   {
  195.                   cont = 1;
  196.                   ungetc(c,fp);
  197.                   return(0);
  198.                   }
  199.                fprintf(lp,"\n%s",cont1);
  200.                col = strlen(cont1);
  201.                break;
  202.             }
  203.          }
  204.       switch(c)
  205.          {
  206.          case '\n':           /* newline found */
  207.             col = 0;          /* zero column and */
  208.             line++;           /* advance line count */
  209.             if( line < MAXLINE )
  210.                fprintf(lp,"\n");
  211.             break;
  212.          case '\r':           /* CR found */
  213.             break;            /* discard it */
  214.          case '\t':           /* TAB found */
  215.             do
  216.                fputc(' ',lp);
  217.             while ( (++col % TAB) != 0 );
  218.             break;
  219.          case '\f':              /* Page break or */
  220.             line = MAXLINE;      /* force termination of loop */
  221.             break;
  222.          case EOF:            /* EOF mark */
  223.          case '\377':         /* EOF mark */
  224.          case '\032':         /* EOF mark */
  225.             return(-1);
  226.          default:              /* no special case */
  227.             fputc(c,lp);       /* print character */
  228.             col++;
  229.             break;
  230.       }
  231.    }
  232.    return(0);
  233. }
  234.  
  235. /*************************************************************************
  236.  
  237. header
  238.    print a page header
  239.    
  240. *************************************************************************/
  241.  
  242. header( filename, pagenum )
  243. char *filename;
  244. int pagenum;
  245. {
  246.    char datestr[11], timestr[11];
  247.  
  248.    timestamp(timestr);
  249.    datestamp(datestr);
  250.    fprintf(lp, "File: %-40s%s   %s  --  Page: %03d\n\n", 
  251.       filename,datestr,timestr,pagenum);
  252. }
  253.  
  254. timestamp( timestr )
  255. char   *timestr;
  256. {
  257.    int tod[7];
  258.  
  259.    gettime(tod);
  260.  
  261.    sprintf(timestr,"%02d:%02d",tod[3],tod[4]);
  262.    return;
  263. }
  264.  
  265. datestamp( datestr )
  266. char  *datestr;
  267. {
  268.    int tod[7];
  269.  
  270.    gettime(tod);
  271.    sprintf(datestr,"%02d/%02d/%02d",tod[1],tod[2],tod[0]);
  272.  
  273.    return;
  274. }
  275.  
  276. /*************************************************************************
  277.  
  278. dovert()
  279.    draw a vertical line down the center of the physical page
  280.    
  281. *************************************************************************/
  282.  
  283. dovert()
  284. {
  285.    int line = 1;
  286.  
  287.    fprintf(lp,"\033&a0r90m88L\r|");
  288.    
  289.    while(line++ < MAXLINE+2) fprintf(lp,"\n|");
  290. }
  291.  
  292. /*************************************************************************
  293.  
  294. expand_fname
  295.  
  296. fully expands a pc file name.  I.e, given "ABC", will return 
  297. <drive>:<\path\>ABC.
  298.  
  299. usage:
  300.    expand_fname(file)
  301.  
  302.    Note:  The results are returned in the buffer "file", which must
  303.           be long enough to accept the result (at least 65 bytes).
  304.  
  305.    This routine DOES NOT validate the contents of "file". If they do
  306.    not form an acceptable DOS file name, the result is unpredicted.
  307. *************************************************************************/
  308.  
  309. expand_fname(file)
  310.  
  311. char *file;
  312.  
  313. {
  314.    struct reg r;
  315.  
  316.    char temp[100],
  317.         drive,
  318.         *tptr;
  319.         
  320.    int i;
  321.    
  322.    tptr = &temp[0];
  323.    
  324.    for (i=0; file[i]!='\0'; i++)      /* copy w/o blanks */
  325.       {
  326.       if (file[i] != ' ') 
  327.          {
  328.          *tptr = toupper(file[i]);
  329.          tptr++;
  330.          }
  331.       }
  332.    *tptr = '\0';
  333.    
  334.    tptr = &temp[0];
  335.    
  336.    if (*(tptr+1) == ':')             /* drive specification */
  337.       {
  338.       drive = toupper(*tptr);
  339.       tptr += 2;
  340.       }
  341.      else
  342.       {
  343.       r.r_ax = GETDISK;               /* get the current drive */
  344.       intcall (&r,&r,DOSINT);
  345.       drive = r.r_ax + 'A';
  346.       }
  347.       
  348.    if (*tptr == '\\')                /* if start of path, we're done */
  349.       {
  350.       *file = drive;
  351.       *(file+1) = ':';
  352.       *(file+2) = '\0';
  353.       strcat(file+2,tptr);
  354.       return(0);
  355.       }
  356.       
  357.    *file = drive;
  358.    *(file+1) = ':';
  359.    *(file+2) = '\\';   
  360.    *(file+3) = '\0';
  361.    r.r_dx = drive + 1 - 'A';
  362.    r.r_ax = GETCDIR;
  363.    ptoreg (dsreg, r.r_si, r.r_ds, file+3);
  364.    intcall (&r, &r, DOSINT);
  365.    
  366.    if (*(file+3) != '\0') strcat(file,"\\");   /* don't add slash if path */
  367.                                                /* is null */
  368.    strcat(file,tptr);
  369.    return(0);
  370.    }
  371. /*************************************************************************
  372.  
  373. next_file
  374.  
  375. get a file name from the user's input, processing wild cards, if any
  376.  
  377. usage:
  378.    i = next_file(&count,fname_as_supplied);
  379.    
  380. parameters:
  381.    count - a counter to track calls to this function.  should be set to
  382.            zero on the first call for a give fname_as_supplied.
  383.    fname_- a null-terminated file name
  384.    
  385. This function returns its matching file names in the global struct dta.
  386.  
  387. The function value is set to zero if a file is found, and -1 otherwise.
  388.  
  389. *************************************************************************/
  390.  
  391. next_file(cnt,fstr)
  392. char *fstr;
  393. int *cnt;
  394.  
  395.    {
  396.    struct reg r;
  397.  
  398.    if (*cnt==0)
  399.       {
  400.       r.r_ax = NFFIRST;    /* Function code for FIND FIRST */
  401.       r.r_cx = 0;
  402.       ptoreg(dsreg, r.r_dx, r.r_ds, &fstr[0]); /* absolute address of str for DOS */
  403.       intcall (&r, &r, DOSINT);
  404.       if (r.r_ax == 2 || r.r_ax == 18) return(-1);
  405.       }
  406.    
  407.    if (*cnt !=0)
  408.       {
  409.       r.r_ax = NFNEXT;
  410.       intcall (&r, &r, DOSINT);
  411.       if (r.r_ax==18)
  412.          return(-1);
  413.       }    
  414.      
  415.      /* After a FINDFIRST service, DOS returns file information
  416.         in the Disk Transfer Area.  See Norton, function 0x4E, for
  417.         layout of the DTA or FDIR.C, which came with the Mark
  418.         Williams package                                        */
  419.   
  420.    ++*cnt;
  421.    return (0);
  422.    }
  423.