|
|
1.1 ! root 1: #ifndef lint ! 2: static char *rcsid = "$Header: xnftp.c,v 2.13 87/05/28 14:17:14 ed Exp $"; ! 3: #endif lint ! 4: ! 5: /* $Log: xnftp.c,v $ ! 6: * Revision 2.13 87/05/28 14:17:14 ed ! 7: * I botched the compiler bug fix... ! 8: * ! 9: * Revision 2.12 87/05/14 11:37:34 ed ! 10: * Raise error from hookup if connection not established. ! 11: * Better handling of truncated bulk data stream when it overflows buffer. ! 12: * ! 13: * Revision 2.11 87/05/11 14:40:12 ed ! 14: * Incorporated changes from JQ's 4.3e version. ! 15: * ! 16: * Revision 2.11 87/03/08 07:09:53 jqj ! 17: * work around "schain botch" 4.3BSD VAX compiler bug (from Scooter Morris). ! 18: * ! 19: * Revision 2.10 87/05/05 14:49:00 ed ! 20: * Move alarm setting/resetting closer to actual procedure calls. ! 21: * ! 22: * Revision 2.9 87/04/16 15:23:47 ed ! 23: * Fixed lingering bugs in Subset pathname usage. ! 24: * ! 25: * Revision 2.8 87/04/01 09:33:36 ed ! 26: * Changed for new MakeSecondaryCreds call. ! 27: * Reset connection on login failure. ! 28: * ! 29: * Revision 2.7 87/03/27 15:19:19 ed ! 30: * Don't assume secondary username is primary name. ! 31: * Additional check for underscore translation on text files. ! 32: * ! 33: * Revision 2.6 87/03/23 12:32:12 ed ! 34: * allow round-trip transfer of Viewpoint files, retain/specify uninterpreted ! 35: * attributes. ! 36: * Serialization/Deserialization of directories from server. ! 37: * Wildcard deletion. ! 38: * Compatibility with XDE MFileServer. ! 39: * New commands: Archive, Restore, Unify. ! 40: * ! 41: * Revision 2.5 87/01/14 15:59:29 ed ! 42: * Use FilingSubset, if rejected attempt Filing ! 43: * Allows user override with -F switch ! 44: * Maintain FilingSubset mandatory attributes ! 45: * User niceties: echo file name/type on transfer commands ! 46: * prompt on delete ! 47: * guess type which will determine file type implied by content ! 48: * New commands: (type related) Guess, Whatis ! 49: * (file transfer) Copy, Move, Rename ! 50: * ! 51: * Revision 2.4 86/12/15 11:41:16 jqj ! 52: * Added support for more ViewPoint file types (no other attributes, though) ! 53: * ! 54: * Revision 2.3 86/12/11 06:12:22 jqj ! 55: * Eliminated form, mode, and struct commands. Started adding support for ! 56: * more file types. ! 57: * ! 58: * Revision 2.2 86/09/07 07:43:40 jqj ! 59: * Cope with failure return from CourierOpen. ! 60: * ! 61: * Revision 2.1 86/06/30 12:19:39 jqj ! 62: * convert to Authentication v. 2 for compatibility with official spec. ! 63: * ! 64: * Revision 2.0 85/11/21 07:22:51 jqj ! 65: * 4.3BSD standard release ! 66: * ! 67: * Revision 1.5 85/09/24 14:45:10 jqj ! 68: * fix bug in alarm() handling that caused aborts during large file transfers. ! 69: * ! 70: * Revision 1.4 85/09/17 07:49:47 jqj ! 71: * 4.3 changes. Use more routines from CHlookup ! 72: * ! 73: * Revision 1.1 85/05/27 06:31:07 jqj ! 74: * Initial revision ! 75: * ! 76: */ ! 77: ! 78: #include <stdio.h> ! 79: #include <ctype.h> ! 80: #include <sys/time.h> ! 81: #include <sys/param.h> ! 82: #include <sys/stat.h> ! 83: #include <netns/ns.h> ! 84: #include <netns/sp.h> ! 85: #include "ftp_var.h" ! 86: #include <xnscourier/Filing4.h> ! 87: #include <xnscourier/except.h> ! 88: #undef __Clearinghouse2 /* Filing4.h defs this */ ! 89: #include <xnscourier/CH.h> ! 90: ! 91: #define XNS_TIME_DIFFERENCE 2177452800 /* [(1970-1901) years * 365 days/year + 17 leap days */ ! 92: /* * 24 hours/day * 60 minutes/hour * 60 seconds/minute */ ! 93: #define ROOT_DIRECTORY "/" ! 94: #define MAXNAMES 10 ! 95: ! 96: CourierConnection *connected; ! 97: Clearinghouse3_ObjectName hostobjname; ! 98: Authentication3_Verifier verifier; ! 99: ! 100: /* the following 3 items make up the current session */ ! 101: FilingSubset1_Session session; /* the current session */ ! 102: Clearinghouse3_ObjectName username; ! 103: int continuetime; ! 104: int remoteprocpending; ! 105: FilingSubset1_Handle rootHandle; ! 106: char cur_dir[512]= 0; ! 107: char cur_pathname[512]= 0; ! 108: char cur_name[512]= 0; ! 109: ! 110: struct name_entry { ! 111: char *pathname; ! 112: LongCardinal type; ! 113: } ; ! 114: ! 115: static struct name_entry *name_list= 0; ! 116: static int name_count= 0; ! 117: static int name_size= 0; ! 118: ! 119: static FilingSubset1_ControlSequence nullControls = {0,0}; ! 120: static FilingSubset1_ScopeSequence nullScope = {0,0}; ! 121: ! 122: /* global data used to communicate with BDT procedures ! 123: */ ! 124: extern GetAttributeSequences(), ! 125: GetAllAttributes(), ! 126: listproc(), nlistproc(), ! 127: storeproc(), retrieveproc(), ! 128: rlistproc(), mkdirproc(), ! 129: cdproc(), isdirproc(), deleteproc(); ! 130: ! 131: char *malloc(); ! 132: char *AttrToString(); ! 133: Boolean AttrToBoolean(); ! 134: LongCardinal AttrToLongCardinal(); ! 135: Cardinal AttrToCardinal(); ! 136: char *typetostring(); ! 137: ! 138: static (*ProcEachSeq)(); ! 139: static long bytessent; ! 140: static FILE *fout, *fin; ! 141: ! 142: LongCardinal filetypevalue; /* real transfer type */ ! 143: ! 144: struct timeval timbuf[2]; ! 145: Boolean is_a_directory= FALSE; ! 146: Boolean files_found= FALSE; ! 147: Boolean filing_subset= TRUE; ! 148: Boolean isdir= FALSE; ! 149: ! 150: copyhandle(dest,src) ! 151: FilingSubset1_Handle dest,src; ! 152: { ! 153: if (dest == (Unspecified *) 0) { ! 154: fprintf(stderr,"Oops. dest is null in copyhandle\n"); ! 155: exit(1); ! 156: } ! 157: dest[0] = src[0]; ! 158: dest[1] = src[1]; ! 159: } ! 160: ! 161: getfilehandle(filename, handle) ! 162: char *filename; ! 163: FilingSubset1_Handle handle; ! 164: { ! 165: FilingSubset1_Attribute pathattr[1]; ! 166: FilingSubset1_AttributeSequence attrseq; ! 167: FilingSubset1_OpenResults openresult; ! 168: Filing4_OpenResults openresult2; ! 169: ! 170: if (filename == (char *)0 || *filename == '\000' || (strcmp(filename, "/") == 0) ) { ! 171: if ( filing_subset ) ! 172: copyhandle(handle,FilingSubset1_nullHandle); ! 173: else ! 174: copyhandle(handle,rootHandle); ! 175: return; ! 176: } ! 177: ! 178: attrseq.length = 1; ! 179: attrseq.sequence = pathattr; ! 180: pathattr[0].type = FilingSubset1_pathname; ! 181: copyhandle(handle, FilingSubset1_nullHandle); ! 182: #ifdef XEROXFSCOMPATIBILITY ! 183: if ( filename[0] == '/') ! 184: StringToAttr(filename+1, &pathattr[0]); ! 185: else ! 186: StringToAttr(filename, &pathattr[0]); ! 187: #else XEROXFSCOMPATIBILITY ! 188: StringToAttr(filename, &pathattr[0]); ! 189: #endif XEROXFSCOMPATIBILITY ! 190: alarm(0); ! 191: if ( filing_subset ) { ! 192: openresult = FilingSubset1_Open(connected, NULL, attrseq, ! 193: handle, nullControls, ! 194: session); ! 195: copyhandle(handle, openresult.file); ! 196: } else { ! 197: openresult2 = Filing4_Open(connected, NULL, attrseq, ! 198: handle, nullControls, ! 199: session); ! 200: copyhandle(handle, openresult2.file); ! 201: } ! 202: alarm(continuetime); ! 203: } ! 204: ! 205: getdirhandle(filename, handle) ! 206: char *filename; ! 207: FilingSubset1_Handle handle; ! 208: { ! 209: FilingSubset1_Attribute pathattr[1]; ! 210: FilingSubset1_AttributeSequence attrseq; ! 211: FilingSubset1_OpenResults openresult; ! 212: Filing4_OpenResults openresult2; ! 213: char *rindex(); ! 214: char *slash, *bang; ! 215: ! 216: if (filename == (char *)0 || *filename == '\000' || (strcmp(filename, "/") == 0) ) { ! 217: strcpy(cur_pathname, "/"); ! 218: strcpy(cur_name, "/"); ! 219: if ( filing_subset ) ! 220: copyhandle(handle,FilingSubset1_nullHandle); ! 221: else ! 222: copyhandle(handle,rootHandle); ! 223: return; ! 224: } else if ( filename[0] == '/' ) { ! 225: strcpy(cur_pathname, filename); ! 226: } else { ! 227: strcpy(cur_pathname, cur_dir); ! 228: if ( strcmp(cur_pathname, "/") != 0 ) ! 229: strcat(cur_pathname, "/"); ! 230: strcat(cur_pathname, filename); ! 231: } ! 232: ! 233: if ( (slash= rindex(cur_pathname,'/')) == NULL ) ! 234: strcpy(cur_name, cur_pathname); ! 235: else ! 236: strcpy(cur_name, slash+1); ! 237: ! 238: if ( (bang= rindex(cur_name, '!')) != NULL ) ! 239: *bang= '\0'; ! 240: ! 241: if ( filing_subset ) { ! 242: copyhandle(handle, FilingSubset1_nullHandle); ! 243: } else { ! 244: if ( slash == cur_pathname) { ! 245: copyhandle(handle, rootHandle); ! 246: return; ! 247: } ! 248: ! 249: attrseq.length = 1; ! 250: attrseq.sequence = pathattr; ! 251: pathattr[0].type = FilingSubset1_pathname; ! 252: copyhandle(handle, FilingSubset1_nullHandle); ! 253: *slash= '\0'; /* separate pathname from name */ ! 254: #ifdef XEROXFSCOMPATIBILITY ! 255: if ( cur_pathname[0] == '/' ) ! 256: StringToAttr(cur_pathname+1, &pathattr[0]); ! 257: else ! 258: StringToAttr(cur_pathname, &pathattr[0]); ! 259: #else XEROXFSCOMPATIBILITY ! 260: StringToAttr(cur_pathname, &pathattr[0]); ! 261: #endif XEROXFSCOMPATIBILITY ! 262: *slash= '/'; /* and put back */ ! 263: alarm(0); ! 264: if ( filing_subset ) { ! 265: openresult = FilingSubset1_Open(connected, NULL, attrseq, ! 266: handle, nullControls, ! 267: session); ! 268: copyhandle(handle, openresult.file); ! 269: } else { ! 270: openresult2 = Filing4_Open(connected, NULL, attrseq, ! 271: handle, nullControls, ! 272: session); ! 273: copyhandle(handle, openresult2.file); ! 274: } ! 275: alarm(continuetime); ! 276: } ! 277: } ! 278: ! 279: freefilehandle(handle) ! 280: FilingSubset1_Handle handle; ! 281: { ! 282: if (handle[0] == FilingSubset1_nullHandle[0] && ! 283: handle[1] == FilingSubset1_nullHandle[1]) ! 284: return; /* don't free nullHandle */ ! 285: if (handle[0] == rootHandle[0] && ! 286: handle[1] == rootHandle[1]) ! 287: return; /* don't free root directory */ ! 288: alarm(0); ! 289: if ( filing_subset ) ! 290: FilingSubset1_Close(connected, NULL, handle, session); ! 291: else ! 292: Filing4_Close(connected, NULL, handle, session); ! 293: alarm(continuetime); ! 294: } ! 295: ! 296: /* ! 297: * do a continue to make sure that the session doesn't time out. ! 298: * Note that this is usually called by an ALARM interrupt ! 299: */ ! 300: probe() ! 301: { ! 302: FilingSubset1_ContinueResults cresult; ! 303: Filing4_ContinueResults cresult2; ! 304: alarm(0); /* cancel previous alarms */ ! 305: if ( filing_subset ) { ! 306: cresult = FilingSubset1_Continue(connected, NULL, session); ! 307: continuetime = cresult.continuance / 5; /* seconds */ ! 308: } else { ! 309: cresult2 = Filing4_Continue(connected, NULL, session); ! 310: continuetime = cresult2.continuance / 5; /* seconds */ ! 311: } ! 312: alarm(continuetime); /* reset for another 2 min. or so */ ! 313: } ! 314: ! 315: CourierConnection * ! 316: hookup(name) ! 317: char *name; ! 318: { ! 319: register struct ns_addr *hostaddr; ! 320: extern struct ns_addr *getXNSaddr(); ! 321: Clearinghouse3_ObjectName defaultobjname; ! 322: static char hnamebuf[128]; ! 323: CourierConnection *cconn; ! 324: ! 325: CH_NameDefault(&defaultobjname); ! 326: hostobjname = CH_StringToName(name, &defaultobjname); ! 327: if ((hostaddr = CH_LookupAddrDN( hostobjname, 0, hnamebuf, 128))) { ! 328: /* should check here to be sure host is a file service */ ! 329: hostaddr->x_port = htons(5); /* ?? */ ! 330: cconn = CourierOpen(hostaddr); ! 331: if ( cconn == (CourierConnection *) 0 ) { ! 332: Cardinal problem; ! 333: problem= FilingSubset1_noResponse; ! 334: raise(FilingSubset1_ConnectionError, &problem); ! 335: } ! 336: /* reset objname to flush wildcards */ ! 337: /* clear_Clearinghouse3_ThreePartName(&hostobjname); */ ! 338: hostobjname = CH_StringToName(hnamebuf, &defaultobjname); ! 339: hostname = hnamebuf; ! 340: if (verbose) ! 341: printf("Connected to %s\n", hnamebuf); ! 342: } else { ! 343: printf("%s: unknown host\n", name); ! 344: usefiling= 0; ! 345: cconn = (CourierConnection*)0; ! 346: } ! 347: return(cconn); ! 348: } ! 349: ! 350: ! 351: login(name,pwd) ! 352: char *pwd; ! 353: char *name; ! 354: { ! 355: FilingSubset1_Credentials credentials; ! 356: FilingSubset1_LogonResults logonresult; ! 357: FilingSubset1_LogonResults *resultptr= &logonresult; ! 358: Filing4_LogonResults logonresult2; ! 359: FilingSubset1_AttributeSequence attrseq; ! 360: FilingSubset1_OpenResults openresult; ! 361: Filing4_OpenResults openresult2; ! 362: ! 363: ! 364: if ( name != 0 ) ! 365: username = CH_StringToName(name,&hostobjname); ! 366: ! 367: if ( usefiling ) { ! 368: usefiling= 0; ! 369: filing_subset= FALSE; ! 370: if ( name == 0 && pwd == 0 ) { ! 371: GetSimpleCredsAndVerifier(&username, 0, ! 372: &credentials.primary, &verifier); ! 373: } else { ! 374: MakeSimpleCredsAndVerifier(&username,pwd, ! 375: &credentials.primary, &verifier); ! 376: } ! 377: logonresult2= Filing4_Logon(connected, NULL, hostobjname, ! 378: credentials.primary, verifier); ! 379: resultptr= (FilingSubset1_LogonResults *) &logonresult2; ! 380: ! 381: } else { ! 382: usefiling= 0; ! 383: if ( name == 0 && pwd == 0 ) { ! 384: GetSimpleCredsAndVerifier(&username, 0, &credentials.primary, &verifier); ! 385: MakeSecondaryCreds(hostobjname.object, 0, 0, &credentials.secondary); ! 386: } else { ! 387: MakeSimpleCredsAndVerifier(0, pwd, &credentials.primary, &verifier); ! 388: MakeSecondaryCreds(hostobjname.object, name, pwd, &credentials.secondary); ! 389: } ! 390: filing_subset= TRUE; ! 391: DURING ! 392: logonresult = FilingSubset1_Logon(connected, NULL, hostobjname, ! 393: credentials, verifier); ! 394: HANDLER { ! 395: switch (Exception.Code) { ! 396: case REJECT_ERROR: ! 397: filing_subset= FALSE; ! 398: logonresult2= Filing4_Logon(connected, NULL, hostobjname, ! 399: credentials.primary, verifier); ! 400: resultptr= (FilingSubset1_LogonResults *) &logonresult2; ! 401: break; ! 402: default: ! 403: connected= (CourierConnection *)0; /* reset */ ! 404: RERAISE; ! 405: } ! 406: } END_HANDLER; ! 407: } ! 408: ! 409: if ( filing_subset ) ! 410: session = resultptr->session; ! 411: else ! 412: session = resultptr->session; ! 413: if (verbose) ! 414: printf("User %s:%s:%s logged on\n", username.object, ! 415: username.domain, username.organization); ! 416: ! 417: attrseq.length= 0; ! 418: attrseq.sequence= 0; ! 419: if ( filing_subset ) { ! 420: openresult= FilingSubset1_Open(connected, NULL, attrseq, ! 421: FilingSubset1_nullHandle, nullControls, ! 422: session); ! 423: copyhandle(rootHandle, openresult.file); ! 424: } else { ! 425: openresult2= Filing4_Open(connected, NULL, attrseq, ! 426: FilingSubset1_nullHandle, nullControls, ! 427: session); ! 428: copyhandle(rootHandle, openresult2.file); ! 429: } ! 430: strcpy(cur_dir, ROOT_DIRECTORY); ! 431: alarm(0); ! 432: signal(SIGALRM, probe); ! 433: probe(); ! 434: } ! 435: ! 436: logout() ! 437: { ! 438: signal(SIGALRM, SIG_IGN); ! 439: if ( filing_subset ) ! 440: FilingSubset1_Logoff(connected, NULL, session); ! 441: else ! 442: Filing4_Logoff(connected, NULL, session); ! 443: clear_FilingSubset1_Session(&session); ! 444: } ! 445: ! 446: domakedir(dest) ! 447: char *dest; ! 448: { ! 449: struct timeval start, stop, time; ! 450: FilingSubset1_StoreResults storeresults; ! 451: Filing4_StoreResults storeresults2; ! 452: FilingSubset1_Handle dirhandle; ! 453: FilingSubset1_AttributeSequence attrseq; ! 454: FilingSubset1_Attribute attrvals[5]; ! 455: ! 456: gettimeofday(&time, (struct timezone *) 0); ! 457: ! 458: if (dest) { ! 459: getdirhandle(dest, dirhandle); ! 460: } else { ! 461: printf("No remote name specified\n"); ! 462: return; ! 463: } ! 464: ! 465: bytessent= 0; ! 466: alarm(0); ! 467: ! 468: attrseq.length= 3; ! 469: attrseq.sequence= attrvals; ! 470: ! 471: if ( filing_subset ) { ! 472: attrvals[0].type= FilingSubset1_pathname; ! 473: StringToAttr(cur_pathname, &attrvals[0]); ! 474: } else { ! 475: attrvals[0].type= FilingSubset1_name; ! 476: StringToAttr(cur_name, &attrvals[0]); ! 477: } ! 478: attrvals[1].type = FilingSubset1_isDirectory; ! 479: BooleanToAttr(TRUE, &attrvals[1]); ! 480: attrvals[2].type = FilingSubset1_type; ! 481: LongCardinalToAttr(FilingSubset1_tDirectory, &attrvals[2]); ! 482: gettimeofday(&start, (struct timezone *)0); ! 483: if ( filing_subset ) ! 484: storeresults = FilingSubset1_Store(connected, BDTclosewrite, ! 485: dirhandle, attrseq, ! 486: nullControls, ! 487: BulkData1_immediateSource, session); ! 488: else ! 489: storeresults2 = Filing4_Store(connected, BDTclosewrite, ! 490: dirhandle, attrseq, ! 491: nullControls, ! 492: BulkData1_immediateSource, session); ! 493: alarm(continuetime); ! 494: gettimeofday(&stop, (struct timezone *)0); ! 495: if ( filing_subset ) ! 496: freefilehandle(storeresults.file); ! 497: else ! 498: freefilehandle(storeresults2.file); ! 499: ! 500: freefilehandle(dirhandle); ! 501: } ! 502: ! 503: doremovedir(src) ! 504: char *src; ! 505: { ! 506: dodelete(src); ! 507: } ! 508: ! 509: dostore(src, dest) ! 510: char *src, *dest; ! 511: { ! 512: sendrequest("STOR", src, dest); ! 513: } ! 514: ! 515: doappend(src, dest) ! 516: char *src, *dest; ! 517: { ! 518: NYI(); ! 519: } ! 520: ! 521: dorename(src, dest) ! 522: char *src, *dest; ! 523: { ! 524: Filing4_Handle srchandle, dirhandle; ! 525: Filing4_AttributeSequence attrseq; ! 526: Filing4_Attribute attrvals[1]; ! 527: ! 528: if ( filing_subset ) { ! 529: NotAvailableUnderSubset("Rename function not available"); ! 530: return; ! 531: } ! 532: ! 533: if ( index(dest, '/') != 0 ) { /* rename across directory */ ! 534: docopy("MOVE", src, dest); /* use move */ ! 535: return; ! 536: } ! 537: ! 538: getdirhandle(src, dirhandle); ! 539: getfilehandle(cur_pathname, srchandle); ! 540: ! 541: attrseq.length= 1; ! 542: attrseq.sequence= attrvals; ! 543: ! 544: attrvals[0].type= Filing4_name; ! 545: StringToAttr(dest, &attrvals[0]); ! 546: ! 547: if (verbose) { ! 548: printf("renaming %s to %s...\n", src, dest); ! 549: } ! 550: ! 551: alarm(0); ! 552: Filing4_ChangeAttributes(connected, NULL, srchandle, attrseq, session); ! 553: alarm(continuetime); ! 554: ! 555: freefilehandle(srchandle); ! 556: freefilehandle(dirhandle); ! 557: } ! 558: ! 559: docopy(cmd, src, dest) ! 560: char *cmd, *src, *dest; ! 561: { ! 562: Filing4_Handle srchandle, srcdirhandle, dirhandle, newhandle; ! 563: Filing4_AttributeSequence attrseq; ! 564: Filing4_Attribute attrvals[1]; ! 565: Filing4_AttributeTypeSequence typeseq; ! 566: Filing4_AttributeType attrs[2]; ! 567: Filing4_ScopeSequence scopeseq; ! 568: Filing4_Scope scope; ! 569: Filing4_CopyResults copyresults; ! 570: Boolean copy= FALSE; ! 571: ! 572: if ( filing_subset ) { ! 573: NotAvailableUnderSubset("Copy/Move function not available"); ! 574: return; ! 575: } ! 576: ! 577: if ( strcmp(cmd, "COPY") == 0 ) ! 578: copy= TRUE; ! 579: ! 580: getdirhandle(src, srcdirhandle); ! 581: getfilehandle(cur_pathname, srchandle); ! 582: freefilehandle(srcdirhandle); ! 583: ! 584: getdirhandle(dest, dirhandle); ! 585: ! 586: typeseq.length= 2; typeseq.sequence= attrs; ! 587: attrs[0]= Filing4_isDirectory; ! 588: attrs[1]= Filing4_pathname; ! 589: ! 590: scopeseq.length= 1; scopeseq.sequence= &scope; ! 591: scope.designator= Filing4_filter; ! 592: scope.Filing4_filter_case.designator= Filing4_matches; ! 593: scope.Filing4_filter_case.Filing4_matches_case.attribute.type= Filing4_name; ! 594: StringToAttr(cur_name, &scope.Filing4_filter_case.Filing4_matches_case.attribute); ! 595: ProcEachSeq= isdirproc; ! 596: isdir= FALSE; ! 597: ! 598: alarm(0); ! 599: Filing4_List(connected, GetAttributeSequences, dirhandle, typeseq, ! 600: scopeseq, BulkData1_immediateSink, session); ! 601: alarm(continuetime); ! 602: ! 603: if ( isdir ) { ! 604: getfilehandle(cur_pathname, dirhandle); /* open directory as file */ ! 605: ! 606: attrseq.length= 0; ! 607: attrseq.sequence= attrvals; ! 608: } else { ! 609: attrseq.length= 1; ! 610: attrseq.sequence= attrvals; ! 611: ! 612: attrvals[0].type= Filing4_name; ! 613: StringToAttr(cur_name, &attrvals[0]); ! 614: } ! 615: ! 616: if (verbose) { ! 617: if ( copy ) ! 618: printf("copying "); ! 619: else ! 620: printf("moving "); ! 621: printf("%s to %s%s%s...\n", src, dest, (isdir ? "/" : ""), ! 622: (isdir ? src : "")); ! 623: } ! 624: ! 625: alarm(0); ! 626: if ( copy ) { ! 627: copyresults= Filing4_Copy(connected, NULL, srchandle, dirhandle, ! 628: attrseq, nullControls, session); ! 629: ! 630: freefilehandle(copyresults.newFile); ! 631: } else { ! 632: Filing4_Move(connected, NULL, srchandle, dirhandle, ! 633: attrseq, session); ! 634: } ! 635: alarm(continuetime); ! 636: ! 637: freefilehandle(srchandle); ! 638: freefilehandle(dirhandle); ! 639: } ! 640: ! 641: dounify(remote) ! 642: char *remote; ! 643: { ! 644: Filing4_Handle dirhandle, remotehandle; ! 645: ! 646: if ( filing_subset ) { ! 647: NotAvailableUnderSubset("Unify AccessLists"); ! 648: return; ! 649: } ! 650: ! 651: getdirhandle(remote, dirhandle); ! 652: getfilehandle(cur_pathname, remotehandle); ! 653: freefilehandle(dirhandle); ! 654: ! 655: if ( verbose ) { ! 656: printf("unify access lists for %s\n", remote); ! 657: } ! 658: ! 659: alarm(0); ! 660: Filing4_UnifyAccessLists(connected, NULL, remotehandle, session); ! 661: alarm(continuetime); ! 662: ! 663: freefilehandle(remotehandle); ! 664: ! 665: } ! 666: recvrequest(cmd, local, remote, mode) ! 667: char *cmd, *local, *remote, *mode; ! 668: { ! 669: FILE *popen(); ! 670: int (*closefunc)(), pclose(), fclose(); ! 671: int do_unlink= FALSE; ! 672: int pos, i; ! 673: struct timeval start, stop; ! 674: FilingSubset1_Handle remotehandle; /* note: an array */ ! 675: FilingSubset1_Handle dirhandle; /* note: an array */ ! 676: FilingSubset1_AttributeTypeSequence typeseq; ! 677: FilingSubset1_AttributeType tsvals[10]; ! 678: char *dir; ! 679: FilingSubset1_ScopeSequence scopeseq; ! 680: FilingSubset1_Scope scope; ! 681: ! 682: closefunc = NULL; ! 683: ! 684: fout = stdout; ! 685: typeseq.length = 0; typeseq.sequence = tsvals; ! 686: scopeseq.length= 1; scopeseq.sequence= &scope; ! 687: scope.designator= FilingSubset1_filter; ! 688: scope.FilingSubset1_filter_case.designator= FilingSubset1_matches; ! 689: if ( filing_subset ) ! 690: scope.FilingSubset1_filter_case.FilingSubset1_matches_case.attribute.type= FilingSubset1_pathname; ! 691: else ! 692: scope.FilingSubset1_filter_case.FilingSubset1_matches_case.attribute.type= FilingSubset1_name; ! 693: timbuf[0].tv_sec= 0; ! 694: ! 695: copyhandle(remotehandle, FilingSubset1_nullHandle); ! 696: ! 697: if (strcmp(local, "-") && *local != '|') ! 698: if (access(local, 2) < 0) { ! 699: dir = rindex(local, '/'); ! 700: /* get a good error message */ ! 701: if (dir != NULL) *dir = '\0'; ! 702: if (access(dir ? local : ".", 2) < 0) { ! 703: perror(local); ! 704: goto bad; ! 705: } ! 706: if (dir != NULL) *dir = '/'; ! 707: } ! 708: if (strcmp(local, "-") == 0) ! 709: fout = stdout; ! 710: else if (*local == '|') { ! 711: char *ptr; ! 712: ptr= local+1; ! 713: while (isspace(*ptr)) ptr++; ! 714: fout = popen(ptr, "w"); ! 715: if (fout == NULL) { ! 716: perror(ptr); ! 717: goto bad; ! 718: } ! 719: closefunc = pclose; ! 720: } else { ! 721: fout = fopen(local, mode); ! 722: if (fout == NULL) { ! 723: perror(local); ! 724: goto bad; ! 725: } ! 726: closefunc = fclose; ! 727: } ! 728: ! 729: if (remote) { ! 730: getdirhandle(remote, dirhandle); ! 731: } ! 732: bytessent= 0; ! 733: filetypevalue= typevalue; ! 734: ! 735: if ( filing_subset ) ! 736: StringToAttr(cur_pathname+1,&scope.FilingSubset1_filter_case.FilingSubset1_matches_case.attribute); ! 737: else ! 738: StringToAttr(cur_name,&scope.FilingSubset1_filter_case.FilingSubset1_matches_case.attribute); ! 739: ! 740: if (strcmp(cmd,"NLST") == 0) { ! 741: typeseq.length = 1; ! 742: typeseq.sequence[0] = FilingSubset1_pathname; ! 743: ProcEachSeq = nlistproc; ! 744: alarm(0); ! 745: gettimeofday(&start, (struct timezone *)0); ! 746: if ( filing_subset ) ! 747: FilingSubset1_List(connected, GetAttributeSequences, dirhandle, ! 748: typeseq, scopeseq, ! 749: BulkData1_immediateSink, session); ! 750: else ! 751: Filing4_List(connected, GetAttributeSequences, dirhandle, ! 752: typeseq, scopeseq, ! 753: BulkData1_immediateSink, session); ! 754: alarm(continuetime); ! 755: } ! 756: else if (strcmp(cmd,"LIST") == 0) { ! 757: typeseq.length = 7; ! 758: if ( filing_subset ) ! 759: typeseq.sequence[0] = FilingSubset1_pathname; ! 760: else ! 761: typeseq.sequence[0] = FilingSubset1_name; ! 762: typeseq.sequence[1] = FilingSubset1_dataSize; ! 763: typeseq.sequence[2] = FilingSubset1_isDirectory; ! 764: typeseq.sequence[3] = FilingSubset1_isTemporary; ! 765: typeseq.sequence[4] = FilingSubset1_type; ! 766: typeseq.sequence[5] = FilingSubset1_createdOn; ! 767: typeseq.sequence[6] = FilingSubset1_version; ! 768: ProcEachSeq = listproc; ! 769: alarm(0); ! 770: gettimeofday(&start, (struct timezone *)0); ! 771: if ( filing_subset ) ! 772: FilingSubset1_List(connected, GetAttributeSequences, dirhandle, ! 773: typeseq, scopeseq, ! 774: BulkData1_immediateSink, session); ! 775: else ! 776: Filing4_List(connected, GetAttributeSequences, dirhandle, ! 777: typeseq, scopeseq, ! 778: BulkData1_immediateSink, session); ! 779: alarm(continuetime); ! 780: } ! 781: else if (strcmp(cmd,"RETR") == 0) { ! 782: typeseq.length= 4; ! 783: typeseq.sequence[0]= FilingSubset1_createdOn; ! 784: typeseq.sequence[1]= FilingSubset1_pathname; ! 785: typeseq.sequence[2]= FilingSubset1_type; ! 786: typeseq.sequence[3]= FilingSubset1_isDirectory; ! 787: ! 788: is_a_directory= FALSE; ! 789: ProcEachSeq= rlistproc; ! 790: ! 791: alarm(0); ! 792: if ( filing_subset ) ! 793: FilingSubset1_List(connected, GetAttributeSequences, dirhandle, ! 794: typeseq, scopeseq, ! 795: BulkData1_immediateSink, session); ! 796: else ! 797: Filing4_List(connected, GetAttributeSequences, dirhandle, ! 798: typeseq, scopeseq, ! 799: BulkData1_immediateSink, session); ! 800: ! 801: alarm(continuetime); ! 802: ! 803: if ( files_found ) { ! 804: if ( is_a_directory && (filetypevalue == FilingSubset1_tDirectory) ) { ! 805: if ( filing_subset ) { ! 806: NotAvailableUnderSubset("Cannot retrieve directory files"); ! 807: do_unlink= TRUE; ! 808: goto error; ! 809: } ! 810: } ! 811: ! 812: if (verbose) { ! 813: printf("%s...(%s)...", local, typetostring(filetypevalue)); ! 814: fflush(stdout); ! 815: } ! 816: ! 817: if ( (filetypevalue == FilingSubset1_tDirectory) || ! 818: ((filetypevalue > LAST_FILING_TYPE) && ! 819: (filetypevalue != TYPE_Interpress) && ! 820: (filetypevalue != TYPE_VPCanvas)) ) { ! 821: if ( filing_subset ) { ! 822: NotAvailableUnderSubset("Cannot retrieve Viewpoint files"); ! 823: do_unlink= TRUE; ! 824: goto error; ! 825: } ! 826: ! 827: alarm(0); ! 828: ProcEachSeq= GetAllAttributes; ! 829: Filing4_List(connected, GetAttributeSequences, dirhandle, ! 830: Filing4_allAttributeTypes, scopeseq, ! 831: BulkData1_immediateSink, session); ! 832: alarm(continuetime); ! 833: } ! 834: ! 835: bytessent= 0; ! 836: getfilehandle(cur_pathname, remotehandle); /* get file handle */ ! 837: alarm(0); ! 838: gettimeofday(&start, (struct timezone *)0); ! 839: if ( filing_subset ) { ! 840: FilingSubset1_Retrieve(connected, retrieveproc, remotehandle, ! 841: BulkData1_immediateSink, session); ! 842: } else { ! 843: if ( is_a_directory ) ! 844: Filing4_Serialize(connected, retrieveproc, remotehandle, ! 845: BulkData1_immediateSink, session); ! 846: else ! 847: Filing4_Retrieve(connected, retrieveproc, remotehandle, ! 848: BulkData1_immediateSink, session); ! 849: } ! 850: alarm(continuetime); ! 851: } ! 852: } else if (strcmp(cmd,"SER") == 0) { ! 853: ProcEachSeq= GetAllAttributes; ! 854: ! 855: alarm(0); ! 856: if ( filing_subset ) { ! 857: NotAvailableUnderSubset("Cannot serialize files"); ! 858: do_unlink= TRUE; ! 859: goto error; ! 860: } else { ! 861: Filing4_List(connected, GetAttributeSequences, dirhandle, ! 862: Filing4_allAttributeTypes, scopeseq, ! 863: BulkData1_immediateSink, session); ! 864: } ! 865: alarm(continuetime); ! 866: ! 867: if ( files_found ) { ! 868: if (verbose) { ! 869: printf("%s to %s...(%s)...",cur_pathname, local, typetostring(filetypevalue)); ! 870: fflush(stdout); ! 871: } ! 872: ! 873: bytessent= 0; ! 874: getfilehandle(cur_pathname, remotehandle); /* get file handle */ ! 875: alarm(0); ! 876: gettimeofday(&start, (struct timezone *)0); ! 877: Filing4_Serialize(connected, retrieveproc, remotehandle, ! 878: BulkData1_immediateSink, session); ! 879: alarm(continuetime); ! 880: } ! 881: } ! 882: else printf("unrecognized command %s\n",cmd); ! 883: gettimeofday(&stop, (struct timezone *)0); ! 884: freefilehandle(remotehandle); ! 885: ! 886: if ( files_found ) { ! 887: if (bytessent > 0 && verbose) ! 888: ptransfer("received", bytessent, &start, &stop); ! 889: } else { ! 890: printf("%s not found\n",cur_pathname); ! 891: do_unlink= TRUE; ! 892: } ! 893: ! 894: error: ! 895: freefilehandle(dirhandle); ! 896: ! 897: bad: ! 898: if (closefunc != NULL && fout != NULL) { ! 899: (*closefunc)(fout); ! 900: if ( closefunc == fclose ) { ! 901: if (timbuf[0].tv_sec != 0 ) ! 902: utimes(local,&timbuf[0]); ! 903: } ! 904: } ! 905: if ( do_unlink ) ! 906: unlink(local); ! 907: ! 908: fout = NULL; ! 909: } ! 910: ! 911: ! 912: sendrequest(cmd, local, remote) ! 913: char *cmd, *local, *remote; ! 914: { ! 915: FILE *popen(); ! 916: int (*closefunc)(), pclose(), fclose(); ! 917: struct stat st; ! 918: struct timeval start, stop; ! 919: FilingSubset1_StoreResults storeresults; ! 920: Filing4_DeserializeResults deserializeresults; ! 921: Filing4_StoreResults storeresults2; ! 922: FilingSubset1_Handle dirhandle; ! 923: FilingSubset1_AttributeSequence attrseq; ! 924: FilingSubset1_Attribute attrvals[50]; ! 925: Boolean GetDirectoryAttribute(); ! 926: struct timeval time; ! 927: long createdate; ! 928: long datasize; ! 929: ! 930: gettimeofday(&time,(struct timezone *) 0); ! 931: createdate= time.tv_sec + XNS_TIME_DIFFERENCE; ! 932: filetypevalue= typevalue; ! 933: ! 934: closefunc = NULL; ! 935: if (strcmp(local, "-") == 0) { ! 936: fin = stdin; ! 937: closefunc = NULL; ! 938: } else if (*local == '|') { ! 939: char *ptr; ! 940: ptr= local+1; ! 941: while (isspace(*ptr)) ptr++; ! 942: fin = popen(ptr, "r"); ! 943: if (fin == NULL) { ! 944: perror(ptr); ! 945: return; ! 946: } ! 947: closefunc = pclose; ! 948: } else { ! 949: if (typevalue == TYPE_Guess) { ! 950: filetypevalue= get_type(local); /* guess file type */ ! 951: } ! 952: fin = fopen(local, "r"); ! 953: if (fin == NULL) { ! 954: perror(local); ! 955: return; ! 956: } ! 957: closefunc = fclose; ! 958: if (fstat(fileno(fin), &st) < 0 || ! 959: (st.st_mode&S_IFMT) != S_IFREG) { ! 960: fprintf(stderr, "%s: not a plain file.", local); ! 961: fclose(fin); ! 962: fin= NULL; ! 963: return; ! 964: } ! 965: createdate= st.st_mtime + XNS_TIME_DIFFERENCE; ! 966: datasize= st.st_size; ! 967: } ! 968: ! 969: if (filetypevalue == TYPE_Guess) /* if input from file, TYPE_G should already be replaced */ ! 970: filetypevalue= TYPE_A; /* assume ascii for pipes/stdin... */ ! 971: ! 972: if (remote) { ! 973: getdirhandle(remote, dirhandle); ! 974: } else { ! 975: printf("No remote name specified\n"); ! 976: return; ! 977: } ! 978: bytessent = 0; ! 979: if (strcmp(cmd,"STOR") == 0) { ! 980: if (verbose) { ! 981: printf("%s to %s...",local,remote); ! 982: fflush(stdout); ! 983: } ! 984: attrseq.length = 1; ! 985: attrseq.sequence = attrvals; ! 986: if ( filing_subset ) { ! 987: attrvals[0].type = FilingSubset1_pathname; ! 988: StringToAttr(cur_pathname, &attrvals[0]); ! 989: } else { ! 990: attrvals[0].type = FilingSubset1_name; ! 991: StringToAttr(cur_name, &attrvals[0]); ! 992: } ! 993: ! 994: if ( (filetypevalue == TYPE_Directory) || ! 995: ((filetypevalue > LAST_FILING_TYPE) && ! 996: (filetypevalue != TYPE_Interpress) && ! 997: (filetypevalue != TYPE_VPCanvas)) ) { ! 998: isdir= GetDirectoryAttribute(fin); ! 999: } else { ! 1000: isdir= FALSE; ! 1001: } ! 1002: ! 1003: if ( !isdir ) { ! 1004: attrseq.length += 4; ! 1005: attrvals[1].type = FilingSubset1_type; ! 1006: LongCardinalToAttr(filetypevalue, &attrvals[1]); ! 1007: attrvals[2].type = FilingSubset1_createdOn; ! 1008: LongCardinalToAttr(createdate,&attrvals[2]); ! 1009: attrvals[3].type= FilingSubset1_isDirectory; ! 1010: BooleanToAttr(FALSE, &attrvals[3]); ! 1011: attrvals[4].type= FilingSubset1_dataSize; ! 1012: LongCardinalToAttr(datasize, &attrvals[4]); ! 1013: } ! 1014: ! 1015: if (verbose) { ! 1016: printf("(%s)...", typetostring(filetypevalue)); ! 1017: fflush(stdout); ! 1018: } ! 1019: ! 1020: if ( (filetypevalue == TYPE_Directory) || ! 1021: ((filetypevalue > LAST_FILING_TYPE) && ! 1022: (filetypevalue != TYPE_Interpress) && ! 1023: (filetypevalue != TYPE_VPCanvas)) ) { ! 1024: if ( filing_subset ) { ! 1025: NotAvailableUnderSubset("Cannot store Viewpoint files"); ! 1026: goto error; ! 1027: } ! 1028: if ( isdir ) { ! 1029: if ( AddExtendedDeserializeAttributes(fin, &attrseq) == 0 ) { ! 1030: goto error; ! 1031: } ! 1032: } else { ! 1033: if ( AddExtendedStoreAttributes(fin, &attrseq) == 0 ) { ! 1034: goto error; ! 1035: } ! 1036: } ! 1037: } ! 1038: ! 1039: alarm(0); ! 1040: gettimeofday(&start, (struct timezone *)0); ! 1041: if ( filing_subset ) { ! 1042: storeresults = FilingSubset1_Store(connected, storeproc, ! 1043: dirhandle, attrseq, ! 1044: nullControls, ! 1045: BulkData1_immediateSource, ! 1046: session); ! 1047: } else { ! 1048: if ( isdir ) ! 1049: deserializeresults = Filing4_Deserialize(connected, storeproc, ! 1050: dirhandle, attrseq, ! 1051: nullControls, ! 1052: BulkData1_immediateSource, ! 1053: session); ! 1054: else ! 1055: storeresults2 = Filing4_Store(connected, storeproc, ! 1056: dirhandle, attrseq, ! 1057: nullControls, ! 1058: BulkData1_immediateSource, ! 1059: session); ! 1060: } ! 1061: alarm(continuetime); ! 1062: gettimeofday(&stop, (struct timezone *)0); ! 1063: if ( filing_subset ) { ! 1064: freefilehandle(storeresults.file); ! 1065: } else { ! 1066: if ( isdir ) ! 1067: freefilehandle(deserializeresults.file); ! 1068: else ! 1069: freefilehandle(storeresults2.file); ! 1070: } ! 1071: } else if (strcmp(cmd,"DSER") == 0) { ! 1072: if ( filing_subset ) { ! 1073: NotAvailableUnderSubset("Cannot Deserialize files"); ! 1074: goto error; ! 1075: } ! 1076: if (verbose) { ! 1077: printf("%s to %s...",local,remote); ! 1078: fflush(stdout); ! 1079: } ! 1080: attrseq.length = 1; ! 1081: attrseq.sequence = attrvals; ! 1082: attrvals[0].type = FilingSubset1_name; ! 1083: StringToAttr(cur_name, &attrvals[0]); ! 1084: ! 1085: if (verbose) { ! 1086: printf("(%s)...", typetostring(filetypevalue)); ! 1087: fflush(stdout); ! 1088: } ! 1089: ! 1090: if ( AddExtendedDeserializeAttributes(fin, &attrseq) == 0 ) { ! 1091: goto error; ! 1092: } ! 1093: ! 1094: alarm(0); ! 1095: gettimeofday(&start, (struct timezone *)0); ! 1096: deserializeresults = Filing4_Deserialize(connected, storeproc, ! 1097: dirhandle, attrseq, nullControls, ! 1098: BulkData1_immediateSource, session); ! 1099: alarm(continuetime); ! 1100: gettimeofday(&stop, (struct timezone *)0); ! 1101: freefilehandle(deserializeresults.file); ! 1102: } ! 1103: else { ! 1104: printf("unrecognized command %s\n",cmd); ! 1105: alarm(continuetime); ! 1106: } ! 1107: if (bytessent > 0 && verbose) ! 1108: ptransfer("sent", bytessent, &start, &stop); ! 1109: error: ! 1110: freefilehandle(dirhandle); ! 1111: if (closefunc != NULL && fin != NULL) ! 1112: (*closefunc)(fin); ! 1113: fin = NULL; ! 1114: } ! 1115: ! 1116: ! 1117: ! 1118: docd(dest) ! 1119: char *dest; ! 1120: { ! 1121: FilingSubset1_AttributeSequence attrseq; ! 1122: FilingSubset1_AttributeTypeSequence typeseq; ! 1123: Boolean current= FALSE; ! 1124: FilingSubset1_AttributeType cdattrs[2]; ! 1125: FilingSubset1_ScopeSequence scopeseq; ! 1126: FilingSubset1_Scope scope; ! 1127: FilingSubset1_Handle remotehandle; ! 1128: ! 1129: if (dest == (char*)NULL || *dest == '\0' || (strcmp(dest, "/") == 0) ) { ! 1130: getdirhandle("/", remotehandle); ! 1131: strcpy(cur_dir, "/"); ! 1132: dopwd(); ! 1133: return; ! 1134: } else { ! 1135: getdirhandle(dest, remotehandle); ! 1136: } ! 1137: ! 1138: isdir= FALSE; ! 1139: ! 1140: if ( filing_subset ) { ! 1141: StringToAttr(cur_pathname+1,&scope.FilingSubset1_filter_case.FilingSubset1_matches_case.attribute); ! 1142: scope.FilingSubset1_filter_case.FilingSubset1_matches_case.attribute.type= FilingSubset1_pathname; ! 1143: } else { ! 1144: StringToAttr(cur_name,&scope.FilingSubset1_filter_case.FilingSubset1_matches_case.attribute); ! 1145: scope.FilingSubset1_filter_case.FilingSubset1_matches_case.attribute.type= FilingSubset1_name; ! 1146: } ! 1147: typeseq.length = 2; typeseq.sequence = cdattrs; ! 1148: cdattrs[0] = FilingSubset1_isDirectory; ! 1149: cdattrs[1] = FilingSubset1_pathname; ! 1150: scopeseq.length= 1; scopeseq.sequence= &scope; ! 1151: scope.designator= FilingSubset1_filter; ! 1152: scope.FilingSubset1_filter_case.designator= FilingSubset1_matches; ! 1153: ProcEachSeq= cdproc; ! 1154: alarm(0); ! 1155: if ( filing_subset ) ! 1156: FilingSubset1_List(connected, GetAttributeSequences, remotehandle, typeseq, ! 1157: scopeseq, BulkData1_immediateSink, session); ! 1158: else ! 1159: Filing4_List(connected, GetAttributeSequences, remotehandle, typeseq, ! 1160: scopeseq, BulkData1_immediateSink, session); ! 1161: ! 1162: alarm(continuetime); ! 1163: freefilehandle(remotehandle); ! 1164: ! 1165: if ( files_found == FALSE ) { ! 1166: printf("%s not found\n", dest); ! 1167: } else if ( !isdir ) { ! 1168: printf("%s not a directory\n", dest); ! 1169: } else { ! 1170: if ( dest[0] != '/' ) { ! 1171: if ( strcmp(cur_dir, "/") != 0 ) ! 1172: strcat(cur_dir, "/"); ! 1173: strcat(cur_dir, dest); ! 1174: } else { ! 1175: strcpy(cur_dir, dest); ! 1176: } ! 1177: if (verbose) dopwd(); ! 1178: } ! 1179: ! 1180: } ! 1181: ! 1182: dopwd() ! 1183: { ! 1184: printf("Remote working directory: %s\n",cur_dir); ! 1185: } ! 1186: ! 1187: dodelete(src) ! 1188: char *src; ! 1189: { ! 1190: int i; ! 1191: FilingSubset1_Handle remotehandle; ! 1192: FilingSubset1_Handle dirhandle; ! 1193: FilingSubset1_AttributeSequence attrseq; ! 1194: FilingSubset1_AttributeTypeSequence typeseq; ! 1195: FilingSubset1_AttributeType delattrs[2]; ! 1196: FilingSubset1_ScopeSequence scopeseq; ! 1197: FilingSubset1_Scope scope; ! 1198: ! 1199: typeseq.length = 2; typeseq.sequence= delattrs; ! 1200: delattrs[0] = FilingSubset1_type; ! 1201: delattrs[1]= FilingSubset1_pathname; ! 1202: ! 1203: scopeseq.length= 1; scopeseq.sequence= &scope; ! 1204: scope.designator= FilingSubset1_filter; ! 1205: scope.FilingSubset1_filter_case.designator= FilingSubset1_matches; ! 1206: ! 1207: name_count= 0; ! 1208: name_size= MAXNAMES; ! 1209: if ( (name_list= (struct name_entry *)malloc(sizeof(struct name_entry) * name_size)) == 0 ) { ! 1210: perror("dodelete"); ! 1211: return; ! 1212: } ! 1213: ! 1214: getdirhandle(src, dirhandle); ! 1215: ! 1216: if ( filing_subset ) { ! 1217: scope.FilingSubset1_filter_case.FilingSubset1_matches_case.attribute.type= FilingSubset1_pathname; ! 1218: StringToAttr(cur_pathname+1,&scope.FilingSubset1_filter_case.FilingSubset1_matches_case.attribute); ! 1219: } else { ! 1220: scope.FilingSubset1_filter_case.FilingSubset1_matches_case.attribute.type= FilingSubset1_name; ! 1221: StringToAttr(cur_name,&scope.FilingSubset1_filter_case.FilingSubset1_matches_case.attribute); ! 1222: } ! 1223: ! 1224: ProcEachSeq= deleteproc; ! 1225: alarm(0); ! 1226: if ( filing_subset ) ! 1227: FilingSubset1_List(connected, GetAttributeSequences, dirhandle, typeseq, ! 1228: scopeseq, BulkData1_immediateSink, session); ! 1229: else ! 1230: Filing4_List(connected, GetAttributeSequences, dirhandle, typeseq, ! 1231: scopeseq, BulkData1_immediateSink, session); ! 1232: ! 1233: alarm(continuetime); ! 1234: freefilehandle(dirhandle); ! 1235: ! 1236: for ( i= 0 ; i < name_count ; i++ ) { ! 1237: struct name_entry *entry; ! 1238: ! 1239: entry= &name_list[i]; ! 1240: if ( verbose ) { ! 1241: if ( entry->type == TYPE_Directory ) { ! 1242: if (!confirm("Delete directory", entry->pathname) ) { ! 1243: clear_String(&entry->pathname); ! 1244: continue; ! 1245: } ! 1246: } else if ( entry->type == TYPE_VPDrawer ) { ! 1247: if (!confirm("Delete file drawer", entry->pathname) ) { ! 1248: clear_String(&entry->pathname); ! 1249: continue; ! 1250: } ! 1251: } else { ! 1252: if (!confirm("Delete file",entry->pathname) ) { ! 1253: clear_String(&entry->pathname); ! 1254: continue; ! 1255: } ! 1256: } ! 1257: } ! 1258: ! 1259: getfilehandle(entry->pathname,remotehandle); ! 1260: alarm(0); ! 1261: if ( filing_subset ) ! 1262: FilingSubset1_Delete(connected, NULL, remotehandle, session); ! 1263: else ! 1264: Filing4_Delete(connected, NULL, remotehandle, session); ! 1265: alarm(continuetime); ! 1266: ! 1267: clear_String(&entry->pathname); ! 1268: } ! 1269: } ! 1270: ! 1271: NYI() ! 1272: { ! 1273: printf("Not yet implemented\n"); ! 1274: } ! 1275: ! 1276: NotAvailableUnderSubset(message) ! 1277: char *message; ! 1278: { ! 1279: printf("%s under Subset,\n Reopen connection with -F switch and retry\n", message); ! 1280: } ! 1281: ! 1282: ptransfer(direction, bytes, t0, t1) ! 1283: char *direction; ! 1284: long bytes; ! 1285: struct timeval *t0, *t1; ! 1286: { ! 1287: struct timeval td; ! 1288: long ms; ! 1289: float bs; ! 1290: ! 1291: tvsub(&td, t1, t0); ! 1292: ms = (td.tv_sec * 1000) + (td.tv_usec / 1000); ! 1293: #define nz(x) ((x) == 0 ? 1 : (x)) ! 1294: bs = ((1000. * (float) bytes) / (float) nz(ms)); ! 1295: printf("\n%ld bytes %s in %d.%02d seconds (%.2g Kbytes/s)\n", ! 1296: bytes, direction, td.tv_sec, td.tv_usec / 10000, bs / 1024.); ! 1297: } ! 1298: ! 1299: tvadd(tsum, t0) ! 1300: struct timeval *tsum, *t0; ! 1301: { ! 1302: ! 1303: tsum->tv_sec += t0->tv_sec; ! 1304: tsum->tv_usec += t0->tv_usec; ! 1305: if (tsum->tv_usec > 1000000) ! 1306: tsum->tv_sec++, tsum->tv_usec -= 1000000; ! 1307: } ! 1308: ! 1309: tvsub(tdiff, t1, t0) ! 1310: struct timeval *tdiff, *t1, *t0; ! 1311: { ! 1312: ! 1313: tdiff->tv_sec = t1->tv_sec - t0->tv_sec; ! 1314: tdiff->tv_usec = t1->tv_usec - t0->tv_usec; ! 1315: if (tdiff->tv_usec < 0) ! 1316: tdiff->tv_sec--, tdiff->tv_usec += 1000000; ! 1317: } ! 1318: ! 1319: nlistproc(attr) ! 1320: FilingSubset1_AttributeSequence attr; ! 1321: { ! 1322: int i; ! 1323: char *thisname; ! 1324: FilingSubset1_AttributeType t; ! 1325: ! 1326: files_found= TRUE; ! 1327: ! 1328: for (i = 0; i < attr.length; i++) { ! 1329: t = attr.sequence[i].type; ! 1330: if (t == FilingSubset1_pathname) { ! 1331: thisname = AttrToString(&attr.sequence[i]); ! 1332: #ifdef XEROXFSCOMPATIBILITY ! 1333: /* ! 1334: * Xerox File servers don't include beginning / ! 1335: */ ! 1336: if ( *thisname != '/' ) ! 1337: fputc('/', fout); ! 1338: #endif XEROXFSCOMPATIIBLITY ! 1339: fputs(thisname, fout); ! 1340: fputc('\n', fout); ! 1341: clear_String(&thisname); ! 1342: return; ! 1343: } ! 1344: } ! 1345: } ! 1346: ! 1347: ! 1348: listproc(attr) ! 1349: FilingSubset1_AttributeSequence attr; ! 1350: { ! 1351: int i; ! 1352: char *thisname; ! 1353: char *slash; ! 1354: Boolean istemp = 0; ! 1355: Boolean isdir = 0; ! 1356: LongCardinal thistype = 0; ! 1357: LongCardinal thissize = 0; ! 1358: LongCardinal thisdate = 0; ! 1359: FilingSubset1_AttributeType t; ! 1360: char filetypestr[25]; ! 1361: char filetypebuf[20]; ! 1362: Cardinal thisversion = 0; ! 1363: char *filedatestr; ! 1364: char *ctime(); ! 1365: char *rindex(); ! 1366: ! 1367: files_found= TRUE; ! 1368: ! 1369: for (i = 0; i < attr.length; i++) { ! 1370: t = attr.sequence[i].type; ! 1371: if (t == FilingSubset1_name || t == FilingSubset1_pathname) ! 1372: thisname = AttrToString(&attr.sequence[i]); ! 1373: else if (t == FilingSubset1_isDirectory) ! 1374: isdir = AttrToBoolean(&attr.sequence[i]); ! 1375: else if (t == FilingSubset1_isTemporary) ! 1376: istemp = AttrToBoolean(&attr.sequence[i]); ! 1377: else if (t == FilingSubset1_type) ! 1378: thistype = AttrToLongCardinal(&attr.sequence[i]); ! 1379: else if (t == FilingSubset1_dataSize) ! 1380: thissize = AttrToLongCardinal(&attr.sequence[i]); ! 1381: else if (t == FilingSubset1_version) ! 1382: thisversion = AttrToCardinal(&attr.sequence[i]); ! 1383: else if (t == FilingSubset1_createdOn) { ! 1384: thisdate = AttrToLongCardinal(&attr.sequence[i]); ! 1385: thisdate = thisdate - XNS_TIME_DIFFERENCE; ! 1386: filedatestr= ctime(&thisdate); ! 1387: filedatestr[24]= '\0'; ! 1388: filedatestr += 4; ! 1389: } ! 1390: } ! 1391: ! 1392: strcpy(filetypestr, "("); ! 1393: strcat(filetypestr, typetostring(thistype)); ! 1394: strcat(filetypestr, ")"); ! 1395: ! 1396: if ( (slash= rindex(thisname, '/')) == NULL ) ! 1397: slash= thisname; ! 1398: else ! 1399: slash++; ! 1400: ! 1401: fprintf(fout, "%c%c%-16s%7ld %s %s", ! 1402: isdir?'D':' ', istemp?'T':' ', ! 1403: filetypestr, thissize, filedatestr, slash); ! 1404: if ( thisversion != 0) ! 1405: fprintf(fout,"!%d",thisversion); ! 1406: fprintf(fout,"\n"); ! 1407: clear_String(&thisname); ! 1408: } ! 1409: ! 1410: /* ! 1411: * process used by retrieve to get file type, createdOn and pathname ! 1412: */ ! 1413: rlistproc(attr) ! 1414: FilingSubset1_AttributeSequence attr; ! 1415: { ! 1416: int i; ! 1417: char *thisname; ! 1418: FilingSubset1_AttributeType t; ! 1419: char *AttrToString(); ! 1420: ! 1421: files_found= TRUE; ! 1422: ! 1423: /* ! 1424: * Xerox file servers will return all versions of the requested file in ! 1425: * ascending version order. We assume that the last version will be the ! 1426: * highest and remember that name so that the retrieve will pull the ! 1427: * highest version of the file. If we request just the file with no ! 1428: * version, the server will return the oldest version (not what I would ! 1429: * expect...) ! 1430: */ ! 1431: ! 1432: for (i= 0; i < attr.length; i++) { ! 1433: t= attr.sequence[i].type; ! 1434: if (t == FilingSubset1_createdOn) { ! 1435: gettimeofday(&timbuf[0],(struct timezone *)0); ! 1436: timbuf[1].tv_sec= AttrToLongCardinal(&attr.sequence[i]) - XNS_TIME_DIFFERENCE; ! 1437: timbuf[1].tv_usec= 0; ! 1438: } else if (t == FilingSubset1_type) { ! 1439: if (typevalue == TYPE_Guess) { ! 1440: filetypevalue= AttrToLongCardinal(&attr.sequence[i]); ! 1441: } ! 1442: } else if (t == FilingSubset1_pathname) { ! 1443: thisname= AttrToString(&attr.sequence[i]); ! 1444: if (verbose) { ! 1445: printf("%s to ", thisname); ! 1446: fflush(stdout); ! 1447: } ! 1448: clear_String(&thisname); ! 1449: } else if (t == FilingSubset1_isDirectory) { ! 1450: is_a_directory= AttrToBoolean(&attr.sequence[i]); ! 1451: } ! 1452: } ! 1453: ! 1454: } ! 1455: ! 1456: cdproc(attr) ! 1457: FilingSubset1_AttributeSequence attr; ! 1458: { ! 1459: char *AttrtoString(); ! 1460: char *dest; ! 1461: int i; ! 1462: ! 1463: files_found= TRUE; ! 1464: ! 1465: dest= 0; ! 1466: for (i= 0; i < attr.length; i++) { ! 1467: if (attr.sequence[i].type == FilingSubset1_isDirectory ! 1468: && AttrToBoolean(&attr.sequence[i])) { ! 1469: isdir= TRUE; /* if directory, change handles */ ! 1470: } ! 1471: if (attr.sequence[i].type == FilingSubset1_pathname) ! 1472: dest= AttrToString(&attr.sequence[i]); ! 1473: } ! 1474: ! 1475: if (!isdir || dest == 0) { /* if no directory or pathname */ ! 1476: isdir= FALSE; /* assume failure */ ! 1477: } ! 1478: } ! 1479: ! 1480: #define MAXPACKS 20 ! 1481: static ! 1482: GetAttributeSequences(conn) ! 1483: CourierConnection *conn; ! 1484: { ! 1485: int count, i; ! 1486: Unspecified buffer[MAXWORDS*MAXPACKS], *bp, *bufend; ! 1487: FilingSubset1_StreamOfAttributeSequence attrs; ! 1488: Boolean overflow= FALSE; ! 1489: ! 1490: files_found= FALSE; ! 1491: ! 1492: bufend = buffer; ! 1493: bp = buffer+((MAXWORDS-1)*MAXPACKS); /* end of available space */ ! 1494: while ((count = BDTread(conn, (char*)bufend, ! 1495: MAXWORDS*sizeof(Unspecified))) > 0) { ! 1496: bufend += count/sizeof(Unspecified); ! 1497: bytessent += count; ! 1498: if (bufend > bp) { ! 1499: fprintf(stderr,"BDT read too big to fit\n"); ! 1500: BDTabort(conn); ! 1501: /* should clear out stuff here if we knew how much ! 1502: * fall back to previous block on the assumption ! 1503: * we can give a truncated list ! 1504: */ ! 1505: bufend -= count/sizeof(Unspecified); ! 1506: overflow=TRUE; ! 1507: } ! 1508: } ! 1509: bp = buffer; ! 1510: while (bp < bufend) { ! 1511: bp += internalize_FilingSubset1_StreamOfAttributeSequence(&attrs,bp); ! 1512: if (0 == (int) attrs.designator) { ! 1513: for (i=0; i < attrs.nextSegment_case.segment.length; i++) { ! 1514: (*ProcEachSeq)( ! 1515: attrs.nextSegment_case.segment.sequence[i]); ! 1516: } ! 1517: free(attrs.nextSegment_case.segment.sequence); ! 1518: } else { ! 1519: for (i = 0; i < attrs.lastSegment_case.length; i++) { ! 1520: (*ProcEachSeq)( ! 1521: attrs.lastSegment_case.sequence[i]); ! 1522: } ! 1523: free(attrs.lastSegment_case.sequence); ! 1524: return; ! 1525: } ! 1526: } ! 1527: if ( overflow ) { ! 1528: fprintf(stderr, "\nListing was truncated due to internal bulk data buffer size\n"); ! 1529: overflow= FALSE; ! 1530: } ! 1531: } ! 1532: ! 1533: int ! 1534: getBDTch(conn,bpp) ! 1535: CourierConnection *conn; ! 1536: u_char **bpp; ! 1537: { ! 1538: static u_char buffer[SPPMAXDATA]; ! 1539: static int count; ! 1540: ! 1541: if (*bpp == NULL) {*bpp = buffer; count = 0;} ! 1542: if (*bpp >= buffer+count) { ! 1543: count=BDTread(conn,buffer,sizeof(buffer)); ! 1544: *bpp = buffer; ! 1545: } ! 1546: if (count <= 0) return(EOF); ! 1547: else return(*((*bpp)++)); ! 1548: ! 1549: } ! 1550: ! 1551: retrieveproc(conn) ! 1552: CourierConnection *conn; ! 1553: { ! 1554: int count, ocount, ch, hashbytes; ! 1555: char buffer[SPPMAXDATA]; ! 1556: int charset, charset16; ! 1557: char *bp; ! 1558: ! 1559: switch (filetypevalue) { ! 1560: default : ! 1561: errno = ocount = 0; ! 1562: fflush(fout); ! 1563: while ((count = BDTread(conn, buffer, sizeof(buffer))) > 0) { ! 1564: if ((ocount = write(fileno(fout),buffer,count)) < 0) { ! 1565: perror("write"); ! 1566: BDTabort(conn); ! 1567: break; ! 1568: } ! 1569: bytessent += count; ! 1570: if (hash) { ! 1571: putchar('#'); ! 1572: fflush(stdout); ! 1573: } ! 1574: } ! 1575: if (count < 0) perror("netin"); ! 1576: break; ! 1577: ! 1578: case TYPE_VPMailNote : ! 1579: case TYPE_A : ! 1580: charset = 0; charset16 = 0; bp = NULL; ! 1581: hashbytes = 0; ! 1582: while ((ch = getBDTch(conn,&bp)) != EOF) { ! 1583: if (ch == '\377') { ! 1584: ch = getBDTch(conn,&bp); ! 1585: if (ch == '\377') charset16 = 1; ! 1586: else charset = ch; ! 1587: continue; ! 1588: } ! 1589: if (charset16) { ! 1590: charset = ch; ! 1591: ch = getBDTch(conn,&bp); ! 1592: } ! 1593: switch (charset) { ! 1594: case 0: /* normal character set -- minimal xlation */ ! 1595: if (ch == '\r') { ! 1596: int nextch; ! 1597: ! 1598: putc('\n',fout); ! 1599: bytessent++; ! 1600: if ( (nextch = getBDTch(conn,&bp)) != '\n'){ ! 1601: if (nextch == '\r') ! 1602: putc('\n',fout); ! 1603: else if ( nextch == ','+0200 ) ! 1604: putc('_',fout); ! 1605: else if ( nextch != EOF ) ! 1606: putc(nextch,fout); ! 1607: else ! 1608: continue; ! 1609: } ! 1610: bytessent= bytessent++; ! 1611: ! 1612: while (hash && bytessent >= hashbytes){ ! 1613: putchar('#'); ! 1614: fflush(stdout); ! 1615: hashbytes += sizeof(buffer); ! 1616: } ! 1617: break; ! 1618: } ! 1619: else if (ch == ','+0200) ch = '_'; ! 1620: /* more mapping here */ ! 1621: putc(ch,fout); ! 1622: bytessent++; ! 1623: break; ! 1624: default: ! 1625: break; /* ignore */ ! 1626: } ! 1627: } ! 1628: if (hash) { ! 1629: while (bytessent >= hashbytes) { ! 1630: putchar('#'); ! 1631: hashbytes += sizeof(buffer); ! 1632: } ! 1633: putchar('\n'); ! 1634: fflush(stdout); ! 1635: } ! 1636: /* if (count < 0) perror("netin"); */ ! 1637: break; ! 1638: } ! 1639: } ! 1640: ! 1641: storeproc(conn) ! 1642: CourierConnection *conn; ! 1643: { ! 1644: int count, ocount; ! 1645: u_char buffer[SPPMAXDATA]; ! 1646: u_char *bp; ! 1647: ! 1648: errno = ocount = 0; ! 1649: clearerr(fin); ! 1650: switch (filetypevalue) { ! 1651: ! 1652: default : ! 1653: while ((count = fread(buffer, sizeof(char), SPPMAXDATA, fin)) > 0 ! 1654: && (ocount = BDTwrite(conn, buffer, count)) > 0) { ! 1655: bytessent += count; ! 1656: if (hash) { ! 1657: putchar('#'); ! 1658: fflush(stdout); ! 1659: } ! 1660: } ! 1661: break; ! 1662: case TYPE_VPMailNote : ! 1663: case TYPE_A : ! 1664: while ((count = fread(buffer, sizeof(char), SPPMAXDATA, fin)) ! 1665: > 0) { ! 1666: ocount = count; ! 1667: for (bp = buffer; count > 0; count--, bp++) { ! 1668: if (*bp == '\n') *bp = '\r'; ! 1669: else if (*bp == '_') *bp = ','+0200; ! 1670: /* more translations here */ ! 1671: } ! 1672: if ((ocount = BDTwrite(conn, buffer, ocount)) <= 0) ! 1673: break; ! 1674: bytessent += ocount; ! 1675: if (hash) { ! 1676: putchar('#'); ! 1677: fflush(stdout); ! 1678: } ! 1679: } ! 1680: break; ! 1681: } ! 1682: if (ocount < 0) { ! 1683: BDTabort(conn); ! 1684: perror("netout"); ! 1685: } ! 1686: else if (ferror(fin)) { ! 1687: BDTabort(conn); ! 1688: perror("fread"); ! 1689: } ! 1690: else ! 1691: BDTclosewrite(conn); ! 1692: } ! 1693: ! 1694: isdirproc(attr) ! 1695: FilingSubset1_AttributeSequence attr; ! 1696: { ! 1697: int i; ! 1698: char *name; ! 1699: FilingSubset1_AttributeType t; ! 1700: ! 1701: for ( i= 0; i < attr.length; i++ ) { ! 1702: t= attr.sequence[i].type; ! 1703: if ( t == FilingSubset1_isDirectory ) { ! 1704: isdir= AttrToBoolean(&attr.sequence[i]); ! 1705: } else if ( t == FilingSubset1_pathname ) { ! 1706: name= AttrToString(&attr.sequence[1]); ! 1707: strcpy(cur_pathname, name); ! 1708: clear_String(&name); ! 1709: } ! 1710: } ! 1711: } ! 1712: ! 1713: deleteproc(attr) ! 1714: FilingSubset1_AttributeSequence attr; ! 1715: { ! 1716: int i; ! 1717: char *name; ! 1718: struct name_entry *entry; ! 1719: FilingSubset1_AttributeType t; ! 1720: ! 1721: if ( name_count > name_size ) { ! 1722: name_size += MAXNAMES; ! 1723: name_list= (struct name_entry *) realloc(name_list, ! 1724: sizeof(struct name_entry) * name_size); ! 1725: } ! 1726: ! 1727: entry= &name_list[name_count]; ! 1728: for ( i= 0; i < attr.length; i++ ) { ! 1729: t= attr.sequence[i].type; ! 1730: if ( t == FilingSubset1_type ) { ! 1731: entry->type= AttrToLongCardinal(&attr.sequence[i]); ! 1732: } else if ( t == FilingSubset1_pathname ) { ! 1733: entry->pathname= AttrToString(&attr.sequence[1]); ! 1734: } ! 1735: } ! 1736: name_count++; ! 1737: } ! 1738: ! 1739: GetAllAttributes(attr) ! 1740: FilingSubset1_AttributeSequence attr; ! 1741: { ! 1742: int i; ! 1743: char *thisname; ! 1744: FilingSubset1_AttributeType t; ! 1745: int got_createdon, got_type, got_pathname; ! 1746: ! 1747: files_found= TRUE; ! 1748: got_createdon= got_pathname= got_type= 0; ! 1749: ! 1750: /* ! 1751: * Xerox file servers will return all versions of the requested file in ! 1752: * ascending version order. We assume that the last version will be the ! 1753: * highest and remember that name so that the retrieve will pull the ! 1754: * highest version of the file. If we request just the file with no ! 1755: * version, the server will return the oldest version (not what I would ! 1756: * expect...) ! 1757: */ ! 1758: for (i= 0; i < attr.length; i++) { ! 1759: t= attr.sequence[i].type; ! 1760: if (t == FilingSubset1_createdOn) { ! 1761: gettimeofday(&timbuf[0],(struct timezone *)0); ! 1762: timbuf[1].tv_sec= AttrToLongCardinal(&attr.sequence[i]) - XNS_TIME_DIFFERENCE; ! 1763: timbuf[1].tv_usec= 0; ! 1764: got_createdon++; ! 1765: } else if (t == FilingSubset1_type) { ! 1766: if (typevalue == TYPE_Guess) { ! 1767: filetypevalue= AttrToLongCardinal(&attr.sequence[i]); ! 1768: } ! 1769: got_type++; ! 1770: } else if (t == FilingSubset1_pathname) { ! 1771: thisname= AttrToString(&attr.sequence[i]); ! 1772: strcpy(cur_pathname, thisname); ! 1773: clear_String(&thisname); ! 1774: got_pathname++; ! 1775: } ! 1776: ! 1777: if ( got_createdon && got_type && got_pathname ) ! 1778: break; ! 1779: } ! 1780: ! 1781: SaveExtendedAttributes(fout, attr); ! 1782: ! 1783: return; ! 1784: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.