dpw@rayssd.RAY.COM (Darryl P. Wagoner) (01/14/87)
Here is the source for uuslave that has been discussed on the net. I have tried to compile it with MicroSoft C without any success. Please note there are no comments. From the defines I would guess that it was ported from CP/M. If anyone successfully compiles it, please post the new version. Don't for the signature -------------------- cut here ------------------------ /* @[$]uuslave.c 1.7 08/12/85 14:04:20 */ #include <stdio.h> #include <fcntl.h> #ifndef CPM #include <termio.h> #include <signal.h> #endif #define MAGIC 0125252 #define EOT 4 #define CTRL 0 #define ALTCHN 1 #define LNGDAT 2 #define SHTDAT 3 #define CLOSE 1 #define RJ 2 #define SRJ 3 #define RR 4 #define INITC 5 #define INITB 6 #define INITA 7 extern errno; char msgi[256],msgo[256],ttynam[32],cmnd[8],srcnam[32],dstnam[32],dskbuf[256],msgbld[256]; int fdtty,fddsk,tt,xxx,yyy,rseq,wseq; #ifndef CPM struct termio atermio,btermio; #endif #ifdef ERRLOG FILE *file; #endif int wndsiz = 1; int segsiz = 1; char msgo0[] = "9800rcs login: "; char msgo1[] = "Password:"; char msgo2[] = "\20Shere\0"; char msgo3[] = "\20ROK\0\20Pg\0"; char msgo4[] = "\20OOOOOO\0"; char msgo5[] = "...abort..."; char msgi0[] = "uucp\n"; char msgi1[] = "s8000\n"; char msgi2[] = "\20S*\0"; char msgi3[] = "\20Ug\0"; #ifdef CPM extern xgetc(),xwrite(); #else sigint() { ioctl(fdtty,TCSETA,&atermio); close(fdtty); exit(0); } sigalrm() { } xgetc() { char data; signal(SIGALRM,sigalrm); alarm(10); if (read(fdtty,&data,1) > 0) { alarm(0); return(data & 0xFF); } return(EOF); } xwrite(fd,buf,ctr) int fd; char *buf; int ctr; { write(fd,buf,ctr); } #endif zero(p,c) char *p; int c; { while (c--) *p++ = 0; } ackmsg() { int cksm,index; msgo[0] = 020; msgo[1] = 9; msgo[4] = (CTRL << 6) | (RR << 3) | rseq; cksm = MAGIC - msgo[4]; msgo[2] = cksm; msgo[3] = cksm >> 8; msgo[5] = msgo[1] ^ msgo[2] ^ msgo[3] ^ msgo[4]; #ifdef DEBUG printf("T "); for (index = 0; index < 6; index++) printf("%03o ",msgo[index] & 0xFF); putchar('\n'); #endif xwrite(fdtty,msgo,6); rseq = (rseq + 1) & 7; } ctlmsg(byte) char byte; { int cksm,index; msgo[0] = 020; msgo[1] = 9; msgo[4] = (CTRL << 6) | byte; cksm = MAGIC - msgo[4]; msgo[2] = cksm; msgo[3] = cksm >> 8; msgo[5] = msgo[1] ^ msgo[2] ^ msgo[3] ^ msgo[4]; #ifdef DEBUG printf("T "); for (index = 0; index < 6; index++) printf("%03o ",msgo[index] & 0xFF); putchar('\n'); #endif xwrite(fdtty,msgo,6); } lngput(s,n) char *s; int n; { int cksm,index; zero(msgo,256); msgo[0] = 020; msgo[1] = segsiz + 1; msgo[4] = (LNGDAT << 6) + (wseq << 3) + rseq; for (index = 0; index < (segsiz + 1) * 32; index++) msgo[6+index] = 0; for (index = 0; index < n; index++) msgo[6+index] = *(s+index); cksm = MAGIC - (chksum(&msgo[6],(segsiz + 1) * 32) ^ (0377 & msgo[4])); msgo[2] = cksm; msgo[3] = cksm >> 8; msgo[5] = msgo[1] ^ msgo[2] ^ msgo[3] ^ msgo[4]; #ifdef DEBUG printf("T "); for (index = 0; index < (segsiz + 1) * 32 + 6; index++) printf("%03o ",msgo[index] & 0xFF); putchar('\n'); #endif do { xwrite(fdtty,msgo,(segsiz + 1) * 32 + 6); if (inpkt()) return(1); } while (tt != CTRL || xxx != RR || yyy != wseq); wseq = (wseq + 1) & 7; return(0); } shtput(s,n) char *s; int n; { int cksm,index; zero(msgo,256); msgo[0] = 020; msgo[1] = segsiz + 1; msgo[4] = (SHTDAT << 6) + (wseq << 3) + rseq; for (index = 0; index < (segsiz + 1) * 32; index++) msgo[6+index] = 0; msgo[6] = (segsiz + 1) * 32 - n; for (index = 0; index < n; index++) msgo[7+index] = *(s+index); cksm = MAGIC - (chksum(&msgo[6],(segsiz + 1) * 32) ^ (0377 & msgo[4])); msgo[2] = cksm; msgo[3] = cksm >> 8; msgo[5] = msgo[1] ^ msgo[2] ^ msgo[3] ^ msgo[4]; #ifdef DEBUG printf("T "); for (index = 0; index < (segsiz + 1) * 32 + 6; index++) printf("%03o ",msgo[index] & 0xFF); putchar('\n'); #endif do { xwrite(fdtty,msgo,(segsiz + 1) * 32 + 6); if (inpkt()) return(1); } while (tt != CTRL || xxx != RR || yyy != wseq); wseq = (wseq + 1) & 7; return(0); } instr(s,n) char *s; int n; { int data,count,i,j; count = 0; #ifdef DEBUG printf("Expecting "); for (i = 0; i < n; i++) printf("%03o ",*(s+i)); printf("\nR "); #endif while ((data = xgetc()) != EOF) { msgi[count++] = data & 0x7F; #ifdef DEBUG printf("%03o ",msgi[count-1]); #endif if (count >= n) { for (i = n - 1, j = count - 1; i >= 0; i--, j--) if (*(s+i) == '*' || *(s+i) != msgi[j]) break; if (i < 0 || *(s+i) == '*') { #ifdef DEBUG putchar('\n'); #endif return(0); } } } #ifdef DEBUG putchar('\n'); #endif msgi[count] = 0; return(1); } inpkt() { int data,count,need; count = 0; #ifdef DEBUG printf("R "); #endif while ((data = xgetc()) != EOF) { #ifdef DEBUG printf("%03o ",data & 0xFF); #endif switch (count) { case 0 : if (data == 020) msgi[count++] = 020; break; case 1 : msgi[count++] = data; if (data == 9) need = 4; else need = 32 * data + 4; break; case 4 : tt = (data >> 6) & 3; xxx = (data >> 3) & 7; yyy = data & 7; default : msgi[count++] = data; if (!--need) { #ifdef DEBUG putchar('\n'); #endif return(0); } break; } } #ifdef DEBUG putchar('\n'); #endif return(1); } chksum(s,n) register char *s; register n; { register short sum; register unsigned short t; register short x; sum = -1; x = 0; do { if (sum < 0) { sum <<= 1; sum++; } else sum <<= 1; t = sum; sum += *s++ & 0377; x += sum ^ n; if ((unsigned) sum <= t) sum ^= x; } while (--n > 0); return(sum); } main(argc,argv) int argc; char *argv[]; { char *p; int data,count; #ifdef CPM sioinit(); #else if (argc > 1) strcpy(ttynam,argv[1]); else strcpy(ttynam,"/dev/tty12"); if ((fdtty = open(ttynam,O_RDWR)) < 0) { printf("Cannot open %s for read/write %d\n",ttynam,errno); exit(1); } ioctl(fdtty,TCGETA,&atermio); btermio = atermio; btermio.c_iflag = btermio.c_oflag = btermio.c_lflag = 0; btermio.c_cc[VMIN] = 1; btermio.c_cc[VTIME] = 0; btermio.c_cflag = (btermio.c_cflag & ~CBAUD) | B1200; ioctl(fdtty,TCSETA,&btermio); signal(SIGINT,sigint); #endif while (1) { #ifdef DEBUG puts("restarting"); #endif rseq = 0; wseq = 1; /* wait for EOT */ while ((data = xgetc()) == EOF || (data &= 0x7F) != EOT); /* output login request, verify uucp */ xwrite(fdtty,msgo0,sizeof(msgo0)-1); if (instr(msgi0,sizeof(msgi0)-1)) goto abort; /* output password request, verify s8000 */ xwrite(fdtty,msgo1,sizeof(msgo1)-1); if (instr(msgi1,sizeof(msgi1)-1)) goto abort; /* output here message, wait for response */ xwrite(fdtty,msgo2,sizeof(msgo2)-1); if (instr(msgi2,sizeof(msgi2)-1)) goto abort; /* output ok message, output protocol request, wait for response */ xwrite(fdtty,msgo3,sizeof(msgo3)-1); if (instr(msgi3,sizeof(msgi3)-1)) goto abort; /* output inita message, wait for response */ ctlmsg((INITA << 3) | wndsiz); if (inpkt() || tt != CTRL || xxx != INITA) goto abort; /* output initb message, wait for response */ ctlmsg((INITB << 3) | segsiz); if (inpkt() || tt != CTRL || xxx != INITB) goto abort; /* output initc message, wait for response */ ctlmsg((INITC << 3) | wndsiz); if (inpkt() || tt != CTRL || xxx != INITC) goto abort; /* output initial acknowledge, wait for command */ ackmsg(); while (1) { if (inpkt() || tt != LNGDAT) { intf("OVER EIGHT"); goto abort; } strcpy(msgbld,&msgi[6]); while (strlen(&msgi[6]) == (segsiz + 1) * 32) { ackmsg(); if (inpkt() || tt != LNGDAT) { intf("OVER ABORT SEVEN"); goto abort; } strcat(msgbld,&msgi[6]); } switch (msgbld[0]) { case 'S' : sscanf(msgbld,"%s %s %s",cmnd,srcnam,dstnam); #ifdef CPM for (p = dstnam + strlen(dstnam); p != dstnam && *(p-1) != '/'; p--); #else p = dstnam; #endif if ((fddsk = creat(p,0644)) >= 0) { ackmsg(); if (lngput("SY",2)) { intf("OVER NINE"); goto abort; } do if (inpkt()) { intf("OVER TEN"); goto abort; } else switch (tt) { case LNGDAT : write(fddsk,&msgi[6],(segsiz + 1) * 32); ackmsg(); break; case SHTDAT : if (msgi[6] & 0x80) { intf("OVER ELEVEN"); #ifdef DEBUG puts("short packet error"); #endif goto abort; } else { if (msgi[6] != (segsiz + 1) * 32) write(fddsk,&msgi[7],(segsiz + 1) * 32 - msgi[6]); ackmsg(); } break; default : intf("OVER TWELVE"); goto abort; } while (tt != SHTDAT || msgi[6] != (segsiz + 1) * 32); close(fddsk); if (lngput("CY",2)) goto abort; } else { ackmsg(); #ifdef ERRLOG if (file = fopen("uuslave.log","a+")) { fprintf(file,"Cannot open file=%s for writing errno=%d\n",p,errno); fclose(file); } #endif sprintf(dskbuf,"SN%d",errno); if (lngput(dskbuf,strlen(dskbuf))) goto abort; } break; case 'R' : sscanf(msgbld,"%s %s %s",cmnd,srcnam,dstnam); #ifdef CPM for (p = srcnam + strlen(srcnam); p != srcnam && *(p-1) != '/'; p--); #else p = srcnam; #endif if ((fddsk = open(p,O_RDONLY)) >= 0) { ackmsg(); if (lngput("RY",2)) goto abort; do if ((count = read(fddsk,dskbuf,(segsiz + 1) * 32)) == (segsiz + 1) * 32) if (lngput(dskbuf,(segsiz + 1) * 32)) goto abort; else; else if (shtput(dskbuf,count)) goto abort; while (count); close(fddsk); do if (inpkt()) goto abort; while (tt != LNGDAT); ackmsg(); } else { ackmsg(); #ifdef ERRLOG if (file = fopen("uuslave.log","a+")) { fprintf(file,"Cannot open file=%s for reading errno=%d\n",p,errno); fclose(file); } #endif sprintf(dskbuf,"RN%d",errno); if (lngput(dskbuf,strlen(dskbuf))) goto abort; } break; case 'H' : intf("IN H CASE"); if (lngput("HY",2)) { intf("OVER ABORT ONE"); goto abort; } if (inpkt() || tt != LNGDAT) { intf("OVER ABORT TWO"); goto abort; } if (!strcmp(&msgi[6],"HY")) { ctlmsg(CLOSE << 3); do if (inpkt()) { intf("OVER ABORT THREE"); goto abort; } while (tt != CTRL && xxx != CLOSE); xwrite(fdtty,msgo4,sizeof(msgo4)-1); instr(msgo4,sizeof(msgo4)-1); } intf("OVER ABORT FIVE"); break; /*goto abort;*/ } } abort:; xwrite(fdtty,msgo5,sizeof(msgo5)-1); } } intf(buffer) register char *buffer; { int fd; fd = open("UUCP.DAT",O_RDWR + O_CREAT); lseek(fd,0L,2); write(fd,buffer,strlen(buffer)); close(fd); }