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