|
|
1.1 ! root 1: ! 2: static char SCCSID[] = "@(#)pupucommon.c 2.1 DKHOST 85/01/15"; ! 3: ! 4: #include "pupu.h" ! 5: #include <varargs.h> ! 6: #include <errno.h> ! 7: #include "string.h" ! 8: extern int errno ; ! 9: ! 10: Xint cfd; ! 11: ! 12: Xchar mhead[H_DATA] = "\206\006"; ! 13: Xchar buf[BLOCKSIZE]; ! 14: XcharP mnext; ! 15: Xchar sseq, rseq; ! 16: ! 17: Xjmp giveup; ! 18: XfnP alarmwas; ! 19: ! 20: Xchar wdir[NAMELEN]; ! 21: Xchar basedir[NAMELEN]; ! 22: Xchar wholename[NAMELEN]; ! 23: ! 24: Xlink linkhead; ! 25: ! 26: XfnP errorfunction; ! 27: Xint lasterror; ! 28: XcharP remoteorlocal; ! 29: XcharP currentfile, timeoutmsg; ! 30: ! 31: Xchar openfiles[TOPFD+4]; ! 32: ! 33: Efn gotinit, gotinitreply; ! 34: ! 35: Xexp inittable[] = { ! 36: 'I', gotinit, ! 37: 'i', gotinitreply, ! 38: 0, 0 ! 39: }; ! 40: ! 41: Efn remotedone, remoteerror, alldone; ! 42: ! 43: Xexp justquit[] = { ! 44: 'x', remotedone, ! 45: 'e', remoteerror, ! 46: 'X', alldone, ! 47: 0, 0 ! 48: }; ! 49: ! 50: SexpP toexpect; ! 51: ! 52: Xchar myversion[6] = "1"; ! 53: Xchar theirversion[6]; ! 54: ! 55: Xchar options[32]; ! 56: ! 57: Efn timeout; ! 58: ! 59: begin(fd, errfcn, rol, initwdir) ! 60: PfnP errfcn; ! 61: PcharP rol, initwdir; ! 62: { ! 63: cfd = fd; ! 64: errorfunction = errfcn; ! 65: remoteorlocal = rol; ! 66: currentfile = NIL; ! 67: lasterror = 0; ! 68: ! 69: strcpy(wdir, initwdir); ! 70: ! 71: signal(SIGALRM, timeout); ! 72: } ! 73: ! 74: sendinit(opt) ! 75: PcharP opt; ! 76: { ! 77: msginit('I'); ! 78: msgfmt("%s", myversion); ! 79: msgfmt("%s", opt); ! 80: ! 81: msgconf(inittable); ! 82: } ! 83: ! 84: gotinit() ! 85: { ! 86: msgtake("%s", theirversion); ! 87: msgtake("%s", options); ! 88: ! 89: msginit('i'); ! 90: msgfmt("%s", myversion); ! 91: msgsend(); ! 92: ! 93: return(1); ! 94: } ! 95: ! 96: gotinitreply() ! 97: { ! 98: msgtake("%s", theirversion); ! 99: ! 100: return(1); ! 101: } ! 102: ! 103: err(msg, parm, en) ! 104: PcharP msg, parm; ! 105: { ! 106: warn(msg, parm, en); ! 107: ! 108: if(*remoteorlocal == 'r') ! 109: reply('X'); ! 110: ! 111: stopnow(en); ! 112: } ! 113: ! 114: warn(msg, parm, en) ! 115: PcharP msg, parm; ! 116: { ! 117: RcharP ep; ! 118: Achar ebuf[BUFSIZ]; ! 119: ! 120: ep = ebuf; ! 121: ! 122: ep += sprintf(ep, "(%s): %s", remoteorlocal, msg); ! 123: ! 124: if(parm) ! 125: ep += sprintf(ep, " [%s]", parm); ! 126: ! 127: if(en > 0 && errno >= 0 && errno <= sys_nerr) ! 128: sprintf(ep, " -- %s", sys_errlist[errno]); ! 129: ! 130: db(stderr, "warn * %s\n", ebuf); ! 131: if(*remoteorlocal == 'l') ! 132: (*errorfunction)(ebuf); ! 133: else{ ! 134: msginit('e'); ! 135: msgfmt("%s", ebuf); ! 136: msgsend(); ! 137: } ! 138: ! 139: lasterror = en < 0 ? -en : en; ! 140: } ! 141: ! 142: creatn(name, mode) ! 143: PcharP name; ! 144: { ! 145: Rint fd; ! 146: ! 147: fd = creat(name, mode); ! 148: ! 149: if(fd >= 0) ! 150: openfiles[fd] = 1; ! 151: ! 152: return(fd); ! 153: } ! 154: ! 155: openn(name, flags) ! 156: PcharP name; ! 157: { ! 158: Rint fd; ! 159: ! 160: fd = open(name, flags); ! 161: ! 162: if(fd >= 0) ! 163: openfiles[fd] = 1; ! 164: ! 165: return(fd); ! 166: } ! 167: ! 168: closen(fd) ! 169: { ! 170: close(fd); ! 171: ! 172: openfiles[fd] = 0; ! 173: } ! 174: ! 175: remotedone() ! 176: { ! 177: Aint en; ! 178: ! 179: msgtake("%d", &en); ! 180: ! 181: if(en) ! 182: lasterror = en; ! 183: ! 184: return(1); ! 185: } ! 186: ! 187: alldone() ! 188: { ! 189: stopnow(0); ! 190: } ! 191: ! 192: stopnow(en) ! 193: { ! 194: Rint i; ! 195: RlinkP lp, nlp; ! 196: ! 197: alarm(0); ! 198: signal(SIGALRM, alarmwas); ! 199: ! 200: for(i = 0; i < sizeof(openfiles)/sizeof(openfiles[0]); i++) ! 201: if(openfiles[i]) ! 202: closen(i); ! 203: ! 204: for(lp = linkhead.next; lp; lp = nlp){ ! 205: nlp = lp->next; ! 206: free(lp); ! 207: } ! 208: linkhead.next = 0; ! 209: ! 210: if(en > 0) ! 211: lasterror = en; ! 212: else if(en < 0) ! 213: lasterror = -en; ! 214: ! 215: longjmp(giveup, 1); ! 216: } ! 217: ! 218: msgtake(fmt, ptr) ! 219: PcharP fmt, ptr; ! 220: { ! 221: if(strcmp(fmt, "%s") == 0) ! 222: strcpy(ptr, mnext); /* Foo! sscanf stops at white space */ ! 223: else ! 224: sscanf(mnext, fmt, ptr); ! 225: ! 226: mnext += strlen(mnext)+1; ! 227: } ! 228: ! 229: reply(type) ! 230: Pchar type; ! 231: { ! 232: if(++sseq > SEQMAX) ! 233: sseq = SEQMIN; ! 234: mhead[H_SEQN] = sseq; ! 235: ! 236: mhead[H_TYPE] = type; ! 237: ! 238: timeoutmsg = "Protocol exchange timed out"; ! 239: ! 240: alarm(WTIMEOUT); ! 241: ! 242: write(cfd, mhead, sizeof(mhead)); ! 243: ! 244: alarm(0); ! 245: } ! 246: ! 247: confirmed() ! 248: { ! 249: return(1); ! 250: } ! 251: ! 252: remoteerror() ! 253: { ! 254: Achar ebuf[BUFSIZ]; ! 255: ! 256: msgtake("%s", ebuf); ! 257: ! 258: (*errorfunction)(ebuf); ! 259: ! 260: return(0); ! 261: } ! 262: ! 263: msginit(type) ! 264: Pchar type; ! 265: { ! 266: if(toexpect){ ! 267: msgwait(toexpect); ! 268: toexpect = 0; ! 269: } ! 270: ! 271: if(++sseq > SEQMAX) ! 272: sseq = SEQMIN; ! 273: mhead[H_SEQN] = sseq; ! 274: ! 275: mhead[H_TYPE] = type; ! 276: ! 277: strcpy(buf, mhead); ! 278: ! 279: mnext = &buf[H_DATA]; ! 280: } ! 281: ! 282: /* VARARGS0 */ ! 283: msgfmt(va_alist) ! 284: va_dcl ! 285: { ! 286: RcharP fmt; ! 287: va_list args; ! 288: ! 289: va_start(args); ! 290: ! 291: fmt = va_arg(args, TcharP); ! 292: ! 293: mnext += vsprintf(mnext, fmt, args) + 1; ! 294: } ! 295: ! 296: msgconf(expect) ! 297: PexpP expect; ! 298: { ! 299: msgsend(); ! 300: ! 301: toexpect = expect; ! 302: } ! 303: ! 304: msgsend() ! 305: { ! 306: Rint len; ! 307: db(stderr, "msgsend %c\n", buf[H_TYPE]); ! 308: ! 309: len = mnext - buf; ! 310: ! 311: timeoutmsg = "Protocol exchange timed out"; ! 312: ! 313: alarm(WTIMEOUT); ! 314: ! 315: if(write(cfd, buf, len) != len) ! 316: if(*remoteorlocal == 'r') ! 317: stopnow(EX_IOERR); ! 318: else ! 319: err("Message write failed", NIL, EX_IOERR); ! 320: ! 321: alarm(0); ! 322: } ! 323: ! 324: msgwait(expect) ! 325: PexpP expect; ! 326: { ! 327: Rint len; ! 328: RexpP ep; ! 329: ! 330: db(stderr, "msgwait %X\n", expect); ! 331: timeoutmsg = "Protocol exchange timed out"; ! 332: ! 333: for(;;){ ! 334: alarm(RTIMEOUT); ! 335: ! 336: len = read(cfd, buf, sizeof(buf)); ! 337: ! 338: alarm(0); ! 339: db(stderr, "read len %d type %c\n", len, buf[H_TYPE]); ! 340: ! 341: if(len <= 0) ! 342: err("Message read error", NIL, EX_IOERR); ! 343: ! 344: if(++rseq > SEQMAX) ! 345: rseq = SEQMIN; ! 346: if(buf[H_MAG1] != mhead[H_MAG1] || buf[H_MAG2] != mhead[H_MAG2]) ! 347: err("Bad magic number on message", NIL, -EX_PROTOCOL); ! 348: if(buf[H_SEQN] != rseq) ! 349: err("Bad sequence number on message", NIL, -EX_PROTOCOL); ! 350: ! 351: mnext = &buf[H_DATA]; ! 352: ! 353: for(ep = expect; ep->type; ep++) ! 354: if(ep->type == buf[H_TYPE]) ! 355: if((*ep->fn)()) ! 356: return; ! 357: else ! 358: break; ! 359: ! 360: if(!ep->type) ! 361: err("Unexpected message type", &buf[H_TYPE], -EX_PROTOCOL); ! 362: } ! 363: } ! 364: ! 365: ! 366: sendfile(name) ! 367: RcharP name; ! 368: { ! 369: AcharP d; ! 370: ! 371: if(d = strrchr(name, '/')){ ! 372: if(!wdir[0]) ! 373: curdir(wdir); ! 374: ! 375: if(d == name) ! 376: name = "/"; ! 377: else ! 378: *d = '\0'; ! 379: ! 380: if(chdir(name) < 0){ ! 381: warn("Can't change directory to", name, EX_NOINPUT); ! 382: return; ! 383: } ! 384: ! 385: name = d+1; ! 386: } ! 387: ! 388: putfile(name, name); ! 389: ! 390: if(d) ! 391: chdir(wdir); ! 392: } ! 393: ! 394: timeout() ! 395: { ! 396: err(timeoutmsg, currentfile, -EX_IOERR); ! 397: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.