|
|
1.1 ! root 1: #include <errno.h> ! 2: #include <signal.h> ! 3: #include <stdio.h> ! 4: #include <sgtty.h> ! 5: #include <pwd.h> ! 6: #include <sys/vcmd.h> ! 7: #include <vfont.h> ! 8: ! 9: /* ! 10: * Cat Simulator for Versatec and Varian ! 11: * Modified for Varian with rotated fonts: wnj 5/30/80. ! 12: * ! 13: * Takes two extra special codes defined by rvsort: ! 14: * 0115 - break for new page, goto (0,0) ! 15: * 0116 - lead 64* following byte ! 16: */ ! 17: ! 18: static char *sccsid ="@(#)rvcat.c 1.2 (Berkeley) 8/9/81"; ! 19: ! 20: int prtmode[] = {VPRINT, 0, 0}; ! 21: int pltmode[] = {VPLOT, 0, 0}; ! 22: ! 23: #define DISPATCHSIZE 256 /* must be a power of two */ ! 24: #define CHARMASK (DISPATCHSIZE-1) ! 25: #define NFONTS 25 ! 26: #define SPECIALFONT 3 ! 27: #define DSIZ ((sizeof *dispatch)*DISPATCHSIZE) ! 28: #define MAXF 4 ! 29: ! 30: #define LOCAL_RAILMAG ".railmag" ! 31: #define GLOBAL_RAILMAG "/usr/lib/vfont/railmag" ! 32: ! 33: /* ! 34: * Here we make up for the fact that we only have 2112 ! 35: * bits vertically when we need 2200 (11''*200/in), by ! 36: * a 4% vertical size squashing. ! 37: */ ! 38: #define CONVERT(n) ((n*(200./432.))*(2112./2200.)) ! 39: #define RECONVERT(n) ((n*(432./200.))*(2200./2112.)) ! 40: ! 41: #define VA_RASTER_LENGTH 2112 ! 42: ! 43: #define VA_BYTES_PER_LINE (VA_RASTER_LENGTH/8) ! 44: ! 45: #define NLINES 110 ! 46: #define VA_BUFFER_SIZE (NLINES*VA_BYTES_PER_LINE) ! 47: ! 48: #define FF_LINES 1600 /* Scan lines to output before formfeeding. */ ! 49: #define PAGE_LINES 1700 /* 8.5 inches * 200 lines/inch. */ ! 50: ! 51: #define TOF_TO_BOF (83-19+2) ! 52: #define BAN_TO_BOF (49-19+2) ! 53: ! 54: #define min(a,b) (a<b ? a : b) ! 55: ! 56: char buffer[VA_BUFFER_SIZE]; /* Big line buffers */ ! 57: char *buf0p = &buffer[0]; /* Zero origin in circular buffer */ ! 58: ! 59: char *calloc(); ! 60: char *nalloc(); ! 61: char *allpanic(); ! 62: char chrtab[][16]; ! 63: ! 64: struct header header; ! 65: struct dispatch *dispatch; ! 66: ! 67: struct fontdes { ! 68: int fnum; ! 69: int psize; ! 70: struct dispatch *disp; ! 71: char *bits; ! 72: } fontdes[NFONTS] = { ! 73: -1, ! 74: -1 ! 75: }; ! 76: ! 77: struct point_sizes { ! 78: int stupid_code; ! 79: int real_code; ! 80: } point_sizes[] = { ! 81: 010, 6, ! 82: 0, 7, ! 83: 01, 8, ! 84: 07, 9, ! 85: 02, 10, ! 86: 03, 11, ! 87: 04, 12, ! 88: 05, 14, ! 89: 0211, 16, ! 90: 06, 18, ! 91: 0212, 20, ! 92: 0213, 22, ! 93: 0214, 24, ! 94: 0215, 28, ! 95: 0216, 36, ! 96: 0, 0 ! 97: }; ! 98: ! 99: #define VA_FFLINES 2200 ! 100: #define VP_FFLINES 650 ! 101: #define VP_EOTLINES 1400 ! 102: #define VA_ACCTFILE "/usr/adm/vaacct" ! 103: #define VP_ACCTFILE "/usr/adm/vpacct" ! 104: ! 105: int lines; ! 106: ! 107: int vc; /* varian/versatec output file descriptor */ ! 108: int varian; /* 0 for versatec, 1 for varian. */ ! 109: int BYTES_PER_LINE; /* VA_BYTES_PER_LINE or VP_BYTES_PER_LINE. */ ! 110: int BUFFER_SIZE; /* VA_BUFFER_SIZE or VP_BUFFER_SIZE. */ ! 111: int cfnum = -1; ! 112: int cpsize = 10; ! 113: int cfont = 1; ! 114: char *bits; ! 115: int nfontnum = -1; ! 116: int fontwanted = 1; ! 117: int npsize = 10; ! 118: int last_ssize = 02; ! 119: int xpos, ypos; ! 120: int esc, lead, back, verd, mcase, railmag; ! 121: double row, col; ! 122: char *fontname[MAXF]; ! 123: char fnbuf[120]; ! 124: char *scanline; ! 125: int linecount; ! 126: ! 127: char asctab[128] = { ! 128: '\0', /*blank*/ ! 129: 'h', /*h*/ ! 130: 't', /*t*/ ! 131: 'n', /*n*/ ! 132: 'm', /*m*/ ! 133: 'l', /*l*/ ! 134: 'i', /*i*/ ! 135: 'z', /*z*/ ! 136: 's', /*s*/ ! 137: 'd', /*d*/ ! 138: 'b', /*b*/ ! 139: 'x', /*x*/ ! 140: 'f', /*f*/ ! 141: 'j', /*j*/ ! 142: 'u', /*u*/ ! 143: 'k', /*k*/ ! 144: '\0', /*blank*/ ! 145: 'p', /*p*/ ! 146: '\06', /*_ 3/4 em dash*/ ! 147: ';', /*;*/ ! 148: '\0', /*blank*/ ! 149: 'a', /*a*/ ! 150: '\05', /*rule*/ ! 151: 'c', /*c*/ ! 152: '`', /*` open*/ ! 153: 'e', /*e*/ ! 154: '\'', /*' close*/ ! 155: 'o', /*o*/ ! 156: '\021', /*1/4*/ ! 157: 'r', /*r*/ ! 158: '\022', /*1/2*/ ! 159: 'v', /*v*/ ! 160: '-', /*- hyphen*/ ! 161: 'w', /*w*/ ! 162: 'q', /*q*/ ! 163: '/', /*/*/ ! 164: '.', /*.*/ ! 165: 'g', /*g*/ ! 166: '\023', /*3/4*/ ! 167: ',', /*,*/ ! 168: '&', /*&*/ ! 169: 'y', /*y*/ ! 170: '\0', /*blank*/ ! 171: '%', /*%*/ ! 172: '\0', /*blank*/ ! 173: 'Q', /*Q*/ ! 174: 'T', /*T*/ ! 175: 'O', /*O*/ ! 176: 'H', /*H*/ ! 177: 'N', /*N*/ ! 178: 'M', /*M*/ ! 179: 'L', /*L*/ ! 180: 'R', /*R*/ ! 181: 'G', /*G*/ ! 182: 'I', /*I*/ ! 183: 'P', /*P*/ ! 184: 'C', /*C*/ ! 185: 'V', /*V*/ ! 186: 'E', /*E*/ ! 187: 'Z', /*Z*/ ! 188: 'D', /*D*/ ! 189: 'B', /*B*/ ! 190: 'S', /*S*/ ! 191: 'Y', /*Y*/ ! 192: '\0', /*blank*/ ! 193: 'F', /*F*/ ! 194: 'X', /*X*/ ! 195: 'A', /*A*/ ! 196: 'W', /*W*/ ! 197: 'J', /*J*/ ! 198: 'U', /*U*/ ! 199: 'K', /*K*/ ! 200: '0', /*0*/ ! 201: '1', /*1*/ ! 202: '2', /*2*/ ! 203: '3', /*3*/ ! 204: '4', /*4*/ ! 205: '5', /*5*/ ! 206: '6', /*6*/ ! 207: '7', /*7*/ ! 208: '8', /*8*/ ! 209: '9', /*9*/ ! 210: '*', /***/ ! 211: '\04', /*minus*/ ! 212: '\01', /*fi*/ ! 213: '\02', /*fl*/ ! 214: '\03', /*ff*/ ! 215: '\020', /* cent sign */ ! 216: '\012', /*ffl*/ ! 217: '\011', /*ffi*/ ! 218: '(', /*(*/ ! 219: ')', /*)*/ ! 220: '[', /*[*/ ! 221: ']', /*]*/ ! 222: '\013', /* degree */ ! 223: '\014', /* dagger */ ! 224: '=', /*=*/ ! 225: '\017', /* registered */ ! 226: ':', /*:*/ ! 227: '+', /*+*/ ! 228: '\0', /*blank*/ ! 229: '!', /*!*/ ! 230: '\07', /* bullet */ ! 231: '?', /*?*/ ! 232: '\015', /*foot mark*/ ! 233: '|', /*|*/ ! 234: '\0', /*blank*/ ! 235: '\016', /* copyright */ ! 236: '\010', /* square */ ! 237: '$', /*$*/ ! 238: '\0', ! 239: '\0', ! 240: '"', /*"*/ ! 241: '#', /*#*/ ! 242: '<', /*<*/ ! 243: '>', /*>*/ ! 244: '@', /*@*/ ! 245: '\\', /*\\*/ ! 246: '^', /*^*/ ! 247: '{', /*{*/ ! 248: '}', /*}*/ ! 249: '~' /*~*/ ! 250: }; ! 251: ! 252: char spectab[128] = { ! 253: '\0', /*blank*/ ! 254: 'w', /*psi*/ ! 255: 'h', /*theta*/ ! 256: 'm', /*nu*/ ! 257: 'l', /*mu*/ ! 258: 'k', /*lambda*/ ! 259: 'i', /*iota*/ ! 260: 'f', /*zeta*/ ! 261: 'r', /*sigma*/ ! 262: 'd', /*delta*/ ! 263: 'b', /*beta*/ ! 264: 'n', /*xi*/ ! 265: 'g', /*eta*/ ! 266: 'u', /*phi*/ ! 267: 't', /*upsilon*/ ! 268: 'j', /*kappa*/ ! 269: '\0', /*blank*/ ! 270: 'p', /*pi*/ ! 271: '@', /*at-sign*/ ! 272: '7', /*down arrow*/ ! 273: '\0', /*blank*/ ! 274: 'a', /*alpha*/ ! 275: '|', /*or*/ ! 276: 'v', /*chi*/ ! 277: '"', /*"*/ ! 278: 'e', /*epsilon*/ ! 279: '=', /*=*/ ! 280: 'o', /*omicron*/ ! 281: '4', /*left arrow*/ ! 282: 'q', /*rho*/ ! 283: '6', /*up arrow*/ ! 284: 's', /*tau*/ ! 285: '_', /*underrule*/ ! 286: '\\', /*\*/ ! 287: 'W', /*Psi*/ ! 288: '\07', /*bell system sign*/ ! 289: '\001', /*infinity*/ ! 290: 'c', /*gamma*/ ! 291: '\002', /*improper superset*/ ! 292: '\003', /*proportional to*/ ! 293: '\004', /*right hand*/ ! 294: 'x', /*omega*/ ! 295: '\0', /*blank*/ ! 296: '(', /*gradient*/ ! 297: '\0', /*blank*/ ! 298: 'U', /*Phi*/ ! 299: 'H', /*Theta*/ ! 300: 'X', /*Omega*/ ! 301: '\005', /*cup (union)*/ ! 302: '\006', /*root en*/ ! 303: '\014', /*terminal sigma*/ ! 304: 'K', /*Lambda*/ ! 305: '-', /*minus*/ ! 306: 'C', /*Gamma*/ ! 307: '\015', /*integral sign*/ ! 308: 'P', /*Pi*/ ! 309: '\032', /*subset of*/ ! 310: '\033', /*superset of*/ ! 311: '2', /*approximates*/ ! 312: 'y', /*partial derivative*/ ! 313: 'D', /*Delta*/ ! 314: '\013', /*square root*/ ! 315: 'R', /*Sigma*/ ! 316: '1', /*approx =*/ ! 317: '\0', /*blank*/ ! 318: '>', /*>*/ ! 319: 'N', /*Xi*/ ! 320: '<', /*<*/ ! 321: '\016', /*slash (longer)*/ ! 322: '\034', /*cap (intersection)*/ ! 323: 'T', /*Upsilon*/ ! 324: '\035', /*not*/ ! 325: '\023', /*right ceiling (rt of ")*/ ! 326: '\024', /*left top (of big curly)*/ ! 327: '\017', /*bold vertical*/ ! 328: '\030', /*left center of big curly bracket*/ ! 329: '\025', /*left bottom*/ ! 330: '\026', /*right top*/ ! 331: '\031', /*right center of big curly bracket*/ ! 332: '\027', /*right bot*/ ! 333: '\021', /*right floor (rb of ")*/ ! 334: '\020', /*left floor (left bot of big sq bract)*/ ! 335: '\022', /*left ceiling (lt of ")*/ ! 336: '*', /*multiply*/ ! 337: '/', /*divide*/ ! 338: '\010', /*plus-minus*/ ! 339: '\011', /*<=*/ ! 340: '\012', /*>=*/ ! 341: '0', /*identically equal*/ ! 342: '3', /*not equal*/ ! 343: '{', /*{*/ ! 344: '}', /*}*/ ! 345: '\'', /*' acute accent*/ ! 346: '\`', /*` grave accent*/ ! 347: '^', /*^*/ ! 348: '#', /*sharp*/ ! 349: '\036', /*left hand*/ ! 350: '\037', /*member of*/ ! 351: '~', /*~*/ ! 352: 'z', /*empty set*/ ! 353: '\0', /*blank*/ ! 354: 'Y', /*dbl dagger*/ ! 355: 'Z', /*box rule*/ ! 356: '9', /*asterisk*/ ! 357: '[', /*improper subset*/ ! 358: ']', /*circle*/ ! 359: '\0', /*blank*/ ! 360: '+', /*eqn plus*/ ! 361: '5', /*right arrow*/ ! 362: '8' /*section mark*/ ! 363: }; ! 364: ! 365: ! 366: onintr() ! 367: { ! 368: signal(SIGINT, SIG_IGN); ! 369: signal(SIGHUP, SIG_IGN); ! 370: signal(SIGTERM, SIG_IGN); ! 371: exit(1); ! 372: } ! 373: ! 374: main(argc, argv) ! 375: int argc; ! 376: char *argv[]; ! 377: { ! 378: register int wait = 0; ! 379: char *banarg; ! 380: ! 381: if (geteuid() == 0) { ! 382: nice(-40); nice(20); nice(-4); ! 383: setuid(1); /* daemon */ ! 384: } ! 385: if (signal(SIGINT, SIG_IGN) == SIG_DFL) { ! 386: signal(SIGPIPE, SIG_IGN); ! 387: signal(SIGINT, onintr); ! 388: signal(SIGHUP, onintr); ! 389: } else ! 390: signal(SIGHUP, SIG_IGN); ! 391: if (signal(SIGTERM, SIG_IGN) == SIG_DFL) ! 392: signal(SIGTERM, onintr); ! 393: argc--, argv++; ! 394: ! 395: varian = 1; /* Assume varian unless -W. */ ! 396: banarg = NULL; ! 397: BYTES_PER_LINE = VA_BYTES_PER_LINE; ! 398: BUFFER_SIZE = VA_BUFFER_SIZE; ! 399: ! 400: while (argc > 0 && argv[0][0] == '-') { ! 401: switch (argv[0][1]) { ! 402: ! 403: case 'W': /* Wide: the versatec. */ ! 404: /* ! 405: varian = 0; ! 406: BYTES_PER_LINE = VP_BYTES_PER_LINE; ! 407: BUFFER_SIZE = VP_BUFFER_SIZE; ! 408: */ ! 409: fprintf(stderr, "rvcat: -W not implemented\n"); ! 410: break; ! 411: ! 412: case 't': ! 413: vc = 1; ! 414: break; ! 415: ! 416: case 'w': ! 417: wait = 1; ! 418: break; ! 419: ! 420: case '3': ! 421: vc = 3; /* from vpd */ ! 422: break; ! 423: ! 424: case 'b': ! 425: if (argc != 1) { ! 426: banarg = argv[1]; ! 427: argc--, argv++; ! 428: } ! 429: break; ! 430: ! 431: default: ! 432: fprintf(stderr, "usage: rvcat [ -t ] [ -w ] [ -b banner ] [ file... ]\n"); ! 433: exit(1); ! 434: } ! 435: argc--, argv++; ! 436: } ! 437: if (vc == 0) { ! 438: /* directly to plotter */ ! 439: for (;;) { ! 440: extern int errno; ! 441: ! 442: if ((vc = open((varian ? "/dev/va0" : "/dev/vp0"), 1)) >= 0) ! 443: break; ! 444: if (!wait) ! 445: break; ! 446: if (errno != EIO && errno != ENXIO) ! 447: break; ! 448: sleep(10); ! 449: } ! 450: } ! 451: ioctl(vc, VSETSTATE, prtmode); ! 452: banner(banarg); ! 453: ioctl(vc, VSETSTATE, pltmode); ! 454: readrm(); ! 455: for (;;) { ! 456: if (argc > 0) { ! 457: if (freopen(argv[0], "r", stdin) == NULL) { ! 458: perror(argv[0]); ! 459: argc--, argv++; ! 460: continue; ! 461: } ! 462: argc--, argv++; ! 463: } ! 464: ofile(); ! 465: if (argc <= 0) ! 466: break; ! 467: ioctl(vc, VSETSTATE, prtmode); ! 468: if (varian) { ! 469: write(vc, "\014\0", 2); ! 470: } else ! 471: write (vc, "\n\n\n\n\n", 5); ! 472: ioctl(vc, VSETSTATE, pltmode); ! 473: } ! 474: ioctl(vc, VSETSTATE, prtmode); ! 475: account(banarg); ! 476: exit(0); ! 477: } ! 478: ! 479: readrm() ! 480: { ! 481: register int i; ! 482: register char *cp; ! 483: register int rmfd; ! 484: char c; ! 485: ! 486: if ((rmfd = open(LOCAL_RAILMAG, 0)) < 0) ! 487: if ((rmfd = open(GLOBAL_RAILMAG, 0)) < 0) { ! 488: fprintf(stderr, "No railmag file\n"); ! 489: exit(1); ! 490: } ! 491: cp = fnbuf; ! 492: for (i = 0; i < 4; i++) { ! 493: fontname[i] = cp; ! 494: while (read(rmfd, &c, 1) == 1 && c != '\n') ! 495: *cp++ = c; ! 496: *cp++ = '\0'; ! 497: } ! 498: close(rmfd); ! 499: } ! 500: ! 501: ofile() ! 502: { ! 503: register int c; ! 504: register int i; ! 505: double scol; ! 506: static int initialized; ! 507: ! 508: lines = 0; ! 509: while ((c = getchar()) != EOF) { ! 510: if (!c) ! 511: continue; ! 512: if (c & 0200) { ! 513: esc += (~c) & 0177; ! 514: continue; ! 515: } ! 516: if (esc) { ! 517: if (back) ! 518: esc = -esc; ! 519: col += esc; ! 520: esc = 0; ! 521: i = CONVERT(col); ! 522: while (i >= NLINES) { ! 523: slop_lines(15); ! 524: i = CONVERT(col); ! 525: } ! 526: ypos = i; ! 527: } ! 528: if ((c & 0377) < 0100) /* Purely for efficiency */ ! 529: goto normal_char; ! 530: switch (c) { ! 531: ! 532: case 0100: ! 533: esc = 0; ! 534: lead = 0; ! 535: linecount = 0; ! 536: verd = 0; ! 537: back = 0; ! 538: mcase = 0; ! 539: railmag = 0; ! 540: if (loadfont(railmag, cpsize) < 0) ! 541: fprintf(stderr, "Can't load initial font\n"); ! 542: if (initialized) ! 543: goto reset; ! 544: initialized = 1; ! 545: row = 0; ! 546: xpos = CONVERT(row); ! 547: for (c = 0; c < BUFFER_SIZE; c++) ! 548: buffer[c] = 0; ! 549: col = 0; ! 550: ypos = 0; ! 551: break; ! 552: ! 553: case 0101: /* lower rail */ ! 554: crail(railmag &= ~01); ! 555: break; ! 556: ! 557: case 0102: /* upper rail */ ! 558: crail(railmag |= 01); ! 559: break; ! 560: ! 561: case 0103: /* upper mag */ ! 562: crail(railmag |= 02); ! 563: break; ! 564: ! 565: case 0104: /* lower mag */ ! 566: crail(railmag &= ~02); ! 567: break; ! 568: ! 569: case 0105: /* lower case */ ! 570: mcase = 0; ! 571: break; ! 572: ! 573: case 0106: /* upper case */ ! 574: mcase = 0100; ! 575: break; ! 576: ! 577: case 0107: /* escape forward */ ! 578: back = 0; ! 579: break; ! 580: ! 581: case 0110: /* escape backwards */ ! 582: back = 1; ! 583: break; ! 584: ! 585: case 0111: /* stop */ ! 586: break; ! 587: ! 588: case 0112: /* lead forward */ ! 589: verd = 0; ! 590: break; ! 591: ! 592: case 0113: /* undefined */ ! 593: break; ! 594: ! 595: case 0114: /* lead backward */ ! 596: verd = 1; ! 597: break; ! 598: ! 599: case 0115: /* undefined */ ! 600: reset: ! 601: c = lines % PAGE_LINES; ! 602: while (c < FF_LINES) { ! 603: slop_lines(min(FF_LINES - c, NLINES)); ! 604: c = lines % PAGE_LINES; ! 605: } ! 606: new_page(PAGE_LINES - c); ! 607: break; ! 608: ! 609: case 0116: ! 610: lead = (getchar() & 0377) * 64; ! 611: goto leadin; ! 612: ! 613: case 0117: ! 614: break; ! 615: ! 616: default: ! 617: if ((c & 0340) == 0140) /* leading */ { ! 618: lead = (~c) & 037; ! 619: leadin: ! 620: if (verd) ! 621: lead = -lead; ! 622: row += lead*3; /* Lead is 3 units */ ! 623: xpos = CONVERT(row); ! 624: continue; ! 625: } ! 626: if ((c & 0360) == 0120) /* size change */ { ! 627: loadfont(railmag, findsize(c & 017)); ! 628: continue; ! 629: } ! 630: if (c & 0300) ! 631: continue; ! 632: ! 633: normal_char: ! 634: if (row < 0 || CONVERT(row) >= VA_RASTER_LENGTH) ! 635: continue; ! 636: c = (c & 077) | mcase; ! 637: outc(c); ! 638: } ! 639: } ! 640: out: ! 641: slop_lines(NLINES); ! 642: } ! 643: ! 644: findsize(code) ! 645: register int code; ! 646: { ! 647: register struct point_sizes *psp; ! 648: ! 649: psp = point_sizes; ! 650: while (psp->real_code != 0) { ! 651: if ((psp->stupid_code & 017) == code) ! 652: break; ! 653: psp++; ! 654: } ! 655: code = 0; ! 656: if (!(last_ssize & 0200) && (psp->stupid_code & 0200)) ! 657: code = -55; ! 658: else if ((last_ssize & 0200) && !(psp->stupid_code & 0200)) ! 659: code = 55; ! 660: if (back) ! 661: code = -code; ! 662: esc += code; ! 663: last_ssize = psp->stupid_code; ! 664: return (psp->real_code); ! 665: } ! 666: ! 667: account(who) ! 668: char *who; ! 669: { ! 670: register FILE *a; ! 671: ! 672: if (who == NULL) ! 673: return; ! 674: a = fopen(varian ? VA_ACCTFILE : VP_ACCTFILE, "a"); ! 675: if (a == NULL) ! 676: return; ! 677: /* ! 678: * Varian accounting is done by 8.5 inch pages; ! 679: * Versatec accounting is by the (12 inch) foot. ! 680: */ ! 681: fprintf(a, "t%6.2f\t%s\n", ! 682: (lines / 200.0) / (varian ? 8.5 : 12.0), who); ! 683: fclose(a); ! 684: } ! 685: ! 686: crail(nrail) ! 687: register int nrail; ! 688: { ! 689: register int psize; ! 690: ! 691: psize = cpsize; ! 692: if (fontwanted && psize != npsize) ! 693: psize = npsize; ! 694: loadfont(nrail, psize); ! 695: } ! 696: ! 697: ! 698: loadfont(fnum, size) ! 699: register int fnum; ! 700: register int size; ! 701: { ! 702: register int i; ! 703: char cbuf[80]; ! 704: ! 705: fontwanted = 0; ! 706: if (fnum == cfnum && size == cpsize) ! 707: return(0); ! 708: for (i = 0; i < NFONTS; i++) ! 709: if (fontdes[i].fnum == fnum && fontdes[i].psize == size) { ! 710: cfnum = fontdes[i].fnum; ! 711: cpsize = fontdes[i].psize; ! 712: dispatch = &fontdes[i].disp[0]; ! 713: bits = fontdes[i].bits; ! 714: cfont = i; ! 715: return (0); ! 716: } ! 717: if (fnum < 0 || fnum >= MAXF) { ! 718: fprintf(stderr, "Internal error: illegal font\n"); ! 719: return(-1); ! 720: } ! 721: nfontnum = fnum; ! 722: npsize = size; ! 723: fontwanted++; ! 724: return (0); ! 725: } ! 726: ! 727: ! 728: getfont() ! 729: { ! 730: register int fnum, size, font; ! 731: int d; ! 732: char cbuf[BUFSIZ]; ! 733: char *cp = cbuf; ! 734: char *dp; ! 735: ! 736: if (!fontwanted) ! 737: return(0); ! 738: fnum = nfontnum; ! 739: size = npsize; ! 740: sprintf(cbuf, "%s.%dr", fontname[fnum], size); ! 741: font = open(cbuf, 0); ! 742: if (font == -1) { ! 743: perror(cbuf); ! 744: fontwanted = 0; ! 745: return (-1); ! 746: } ! 747: if (read(font, &header, sizeof header)!=sizeof header || header.magic!=0436) ! 748: fprintf(stderr, "%s: Bad font file", cbuf); ! 749: else { ! 750: cfont = relfont(); ! 751: if (((bits=nalloc(header.size+DSIZ+1,1))== NULL) ! 752: && ((bits=allpanic(header.size+DSIZ+1))== NULL)) { ! 753: fprintf(stderr, "%s: ran out of memory\n", cbuf); ! 754: exit(1); ! 755: } else { ! 756: /* ! 757: * have allocated one chunk of mem for font, dispatch. ! 758: * get the dispatch addr, align to word boundary. ! 759: */ ! 760: d = (int) bits+header.size; ! 761: d += 1; ! 762: d &= ~1; ! 763: if (read(font, d, DSIZ)!=DSIZ ! 764: || read(font, bits, header.size)!=header.size) ! 765: fprintf(stderr, "bad font header"); ! 766: else { ! 767: close(font); ! 768: cfnum = fontdes[cfont].fnum = fnum; ! 769: cpsize = fontdes[cfont].psize = size; ! 770: fontdes[cfont].bits = bits; ! 771: fontdes[cfont].disp = (struct dispatch *) d; ! 772: dispatch = &fontdes[cfont].disp[0]; ! 773: fontwanted = 0; ! 774: return (0); ! 775: } ! 776: } ! 777: } ! 778: close(font); ! 779: fontwanted = 0; ! 780: return(-1); ! 781: } ! 782: ! 783: int lastloaded = -1; ! 784: ! 785: relfont() ! 786: { ! 787: register int newfont; ! 788: ! 789: newfont = lastloaded; ! 790: /* ! 791: * optimization for special font. since we think that usually ! 792: * there is only one character at a time from any special math ! 793: * font, make it the candidate for removal. ! 794: */ ! 795: if (fontdes[cfont].fnum != SPECIALFONT || fontdes[cfont].bits==0) ! 796: if (++newfont>=NFONTS) ! 797: newfont = 0; ! 798: lastloaded = newfont; ! 799: if ((int)fontdes[newfont].bits != -1 && fontdes[newfont].bits != 0) { ! 800: /* fprintf(stderr, "freeing position %d\n", newfont); */ ! 801: nfree(fontdes[newfont].bits); ! 802: } else ! 803: /* fprintf(stderr, "taking without freeing position %d\n", newfont); */ ! 804: ; ! 805: fontdes[newfont].bits = 0; ! 806: return (newfont); ! 807: } ! 808: ! 809: char * ! 810: allpanic(nbytes) ! 811: int nbytes; ! 812: { ! 813: register int i; ! 814: ! 815: for (i = 0; i <= NFONTS; i++) ! 816: if (fontdes[i].bits != (char *)-1 && fontdes[i].bits != (char *)0) ! 817: nfree(fontdes[i].bits); ! 818: lastloaded = cfont; ! 819: for (i = 0; i <= NFONTS; i++) { ! 820: fontdes[i].fnum = fontdes[i].psize = -1; ! 821: fontdes[i].bits = 0; ! 822: cfnum = cpsize = -1; ! 823: } ! 824: return(nalloc(nbytes,1)); ! 825: } ! 826: ! 827: int M[] = { 0xffffffff, 0xfefefefe, 0xfcfcfcfc, 0xf8f8f8f8, ! 828: 0xf0f0f0f0, 0xe0e0e0e0, 0xc0c0c0c0, 0x80808080, 0x0 }; ! 829: int N[] = { 0x00000000, 0x01010101, 0x03030303, 0x07070707, ! 830: 0x0f0f0f0f, 0x1f1f1f1f, 0x3f3f3f3f, 0x7f7f7f7f, 0xffffffff }; ! 831: int strim[] = { 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000, 0 }; ! 832: ! 833: outc(code) ! 834: int code; ! 835: { ! 836: char c; /* character to print */ ! 837: register struct dispatch *d; /* ptr to character font record */ ! 838: register char *addr; /* addr of font data */ ! 839: int llen; /* length of each font line */ ! 840: int nlines; /* number of font lines */ ! 841: register char *scanp; /* ptr to output buffer */ ! 842: int scanp_inc; /* increment to start of next buffer */ ! 843: int offset; /* bit offset to start of font data */ ! 844: int i; /* loop counter */ ! 845: register int count; /* font data ptr */ ! 846: register unsigned fontdata; /* font data temporary */ ! 847: register int off8; /* offset + 8 */ ! 848: int b0poff; /* bit offset back towards buf0p */ ! 849: ! 850: if (fontwanted) ! 851: getfont(); ! 852: if (railmag == SPECIALFONT) { ! 853: if ((c = spectab[code]) < 0) ! 854: return(0); ! 855: } else if ((c = asctab[code]) < 0) ! 856: return(0); ! 857: d = dispatch+c; ! 858: if (d->nbytes) { ! 859: addr = bits+d->addr; ! 860: llen = (d->down+d->up+7)/8; ! 861: nlines = d->left+d->right; ! 862: if (ypos+d->right >= NLINES) ! 863: slop_lines(ypos+d->right-NLINES+6); ! 864: b0poff = BYTES_PER_LINE*8 - 1 - (xpos+d->down); ! 865: scanp = ((ypos-d->left-1)*BYTES_PER_LINE+b0poff/8)+buf0p; ! 866: if (scanp < &buffer[0]) ! 867: scanp += BUFFER_SIZE; ! 868: scanp_inc = BYTES_PER_LINE-llen; ! 869: offset = -(b0poff&07); ! 870: off8 = offset+8; ! 871: for (i = 0; i < nlines; i++) { ! 872: if (scanp >= &buffer[BUFFER_SIZE]) ! 873: scanp -= BUFFER_SIZE; ! 874: count = llen; ! 875: if (scanp + count <= &buffer[BUFFER_SIZE]) ! 876: do { ! 877: fontdata = *(unsigned *)addr; ! 878: addr += 4; ! 879: if (count < 4) ! 880: fontdata &= ~strim[count]; ! 881: *(unsigned *)scanp |= (fontdata << offset) &~ M[off8]; ! 882: scanp++; ! 883: *(unsigned *)scanp |= (fontdata << off8) &~ N[off8]; ! 884: scanp += 3; ! 885: count -= 4; ! 886: } while (count > 0); ! 887: scanp += scanp_inc+count; ! 888: addr += count; ! 889: } ! 890: return (1); ! 891: } ! 892: return (0); ! 893: } ! 894: ! 895: slop_lines(ncols) ! 896: int ncols; ! 897: { ! 898: register int i, rcols; ! 899: ! 900: lines += ncols; ! 901: rcols = (&buffer[BUFFER_SIZE] - buf0p) / BYTES_PER_LINE; ! 902: if (rcols < ncols) { ! 903: if (write(vc, buf0p, BYTES_PER_LINE * rcols) < 0) ! 904: exit(1); ! 905: clear(buf0p, rcols * BYTES_PER_LINE); ! 906: buf0p = buffer; ! 907: ncols -= rcols; ! 908: ypos -= rcols; ! 909: col -= RECONVERT(rcols); ! 910: } ! 911: if (write(vc, buf0p, BYTES_PER_LINE * ncols) < 0) ! 912: exit(1); ! 913: clear(buf0p, BYTES_PER_LINE * ncols); ! 914: buf0p += BYTES_PER_LINE * ncols; ! 915: if (buf0p >= &buffer[BUFFER_SIZE]) ! 916: buf0p -= BUFFER_SIZE; ! 917: ypos -= ncols; ! 918: col -= RECONVERT(ncols); ! 919: } ! 920: ! 921: /*ARGSUSED*/ ! 922: clear(lp, nbytes) ! 923: int *lp; ! 924: int nbytes; ! 925: { ! 926: ! 927: asm("movc5 $0,(sp),$0,8(ap),*4(ap)"); ! 928: ! 929: } ! 930: ! 931: /* Start a new page by formfeeding, resetting buffer and column counters. */ ! 932: new_page(lines_left) ! 933: int lines_left; /* ... on page. */ ! 934: { ! 935: lines += lines_left; ! 936: buf0p = buffer; /* Clear out buffer and reset pointers. */ ! 937: clear(buf0p, BYTES_PER_LINE * NLINES); ! 938: row = 0; ! 939: col = 0; ! 940: xpos = CONVERT(row); ! 941: ypos = 0; ! 942: ioctl(vc, VSETSTATE, prtmode); ! 943: write (vc, "\014\0", 2); ! 944: ioctl(vc, VSETSTATE, pltmode); ! 945: } ! 946: ! 947: ! 948: char * ! 949: nalloc(i, j) ! 950: int i, j; ! 951: { ! 952: register char *cp; ! 953: ! 954: cp = calloc(i, j); ! 955: /* fprintf(stderr, "allocated %d bytes at %x\n", i * j, cp); */ ! 956: return(cp); ! 957: } ! 958: ! 959: nfree(cp) ! 960: char *cp; ! 961: { ! 962: ! 963: /* fprintf(stderr, "freeing at %x\n", cp); */ ! 964: free(cp); ! 965: } ! 966: ! 967: banner(s) ! 968: char *s; ! 969: { ! 970: long timeb; ! 971: register char *sp; ! 972: int i, j, t; ! 973: ! 974: if (!varian) { /* Versatec uses just a small banner. */ ! 975: if (s == NULL) /* No banner, just return. */ ! 976: return; ! 977: write(vc, s, strlen(s)); ! 978: write(vc, " ", 1); ! 979: time(&timeb); ! 980: write(vc, ctime(&timeb), 26); ! 981: return; ! 982: } ! 983: ! 984: if (s == NULL) { ! 985: write(vc, "\014\0", 2); ! 986: return; ! 987: } ! 988: newlines(8); ! 989: for (i=0; i<16; i++) ! 990: { ! 991: write(vc, " ", 16); ! 992: for (sp=s; *sp; sp++) ! 993: { ! 994: char obuf[10]; ! 995: char *cp = obuf; ! 996: ! 997: if (*sp<=' '|| *sp >'}') ! 998: continue; ! 999: *cp++ = ' ', *cp++ = ' '; ! 1000: t = chrtab[*sp - ' '][i]; ! 1001: for (j=7; j>=0; j--) ! 1002: if ((t>>j) & 01) ! 1003: *cp++ = 'X'; ! 1004: else ! 1005: *cp++ = ' '; ! 1006: write(vc, obuf, 10); ! 1007: } ! 1008: write (vc, " \n", 2); ! 1009: } ! 1010: newlines(8); ! 1011: write(vc, " ", 16); ! 1012: time(&timeb); ! 1013: write(vc, ctime(&timeb), 26); ! 1014: write(vc, "\014\0", 2); ! 1015: } ! 1016: ! 1017: newlines(count) ! 1018: int count; ! 1019: { ! 1020: char buf[100]; ! 1021: register int i; ! 1022: ! 1023: for (i = 0; i < count; i++) ! 1024: buf[i] = '\n'; ! 1025: buf[i] = '\0'; ! 1026: write(vc, buf, i+1); ! 1027: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.