Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!cbatt!cwruecmp!hal!ncoast!simpsong From: simpsong@ncoast.UUCP Newsgroups: net.sources,comp.sys.ibm.pc Subject: uuslave.c (Straight from the BBS in NJ) Message-ID: <1911@ncoast.UUCP> Date: Sat, 17-Jan-87 11:16:37 EST Article-I.D.: ncoast.1911 Posted: Sat Jan 17 11:16:37 1987 Date-Received: Tue, 20-Jan-87 06:40:48 EST Distribution: net Organization: Cleveland Public Access UNIX, Cleveland, OH Lines: 627 Xref: watmath net.sources:6173 comp.sys.ibm.pc:998 *** Line-eater foo-d. *** Greetings Fellow Neter's... There was a lot of talk about UUCP for MS-DOS a week or two ago, and one thing that was mentioned was a program called uuslave.c from a BBS in NJ. Well, even though I am in Cleveland, I went ahead and registered just so I could get this program... Unfortunately, it contains very few comments, and appears to be originally targeted for CPM, as well as having lots of stuff hard-wired into the code... I really don't know if it will be of any use, but it may be a building block from which the readers of net-land can produce a usable uucp for msdos. (Does Minix have uucp?) There was absolutely no documentation, and after looking at it briefly, I really don't know where to start... So, I ask... can anyone out there make heads or tails of this? I will be trying to, but it really isn't my cup of tea. If anyone can make this work, please repost your enhanced version with some documentation. Thanks, and Enjoy. Gregory R. Simpson UUCP: {ihnp4, seismo, decwrl, philabs, ucbvax}!decvax!cwruecmp!ncoast!simpsong CSNET: ncoast!simpsong@case.CSNET ARPA: ncoast!simpsong%case.CSNET@Csnet-Relay.ARPA ------- This is NOT a shar, or an arc, or anything... just straight code ---- /* @[$]uuslave.c 1.7 08/12/85 14:04:20 */ #include #include #ifndef CPM #include #include #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); } -- Gregory R. Simpson UUCP: {ihnp4, seismo, decwrl, philabs, ucbvax}!decvax!cwruecmp!ncoast!simpsong CSNET: ncoast!simpsong@case.CSNET ARPA: ncoast!simpsong%case.CSNET@Csnet-Relay.ARPA