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