jeff@voder.UUCP (03/27/87)
Index: usr.bin/uucp/cntrl.c 4.3BSD +FIX Description: The 4.3BSD uucp contains some new code that tries to turn the line around periodically. The intent is keep one side from being master for a very long period of time. This is implemented by having the slave periodically request to become master. Unfortunately, the turnaround code doesn't work with 'R' requests (i.e., when the master is receiving a file from the slave). When the transfer completes the *master* sends a 'CYM' message; the slave tries to turn the line around, but the master is trying to send the next work request. Repeat-By: Get another 4.3 site to put a couple of files in their public uucp directory. Make sure their length is such that it will take more than a minute to transfer the first. Queue a couple of requests to retrieve these files from the other system, then start a uucico. Note that the first file is transferred, then the the protocol breaks down and the slave hangs up the line [complaining "BAD READ (expected 'H', got R ..."]. uucp -r remote!~/publicfile1 ~uucp uucp -r remote!~/publicfile2 ~uucp /usr/lib/uucp/uucico -r1 -sremote -x5 -t1 Fix: The following patch solves the problem. Basically there are two pieces here. First, make sure that we only try to turn the line around if we are the master. This protects us from other 4.3 sites running the broken uucp. Second, implement the turnaround code for 'R' request so that it actually works (assuming the other site has made the same change). This is done by having the slave return 'RY 644 M' if it wants the line turned around after this transfer. (Note that we can't return 'RYM 644'. The receiving end does a scanf() to find the file mode, starting at the third character of the string.) This should interroperate properly with pre-4.3 uucp's, broken 4.3 uucp's, as well as fixed 4.3 uucp's. RCS file: RCS/cntrl.c,v retrieving revision 1.2 diff -c -r1.2 cntrl.c *** /tmp/,RCSt1005969 Thu Mar 26 19:23:41 1987 --- cntrl.c Wed Mar 25 18:47:11 1987 *************** *** 302,308 **** if (role == MASTER) { notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]); } ! if (msg[2] == 'M') { extern int Nfiles; WMESG(HUP, ""); RMESG(HUP, msg, 1); --- 302,308 ---- if (role == MASTER) { notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]); } ! if (msg[2] == 'M' && role == MASTER) { extern int Nfiles; WMESG(HUP, ""); RMESG(HUP, msg, 1); *************** *** 569,580 **** strcat(filename, lastpart(W_FILE1)); } status = xmv(Dfile, filename); ! if (willturn && Now.time > (LastTurned.time+turntime) ! && iswrk(Wfile, "chk", Spool, wkpre)) { ! WMESG(RQSTCMPT, status ? EM_RMTCP : "YM"); ! willturn = -1; ! } else ! WMESG(RQSTCMPT, status ? EM_RMTCP : YES); notify(mailopt, W_USER, filename, Rmtname, status ? EM_LOCCP : YES); if (status == 0) { --- 569,575 ---- strcat(filename, lastpart(W_FILE1)); } status = xmv(Dfile, filename); ! WMESG(RQSTCMPT, status ? EM_RMTCP : YES); notify(mailopt, W_USER, filename, Rmtname, status ? EM_LOCCP : YES); if (status == 0) { *************** *** 588,593 **** --- 583,602 ---- putinpub(filename, Dfile, W_USER); USRF(USR_LOCCP); } + if (msg[strlen(msg)-1] == 'M') { + extern int Nfiles; + WMESG(HUP, ""); + RMESG(HUP, msg, 1); + logent(Rmtname, "TURNAROUND"); + #ifdef USG + time(&LastTurned.time); + LastTurned.millitm = 0; + #else !USG + ftime(&LastTurned); + #endif !USG + Nfiles = 0; /* force rescan of queue for work */ + goto process; + } goto top; } *************** *** 635,641 **** ret = fstat(fileno(fp), &stbuf); ASSERT(ret != -1, "STAT FAILED", filename, 0); i = 1 + (int)(stbuf.st_size / XFRRATE); ! sprintf(msg, "%s %o", YES, (int)stbuf.st_mode & 0777); WMESG(RCVFILE, msg); if (send_or_receive != SNDFILE) { send_or_receive = SNDFILE; --- 644,655 ---- ret = fstat(fileno(fp), &stbuf); ASSERT(ret != -1, "STAT FAILED", filename, 0); i = 1 + (int)(stbuf.st_size / XFRRATE); ! if (willturn && Now.time > (LastTurned.time+turntime) ! && iswrk(Wfile, "chk", Spool, wkpre)) { ! willturn = -1; ! } ! sprintf(msg, "%s %o %s", YES, (int)stbuf.st_mode & 0777, ! willturn < 0 ? "M" : ""); WMESG(RCVFILE, msg); if (send_or_receive != SNDFILE) { send_or_receive = SNDFILE; -- Jeff Gilliam {ucbvax,pyramid,nsc}!voder!jeff