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