|
|
1.1 ! root 1: #ifndef lint ! 2: static char *rcsid = "$Header: xnftp.c,v 2.5 87/03/08 07:09:53 jqj Exp $"; ! 3: #endif lint ! 4: ! 5: /* $Log: xnftp.c,v $ ! 6: * Revision 2.5 87/03/08 07:09:53 jqj ! 7: * work around "schain botch" 4.3BSD VAX compiler bug (from Scooter Morris). ! 8: * ! 9: * Revision 2.4 86/12/15 11:41:16 jqj ! 10: * Added support for more ViewPoint file types (no other attributes, though) ! 11: * ! 12: * Revision 2.3 86/12/11 06:12:22 jqj ! 13: * Eliminated form, mode, and struct commands. Started adding support for ! 14: * more file types. ! 15: * ! 16: * Revision 2.2 86/09/07 07:43:40 jqj ! 17: * Cope with failure return from CourierOpen. ! 18: * ! 19: * Revision 2.1 86/06/30 12:19:39 jqj ! 20: * convert to Authentication v. 2 for compatibility with official spec. ! 21: * ! 22: * Revision 2.0 85/11/21 07:22:51 jqj ! 23: * 4.3BSD standard release ! 24: * ! 25: * Revision 1.5 85/09/24 14:45:10 jqj ! 26: * fix bug in alarm() handling that caused aborts during large file transfers. ! 27: * ! 28: * Revision 1.4 85/09/17 07:49:47 jqj ! 29: * 4.3 changes. Use more routines from CHlookup ! 30: * ! 31: * Revision 1.1 85/05/27 06:31:07 jqj ! 32: * Initial revision ! 33: * ! 34: */ ! 35: ! 36: #include <stdio.h> ! 37: #include <sys/time.h> ! 38: #include <sys/param.h> ! 39: #include <sys/stat.h> ! 40: #include <netns/ns.h> ! 41: #include <netns/sp.h> ! 42: #include "ftp_var.h" ! 43: #include <xnscourier/CH.h> ! 44: ! 45: CourierConnection *connected; ! 46: Clearinghouse2_ObjectName hostobjname; ! 47: Authentication2_Verifier verifier; ! 48: ! 49: /* the following 3 items make up the current session */ ! 50: Filing4_Session session; /* the current session */ ! 51: Clearinghouse2_ObjectName username; ! 52: int continuetime; ! 53: int remoteprocpending; ! 54: Filing4_Handle wdHandle; /* the current remote working dir */ ! 55: ! 56: static Filing4_ControlSequence nullControls = {0,0}; ! 57: static Filing4_ScopeSequence nullScope = {0,0}; ! 58: ! 59: /* global data used to communicate with BDT procedures ! 60: */ ! 61: extern GetAttributeSequences(), ! 62: listproc(), nlistproc(), ! 63: storeproc(), retrieveproc(); ! 64: static (*ProcEachSeq)(); ! 65: static long bytessent; ! 66: static FILE *fout, *fin; ! 67: ! 68: copyhandle(dest,src) ! 69: Filing4_Handle dest,src; ! 70: { ! 71: if (dest == (Unspecified *) 0) { ! 72: fprintf(stderr,"Oops. dest is null in copyhandle\n"); ! 73: exit(1); ! 74: } ! 75: dest[0] = src[0]; ! 76: dest[1] = src[1]; ! 77: } ! 78: ! 79: StringToAttr(str, attr) ! 80: char *str; ! 81: Filing4_Attribute *attr; ! 82: { ! 83: Unspecified buf[2049], *bp; ! 84: Cardinal len; ! 85: ! 86: bp = buf + sizeof_Cardinal(len); ! 87: len = externalize_String(&str, bp); ! 88: (void) externalize_Cardinal(&len, buf); ! 89: internalize_Clearinghouse2_Item(&(attr->value), buf); ! 90: return; ! 91: } ! 92: ! 93: char * ! 94: AttrToString(attr) ! 95: Filing4_Attribute *attr; ! 96: { ! 97: Unspecified buf[2049], *bp; ! 98: Cardinal len; ! 99: char *strval; ! 100: ! 101: externalize_Clearinghouse2_Item(&(attr->value), buf); ! 102: bp = buf; ! 103: bp += internalize_Cardinal(&len, bp); ! 104: bp += internalize_String(&strval, bp); ! 105: return(strval); ! 106: } ! 107: ! 108: UserToAttr(id, attr) ! 109: Clearinghouse2_Name id; ! 110: Filing4_Attribute *attr; ! 111: { ! 112: Unspecified buf[2049], *bp; ! 113: Cardinal len; ! 114: ! 115: bp = buf + sizeof_Cardinal(len); ! 116: len = externalize_Clearinghouse2_Name(&id, bp); ! 117: (void) externalize_Cardinal(&len, buf); ! 118: internalize_Clearinghouse2_Item(&(attr->value), buf); ! 119: return; ! 120: } ! 121: ! 122: LongCardinalToAttr(val, attr) ! 123: LongCardinal val; ! 124: Filing4_Attribute *attr; ! 125: { ! 126: Unspecified buf[3], *bp; ! 127: Cardinal len; ! 128: ! 129: bp = buf + sizeof_Cardinal(len); ! 130: len = externalize_LongCardinal(&val, bp); ! 131: (void) externalize_Cardinal(&len, buf); ! 132: internalize_Clearinghouse2_Item(&(attr->value), buf); ! 133: return; ! 134: } ! 135: ! 136: BooleanToAttr(val, attr) ! 137: int val; ! 138: Filing4_Attribute *attr; ! 139: { ! 140: Boolean boolval; ! 141: Unspecified buf[3], *bp; ! 142: Cardinal len; ! 143: ! 144: boolval = (Boolean) val; ! 145: bp = buf + sizeof_Cardinal(len); ! 146: len = externalize_Boolean(&boolval, bp); ! 147: (void) externalize_Cardinal(&len, buf); ! 148: internalize_Clearinghouse2_Item(&(attr->value), buf); ! 149: return; ! 150: } ! 151: ! 152: int ! 153: AttrToBoolean(attr) ! 154: Filing4_Attribute *attr; ! 155: { ! 156: Unspecified buf[1]; ! 157: Boolean result; ! 158: ! 159: (void) externalize_Unspecified(attr->value.sequence, buf); ! 160: (void) internalize_Boolean(&result, buf); ! 161: return(result); ! 162: } ! 163: ! 164: LongCardinal ! 165: AttrToLongCardinal(attr) ! 166: Filing4_Attribute *attr; ! 167: { ! 168: Unspecified buf[2]; ! 169: LongCardinal result; ! 170: ! 171: (void) externalize_Unspecified(attr->value.sequence, buf); ! 172: (void) externalize_Unspecified((attr->value.sequence)+1, buf+1); ! 173: (void) internalize_LongCardinal(&result, buf); ! 174: return(result); ! 175: } ! 176: ! 177: ! 178: getfilehandle(filename, handle) ! 179: char *filename; ! 180: Filing4_Handle handle; ! 181: { ! 182: Filing4_Attribute pathattr[1]; ! 183: Filing4_AttributeSequence attrseq; ! 184: Filing4_OpenResults openresult; ! 185: ! 186: if (filename == (char *)0 || *filename == '\000') { ! 187: copyhandle(handle,wdHandle); ! 188: return; ! 189: } ! 190: attrseq.length = 1; ! 191: attrseq.sequence = pathattr; ! 192: pathattr[0].type = Filing4_pathname; ! 193: copyhandle(handle, Filing4_nullHandle); ! 194: if (*filename != '/') { /* relative pathname specified */ ! 195: StringToAttr(filename, &pathattr[0]); ! 196: copyhandle(handle, wdHandle); ! 197: } else if (filename[1] == '\000') { ! 198: /* root specified */ ! 199: attrseq.length = 0; ! 200: } else { /* absolute pathname specified */ ! 201: StringToAttr(filename+1, &pathattr[0]); ! 202: } ! 203: alarm(0); ! 204: openresult = Filing4_Open(connected, NULL, attrseq, ! 205: handle, nullControls, ! 206: session); ! 207: alarm(continuetime); ! 208: copyhandle(handle, openresult.file); ! 209: } ! 210: ! 211: freefilehandle(handle) ! 212: Filing4_Handle handle; ! 213: { ! 214: if (handle[0] == Filing4_nullHandle[0] && ! 215: handle[1] == Filing4_nullHandle[1]) ! 216: return; /* don't free nullHandle */ ! 217: if (handle[0] == wdHandle[0] && ! 218: handle[1] == wdHandle[1]) ! 219: return; /* don't free working directory */ ! 220: alarm(0); ! 221: Filing4_Close(connected, NULL, handle, session); ! 222: alarm(continuetime); ! 223: } ! 224: ! 225: /* ! 226: * do a continue to make sure that the session doesn't time out. ! 227: * Note that this is usually called by an ALARM interrupt ! 228: */ ! 229: probe() ! 230: { ! 231: Filing4_ContinueResults cresult; ! 232: ! 233: alarm(0); /* cancel previous alarms */ ! 234: cresult = Filing4_Continue(connected, NULL, session); ! 235: continuetime = cresult.continuance / 5; /* seconds */ ! 236: alarm(continuetime); /* reset for another 2 min. or so */ ! 237: } ! 238: ! 239: CourierConnection * ! 240: hookup(name) ! 241: char *name; ! 242: { ! 243: register struct ns_addr *hostaddr; ! 244: extern struct ns_addr *getXNSaddr(); ! 245: Clearinghouse2_ObjectName defaultobjname; ! 246: static char hnamebuf[128]; ! 247: CourierConnection *cconn; ! 248: ! 249: CH_NameDefault(&defaultobjname); ! 250: hostobjname = CH_StringToName(name, &defaultobjname); ! 251: if ((hostaddr = CH_LookupAddrDN( hostobjname, 0, hnamebuf, 128))) { ! 252: /* should check here to be sure host is a file service */ ! 253: hostaddr->x_port = htons(IDPPORT_COURIER); /* ?? */ ! 254: cconn = CourierOpen(hostaddr); ! 255: /* reset objname to flush wildcards */ ! 256: /* clear_Clearinghouse2_ThreePartName(&hostobjname); */ ! 257: hostobjname = CH_StringToName(hnamebuf, &defaultobjname); ! 258: hostname = hnamebuf; ! 259: if (cconn == (CourierConnection*) 0) ! 260: printf("%s: connection failed\n", hnamebuf); ! 261: else if (verbose) ! 262: printf("Connected to %s\n", hnamebuf); ! 263: } else { ! 264: printf("%s: unknown host\n", name); ! 265: cconn = (CourierConnection*)0; ! 266: } ! 267: return(cconn); ! 268: } ! 269: ! 270: ! 271: login(name,pwd) ! 272: char *pwd; ! 273: char *name; ! 274: { ! 275: Authentication2_Credentials credentials; ! 276: Filing4_LogonResults logonresult; ! 277: ! 278: username = CH_StringToName(name,&hostobjname); ! 279: MakeSimpleCredsAndVerifier(&username,pwd, ! 280: &credentials, &verifier); ! 281: logonresult = Filing4_Logon(connected, NULL, hostobjname, ! 282: credentials, verifier); ! 283: session = logonresult.session; ! 284: copyhandle(wdHandle, Filing4_nullHandle); ! 285: if (verbose) ! 286: printf("User %s:%s:%s logged on\n", username.object, ! 287: username.domain, username.organization); ! 288: alarm(0); ! 289: signal(SIGALRM, probe); ! 290: probe(); ! 291: } ! 292: ! 293: logout() ! 294: { ! 295: signal(SIGALRM, SIG_IGN); ! 296: Filing4_Logoff(connected, NULL, session); ! 297: clear_Filing4_Session(&session); ! 298: copyhandle(wdHandle, Filing4_nullHandle); ! 299: } ! 300: ! 301: domakedir(dest) ! 302: char *dest; ! 303: { ! 304: sendrequest("MKDIR", "-", dest); ! 305: } ! 306: ! 307: doremovedir(src) ! 308: char *src; ! 309: { ! 310: dodelete(src); ! 311: } ! 312: ! 313: dostore(src, dest) ! 314: char *src, *dest; ! 315: { ! 316: sendrequest("STOR", src, dest); ! 317: } ! 318: ! 319: doappend(src, dest) ! 320: char *src, *dest; ! 321: { ! 322: NYI(); ! 323: } ! 324: ! 325: dorename(src, dest) ! 326: char *src, *dest; ! 327: { ! 328: NYI(); ! 329: } ! 330: ! 331: recvrequest(cmd, local, remote, mode) ! 332: char *cmd, *local, *remote, *mode; ! 333: { ! 334: FILE *popen(); ! 335: int (*closefunc)(), pclose(), fclose(); ! 336: struct timeval start, stop; ! 337: Filing4_Handle remotehandle; /* note: an array */ ! 338: Filing4_AttributeTypeSequence typeseq; ! 339: Filing4_AttributeType tsvals[10]; ! 340: char *dir; ! 341: ! 342: closefunc = NULL; ! 343: fout = stdout; ! 344: typeseq.length = 0; typeseq.sequence = tsvals; ! 345: if (strcmp(local, "-") && *local != '|') ! 346: if (access(local, 2) < 0) { ! 347: dir = rindex(local, '/'); ! 348: /* get a good error message */ ! 349: if (dir != NULL) *dir = '\0'; ! 350: if (access(dir ? local : ".", 2) < 0) { ! 351: perror(local); ! 352: goto bad; ! 353: } ! 354: if (dir != NULL) *dir = '/'; ! 355: } ! 356: if (strcmp(local, "-") == 0) ! 357: fout = stdout; ! 358: else if (*local == '|') { ! 359: fout = popen(local + 1, "w"); ! 360: if (fout == NULL) { ! 361: perror(local + 1); ! 362: goto bad; ! 363: } ! 364: closefunc = pclose; ! 365: } else { ! 366: fout = fopen(local, mode); ! 367: if (fout == NULL) { ! 368: perror(local); ! 369: goto bad; ! 370: } ! 371: closefunc = fclose; ! 372: } ! 373: bytessent = 0; ! 374: gettimeofday(&start, (struct timezone *)0); ! 375: getfilehandle(remote, remotehandle); ! 376: alarm(0); ! 377: if (strcmp(cmd,"NLST") == 0) { ! 378: typeseq.length = 1; ! 379: typeseq.sequence[0] = Filing4_pathname; ! 380: ProcEachSeq = nlistproc; ! 381: Filing4_List(connected, GetAttributeSequences, remotehandle, ! 382: typeseq, nullScope, ! 383: BulkData1_immediateSink, session); ! 384: } ! 385: else if (strcmp(cmd,"LIST") == 0) { ! 386: typeseq.length = 5; ! 387: typeseq.sequence[0] = Filing4_name; ! 388: typeseq.sequence[1] = Filing4_dataSize; ! 389: typeseq.sequence[2] = Filing4_isDirectory; ! 390: typeseq.sequence[3] = Filing4_isTemporary; ! 391: typeseq.sequence[4] = Filing4_type; ! 392: ProcEachSeq = listproc; ! 393: Filing4_List(connected, GetAttributeSequences, remotehandle, ! 394: typeseq, nullScope, ! 395: BulkData1_immediateSink, session); ! 396: } ! 397: else if (strcmp(cmd,"RETR") == 0) { ! 398: Filing4_Retrieve(connected, retrieveproc, remotehandle, ! 399: BulkData1_immediateSink, session); ! 400: } ! 401: else printf("unrecognized command %s\n",cmd); ! 402: alarm(continuetime); ! 403: gettimeofday(&stop, (struct timezone *)0); ! 404: freefilehandle(remotehandle); ! 405: if (bytessent > 0 && verbose) ! 406: ptransfer("received", bytessent, &start, &stop); ! 407: bad: ! 408: if (closefunc != NULL && fout != NULL) ! 409: (*closefunc)(fout); ! 410: fout = NULL; ! 411: } ! 412: ! 413: ! 414: sendrequest(cmd, local, remote) ! 415: char *cmd, *local, *remote; ! 416: { ! 417: FILE *popen(); ! 418: int (*closefunc)(), pclose(), fclose(); ! 419: struct stat st; ! 420: struct timeval start, stop; ! 421: Filing4_StoreResults storeresults; ! 422: Filing4_CreateResults createresults; ! 423: Filing4_Handle remotehandle; ! 424: Filing4_AttributeSequence attrseq; ! 425: Filing4_Attribute attrvals[5]; ! 426: ! 427: closefunc = NULL; ! 428: if (strcmp(local, "-") == 0) { ! 429: fin = stdin; ! 430: closefunc = NULL; ! 431: } else if (*local == '|') { ! 432: fin = popen(local + 1, "r"); ! 433: if (fin == NULL) { ! 434: perror(local + 1); ! 435: goto bad; ! 436: } ! 437: closefunc = pclose; ! 438: } else { ! 439: fin = fopen(local, "r"); ! 440: if (fin == NULL) { ! 441: perror(local); ! 442: goto bad; ! 443: } ! 444: closefunc = fclose; ! 445: if (fstat(fileno(fin), &st) < 0 || ! 446: (st.st_mode&S_IFMT) != S_IFREG) { ! 447: fprintf(stderr, "%s: not a plain file.", local); ! 448: goto bad; ! 449: } ! 450: } ! 451: if (remote) { ! 452: char *dir = rindex(remote,'/'); ! 453: if (dir != NULL) { ! 454: *dir = '\000'; ! 455: getfilehandle(remote, remotehandle); ! 456: *dir = '/'; ! 457: remote = dir+1; ! 458: } else { ! 459: getfilehandle("", remotehandle); ! 460: } ! 461: } else { ! 462: printf("No remote name specified\n"); ! 463: return; ! 464: } ! 465: bytessent = 0; ! 466: gettimeofday(&start, (struct timezone *)0); ! 467: alarm(0); ! 468: if (strcmp(cmd,"STOR") == 0) { ! 469: attrseq.length = 2; ! 470: attrseq.sequence = attrvals; ! 471: attrvals[0].type = Filing4_name; ! 472: StringToAttr(remote, &attrvals[0]); ! 473: attrvals[1].type = Filing4_type; ! 474: LongCardinalToAttr(typevalue, &attrvals[1]); ! 475: storeresults = Filing4_Store(connected, storeproc, ! 476: remotehandle, attrseq, ! 477: nullControls, ! 478: BulkData1_immediateSource, ! 479: session); ! 480: alarm(continuetime); ! 481: freefilehandle(storeresults.file); ! 482: } ! 483: else if (strcmp(cmd,"MKDIR") == 0) { ! 484: attrseq.length = 3; ! 485: attrseq.sequence = attrvals; ! 486: attrvals[0].type = Filing4_name; ! 487: StringToAttr(remote, &attrvals[0]); ! 488: attrvals[1].type = Filing4_isDirectory; ! 489: BooleanToAttr(1, &attrvals[1]); ! 490: attrvals[2].type = Filing4_type; ! 491: LongCardinalToAttr(Filing4_tDirectory, &attrvals[2]); ! 492: createresults = Filing4_Create(connected, NULL, ! 493: remotehandle, attrseq, ! 494: nullControls, session); ! 495: alarm(continuetime); ! 496: freefilehandle(createresults.file); ! 497: } ! 498: else { ! 499: printf("unrecognized command %s\n",cmd); ! 500: alarm(continuetime); ! 501: } ! 502: gettimeofday(&stop, (struct timezone *)0); ! 503: freefilehandle(remotehandle); ! 504: if (bytessent > 0 && verbose) ! 505: ptransfer("sent", bytessent, &start, &stop); ! 506: bad: ! 507: if (closefunc != NULL && fin != NULL) ! 508: (*closefunc)(fin); ! 509: fin = NULL; ! 510: } ! 511: ! 512: ! 513: ! 514: docd(dest) ! 515: char *dest; ! 516: { ! 517: Filing4_AttributeSequence attrseq; ! 518: Filing4_AttributeTypeSequence typeseq; ! 519: Filing4_AttributeType cdattrs[1]; ! 520: Filing4_GetAttributesResults garesult; ! 521: Filing4_Handle remotehandle, temphandle; ! 522: char trydest[100]; ! 523: int i; ! 524: ! 525: if (dest == (char*)NULL || *dest == '\0') { ! 526: trydest[0] = '/'; /* assume absolute pathname */ ! 527: strcpy(trydest+1,username.object); ! 528: getfilehandle(trydest, remotehandle); ! 529: } ! 530: else ! 531: getfilehandle(dest, remotehandle); ! 532: typeseq.length = 1; typeseq.sequence = cdattrs; ! 533: cdattrs[0] = Filing4_isDirectory; ! 534: alarm(0); ! 535: garesult = Filing4_GetAttributes(connected, NULL, remotehandle, ! 536: typeseq, session); ! 537: alarm(continuetime); ! 538: for (i = 0; i < garesult.attributes.length; i++) { ! 539: if (garesult.attributes.sequence[i].type == Filing4_isDirectory ! 540: && AttrToBoolean(&(garesult.attributes.sequence[i]))) { ! 541: copyhandle(temphandle, wdHandle); ! 542: copyhandle(wdHandle, remotehandle); /* change dir */ ! 543: if (verbose) dopwd(); ! 544: freefilehandle(temphandle); /* free old wdHandle */ ! 545: return; ! 546: } ! 547: } ! 548: printf("%s is not a directory\n", dest); ! 549: freefilehandle(remotehandle); ! 550: } ! 551: ! 552: dopwd() ! 553: { ! 554: Filing4_AttributeSequence attrseq; ! 555: Filing4_AttributeTypeSequence typeseq; ! 556: Filing4_AttributeType pwdattrs[1]; ! 557: Filing4_GetAttributesResults garesult; ! 558: ! 559: if (wdHandle[0] == 0 && wdHandle[1] == 0) { ! 560: printf("Remote working directory: /\n"); ! 561: return; ! 562: } ! 563: typeseq.length = 1; typeseq.sequence = pwdattrs; ! 564: pwdattrs[0] = Filing4_pathname; ! 565: alarm(0); ! 566: garesult = Filing4_GetAttributes(connected, NULL, wdHandle, typeseq, ! 567: session); ! 568: alarm(continuetime); ! 569: if (garesult.attributes.length > 0 && ! 570: garesult.attributes.sequence[0].type == Filing4_pathname) ! 571: printf("Remote working directory: /%s\n", ! 572: AttrToString(&(garesult.attributes.sequence[0]))); ! 573: else printf("Remote working directory not set\n"); ! 574: clear_Filing4_GetAttributesResults(&garesult); ! 575: } ! 576: ! 577: dodelete(src) ! 578: char *src; ! 579: { ! 580: Filing4_Handle remotehandle; ! 581: Filing4_AttributeSequence attrseq; ! 582: Filing4_AttributeTypeSequence typeseq; ! 583: Filing4_AttributeType delattrs[1]; ! 584: Filing4_GetAttributesResults garesult; ! 585: ! 586: typeseq.length = 1; typeseq.sequence = delattrs; ! 587: delattrs[0] = Filing4_isDirectory; ! 588: getfilehandle(src, remotehandle); ! 589: garesult = Filing4_GetAttributes(connected, NULL, remotehandle, ! 590: typeseq, session); ! 591: if (garesult.attributes.length > 0 && ! 592: garesult.attributes.sequence[0].type == Filing4_isDirectory && ! 593: AttrToBoolean(&(garesult.attributes.sequence[0]))) { ! 594: if (!confirm("Delete directory", src)) return; ! 595: } ! 596: ! 597: clear_Filing4_GetAttributesResults(&garesult); ! 598: alarm(0); ! 599: Filing4_Delete(connected, NULL, remotehandle, session); ! 600: alarm(continuetime); ! 601: } ! 602: ! 603: NYI() ! 604: { ! 605: printf("Not yet implemented\n"); ! 606: } ! 607: ! 608: ! 609: ptransfer(direction, bytes, t0, t1) ! 610: char *direction; ! 611: long bytes; ! 612: struct timeval *t0, *t1; ! 613: { ! 614: struct timeval td; ! 615: long ms; ! 616: float bs; ! 617: ! 618: tvsub(&td, t1, t0); ! 619: ms = (td.tv_sec * 1000) + (td.tv_usec / 1000); ! 620: #define nz(x) ((x) == 0 ? 1 : (x)) ! 621: bs = ((1000. * (float) bytes) / (float) nz(ms)); ! 622: printf("\n%ld bytes %s in %d.%02d seconds (%.2g Kbytes/s)\n", ! 623: bytes, direction, td.tv_sec, td.tv_usec / 10000, bs / 1024.); ! 624: } ! 625: ! 626: tvadd(tsum, t0) ! 627: struct timeval *tsum, *t0; ! 628: { ! 629: ! 630: tsum->tv_sec += t0->tv_sec; ! 631: tsum->tv_usec += t0->tv_usec; ! 632: if (tsum->tv_usec > 1000000) ! 633: tsum->tv_sec++, tsum->tv_usec -= 1000000; ! 634: } ! 635: ! 636: tvsub(tdiff, t1, t0) ! 637: struct timeval *tdiff, *t1, *t0; ! 638: { ! 639: ! 640: tdiff->tv_sec = t1->tv_sec - t0->tv_sec; ! 641: tdiff->tv_usec = t1->tv_usec - t0->tv_usec; ! 642: if (tdiff->tv_usec < 0) ! 643: tdiff->tv_sec--, tdiff->tv_usec += 1000000; ! 644: } ! 645: ! 646: nlistproc(attr) ! 647: Filing4_AttributeSequence attr; ! 648: { ! 649: int i; ! 650: char *thisname; ! 651: Filing4_AttributeType t; ! 652: ! 653: for (i = 0; i < attr.length; i++) { ! 654: t = attr.sequence[i].type; ! 655: if (t == Filing4_pathname) fputc('/', fout); ! 656: if (t == Filing4_name || ! 657: t == Filing4_pathname) { ! 658: thisname = AttrToString(&attr.sequence[i]); ! 659: fputs(thisname, fout); ! 660: fputc('\n', fout); ! 661: clear_String(&thisname); ! 662: return; ! 663: } ! 664: } ! 665: } ! 666: ! 667: ! 668: listproc(attr) ! 669: Filing4_AttributeSequence attr; ! 670: { ! 671: int i; ! 672: char *thisname = ""; ! 673: Boolean istemp = 0; ! 674: Boolean isdir = 0; ! 675: LongCardinal thistype = 0; ! 676: LongCardinal thissize = 0; ! 677: Filing4_AttributeType t; ! 678: char *filetypestr; ! 679: char filetypebuf[20]; ! 680: ! 681: for (i = 0; i < attr.length; i++) { ! 682: t = attr.sequence[i].type; ! 683: if (t == Filing4_name || ! 684: t == Filing4_pathname) ! 685: thisname = AttrToString(&attr.sequence[i]); ! 686: else if (t == Filing4_isDirectory) ! 687: isdir = AttrToBoolean(&attr.sequence[i]); ! 688: else if (t == Filing4_isTemporary) ! 689: istemp = AttrToBoolean(&attr.sequence[i]); ! 690: else if (t == Filing4_type) ! 691: thistype = AttrToLongCardinal(&attr.sequence[i]); ! 692: else if (t == Filing4_dataSize) ! 693: thissize = AttrToLongCardinal(&attr.sequence[i]); ! 694: } ! 695: ! 696: if (thistype == Filing4_tUnspecified) ! 697: filetypestr = ""; ! 698: else if (thistype == Filing4_tDirectory) ! 699: filetypestr = "(dir.)"; ! 700: else if (thistype == Filing4_tText) ! 701: filetypestr = "(text)"; ! 702: else if (thistype == Filing4_tSerialized) ! 703: filetypestr = "(serial)"; ! 704: else if (thistype == TYPE_VP) ! 705: filetypestr = "(VP doc)"; ! 706: else if (thistype == TYPE_Interpress) ! 707: filetypestr = "(IPress)"; ! 708: else if (thistype == TYPE_VPCanvas) ! 709: filetypestr = "(VP can)"; ! 710: else if (thistype == TYPE_VPDictionary) ! 711: filetypestr = "(VP dic)"; ! 712: else if (thistype == TYPE_VPMailNote) ! 713: filetypestr = "(VPnote)"; ! 714: else if (thistype == TYPE_VPReference) ! 715: filetypestr = "(VP ref)"; ! 716: else { ! 717: sprintf(filetypebuf, "(%ld)", thistype); ! 718: filetypestr = filetypebuf; ! 719: } ! 720: fprintf(fout, "%c%c%-8s%7ld %s\n", ! 721: isdir?'D':' ', istemp?'T':' ', ! 722: filetypestr, thissize, thisname); ! 723: clear_String(&thisname); ! 724: } ! 725: ! 726: #define MAXPACKS 20 ! 727: static ! 728: GetAttributeSequences(conn) ! 729: CourierConnection *conn; ! 730: { ! 731: int count, i; ! 732: Unspecified buffer[MAXWORDS*MAXPACKS], *bp, *bufend; ! 733: Filing4_StreamOfAttributeSequence attrs; ! 734: ! 735: bufend = buffer; ! 736: bp = buffer+((MAXWORDS-1)*MAXPACKS); /* end of available space */ ! 737: while ((count = BDTread(conn, (char*)bufend, ! 738: MAXWORDS*sizeof(Unspecified))) > 0) { ! 739: bufend += count/sizeof(Unspecified); ! 740: bytessent += count; ! 741: if (bufend > bp) { ! 742: fprintf(stderr,"BDT read too big to fit\n"); ! 743: BDTabort(conn); ! 744: /* should clear out stuff here if we knew how much */ ! 745: } ! 746: } ! 747: bp = buffer; ! 748: while (bp < bufend) { ! 749: bp += internalize_Filing4_StreamOfAttributeSequence(&attrs,bp); ! 750: if (0 == (int) attrs.designator) { ! 751: for (i=0; i < attrs.nextSegment_case.segment.length; i++) { ! 752: (*ProcEachSeq)( ! 753: attrs.nextSegment_case.segment.sequence[i]); ! 754: } ! 755: free(attrs.nextSegment_case.segment.sequence); ! 756: } else { ! 757: for (i = 0; i < attrs.lastSegment_case.length; i++) { ! 758: (*ProcEachSeq)( ! 759: attrs.lastSegment_case.sequence[i]); ! 760: } ! 761: free(attrs.lastSegment_case.sequence); ! 762: return; ! 763: } ! 764: } ! 765: } ! 766: ! 767: int ! 768: getBDTch(conn,bpp) ! 769: CourierConnection *conn; ! 770: u_char **bpp; ! 771: { ! 772: static u_char buffer[SPPMAXDATA]; ! 773: static int count; ! 774: ! 775: if (*bpp == NULL) {*bpp = buffer; count = 0;} ! 776: if (*bpp >= buffer+count) { ! 777: count=BDTread(conn,buffer,sizeof(buffer)); ! 778: *bpp = buffer; ! 779: } ! 780: if (count <= 0) return(EOF); ! 781: else return(*((*bpp)++)); ! 782: ! 783: } ! 784: ! 785: retrieveproc(conn) ! 786: CourierConnection *conn; ! 787: { ! 788: int count, ocount, ch, hashbytes; ! 789: char buffer[SPPMAXDATA]; ! 790: int charset, charset16; ! 791: char *bp; ! 792: ! 793: switch (typevalue) { ! 794: default : ! 795: errno = ocount = 0; ! 796: fflush(fout); ! 797: while ((count = BDTread(conn, buffer, sizeof(buffer))) > 0) { ! 798: if ((ocount = write(fileno(fout),buffer,count)) < 0) { ! 799: perror("write"); ! 800: BDTabort(conn); ! 801: break; ! 802: } ! 803: bytessent += count; ! 804: if (hash) { ! 805: putchar('#'); ! 806: fflush(stdout); ! 807: } ! 808: } ! 809: if (count < 0) perror("netin"); ! 810: break; ! 811: ! 812: case TYPE_VPMailNote : ! 813: case TYPE_A : ! 814: charset = 0; charset16 = 0; bp = NULL; ! 815: hashbytes = 0; ! 816: while ((ch = getBDTch(conn,&bp)) != EOF) { ! 817: if (ch == '\377') { ! 818: ch = getBDTch(conn,&bp); ! 819: if (ch == '\377') charset16 = 1; ! 820: else charset = ch; ! 821: continue; ! 822: } ! 823: if (charset16) { ! 824: charset = ch; ! 825: ch = getBDTch(conn,&bp); ! 826: } ! 827: switch (charset) { ! 828: case 0: /* normal character set -- minimal xlation */ ! 829: if (ch == '\r') { ! 830: ch = '\n'; ! 831: while (hash && bytessent >= hashbytes){ ! 832: putchar('#'); ! 833: fflush(stdout); ! 834: hashbytes += sizeof(buffer); ! 835: } ! 836: } ! 837: else if (ch == ','+0200) ch = '_'; ! 838: /* more mapping here */ ! 839: putc(ch,fout); ! 840: bytessent++; ! 841: break; ! 842: default: ! 843: break; /* ignore */ ! 844: } ! 845: } ! 846: if (hash) { ! 847: while (bytessent < hashbytes) { ! 848: putchar('#'); ! 849: hashbytes += sizeof(buffer); ! 850: } ! 851: putchar('\n'); ! 852: fflush(stdout); ! 853: } ! 854: /* if (count < 0) perror("netin"); */ ! 855: break; ! 856: } ! 857: } ! 858: ! 859: storeproc(conn) ! 860: CourierConnection *conn; ! 861: { ! 862: int count, ocount; ! 863: u_char buffer[SPPMAXDATA]; ! 864: u_char *bp; ! 865: ! 866: errno = ocount = 0; ! 867: clearerr(fin); ! 868: switch (typevalue) { ! 869: default : ! 870: while ((count = fread(buffer,sizeof(char),SPPMAXDATA,fin)) > 0 ! 871: && (ocount = BDTwrite(conn, buffer, count)) > 0) { ! 872: bytessent += count; ! 873: if (hash) { ! 874: putchar('#'); ! 875: fflush(stdout); ! 876: } ! 877: } ! 878: break; ! 879: case TYPE_VPMailNote : ! 880: case TYPE_A : ! 881: while ((count = fread(buffer,sizeof(char),SPPMAXDATA,fin)) ! 882: > 0) { ! 883: ocount = count; ! 884: for (bp = buffer; count > 0; count--, bp++) { ! 885: if (*bp == '\n') *bp = '\r'; ! 886: else if (*bp == '_') *bp = ','+0200; ! 887: /* more translations here */ ! 888: } ! 889: if ((ocount = BDTwrite(conn, buffer, ocount)) <= 0) ! 890: break; ! 891: bytessent += ocount; ! 892: if (hash) { ! 893: putchar('#'); ! 894: fflush(stdout); ! 895: } ! 896: } ! 897: break; ! 898: } ! 899: if (ocount < 0) { ! 900: BDTabort(conn); ! 901: perror("netout"); ! 902: } ! 903: else if (ferror(fin)) { ! 904: BDTabort(conn); ! 905: perror("fread"); ! 906: } ! 907: else ! 908: BDTclosewrite(conn); ! 909: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.