|
|
1.1 ! root 1: /************************************************************************ ! 2: * * ! 3: * dlpt - download a CCI POWERTERMINAL or POWERTERMINAL II * ! 4: * * ! 5: ************************************************************************/ ! 6: ! 7: /************************************************************************ ! 8: * Compilation Notes -- * ! 9: * * ! 10: * - The symbol V7 must be defined when compiling for Version 7 * ! 11: * or Berkeley 4.2. * ! 12: * - No flags are needed when compiling for S3. * ! 13: * - This file contains the changes to support the new Berkeley * ! 14: * 4.2 signaling mechanism that were present at one point, then * ! 15: * deleted, and were restored in version 2.3.1. These changes * ! 16: * are required to make timed-out reads work correctly. * ! 17: * Compile with NEWSEG set to get these changes. * ! 18: * * ! 19: ************************************************************************/ ! 20: ! 21: /************************************************************************ ! 22: Version 1.2.1 changes: ! 23: ! 24: MDS 3/13/84 Implemented logic to circumvent 5/20 CPU port ! 25: problem. CPU port loses input characters ! 26: transmitted by the terminal at 9600 baud. ! 27: Therefore, if this program receives an invalid ! 28: DA response and it is talking to a cpu port, ! 29: then act as if a valid ROM DA response was ! 30: received. ! 31: Implemented "force" option. If specicified at ! 32: execution time the receipt of an invalid DA ! 33: response will be treated as a valid ROM DA ! 34: response. ! 35: ! 36: ************************************************************************* ! 37: ! 38: Version 2.0.0 changes: ! 39: ! 40: MDS 11/6/84 Implemented logic to support CCI POWERTERMINAL II. ! 41: ! 42: ************************************************************************* ! 43: ! 44: Version 2.1.0 changes: ! 45: ! 46: Version 2.1 is an interim version of dlpt created ! 47: by OSG. ! 48: ! 49: ************************************************************************* ! 50: ! 51: Version 2.2.0 changes: ! 52: ! 53: SP & BM @osg ! 54: MDS 2/20/85 1) -a prompt came up twice on PT1 when 'n' ! 55: given. Fixed. ! 56: 2) If tty is tty01 or console, and dlpt ! 57: cannot determine terminal type, message is ! 58: given for user to manually 'dlpt -f[12]'. ! 59: 3) Added argument check to -t option to prevent ! 60: core dump if no arguments given with -t. ! 61: 4) In function whoisit() changed fputs to write. ! 62: Fputs did not work on PERPOS-S. ! 63: 5) Removed CR1 from ttyinit() for System 3. ! 64: CR1 caused a NULL,ACK to be output after CR ! 65: in Terminal loaded message. ! 66: 6) Added XOFF/XON recognition to download by ! 67: adding IXON to ttyinit(). ! 68: 7) Changed source to default compile for S3 ! 69: instead of V7. For V7 need to set V7 flag. ! 70: ! 71: ************************************************************************* ! 72: ! 73: Version 2.3.0 changes: ! 74: ! 75: BJM @osg ! 76: BJM 3/6/85 Added XON/XOFF recognition to download for ! 77: Version 7 and Berkeley 4.2 version by setting ! 78: port to CBREAK mode for 'normal' download and ! 79: RAW mode for download in reliability mode. ! 80: ! 81: Added conditional compilation statements for ! 82: 19.2K baud. ! 83: ! 84: ************************************************************************* ! 85: ! 86: Version 2.3.1 changes: ! 87: ! 88: woe@ccicpg ! 89: WOE 6/17/85 Restored changes for new Berkeley 4.2 signalling ! 90: mechanisms under the compile-time define NEWSIG. ! 91: Timed-out reads require these changes since the ! 92: read system call is "automatically" retried when ! 93: interrupted by a SIGALRM (or any other handled/ ! 94: ignored signal). ! 95: ! 96: *************************************************************************/ ! 97: ! 98: ! 99: /************************************************************************ ! 100: * * ! 101: * Include files. * ! 102: * * ! 103: ************************************************************************/ ! 104: ! 105: #include "stdio.h" ! 106: #include "signal.h" ! 107: ! 108: #ifdef V7 /********* if Version 7 *********/ ! 109: ! 110: #include "sgtty.h" ! 111: ! 112: #else /********* else assume System 3 *********/ ! 113: ! 114: #include "termio.h" ! 115: ! 116: #endif /********* end of System 3 *********/ ! 117: ! 118: #ifdef NEWSIG /* new signal mechanism */ ! 119: #include <setjmp.h> ! 120: #endif ! 121: ! 122: /************************************************************************ ! 123: * * ! 124: * Defines. * ! 125: * * ! 126: ************************************************************************/ ! 127: ! 128: #define VERSION "2.3.1" /* version to be displayed by -v option */ ! 129: ! 130: typedef int BOOL; ! 131: ! 132: #define PT1_DEFLD "/lib/pt/DEFAULT.LD" /* default download file */ ! 133: #define PT2_DEFLD "/lib/pt/PT2DEF.LD" /* default download file */ ! 134: #define TTY_PREFIX "/dev/" /* appended to -t field */ ! 135: ! 136: #define STX 0x02 /* cntrl b */ ! 137: #define ENQ 0x05 /* cntrl e */ ! 138: #define ACK 0x06 /* cntrl f */ ! 139: #define CAN 0x18 /* cntrl x */ ! 140: #define BELL 0x07 /* cntrl g */ ! 141: ! 142: #define INVRESP 0 /* signal no valid DA response from tty */ ! 143: #define PT1ROM 1 /* signal that PT1 ROM responded to DA */ ! 144: #define PT1RAM 2 /* signal that PT1 RAM responded to DA */ ! 145: #define PT2ROM 3 /* signal that PT2 ROM responded to DA */ ! 146: #define PT2RAM 4 /* signal that PT2 RAM responded to DA */ ! 147: ! 148: #define TRUE 1 ! 149: #define FALSE 0 ! 150: ! 151: #define STX_TIMES 3 /* Number of times to send STX block */ ! 152: #define NRETRIES 10 /* Number of retries for load block */ ! 153: #define LD_TIMEOUT 2 /* Loading timeout period */ ! 154: ! 155: /************************************************************************ ! 156: * * ! 157: * Local functions and variables. * ! 158: * * ! 159: ************************************************************************/ ! 160: ! 161: #ifdef NEWSIG /* new signal mechanism */ ! 162: jmp_buf jb; ! 163: #else ! 164: #define timoread read ! 165: #define timowrite write ! 166: #endif ! 167: ! 168: char stxrec [] = {STX,STX,STX,STX,STX,STX,STX,STX,STX,STX}; ! 169: char nulls [15]; ! 170: char can = CAN; ! 171: char enq = ENQ; ! 172: char ack = ACK; ! 173: char devname[25] = TTY_PREFIX; ! 174: ! 175: int nullcnt = 14; ! 176: int timout; ! 177: int bailout(); ! 178: int toterm; /* to terminal file descriptor */ ! 179: int fromterm; /* from terminal file descriptor */ ! 180: ! 181: ! 182: #ifdef V7 /********* if Version 7 *********/ ! 183: ! 184: char baudrate; /* baudrate , set by ttysave or main */ ! 185: ! 186: #else /********* else assume System 3 *********/ ! 187: ! 188: unsigned short baudrate; /* baudrate , set by ttysave or main */ ! 189: ! 190: #endif /********* end of System 3 *********/ ! 191: ! 192: ! 193: char *myname; /* name of this program */ ! 194: ! 195: BOOL rflag = FALSE; /* reliability mode */ ! 196: char fflag = 0; /* force mode (used if inv DA response */ ! 197: char *intro[] = { ! 198: "\n", ! 199: "DO YOU WANT A TERMINAL LOAD SEQUENCE?", ! 200: " ", ! 201: " If you do not answer within 15 seconds,", ! 202: " the terminal load sequence will begin.", ! 203: " ", ! 204: "ENTER: y <return> or <return> to load ", ! 205: " n <return> to avoid load :", ! 206: NULL ! 207: }; ! 208: ! 209: char *wrong[] = { "INVALID ANSWER", ! 210: NULL ! 211: }; ! 212: ! 213: char *loading[]={ ! 214: "\n", ! 215: "Terminal load in progress", ! 216: NULL ! 217: }; ! 218: ! 219: ! 220: /************************************************************************ ! 221: * * ! 222: * main - Do it. * ! 223: * * ! 224: ************************************************************************/ ! 225: ! 226: int ! 227: main (argc, argv) ! 228: int argc; ! 229: char **argv; ! 230: { ! 231: char *pt1file; ! 232: char *pt2file; ! 233: int who; /* who is responding */ ! 234: char *ttyname(); ! 235: BOOL aflag = FALSE; /* TRUE if inquire wanted before load */ ! 236: ! 237: myname = *argv++; /* get the name of this program */ ! 238: --argc; ! 239: ! 240: ttysave(); /* save ioctl params and init default baudrate */ ! 241: ! 242: pt1file = PT1_DEFLD; /* set default hex file for load */ ! 243: pt2file = PT2_DEFLD; /* set default hex file for load */ ! 244: ! 245: while( argc-- ) /* while there are arguments to process */ ! 246: { ! 247: if( **argv == '-' ) /* while flags left */ ! 248: { ! 249: char *fptr = *argv; /* get ptr to flags */ ! 250: ! 251: while( *++fptr ) /* while flags left */ ! 252: { ! 253: char atobaud(); ! 254: ! 255: switch( *fptr ) /* process a flag */ ! 256: { ! 257: ! 258: case 'a': /* ask if load wanted */ ! 259: aflag = TRUE; ! 260: break; ! 261: ! 262: case 'b': /* specific baud rate */ ! 263: if( fptr[1] != '\0' ) ! 264: { ! 265: baudrate = atobaud(++fptr); ! 266: if(baudrate == (char) -1 ) ! 267: { ! 268: fprintf(stderr, ! 269: "%s: %s - invalid baud\n", ! 270: myname, fptr); ! 271: usage(); ! 272: } ! 273: fptr = "x"; /* fake out */ ! 274: break; ! 275: } ! 276: else ! 277: { ! 278: if( argc < 1 ) ! 279: usage(); ! 280: baudrate = atobaud(*++argv); ! 281: --argc; ! 282: if(baudrate == (char) -1 ) ! 283: { ! 284: fprintf(stderr, ! 285: "%s: %s - invalid baud\n", ! 286: myname, *argv); ! 287: usage(); ! 288: } ! 289: } ! 290: break; ! 291: ! 292: case 'f': /* force mode * ! 293: * to force load if * ! 294: * invalid DA response */ ! 295: /* get type '1' or '2' for * ! 296: * PT1 or PT2 */ ! 297: fflag = *++fptr; ! 298: break; ! 299: ! 300: case 'r': /*reliability mode */ ! 301: rflag = TRUE; ! 302: break; ! 303: ! 304: case 't': /* specific port */ ! 305: if( fptr[1] != 0 ) ! 306: { ! 307: strcat(devname,++fptr); ! 308: fptr = "x"; /* fake out */ ! 309: } ! 310: else ! 311: { ! 312: if( argc < 1 ) ! 313: usage(); ! 314: strcat(devname, *++argv); ! 315: --argc; ! 316: } ! 317: if(freopen(devname,"w",stdout) == ! 318: (FILE *)NULL) ! 319: { ! 320: fprintf(stderr, ! 321: "%s: cannot open port for write - %s\n", ! 322: myname,devname); ! 323: usage(); ! 324: } ! 325: if(freopen(devname,"r",stdin) == ! 326: (FILE *)NULL) ! 327: { ! 328: fprintf(stderr, ! 329: "%s: cannot open port for read - %s\n", ! 330: myname,devname); ! 331: usage(); ! 332: } ! 333: break; ! 334: ! 335: case 'v': /* display version */ ! 336: printf("%s: Version %s\n",myname, ! 337: VERSION); ! 338: exit(0); ! 339: break; ! 340: ! 341: default: ! 342: fprintf(stderr, ! 343: "%s: %c - unknown flag\n", ! 344: myname, *fptr); ! 345: usage(); ! 346: break; ! 347: } ! 348: } ! 349: } ! 350: else ! 351: { ! 352: pt1file = *argv; ! 353: pt2file = *argv; ! 354: } ! 355: ++argv; ! 356: } ! 357: ! 358: signal (SIGALRM, bailout); ! 359: toterm = 1; /* standard output */ ! 360: fromterm = 0; /* standard input */ ! 361: ! 362: who = whoisit(); /* find out who is there */ ! 363: ! 364: if( who == INVRESP ) /* if an invalid or no response */ ! 365: switch( fflag ) { /* check for force wanted */ ! 366: case '1': /* if PT1 force wanted */ ! 367: who = PT1ROM; /* force a PT1 download */ ! 368: break; ! 369: ! 370: case '2': /* if PT2 force wanted */ ! 371: who = PT2ROM; /* force a PT2 download */ ! 372: break; ! 373: ! 374: default: { /* else no force */ ! 375: char *devwho; ! 376: devwho = ttyname(toterm); /* get name of port */ ! 377: if ((strcmp(devwho,"/dev/console") == 0) || ! 378: (strcmp(devwho,"/dev/tty01") == 0)) { ! 379: printf( ! 380: "%s: from console or tty01, enter 'dlpt -f#'\n-f1 for PT1, -f2 for PT2\n", myname); ! 381: ttyrestore(); ! 382: exit(0); ! 383: } ! 384: break; ! 385: } ! 386: } ! 387: ! 388: switch( who ) /* depending on who responded */ ! 389: { ! 390: case PT1RAM: /* is a downloaded PT1 ( CT ) */ ! 391: case PT2RAM: /* is a downloaded PT2 */ ! 392: ttytalk(); ! 393: printf("\r\nTerminal loaded\r\n"); ! 394: break; ! 395: ! 396: case PT1ROM: /* is a non-downloaded PT1 */ ! 397: if((!aflag) || ((aflag) && (wantptload()))) ! 398: { ! 399: ttytalk(); ! 400: putmsg(loading, 0); ! 401: dlpt1(pt1file); /* load terminal */ ! 402: ! 403: /************************************************ ! 404: * NOTE: If terminal DTR is tied to CPU DCD * ! 405: * AND the terminal firmware re-initializes * ! 406: * the 8251 I/O chip, DCD is dropped which * ! 407: * causes this program to get killed at this * ! 408: * point. This is the case for the PT * ! 409: * terminal as of 10/25/83. * ! 410: ************************************************/ ! 411: ! 412: sleep(3); /* wait for terminal to initialize */ ! 413: printf("Terminal download complete\r\n"); ! 414: } ! 415: break; ! 416: ! 417: case PT2ROM: /* is a non-downloaded PT2 */ ! 418: if((!aflag) || ((aflag) && (wantptload()))) ! 419: { ! 420: ttytalk(); ! 421: putmsg(loading, 0); ! 422: dlpt2(pt2file); /* load terminal */ ! 423: sleep(3); /* wait for terminal to initialize */ ! 424: printf("Terminal download complete\r\n"); ! 425: } ! 426: break; ! 427: ! 428: default: ! 429: break; ! 430: } ! 431: ttyrestore(); ! 432: } ! 433: ! 434: /************************************************************************ ! 435: * * ! 436: * usage - print usage statement and abort * ! 437: * * ! 438: ************************************************************************/ ! 439: ! 440: usage() ! 441: { ! 442: fprintf(stderr, ! 443: "Usage: %s [-a] [-fTermNo] [-r] [-b BaudRate] [-t ttyXX] [load file]\n", ! 444: myname); ! 445: exit(1); ! 446: } ! 447: ! 448: ! 449: /************************************************************************ ! 450: * * ! 451: * PT down-load rtn * ! 452: * * ! 453: ************************************************************************/ ! 454: dlpt1(hexfile) ! 455: ! 456: char * hexfile; ! 457: ! 458: { ! 459: ! 460: FILE * in; /* input file */ ! 461: int i; /* counter */ ! 462: int rs; /* record size */ ! 463: char record [524]; /* record */ ! 464: int cs; /* checksum */ ! 465: char * rp; /* record pointer */ ! 466: char csum [2]; /* received checksum */ ! 467: ! 468: in = stdin; ! 469: timout = 0; /* Alarm time-out flag */ ! 470: ! 471: if ((in = fopen (hexfile, "r")) == (FILE *)NULL) ! 472: fatal ("Can't open input file."); ! 473: ! 474: ttyinit(); /* set up port for load */ ! 475: ! 476: for (i = STX_TIMES ; i > 0 ; i--) ! 477: if (write (toterm, stxrec, sizeof(stxrec)) != sizeof(stxrec)) ! 478: fatal ("1. Can't write STX to terminal."); ! 479: ! 480: while ((rs = getrec1 (in, record)) > 0) ! 481: { ! 482: for (cs = 0, i = rs, rp = record ; i > 0 ; i--) ! 483: cs += *rp++; ! 484: ! 485: for (i = NRETRIES ; i > 0 ; i--) ! 486: { ! 487: if (write (toterm, record, rs) != rs) ! 488: derror ("3. Can't write record to terminal."); ! 489: ! 490: if (write (toterm, nulls, nullcnt) != nullcnt) ! 491: derror ("4. Can't write NULLS to terminal."); ! 492: ! 493: if(rflag==TRUE) ! 494: { ! 495: alarm(LD_TIMEOUT); /* time limit */ ! 496: timout = 0; ! 497: if (timowrite (toterm, &ack, 1) != 1 || (timout)) ! 498: { ! 499: derror ("6. Can't write ACK to terminal."); ! 500: continue; ! 501: } ! 502: ! 503: alarm(LD_TIMEOUT); /* time limit */ ! 504: timout = 0; ! 505: if (timoread (fromterm, csum, 1) != 1 || (timout)) ! 506: { ! 507: derror ("7. Can't read ACK from terminal."); ! 508: continue; ! 509: } ! 510: ! 511: alarm(LD_TIMEOUT); /* time limit */ ! 512: timout = 0; ! 513: if (timoread (fromterm, csum + 1, 1) != 1 || (timout)) ! 514: { ! 515: derror ("8. Can't read csum count from terminal."); ! 516: continue; ! 517: } ! 518: ! 519: if (csum [0] != ACK) ! 520: { ! 521: derror ("9. Protocol violation not ACK."); ! 522: continue; ! 523: } ! 524: ! 525: if (((cs & 0x3f)+0x20) == csum[1]) ! 526: break; ! 527: ! 528: } /* end of reliabilaty logic */ ! 529: ! 530: else ! 531: break; ! 532: ! 533: } /* end of for loop */ ! 534: ! 535: if (i == 0) ! 536: fatal ("10. Number of retries exceeded."); ! 537: ! 538: if (rs == 11) /* Last record */ ! 539: return; ! 540: ! 541: } ! 542: ! 543: if (rs == 0) ! 544: fatal ("11. End of file reached before end-of-load record."); ! 545: else ! 546: fatal ("12. Bad record read."); ! 547: ! 548: } ! 549: ! 550: /************************************************************************ ! 551: * * ! 552: * TITLE: dlpt2 - down load CCI POWERTERMINAL II * ! 553: * * ! 554: * RETURNS: nothing * ! 555: * * ! 556: ************************************************************************/ ! 557: dlpt2( hexfile ) ! 558: ! 559: char *hexfile; ! 560: ! 561: { ! 562: FILE * in; /* input file */ ! 563: int i; /* counter */ ! 564: int rs; /* record size */ ! 565: char record [524]; /* record */ ! 566: ! 567: in = stdin; ! 568: timout = 0; /* Alarm time-out flag */ ! 569: ! 570: if ((in = fopen (hexfile, "r")) == (FILE *)NULL) ! 571: fatal ("Can't open input file."); ! 572: ! 573: ttyinit(); /* set up port for load */ ! 574: ! 575: ttyflush(); /* flush port before attempting com */ ! 576: ! 577: for (i = STX_TIMES ; i > 0 ; i--) ! 578: if (write (toterm, stxrec, sizeof(stxrec)) != sizeof(stxrec)) ! 579: fatal ("1. Can't write STX to terminal."); ! 580: ! 581: if( rflag == TRUE ) /* if rel mode wanted - tell PT2 */ ! 582: { ! 583: if( write( toterm, &enq, 1 ) != 1 ) ! 584: { ! 585: d2error ("16. Can't write ENQ to terminal."); ! 586: } ! 587: } ! 588: ! 589: while( ( rs = getrec2(in, record) ) > 0 ) ! 590: { ! 591: for( i = NRETRIES ; i > 0 ; i-- ) ! 592: { ! 593: if( write ( toterm, record, rs ) != rs ) ! 594: d2error ("3. Can't write record to terminal."); ! 595: ! 596: /* ! 597: if( write ( toterm, nulls, nullcnt ) != nullcnt ) ! 598: d2error ("4. Can't write NULLS to terminal."); ! 599: */ ! 600: ! 601: if( rflag == TRUE ) ! 602: { ! 603: char resp; /* resp char */ ! 604: ! 605: alarm(LD_TIMEOUT); /* time limit */ ! 606: timout = 0; ! 607: if( (timoread( fromterm, &resp, 1 ) != 1 ) || (timout)) ! 608: { ! 609: d2error ("17. Can't read ACK from terminal."); ! 610: continue; ! 611: } ! 612: if( resp == ACK ) ! 613: break; /* get txmit next char */ ! 614: ! 615: d2error ("19. Protocol violation not ACK."); ! 616: continue; ! 617: ! 618: } /* end of reliabilaty logic */ ! 619: ! 620: else ! 621: break; /* no verification wanted */ ! 622: ! 623: } /* end of error retry loop */ ! 624: ! 625: if( i == 0 ) ! 626: fatal ("20. Number of retries exceeded."); ! 627: ! 628: /* a complete record has been transmitted */ ! 629: /* check if it was the last record */ ! 630: ! 631: if( record[ 1 ] == '8' ) /* was it an S8 record? */ ! 632: return; /* if so, done !! */ ! 633: ! 634: } ! 635: ! 636: if( rs == 0 ) ! 637: fatal ("21. End of file reached before end-of-load record."); ! 638: else ! 639: fatal ("22. Bad record read."); ! 640: ! 641: } ! 642: ! 643: /************************************************************************ ! 644: * * ! 645: * derror - have an error handle and return * ! 646: * * ! 647: ************************************************************************/ ! 648: ! 649: int ! 650: derror (s) ! 651: ! 652: char * s; ! 653: ! 654: { ! 655: ! 656: alarm(0); /* cancel alarms */ ! 657: write (toterm,&can,sizeof(can)); /* cancel */ ! 658: write (toterm,nulls,nullcnt); /* pad for next write */ ! 659: fputs(s, stderr); ! 660: fputs("\r\n", stderr); ! 661: return; ! 662: ! 663: } ! 664: ! 665: /************************************************************************ ! 666: * * ! 667: * d2error - have an error handle and return * ! 668: * * ! 669: ************************************************************************/ ! 670: ! 671: int ! 672: d2error (s) ! 673: ! 674: char *s; ! 675: ! 676: { ! 677: alarm(0); /* cancel alarms */ ! 678: fputs(s, stderr); ! 679: fputs("\r\n", stderr); ! 680: return; ! 681: } ! 682: ! 683: /************************************************************************ ! 684: * * ! 685: * getrec1 - Get a PT1 (CT) record to transmit. * ! 686: * * ! 687: * Returns: * ! 688: * -1 Error in file format. * ! 689: * 0 End of file reached. * ! 690: * > 0 Size of record to transmit. * ! 691: * * ! 692: ************************************************************************/ ! 693: int ! 694: getrec1(fd, rp) ! 695: ! 696: FILE * fd; ! 697: char * rp; ! 698: ! 699: { ! 700: ! 701: int c; ! 702: int nc; /* number of characters */ ! 703: int l; /* length of record bytes */ ! 704: int cc; /* checksum */ ! 705: int i; /* counter */ ! 706: int a; /* address piece */ ! 707: ! 708: while ((c = getc (fd)) != ':') /* Look for start of record */ ! 709: if (c == EOF) ! 710: return 0; /* End of file */ ! 711: ! 712: /***** Start record off. */ ! 713: ! 714: /*%%% printf("At record start\n");/*%%*/ ! 715: *rp++ = ':'; ! 716: nc = 1; ! 717: ! 718: /***** Get number of hex bytes in record. */ ! 719: ! 720: if ((l = getxb (fd, rp)) < 0) ! 721: return -1; ! 722: ! 723: /*%%% printf("%d data bytes\n", l);/*%%*/ ! 724: cc = l; /* Start checksum */ ! 725: rp += 2; /* Past two characters */ ! 726: nc += 2; /* Two more characters */ ! 727: ! 728: /***** Get address portion of data record. */ ! 729: ! 730: for (i = 2 ; i > 0 ; i--) /* Two hex bytes */ ! 731: { ! 732: if ((a = getxb (fd, rp)) < 0) ! 733: return -1; ! 734: ! 735: cc += a; /* Figure address into checksum */ ! 736: rp += 2; /* Past two characters */ ! 737: nc += 2; /* Two more characters */ ! 738: } ! 739: ! 740: /***** Read type byte, which should be zero. */ ! 741: ! 742: if ((i = getxb (fd, rp)) != 0) ! 743: return -1; ! 744: ! 745: cc += i; /* Figure type into checksum */ ! 746: rp += 2; /* Past two characters */ ! 747: nc += 2; /* Two more characters */ ! 748: ! 749: /***** Read in the data record. */ ! 750: ! 751: while (l-- > 0) /* Count down */ ! 752: { ! 753: if ((i = getxb (fd, rp)) < 0) ! 754: return -1; ! 755: ! 756: /*%%% printf ("Read %d\n", i);/*%%*/ ! 757: cc += i; /* Checksum */ ! 758: rp += 2; /* Pointer */ ! 759: nc += 2; /* Number of characters */ ! 760: } ! 761: ! 762: cc = (-cc) & 0377; /* Two's complement byte */ ! 763: ! 764: /*%%% printf ("Checksum = %x\n", cc);/*%%*/ ! 765: *rp = cc >> 4; ! 766: *rp += *rp < 10 ? '0' : 'A' - 10; ! 767: *++rp = cc & 0xF; ! 768: *rp += *rp < 10 ? '0' : 'A' - 10; ! 769: ! 770: /*%%% printf ("record size = %d\n", nc + 2);/*%%*/ ! 771: return nc + 2; ! 772: ! 773: } ! 774: ! 775: /************************************************************************ ! 776: * * ! 777: * TITLE: getrec2 - Get a POWERTERMINAL II record to transmit * ! 778: * * ! 779: * RETURNS: * ! 780: * -1 Error in file format. * ! 781: * 0 End of file reached. * ! 782: * > 0 Size of record to transmit. * ! 783: * * ! 784: ************************************************************************/ ! 785: int ! 786: getrec2 (fd, rp) ! 787: ! 788: FILE *fd; ! 789: char *rp; ! 790: ! 791: { ! 792: register char *rrp; /* register copy of record ptr */ ! 793: char c; /* temp store of read char */ ! 794: int nc; /* number of characters */ ! 795: int l; /* length of record bytes */ ! 796: ! 797: rrp = rp; /* get addr in a register */ ! 798: ! 799: while(( c = getc( fd )) != 'S') /* Look for start of record */ ! 800: if( c == EOF ) ! 801: return( 0 ); /* End of file */ ! 802: ! 803: *rrp++ = c ; /* put first char of record */ ! 804: nc = 1; /* start the char counter */ ! 805: ! 806: if( ( *rrp++ = getc( fd ) ) < 0 ) /* get S-record type */ ! 807: return( -1 ); /* if EOF, return */ ! 808: nc++; /* incre num of chars */ ! 809: ! 810: if( ( l = getxb(fd, rrp) ) < 0) /* get num of bytes */ ! 811: return -1; ! 812: rrp += 2; /* Past two characters */ ! 813: nc += 2; /* Two more characters */ ! 814: ! 815: /* get address, data, and checksum fields */ ! 816: ! 817: l <<= 1 ; /* chg to num nibbles (times 2) */ ! 818: ! 819: while( l-- > 0 ) { /* l now contains num of nibbles*/ ! 820: if ( ( *rrp++ = getc( fd ) ) < 0) ! 821: return( -1 ); ! 822: nc++; /* bump char counter */ ! 823: } ! 824: ! 825: return( nc ); /* return num of chars in rec */ ! 826: ! 827: } ! 828: ! 829: /************************************************************************ ! 830: * * ! 831: * getxb - Get a hex byte. * ! 832: * * ! 833: * Returns: * ! 834: * -1 Error in file format or end of file reached. * ! 835: * >= 0 Integer value of byte. * ! 836: * * ! 837: ************************************************************************/ ! 838: ! 839: int ! 840: getxb (fd, sp) ! 841: ! 842: FILE * fd; ! 843: char * sp; ! 844: ! 845: { ! 846: ! 847: register int i, j; ! 848: ! 849: if ((i = getxn (fd, sp++)) < 0 || (j = getxn (fd, sp)) < 0) ! 850: return -1; ! 851: ! 852: return (i << 4) | j; ! 853: ! 854: } ! 855: ! 856: /************************************************************************ ! 857: * * ! 858: * getxn - Get a hex nibble. * ! 859: * * ! 860: * Returns: * ! 861: * -1 Error in file format or end of file reached. * ! 862: * >= 0 Integer value of nibble. * ! 863: * * ! 864: ************************************************************************/ ! 865: ! 866: int ! 867: getxn (fd, sp) ! 868: ! 869: FILE * fd; ! 870: char * sp; ! 871: ! 872: { ! 873: ! 874: register int c; ! 875: ! 876: *sp = c = getc (fd); ! 877: ! 878: if (c >= '0' && c <= '9') ! 879: return c - '0'; ! 880: else if (c >= 'A' && c <= 'F') ! 881: return c - 'A' + 10; ! 882: else if (c >= 'a' && c <= 'f') ! 883: return c - 'a' + 10; ! 884: ! 885: return -1; ! 886: ! 887: } ! 888: ! 889: ! 890: #ifdef NEWSIG /* new signal mechanism */ ! 891: ! 892: /************************************************************************ ! 893: * * ! 894: * timoread/timowrite - read/write with timeout * ! 895: * * ! 896: ************************************************************************/ ! 897: ! 898: timoread(fd, ptr, size) ! 899: char *ptr; ! 900: { ! 901: if(setjmp(jb) == 0) ! 902: return read(fd, ptr, size); ! 903: return -1; ! 904: } ! 905: timowrite(fd, ptr, size) ! 906: char *ptr; ! 907: { ! 908: if(setjmp(jb) == 0) ! 909: return write(fd, ptr, size); ! 910: return -1; ! 911: } ! 912: #endif ! 913: ! 914: ! 915: /************************************************************************ ! 916: * * ! 917: * fatal - display error message and abort * ! 918: * * ! 919: ************************************************************************/ ! 920: ! 921: int ! 922: fatal (s) ! 923: ! 924: char * s; ! 925: ! 926: { ! 927: ! 928: write(toterm,&can,sizeof(can)); /* write cancel to terminal */ ! 929: write(toterm,nulls,nullcnt); ! 930: fputs(s, stderr); ! 931: fputs("\r\n", stderr); ! 932: ttyrestore(); /* put terminal back to orig state */ ! 933: exit(1); ! 934: ! 935: } ! 936: ! 937: /************************************************************************ ! 938: * * ! 939: * wantptload - inquire if the user wants a download * ! 940: * * ! 941: ************************************************************************/ ! 942: ! 943: #define BUFSIZE 80 /* size of answer buffers */ ! 944: #define WANT_WAIT 15 /* time to wait for answer */ ! 945: ! 946: wantptload () ! 947: { ! 948: char answer[BUFSIZE]; ! 949: ! 950: ttytalk(); /* talk slow - do not lose chars */ ! 951: while (1) ! 952: { ! 953: sleep(1); /* allow time to prevent truncation */ ! 954: putmsg(intro, 0); /* output msg, 0 pad null per line */ ! 955: alarm(WANT_WAIT); ! 956: timout=0; ! 957: *answer = '\0'; ! 958: timoread(0, answer, sizeof answer); ! 959: if(timout) ! 960: return(TRUE); ! 961: else ! 962: { ! 963: alarm(0); /* reset the alarm */ ! 964: switch (*answer) ! 965: { ! 966: case 'y': ! 967: case 'Y': ! 968: case '\n': ! 969: return(TRUE); ! 970: ! 971: case 'n': ! 972: case 'N': ! 973: return(FALSE); ! 974: ! 975: default: ! 976: putmsg(wrong, 0); ! 977: } ! 978: } ! 979: } ! 980: } ! 981: ! 982: /************************************************************************ ! 983: * * ! 984: * putmsg - put a msg to terminal with null padding at end of line * ! 985: * * ! 986: ************************************************************************/ ! 987: ! 988: putmsg(text,pad) ! 989: char **text; /* pointer to list of string pointers */ ! 990: int pad; /* number of nulls to output after each line */ ! 991: { ! 992: while( *text != NULL ) ! 993: { ! 994: register int i; ! 995: char *ptr = *text; ! 996: ! 997: while( *ptr ) ! 998: { ! 999: putchar(*ptr++); ! 1000: } ! 1001: putchar('\n'); ! 1002: for( i = 0; i < pad; i++) ! 1003: putchar('\0'); ! 1004: text++; ! 1005: } ! 1006: } ! 1007: ! 1008: /************************************************************************ ! 1009: * * ! 1010: * whoisit - Determine if the PT terminal is already downloaded * ! 1011: * * ! 1012: * returns PT1ROM if ROM responds to DA command * ! 1013: * returns PT1RAM if RAM responds to DA command * ! 1014: * returns INVRESP if no or invalid response received * ! 1015: * * ! 1016: ************************************************************************/ ! 1017: ! 1018: #define DA "\033[c" /* ANSI DA ESC seq to send to terminal */ ! 1019: ! 1020: /* Note that in the following expected DA response sequences, only the ! 1021: first 7 chars are used to match. This allows for future ! 1022: changes in the software version number without having to change ! 1023: this program. (The PT ROM & RAM respond with version number(s) ! 1024: in addition to the following characters.) ! 1025: */ ! 1026: ! 1027: #define RAM1RSP "\033[=0;1;" /* ANSI DA ESC response from PT (CT) RAM */ ! 1028: #define ROM1RSP "\033[=0;0;" /* ANSI DA ESC response from PT (CT) ROM */ ! 1029: #define RAM2RSP "\033[=1;1;" /* ANSI DA ESC response from PT2 RAM */ ! 1030: #define ROM2RSP "\033[=1;0;" /* ANSI DA ESC response from PT2 ROM */ ! 1031: #define DATERM 'c' /* ANSI DA ESC sequence terminator */ ! 1032: ! 1033: #define ASK_WAIT 3 /* time to wait for ESC response */ ! 1034: #define ASK_TIMES 3 /* number of times to send DA req block */ ! 1035: #define MAX_WRONG_CHARS 30 /* max number of chars to wait for ESC */ ! 1036: ! 1037: whoisit () ! 1038: ! 1039: { ! 1040: char response[MAX_WRONG_CHARS+1]; ! 1041: int i,j; ! 1042: ! 1043: ttyinit(); /* make port raw for ESC sequence */ ! 1044: ! 1045: for( j=0 ; j < ASK_TIMES ; j++ ) /* allow retries */ ! 1046: { ! 1047: ttyflush(); /* flush port before attempting com */ ! 1048: ! 1049: /* send DA cmd, is terminal loaded ? */ ! 1050: write (toterm,DA,sizeof(DA)-1); ! 1051: ! 1052: alarm(ASK_WAIT); ! 1053: timout = 0; ! 1054: response[0] = '\0'; ! 1055: ! 1056: /* Synchronize on first character of expected response */ ! 1057: ! 1058: while (response[0] != *ROM1RSP) ! 1059: { ! 1060: if(timoread(0,&response[0],sizeof(char)) != sizeof(char)) ! 1061: { ! 1062: if(timout) ! 1063: break; ! 1064: alarm(0); ! 1065: puts("\n\rDA ESC char read error\n\r"); ! 1066: return(FALSE); ! 1067: } ! 1068: } ! 1069: ! 1070: if(timout) /* time-out here means no good response */ ! 1071: continue; /* try again */ ! 1072: ! 1073: alarm(0); /* make sure alarm is cleared */ ! 1074: ! 1075: /* At this point we have the first char of expected ! 1076: response. Now get the rest of it. */ ! 1077: ! 1078: for( i=1 ; ((response[i-1] != DATERM) && ! 1079: (i < MAX_WRONG_CHARS-1)) ; i++ ) ! 1080: { ! 1081: alarm(ASK_WAIT); ! 1082: timout=0; ! 1083: if(timoread(0,&response[i],sizeof(char)) != sizeof(char)) ! 1084: { ! 1085: if(timout) ! 1086: break; ! 1087: alarm(0); ! 1088: puts("\n\rDA string read error\n\r"); ! 1089: return(FALSE); ! 1090: } ! 1091: alarm(0); /* make sure alarm is cleared */ ! 1092: } ! 1093: if(timout) /* if time-out, did not get enough chars*/ ! 1094: continue; /* retry DA command */ ! 1095: ! 1096: /* At this point we have at least a matching first char ! 1097: in response. Now compare the complete string read in ! 1098: with the expected response. */ ! 1099: ! 1100: if(strncmp(ROM1RSP,response,sizeof(ROM1RSP)-1) == 0) ! 1101: return(PT1ROM); ! 1102: if(strncmp(RAM1RSP,response,sizeof(RAM1RSP)-1) == 0) ! 1103: return(PT1RAM); ! 1104: if(strncmp(ROM2RSP,response,sizeof(ROM2RSP)-1) == 0) ! 1105: return(PT2ROM); ! 1106: if(strncmp(RAM2RSP,response,sizeof(RAM2RSP)-1) == 0) ! 1107: return(PT2RAM); ! 1108: } ! 1109: return(INVRESP); ! 1110: } ! 1111: ! 1112: /************************************************************************ ! 1113: * * ! 1114: * atobaud - convert an ascii number to a baud rate ala B50, B1200, ... * ! 1115: * returns -1 if invalid baud rate is specified. * ! 1116: * * ! 1117: ************************************************************************/ ! 1118: ! 1119: struct baud { ! 1120: char *abaud; /* name of baud rate */ ! 1121: char ibaud; /* baud rate for ioclt(2) */ ! 1122: }; ! 1123: ! 1124: struct baud baudtbl[] = { ! 1125: { "110", B110 }, ! 1126: { "300", B300 }, ! 1127: { "600", B600 }, ! 1128: { "1200", B1200 }, ! 1129: { "2400", B2400 }, ! 1130: { "4800", B4800 }, ! 1131: { "9600", B9600 }, ! 1132: #ifdef B19200 ! 1133: { "19200", B19200 }, ! 1134: #endif ! 1135: { NULL, 0 } ! 1136: }; ! 1137: ! 1138: char ! 1139: atobaud(string) ! 1140: char *string; ! 1141: { ! 1142: struct baud *bptr = baudtbl; /* index in baud rate table */ ! 1143: ! 1144: while( bptr->abaud != NULL ) ! 1145: { ! 1146: if( strcmp( bptr->abaud, string) == 0) ! 1147: { ! 1148: switch (atoi(string)) ! 1149: { ! 1150: case 19200: nullcnt=14;break; ! 1151: case 9600: nullcnt= 9;break; ! 1152: case 4800: nullcnt= 8;break; ! 1153: case 2400: nullcnt= 6;break; ! 1154: case 1200: nullcnt= 5;break; ! 1155: case 300: ! 1156: case 110: nullcnt= 3;break; ! 1157: default: nullcnt=14;break; ! 1158: } ! 1159: return( bptr->ibaud ); ! 1160: } ! 1161: ++bptr; ! 1162: } ! 1163: return( (char) -1 ); ! 1164: } ! 1165: ! 1166: /************************************************************************ ! 1167: * * ! 1168: * bailout - alarm interrupt handler * ! 1169: * * ! 1170: ************************************************************************/ ! 1171: ! 1172: ! 1173: bailout () ! 1174: { ! 1175: #ifdef NEWSIG /* new signal mechanism */ ! 1176: timout = 1; ! 1177: longjmp(jb, 1); ! 1178: #else ! 1179: signal(SIGALRM,bailout); ! 1180: timout = 1; ! 1181: return; ! 1182: #endif ! 1183: } ! 1184: ! 1185: /************************************************************************ ! 1186: * * ! 1187: * tty utilities for performing get & put ioctl's * ! 1188: * * ! 1189: ************************************************************************/ ! 1190: ! 1191: #define IOC_DELAY 1 /* Delay is needed after ioctl to allow baud- ! 1192: rate change to take effect. This requirement ! 1193: discovered on 2/21/84 when xmit of the DA ! 1194: seq would result in the first DA attempt to ! 1195: be sent at 9600 baud (irregardless of ! 1196: intended setting) and the second DA to go ! 1197: out at the intended (set by ioctl) rate. */ ! 1198: ! 1199: #ifdef V7 /********* if Version 7 tty routines *********/ ! 1200: ! 1201: struct sgttyb tp_new; ! 1202: struct sgttyb tp_orig; ! 1203: struct tchars tc_new = { '\177', '\034', '\021', '\023', '\004', '\377' }; ! 1204: struct tchars tc_orig; ! 1205: ! 1206: ttysave () ! 1207: { ! 1208: ioctl(0, TIOCGETP, &tp_orig); ! 1209: ioctl(0, TIOCGETC, &tc_orig); ! 1210: baudrate = tp_orig.sg_ospeed; ! 1211: } ! 1212: ! 1213: ttyrestore () ! 1214: { ! 1215: ioctl(0, TIOCSETP, &tp_orig); ! 1216: ioctl(0, TIOCSETC, &tc_orig); ! 1217: sleep(IOC_DELAY); /* allow baud to settle */ ! 1218: } ! 1219: ! 1220: ttyinit () ! 1221: { ! 1222: /* ! 1223: * Use CBREAK mode for 'normal' download so that the Dow Jones ! 1224: * mux which generates XON/XOFF will be happy. XON/XOFF appears ! 1225: * to screw up reliability mode, however, so stick with RAW ! 1226: * mode for that. ! 1227: */ ! 1228: ttysetup((short) ANYP + ((rflag) ? RAW : CBREAK)); ! 1229: } ! 1230: ! 1231: ttytalk () ! 1232: { ! 1233: ttysetup((short)ANYP+ECHO+CRMOD); ! 1234: } ! 1235: ! 1236: ttysetup (flags) ! 1237: short flags; ! 1238: { ! 1239: ! 1240: tp_new.sg_flags = flags; ! 1241: tp_new.sg_ispeed = baudrate; ! 1242: tp_new.sg_ospeed = baudrate; ! 1243: tp_new.sg_stopbits = tp_orig.sg_stopbits; ! 1244: ioctl(0, TIOCSETP, &tp_new); ! 1245: ioctl(0, TIOCSETC, &tc_new); ! 1246: sleep(IOC_DELAY); /* allow baud to settle */ ! 1247: ! 1248: } ! 1249: ! 1250: ttyflush() ! 1251: { ! 1252: ioctl(0,TIOCFLUSH,0); ! 1253: } ! 1254: ! 1255: #else /********* else assume System 3 tty routines *********/ ! 1256: ! 1257: struct termio term_orig; /* save area for orig port state */ ! 1258: struct termio term_new; /* new port state */ ! 1259: ! 1260: int count; /* used for 19200 baud delay */ ! 1261: ! 1262: ttysave() ! 1263: { ! 1264: ioctl(0, TCGETA, &term_orig); /* save the initial port state */ ! 1265: baudrate = term_orig.c_cflag & CBAUD; /* get orig baud */ ! 1266: } ! 1267: ! 1268: ttyrestore() ! 1269: { ! 1270: ioctl(0, TCSETAF, &term_orig); /* restore saved port state */ ! 1271: sleep(IOC_DELAY); /* allow baud to settle */ ! 1272: } ! 1273: ! 1274: ttyinit() ! 1275: { ! 1276: term_new.c_iflag = ICRNL|ISTRIP|IXON; ! 1277: term_new.c_oflag = ONLRET|OPOST; ! 1278: term_new.c_cflag = baudrate|CREAD|CS8; ! 1279: term_new.c_lflag = 0; ! 1280: term_new.c_line = 0; ! 1281: term_new.c_cc[VINTR] = CINTR; ! 1282: term_new.c_cc[VQUIT] = CQUIT; ! 1283: term_new.c_cc[VERASE] = 0x08; ! 1284: term_new.c_cc[VKILL] = CKILL; ! 1285: term_new.c_cc[VMIN] = 1; ! 1286: term_new.c_cc[VTIME] = 1; ! 1287: ! 1288: ioctl( 0, TCSETAF, &term_new ); ! 1289: sleep(IOC_DELAY); /* allow baud to settle */ ! 1290: ! 1291: } ! 1292: ! 1293: ttytalk() ! 1294: { ! 1295: term_new.c_iflag = ICRNL|IXON; ! 1296: term_new.c_oflag = ONLCR|OPOST; ! 1297: term_new.c_cflag = baudrate|CREAD|CS8; ! 1298: term_new.c_lflag = ECHO|ECHOE|ECHOK|ICANON|ISIG; ! 1299: ! 1300: ioctl( 0, TCSETAF, &term_new ); ! 1301: sleep(IOC_DELAY); /* allow baud to settle */ ! 1302: ! 1303: } ! 1304: ! 1305: ttyflush() ! 1306: { ! 1307: ioctl( 0, TCFLSH, 2 ); /* flush input & output queues */ ! 1308: } ! 1309: ! 1310: #endif /********* end of System 3 tty routines *********/ ! 1311:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.