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