1*1063Sbill static char *sccsid = "@(#)pr.c 4.1 (Berkeley) 10/01/80"; 2*1063Sbill /* 3*1063Sbill * print file with headings 4*1063Sbill * 2+head+2+page[56]+5 5*1063Sbill */ 6*1063Sbill 7*1063Sbill #include <stdio.h> 8*1063Sbill #include <signal.h> 9*1063Sbill #include <sys/types.h> 10*1063Sbill #include <sys/stat.h> 11*1063Sbill 12*1063Sbill /* Making putcp a macro sped things up by 14%. */ 13*1063Sbill #define putcp(c) if (page >= fpage) putchar(c) 14*1063Sbill 15*1063Sbill int ncol = 1; 16*1063Sbill char *header; 17*1063Sbill int col; 18*1063Sbill int icol; 19*1063Sbill FILE *file; 20*1063Sbill char *bufp; 21*1063Sbill #define BUFS 6720 22*1063Sbill char buffer[BUFS]; /* for multi-column output */ 23*1063Sbill char obuf[BUFSIZ]; 24*1063Sbill #define FF 014 25*1063Sbill int line; 26*1063Sbill char *colp[72]; 27*1063Sbill int nofile; 28*1063Sbill char isclosed[10]; 29*1063Sbill FILE *ifile[10]; 30*1063Sbill char **lastarg; 31*1063Sbill int peekc; 32*1063Sbill int fpage; 33*1063Sbill int page; 34*1063Sbill int colw; 35*1063Sbill int nspace; 36*1063Sbill int width = 72; 37*1063Sbill int length = 66; 38*1063Sbill int plength = 61; 39*1063Sbill int margin = 10; 40*1063Sbill int ntflg; 41*1063Sbill int fflg; 42*1063Sbill int mflg; 43*1063Sbill int tabc; 44*1063Sbill char *tty; 45*1063Sbill int mode; 46*1063Sbill char *ttyname(); 47*1063Sbill char *ctime(); 48*1063Sbill 49*1063Sbill main(argc, argv) 50*1063Sbill char **argv; 51*1063Sbill { 52*1063Sbill int nfdone; 53*1063Sbill int onintr(); 54*1063Sbill 55*1063Sbill setbuf(stdout, obuf); 56*1063Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) 57*1063Sbill signal(SIGINT, onintr); 58*1063Sbill lastarg = &argv[argc-1]; 59*1063Sbill fixtty(); 60*1063Sbill for (nfdone=0; argc>1; argc--) { 61*1063Sbill argv++; 62*1063Sbill if (**argv == '-') { 63*1063Sbill switch (*++*argv) { 64*1063Sbill case 'h': 65*1063Sbill if (argc>=2) { 66*1063Sbill header = *++argv; 67*1063Sbill argc--; 68*1063Sbill } 69*1063Sbill continue; 70*1063Sbill 71*1063Sbill case 't': 72*1063Sbill ntflg++; 73*1063Sbill continue; 74*1063Sbill 75*1063Sbill case 'f': 76*1063Sbill fflg++; 77*1063Sbill plength = 60; 78*1063Sbill continue; 79*1063Sbill 80*1063Sbill case 'l': 81*1063Sbill length = atoi(++*argv); 82*1063Sbill continue; 83*1063Sbill 84*1063Sbill case 'w': 85*1063Sbill width = atoi(++*argv); 86*1063Sbill continue; 87*1063Sbill 88*1063Sbill case 's': 89*1063Sbill if (*++*argv) 90*1063Sbill tabc = **argv; 91*1063Sbill else 92*1063Sbill tabc = '\t'; 93*1063Sbill continue; 94*1063Sbill 95*1063Sbill case 'm': 96*1063Sbill mflg++; 97*1063Sbill continue; 98*1063Sbill 99*1063Sbill default: 100*1063Sbill ncol = atoi(*argv); 101*1063Sbill continue; 102*1063Sbill } 103*1063Sbill } else if (**argv == '+') { 104*1063Sbill fpage = atoi(++*argv); 105*1063Sbill } else { 106*1063Sbill print(*argv, argv); 107*1063Sbill nfdone++; 108*1063Sbill if (mflg) 109*1063Sbill break; 110*1063Sbill } 111*1063Sbill } 112*1063Sbill if (nfdone==0) 113*1063Sbill print((char *)0, (char **)0); 114*1063Sbill done(); 115*1063Sbill } 116*1063Sbill 117*1063Sbill done() 118*1063Sbill { 119*1063Sbill 120*1063Sbill if (tty) 121*1063Sbill chmod(tty, mode); 122*1063Sbill exit(0); 123*1063Sbill } 124*1063Sbill 125*1063Sbill onintr() 126*1063Sbill { 127*1063Sbill 128*1063Sbill if (tty) 129*1063Sbill chmod(tty, mode); 130*1063Sbill _exit(1); 131*1063Sbill } 132*1063Sbill 133*1063Sbill fixtty() 134*1063Sbill { 135*1063Sbill struct stat sbuf; 136*1063Sbill 137*1063Sbill tty = ttyname(1); 138*1063Sbill if (tty == 0) 139*1063Sbill return; 140*1063Sbill stat(tty, &sbuf); 141*1063Sbill mode = sbuf.st_mode&0777; 142*1063Sbill chmod(tty, 0600); 143*1063Sbill } 144*1063Sbill 145*1063Sbill print(fp, argp) 146*1063Sbill char *fp; 147*1063Sbill char **argp; 148*1063Sbill { 149*1063Sbill extern char *sprintf(); 150*1063Sbill struct stat sbuf; 151*1063Sbill register sncol; 152*1063Sbill register char *sheader; 153*1063Sbill register char *cbuf; 154*1063Sbill char linebuf[150], *cp; 155*1063Sbill 156*1063Sbill if (ntflg) 157*1063Sbill margin = 0; 158*1063Sbill else 159*1063Sbill margin = 10; 160*1063Sbill if (length <= margin) 161*1063Sbill length = 66; 162*1063Sbill if (width <= 0) 163*1063Sbill width = 72; 164*1063Sbill if (ncol>72 || ncol>width) { 165*1063Sbill fprintf(stderr, "pr: No room for columns.\n"); 166*1063Sbill done(); 167*1063Sbill } 168*1063Sbill if (mflg) { 169*1063Sbill mopen(argp); 170*1063Sbill ncol = nofile; 171*1063Sbill } 172*1063Sbill colw = width/(ncol==0? 1 : ncol); 173*1063Sbill sncol = ncol; 174*1063Sbill sheader = header; 175*1063Sbill plength = length-5; 176*1063Sbill if (ntflg) 177*1063Sbill plength = length; 178*1063Sbill if (--ncol<0) 179*1063Sbill ncol = 0; 180*1063Sbill if (mflg) 181*1063Sbill fp = 0; 182*1063Sbill if (fp) { 183*1063Sbill if((file=fopen(fp, "r"))==NULL) { 184*1063Sbill if (tty==NULL) 185*1063Sbill fprintf(stderr, "pr: can't open %s\n", fp); 186*1063Sbill ncol = sncol; 187*1063Sbill header = sheader; 188*1063Sbill return; 189*1063Sbill } 190*1063Sbill stat(fp, &sbuf); 191*1063Sbill } else { 192*1063Sbill file = stdin; 193*1063Sbill time(&sbuf.st_mtime); 194*1063Sbill } 195*1063Sbill if (header == 0) 196*1063Sbill header = fp?fp:""; 197*1063Sbill cbuf = ctime(&sbuf.st_mtime); 198*1063Sbill cbuf[16] = '\0'; 199*1063Sbill cbuf[24] = '\0'; 200*1063Sbill page = 1; 201*1063Sbill icol = 0; 202*1063Sbill colp[ncol] = bufp = buffer; 203*1063Sbill if (mflg==0) 204*1063Sbill nexbuf(); 205*1063Sbill while (mflg&&nofile || (!mflg)&&tpgetc(ncol)>0) { 206*1063Sbill if (mflg==0) { 207*1063Sbill colp[ncol]--; 208*1063Sbill if (colp[ncol] < buffer) 209*1063Sbill colp[ncol] = &buffer[BUFS]; 210*1063Sbill } 211*1063Sbill line = 0; 212*1063Sbill if (ntflg==0) { 213*1063Sbill if (fflg) { 214*1063Sbill /* Assume a ff takes two blank lines at the 215*1063Sbill top of the page. */ 216*1063Sbill line = 2; 217*1063Sbill sprintf(linebuf, "%s %s %s Page %d\n\n\n", 218*1063Sbill cbuf+4, cbuf+20, header, page); 219*1063Sbill } else 220*1063Sbill sprintf(linebuf, "\n\n%s %s %s Page %d\n\n\n", 221*1063Sbill cbuf+4, cbuf+20, header, page); 222*1063Sbill for(cp=linebuf;*cp;) put(*cp++); 223*1063Sbill } 224*1063Sbill putpage(); 225*1063Sbill if (ntflg==0) { 226*1063Sbill if (fflg) 227*1063Sbill put('\f'); 228*1063Sbill else 229*1063Sbill while(line<length) 230*1063Sbill put('\n'); 231*1063Sbill } 232*1063Sbill page++; 233*1063Sbill } 234*1063Sbill fclose(file); 235*1063Sbill ncol = sncol; 236*1063Sbill header = sheader; 237*1063Sbill } 238*1063Sbill 239*1063Sbill mopen(ap) 240*1063Sbill char **ap; 241*1063Sbill { 242*1063Sbill register char **p, *p1; 243*1063Sbill 244*1063Sbill p = ap; 245*1063Sbill while((p1 = *p) && p++ <= lastarg) { 246*1063Sbill if((ifile[nofile]=fopen(p1, "r")) == NULL){ 247*1063Sbill isclosed[nofile] = 1; 248*1063Sbill nofile--; 249*1063Sbill } 250*1063Sbill else 251*1063Sbill isclosed[nofile] = 0; 252*1063Sbill if(++nofile>=10) { 253*1063Sbill fprintf(stderr, "pr: Too many args\n"); 254*1063Sbill done(); 255*1063Sbill } 256*1063Sbill } 257*1063Sbill } 258*1063Sbill 259*1063Sbill putpage() 260*1063Sbill { 261*1063Sbill register int lastcol, i, c; 262*1063Sbill int j; 263*1063Sbill 264*1063Sbill if (ncol==0) { 265*1063Sbill while (line<plength) { 266*1063Sbill while((c = tpgetc(0)) && c!='\n' && c!=FF) 267*1063Sbill putcp(c); 268*1063Sbill putcp('\n'); 269*1063Sbill line++; 270*1063Sbill if (c==FF) 271*1063Sbill break; 272*1063Sbill } 273*1063Sbill return; 274*1063Sbill } 275*1063Sbill colp[0] = colp[ncol]; 276*1063Sbill if (mflg==0) for (i=1; i<=ncol; i++) { 277*1063Sbill colp[i] = colp[i-1]; 278*1063Sbill for (j = margin; j<length; j++) 279*1063Sbill while((c=tpgetc(i))!='\n') 280*1063Sbill if (c==0) 281*1063Sbill break; 282*1063Sbill } 283*1063Sbill while (line<plength) { 284*1063Sbill lastcol = colw; 285*1063Sbill for (i=0; i<ncol; i++) { 286*1063Sbill while ((c=pgetc(i)) && c!='\n') 287*1063Sbill if (col<lastcol || tabc!=0) 288*1063Sbill put(c); 289*1063Sbill if (c==0) 290*1063Sbill continue; 291*1063Sbill if (tabc) 292*1063Sbill put(tabc); 293*1063Sbill else while (col<lastcol) 294*1063Sbill put(' '); 295*1063Sbill lastcol += colw; 296*1063Sbill } 297*1063Sbill while ((c = pgetc(ncol)) && c!='\n') 298*1063Sbill put(c); 299*1063Sbill put('\n'); 300*1063Sbill } 301*1063Sbill } 302*1063Sbill 303*1063Sbill nexbuf() 304*1063Sbill { 305*1063Sbill register int n; 306*1063Sbill register char *rbufp; 307*1063Sbill 308*1063Sbill rbufp = bufp; 309*1063Sbill n = &buffer[BUFS] - rbufp; 310*1063Sbill if (n>512) 311*1063Sbill n = 512; 312*1063Sbill if((n=fread(rbufp,1,n,file)) <= 0){ 313*1063Sbill fclose(file); 314*1063Sbill *rbufp = 0376; 315*1063Sbill } 316*1063Sbill else { 317*1063Sbill rbufp += n; 318*1063Sbill if (rbufp >= &buffer[BUFS]) 319*1063Sbill rbufp = buffer; 320*1063Sbill *rbufp = 0375; 321*1063Sbill } 322*1063Sbill bufp = rbufp; 323*1063Sbill } 324*1063Sbill 325*1063Sbill tpgetc(ai) 326*1063Sbill { 327*1063Sbill register char **p; 328*1063Sbill register int c, i; 329*1063Sbill 330*1063Sbill i = ai; 331*1063Sbill if (mflg) { 332*1063Sbill if((c=getc(ifile[i])) == EOF) { 333*1063Sbill if (isclosed[i]==0) { 334*1063Sbill isclosed[i] = 1; 335*1063Sbill if (--nofile <= 0) 336*1063Sbill return(0); 337*1063Sbill } 338*1063Sbill return('\n'); 339*1063Sbill } 340*1063Sbill if (c==FF && ncol>0) 341*1063Sbill c = '\n'; 342*1063Sbill return(c); 343*1063Sbill } 344*1063Sbill loop: 345*1063Sbill c = **(p = &colp[i]) & 0377; 346*1063Sbill if (c == 0375) { 347*1063Sbill nexbuf(); 348*1063Sbill c = **p & 0377; 349*1063Sbill } 350*1063Sbill if (c == 0376) 351*1063Sbill return(0); 352*1063Sbill (*p)++; 353*1063Sbill if (*p >= &buffer[BUFS]) 354*1063Sbill *p = buffer; 355*1063Sbill if (c==0) 356*1063Sbill goto loop; 357*1063Sbill return(c); 358*1063Sbill } 359*1063Sbill 360*1063Sbill pgetc(i) 361*1063Sbill { 362*1063Sbill register int c; 363*1063Sbill 364*1063Sbill if (peekc) { 365*1063Sbill c = peekc; 366*1063Sbill peekc = 0; 367*1063Sbill } else 368*1063Sbill c = tpgetc(i); 369*1063Sbill if (tabc) 370*1063Sbill return(c); 371*1063Sbill switch (c) { 372*1063Sbill 373*1063Sbill case '\t': 374*1063Sbill icol++; 375*1063Sbill if ((icol&07) != 0) 376*1063Sbill peekc = '\t'; 377*1063Sbill return(' '); 378*1063Sbill 379*1063Sbill case '\n': 380*1063Sbill icol = 0; 381*1063Sbill break; 382*1063Sbill 383*1063Sbill case 010: 384*1063Sbill case 033: 385*1063Sbill icol--; 386*1063Sbill break; 387*1063Sbill } 388*1063Sbill if (c >= ' ') 389*1063Sbill icol++; 390*1063Sbill return(c); 391*1063Sbill } 392*1063Sbill put(ac) 393*1063Sbill { 394*1063Sbill register int ns, c; 395*1063Sbill 396*1063Sbill c = ac; 397*1063Sbill if (tabc) { 398*1063Sbill putcp(c); 399*1063Sbill if (c=='\n') 400*1063Sbill line++; 401*1063Sbill return; 402*1063Sbill } 403*1063Sbill switch (c) { 404*1063Sbill 405*1063Sbill case ' ': 406*1063Sbill nspace++; 407*1063Sbill col++; 408*1063Sbill return; 409*1063Sbill 410*1063Sbill case '\n': 411*1063Sbill col = 0; 412*1063Sbill nspace = 0; 413*1063Sbill line++; 414*1063Sbill break; 415*1063Sbill 416*1063Sbill case 010: 417*1063Sbill case 033: 418*1063Sbill if (--col<0) 419*1063Sbill col = 0; 420*1063Sbill if (--nspace<0) 421*1063Sbill nspace = 0; 422*1063Sbill 423*1063Sbill } 424*1063Sbill while(nspace) { 425*1063Sbill if (nspace>2 && col > (ns=((col-nspace)|07))) { 426*1063Sbill nspace = col-ns-1; 427*1063Sbill putcp('\t'); 428*1063Sbill } else { 429*1063Sbill nspace--; 430*1063Sbill putcp(' '); 431*1063Sbill } 432*1063Sbill } 433*1063Sbill if (c >= ' ') 434*1063Sbill col++; 435*1063Sbill putcp(c); 436*1063Sbill } 437