home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 216_01 / minirb.c < prev    next >
Text File  |  1979-12-31  |  4KB  |  180 lines

  1. /*
  2.  * minirb.c By Chuck Forsberg Omen Technology INC
  3.  *        "The High Reliability Communications Software"
  4.  *
  5.  * A bootstrap program for Unix to receive files from computers running
  6.  *  YMODEM Batch (Professional-YAM, PowerCom, ZCOMM, etc.).
  7.  *
  8.  *  Minirb uses system(3) to call stty, avoiding system dependent code.
  9.  *  Please refer to rz.c for comments, etc.
  10.  */
  11. char * Version = "minirb 1.00 11-15-86";
  12.  
  13. #include <stdio.h>
  14. #include <signal.h>
  15. #include <setjmp.h>
  16. #include <ctype.h>
  17.  
  18. #define OK 0
  19. #define FALSE 0
  20. #define TRUE 1
  21. #define ERROR (-1)
  22. #define CAN ('X'&037)
  23. #define SOH 1
  24. #define STX 2
  25. #define EOT 4
  26. #define ACK 6
  27. #define NAK 025
  28. #define TIMEOUT (-2)
  29. #define RETRYMAX 9
  30. #define WCEOT (-10)
  31.  
  32. FILE *fout;
  33. long Bytesleft;
  34. int Blklen;
  35. char secbuf[1024];
  36. char linbuf[1024];
  37. int Lleft=0;
  38. jmp_buf tohere;
  39.  
  40. alrm() { longjmp(tohere, -1); }
  41.  
  42. bibi(n) {
  43.  canit(); mode(0);
  44.  fprintf(stderr, "minirb: caught signal %d; exiting", n);
  45.  exit(128+n);
  46. }
  47.  
  48. mode(n) {
  49.  if (n) system("stty raw -echo");
  50.  else system("stty echo -raw");
  51. }
  52.  
  53. main() {
  54.  mode(1);
  55.  if (signal(SIGINT, bibi) == SIG_IGN) {
  56.   signal(SIGINT, SIG_IGN); signal(SIGKILL, SIG_IGN);
  57.  } else {
  58.   signal(SIGINT, bibi); signal(SIGKILL, bibi);
  59.  }
  60.  printf("minirb: Now send file(s) with \042sb file ...\042 command\r\n");
  61.  
  62.  if (wcreceive()==ERROR)
  63.   canit();
  64.  mode(0); exit(0);
  65. }
  66.  
  67. wcreceive() {
  68.  for (;;) {
  69.   if (wcrxpn(secbuf) == ERROR) break;
  70.   if (secbuf[0]==0) return OK;
  71.   if (procheader(secbuf)==ERROR || wcrx()==ERROR) break;
  72.  }
  73.  canit(); return ERROR;
  74. }
  75.  
  76.  
  77. wcrxpn(rpn) char *rpn; {
  78.  register c;
  79.  
  80.  purgeline();
  81. et_tu:
  82.  sendline(NAK); Lleft=0;
  83.  while ((c = wcgetsec(rpn, 100)) != 0) {
  84.   if (c == WCEOT) { sendline(ACK); Lleft=0; readline(1); goto et_tu; }
  85.   return ERROR;
  86.  }
  87.  sendline(ACK); return OK;
  88. }
  89.  
  90. wcrx() {
  91.  register int sectnum, sectcurr, sendchar, cblklen;
  92.  
  93.  sectnum=0; sendchar=NAK;
  94.  for (;;) {
  95.   sendline(sendchar); Lleft=0;
  96.   sectcurr=wcgetsec(secbuf, (sectnum&0177)?50:130);
  97.   if (sectcurr==(sectnum+1)) {
  98.    sectnum++; cblklen = Bytesleft>Blklen ? Blklen:Bytesleft;
  99.    if (putsec(secbuf, cblklen)==ERROR) return ERROR;
  100.    if ((Bytesleft-=cblklen) < 0) Bytesleft = 0;
  101.    sendchar=ACK;
  102.   }
  103.   else if (sectcurr==sectnum) sendchar=ACK;
  104.   else if (sectcurr==WCEOT) {
  105.    if (fclose(fout)==ERROR) return ERROR;
  106.    sendline(ACK); Lleft=0; return OK;
  107.   }
  108.   else if (sectcurr==ERROR) return ERROR;
  109.   else return ERROR;
  110.  }
  111. }
  112.  
  113. wcgetsec(rxbuf, maxtime) char *rxbuf; int maxtime; {
  114.  register checksum, wcj, firstch; register char *p; int sectcurr, errors;
  115.  for (errors=0; errors<RETRYMAX; errors++) {
  116.   if ((firstch=readline(maxtime))==STX) { Blklen=1024; goto get2; }
  117.   if (firstch==SOH) {
  118.    Blklen=128;
  119. get2:
  120.    sectcurr=readline(1); checksum=0;
  121.    if ((sectcurr+(readline(1)))==0377) {
  122.     for (p=rxbuf,wcj=Blklen; --wcj>=0; ) {
  123.      if ((firstch=readline(1)) < 0) goto bilge;
  124.      checksum += (*p++ = firstch);
  125.     }
  126.     if ((firstch=readline(1)) < 0) goto bilge;
  127.     if (((checksum-firstch)&0377)==0) return sectcurr;
  128.    }
  129.   }
  130.   else if (firstch==EOT) return WCEOT;
  131.   else if (firstch==CAN) return ERROR;
  132. bilge:
  133.   while(readline(1)!=TIMEOUT)
  134.    ;
  135.   maxtime=40; sendline(NAK); Lleft=0;
  136.  }
  137.  canit(); return ERROR;
  138. }
  139.  
  140. readline(timeout) int timeout; {
  141.  register n; static char *cdq;
  142.  
  143.  if (--Lleft >= 0) return (*cdq++ & 0377);
  144.  n = timeout/10;
  145.  if (n < 2) n = 3;
  146.  if (setjmp(tohere)) { Lleft = 0; return TIMEOUT; }
  147.  signal(SIGALRM, alrm); alarm(n);
  148.  Lleft=read(0, cdq=linbuf, 1024); alarm(0);
  149.  if (Lleft < 1) return TIMEOUT;
  150.  --Lleft; return (*cdq++ & 0377);
  151. }
  152.  
  153. purgeline() { Lleft = 0; lseek(0, 0L, 2); }
  154.  
  155.  
  156. procheader(name) char *name; {
  157.  register char *p;
  158.  
  159.  Bytesleft = 2000000000L; p = name + 1 + strlen(name);
  160.  if (*p) sscanf(p, "%ld", &Bytesleft);
  161.  if ((fout=fopen(name, "w")) == NULL) return ERROR;
  162.  return OK;
  163. }
  164.  
  165. putsec(buf, n) char *buf; register n;
  166. {
  167.  register char *p;
  168.  for (p=buf; --n>=0; ) putc( *p++, fout);
  169.  return OK;
  170. }
  171.  
  172. sendline(c) { char d; d = c; write(1, &d, 1); }
  173.  
  174. char canistr[] = { 24,24,24,24,24,24,24,24,0 };
  175.  
  176. canit() { printf(canistr); Lleft=0; }
  177.  
  178. /* END of minirb.c */
  179.  
  180.