|
|
1.1 ! root 1: #ifndef lint ! 2: static char *rcsid = "$Header: xnsarchive.c,v 1.1 87/03/17 16:27:18 ed Exp $"; ! 3: #endif lint ! 4: ! 5: /* ! 6: * Copyright (c) 1986, 1987 Xerox Corporation. ! 7: */ ! 8: ! 9: /* $Log: xnsarchive.c,v $ ! 10: * Revision 1.1 87/03/17 16:27:18 ed ! 11: * Initial revision ! 12: * ! 13: * ! 14: */ ! 15: ! 16: #include <stdio.h> ! 17: #include <sys/time.h> ! 18: #include <sys/param.h> ! 19: #include <sys/stat.h> ! 20: #include <netns/ns.h> ! 21: #include <netns/sp.h> ! 22: #include <xnscourier/Filing4.h> ! 23: #include <xnscourier/except.h> ! 24: #include <xnscourier/CH.h> ! 25: #include <xnscourier/filetypes.h> ! 26: #define XNS_TIME_DIFFERENCE 2177452800 /* [(1970-1901) years * 365 days/year + 17 leap days */ ! 27: /* * 24 hours/day * 60 minutes/hour * 60 seconds/minute */ ! 28: ! 29: #define ROOT_DIRECTORY "/" ! 30: ! 31: CourierConnection *connected; ! 32: Clearinghouse2_ObjectName hostobjname; ! 33: Authentication2_Verifier verifier; ! 34: ! 35: /* the following 3 items make up the current session */ ! 36: Filing4_Session session; /* the current session */ ! 37: Clearinghouse2_ObjectName username; ! 38: Filing4_Handle rootHandle; ! 39: char cur_dir[512]= 0; ! 40: char cur_pathname[512]= 0; ! 41: char cur_name[512]= 0; ! 42: ! 43: static Filing4_ControlSequence nullControls = {0,0}; ! 44: ! 45: /* global data used to communicate with BDT procedures ! 46: */ ! 47: extern GetAttributeSequences(), GetAllAttributes(), ! 48: listproc(), isdirproc(), retrieveproc(); ! 49: ! 50: char *AttrToString(); ! 51: Boolean AttrToBoolean(); ! 52: LongCardinal AttrToLongCardinal(); ! 53: Cardinal AttrToCardinal(); ! 54: ! 55: static (*ProcEachSeq)(); ! 56: static FILE *fout= stdout; ! 57: FILE *lfile= NULL; ! 58: ! 59: Boolean files_found= FALSE; ! 60: Boolean verbose= FALSE; ! 61: Boolean unify= FALSE; ! 62: Boolean is_a_directory= FALSE; ! 63: char *logfile= 0; ! 64: ! 65: char *ctime(); ! 66: long time(); ! 67: char *service; ! 68: extern int errno; ! 69: ! 70: main(argc, argv) ! 71: int argc; ! 72: char *argv[]; ! 73: { ! 74: char *remotefile, *localfile; ! 75: int i; ! 76: CourierConnection *hookup(); ! 77: int opt; ! 78: extern int optind; ! 79: extern char *optarg; ! 80: ! 81: static char *options= "vul:"; ! 82: static char *usage= "Usage: %s [-v] [-u] [-l log-file] remote-file1 local-file\n"; ! 83: ! 84: if ( argc < 2 ) { ! 85: fprintf(stderr, usage, argv[0]); ! 86: exit(1); ! 87: } ! 88: ! 89: while ((opt= getopt(argc, argv, options)) != EOF) ! 90: switch (opt) { ! 91: case 'l' : ! 92: logfile= optarg; ! 93: break; ! 94: ! 95: case 'v' : ! 96: verbose++; ! 97: break; ! 98: ! 99: case 'u' : ! 100: unify++; /* unify accesslists */ ! 101: break; ! 102: ! 103: default: ! 104: fprintf(stderr, "Invalid command option -%c\n", opt); ! 105: exit(1); ! 106: } ! 107: ! 108: if ( getserviceandfile(argv[optind], &service, &remotefile) == 1 ) { ! 109: fprintf(stderr, "Invalid name %s\n", argv[optind]); ! 110: exit(1); ! 111: } ! 112: localfile= argv[++optind]; ! 113: ! 114: DURING { ! 115: if ( (connected= hookup(service)) == (CourierConnection *)0 ) { ! 116: fprintf(stderr, "\nCan't connect to %s\n", service); ! 117: exit(1); ! 118: } ! 119: login(0,0); ! 120: ! 121: if ( serializefile(remotefile,localfile) ) ! 122: exit(1); ! 123: ! 124: } HANDLER { ! 125: FilingErrMsg(Exception.Code, Exception.Message); ! 126: } END_HANDLER; ! 127: ! 128: return(0); ! 129: } ! 130: ! 131: getserviceandfile(name, srvcptr, fileptr) ! 132: char *name; ! 133: char **srvcptr, **fileptr; ! 134: { ! 135: char *sptr, *fptr; ! 136: char *index(), *rindex(); ! 137: ! 138: /* ! 139: * look for Xerox forms first: ! 140: * [host]filename ! 141: */ ! 142: ! 143: if ( (sptr= index(name, '[')) != 0 ) { ! 144: if ( (fptr= index(sptr, ']')) != 0 ) { ! 145: *fptr= '\0'; ! 146: *srvcptr= sptr + 1; ! 147: *fileptr= fptr + 1; ! 148: return(0); ! 149: } else ! 150: return(1); ! 151: } ! 152: ! 153: /* ! 154: * (host)filename ! 155: */ ! 156: ! 157: if ( (sptr= index(name, '(')) != 0 ) { ! 158: if ( (fptr= index(sptr, ')')) != 0 ) { ! 159: *fptr= '\0'; ! 160: *srvcptr= sptr + 1; ! 161: *fileptr= fptr + 1; ! 162: return(0); ! 163: } else ! 164: return(1); ! 165: } ! 166: ! 167: /* ! 168: * look for XNS style with trailing : delimiter ! 169: * (assumes no : in file name, use alternate spec instead) ! 170: * object:domain:organization:filename ! 171: * domain & organization are optional ! 172: */ ! 173: ! 174: if ( (fptr= rindex(name, ':')) != 0 ) { ! 175: *fptr= '\0'; ! 176: *srvcptr= name; ! 177: *fileptr= fptr + 1; ! 178: return(0); ! 179: } else ! 180: return(1); ! 181: } ! 182: ! 183: copyhandle(dest,src) ! 184: Filing4_Handle dest,src; ! 185: { ! 186: if (dest == (Unspecified *) 0) { ! 187: fprintf(stderr,"Oops. dest is null in copyhandle\n"); ! 188: exit(1); ! 189: } ! 190: dest[0] = src[0]; ! 191: dest[1] = src[1]; ! 192: } ! 193: ! 194: getfilehandle(filename, handle) ! 195: char *filename; ! 196: Filing4_Handle handle; ! 197: { ! 198: Filing4_Attribute pathattr[1]; ! 199: Filing4_AttributeSequence attrseq; ! 200: Filing4_OpenResults openresult; ! 201: Filing4_OpenResults openresult2; ! 202: ! 203: if (filename == (char *)0 || *filename == '\000' || (strcmp(filename, "/") == 0) ) { ! 204: copyhandle(handle,rootHandle); ! 205: return; ! 206: } ! 207: ! 208: attrseq.length = 1; ! 209: attrseq.sequence = pathattr; ! 210: pathattr[0].type = Filing4_pathname; ! 211: copyhandle(handle, Filing4_nullHandle); ! 212: #ifdef XEROXFSCOMPATIBILITY ! 213: if ( filename[0] == '/') ! 214: StringToAttr(filename+1, &pathattr[0]); ! 215: else ! 216: StringToAttr(filename, &pathattr[0]); ! 217: #else XEROXFSCOMPATIBILITY ! 218: StringToAttr(filename, &pathattr[0]); ! 219: #endif XEROXFSCOMPATIBILITY ! 220: alarm(0); ! 221: openresult2 = Filing4_Open(connected, NULL, attrseq, ! 222: handle, nullControls, ! 223: session); ! 224: copyhandle(handle, openresult2.file); ! 225: } ! 226: ! 227: getdirhandle(filename, handle) ! 228: char *filename; ! 229: Filing4_Handle handle; ! 230: { ! 231: Filing4_Attribute pathattr[1]; ! 232: Filing4_AttributeSequence attrseq; ! 233: Filing4_OpenResults openresult; ! 234: Filing4_OpenResults openresult2; ! 235: char *rindex(); ! 236: char *slash; ! 237: ! 238: if (filename == (char *)0 || *filename == '\000' || (strcmp(filename, "/") == 0) ) { ! 239: strcpy(cur_pathname, "/"); ! 240: strcpy(cur_name, "/"); ! 241: copyhandle(handle,rootHandle); ! 242: return; ! 243: } else if ( filename[0] == '/' ) { ! 244: strcpy(cur_pathname, filename); ! 245: } else { ! 246: strcpy(cur_pathname, cur_dir); ! 247: if ( strcmp(cur_pathname, "/") != 0 ) ! 248: strcat(cur_pathname, "/"); ! 249: strcat(cur_pathname, filename); ! 250: } ! 251: ! 252: if ( (slash= rindex(cur_pathname,'/')) == NULL ) ! 253: strcpy(cur_name, cur_pathname); ! 254: else ! 255: strcpy(cur_name, slash+1); ! 256: ! 257: if ( slash == cur_pathname) { ! 258: copyhandle(handle, rootHandle); ! 259: return; ! 260: } ! 261: ! 262: attrseq.length = 1; ! 263: attrseq.sequence = pathattr; ! 264: pathattr[0].type = Filing4_pathname; ! 265: copyhandle(handle, Filing4_nullHandle); ! 266: *slash= '\0'; /* separate pathname from name */ ! 267: #ifdef XEROXFSCOMPATIBILITY ! 268: if ( cur_pathname[0] == '/' ) ! 269: StringToAttr(cur_pathname+1, &pathattr[0]); ! 270: else ! 271: StringToAttr(cur_pathname, &pathattr[0]); ! 272: #else XEROXFSCOMPATIBILITY ! 273: StringToAttr(cur_pathname, &pathattr[0]); ! 274: #endif XEROXFSCOMPATIBILITY ! 275: *slash= '/'; /* and put back */ ! 276: alarm(0); ! 277: openresult2 = Filing4_Open(connected, NULL, attrseq, ! 278: handle, nullControls, session); ! 279: copyhandle(handle, openresult2.file); ! 280: } ! 281: ! 282: freefilehandle(handle) ! 283: Filing4_Handle handle; ! 284: { ! 285: if (handle[0] == Filing4_nullHandle[0] && ! 286: handle[1] == Filing4_nullHandle[1]) ! 287: return; /* don't free nullHandle */ ! 288: if (handle[0] == rootHandle[0] && ! 289: handle[1] == rootHandle[1]) ! 290: return; /* don't free root directory */ ! 291: alarm(0); ! 292: Filing4_Close(connected, NULL, handle, session); ! 293: } ! 294: ! 295: CourierConnection * ! 296: hookup(name) ! 297: char *name; ! 298: { ! 299: register struct ns_addr *hostaddr; ! 300: extern struct ns_addr *getXNSaddr(); ! 301: Clearinghouse2_ObjectName defaultobjname; ! 302: static char hnamebuf[128]; ! 303: CourierConnection *cconn; ! 304: ! 305: CH_NameDefault(&defaultobjname); ! 306: hostobjname = CH_StringToName(name, &defaultobjname); ! 307: if ((hostaddr = CH_LookupAddrDN( hostobjname, 0, hnamebuf, 128))) { ! 308: /* should check here to be sure host is a file service */ ! 309: hostaddr->x_port = htons(5); /* ?? */ ! 310: cconn = CourierOpen(hostaddr); ! 311: /* reset objname to flush wildcards */ ! 312: /* clear_Clearinghouse2_ThreePartName(&hostobjname); */ ! 313: hostobjname = CH_StringToName(hnamebuf, &defaultobjname); ! 314: } ! 315: return(cconn); ! 316: } ! 317: ! 318: ! 319: login(name,pwd) ! 320: char *pwd; ! 321: char *name; ! 322: { ! 323: Filing4_Credentials credentials; ! 324: Filing4_LogonResults logonresult; ! 325: Filing4_AttributeSequence attrseq; ! 326: Filing4_OpenResults openresult; ! 327: ! 328: ! 329: if ( name != 0 ) ! 330: username = CH_StringToName(name,&hostobjname); ! 331: ! 332: if ( name == 0 && pwd == 0 ) { ! 333: GetSimpleCredsAndVerifier(&username, 0, ! 334: &credentials, &verifier); ! 335: } else { ! 336: MakeSimpleCredsAndVerifier(&username,pwd, ! 337: &credentials, &verifier); ! 338: } ! 339: logonresult= Filing4_Logon(connected, NULL, hostobjname, ! 340: credentials, verifier); ! 341: session = logonresult.session; ! 342: ! 343: attrseq.length= 0; ! 344: attrseq.sequence= 0; ! 345: openresult= Filing4_Open(connected, NULL, attrseq, ! 346: Filing4_nullHandle, nullControls, ! 347: session); ! 348: copyhandle(rootHandle, openresult.file); ! 349: strcpy(cur_dir, ROOT_DIRECTORY); ! 350: } ! 351: ! 352: logout() ! 353: { ! 354: Filing4_Logoff(connected, NULL, session); ! 355: clear_Filing4_Session(&session); ! 356: } ! 357: ! 358: ! 359: serializefile(remote, local) ! 360: char *remote; ! 361: char *local; ! 362: { ! 363: FILE *fopen(); ! 364: Filing4_Handle remotehandle; /* note: an array */ ! 365: Filing4_Handle dirhandle; /* note: an array */ ! 366: Filing4_Handle listhandle; /* note: an array */ ! 367: Filing4_AttributeTypeSequence typeseq; ! 368: Filing4_AttributeType tsvals[10]; ! 369: Filing4_ScopeSequence scopeseq; ! 370: Filing4_Scope scope; ! 371: Filing4_ScopeSequence lscopeseq; ! 372: Filing4_Scope lscope; ! 373: long date; ! 374: int i; ! 375: ! 376: scopeseq.sequence= &scope; lscopeseq.sequence= &lscope; ! 377: ! 378: getdirhandle(remote, dirhandle); ! 379: getfilehandle(remote, remotehandle); /* get file handle */ ! 380: ! 381: if ( (local == NULL) || (*local == '\0') ) { ! 382: local= cur_name; ! 383: } else if ( strcmp(local,"-") == 0 ) { ! 384: fout=stdout; ! 385: } else { ! 386: if ( (fout= fopen(local, "w")) == NULL ) { ! 387: perror("fopen"); ! 388: return(1); ! 389: } ! 390: } ! 391: ! 392: scopeseq.length= 1; ! 393: scope.designator= Filing4_filter; ! 394: scope.Filing4_filter_case.designator= Filing4_matches; ! 395: scope.Filing4_filter_case.Filing4_matches_case.attribute.type= Filing4_name; ! 396: StringToAttr(cur_name,&scope.Filing4_filter_case.Filing4_matches_case.attribute); ! 397: ! 398: if ( unify ) { ! 399: if ( verbose ) { ! 400: fprintf(stderr, " Unify access lists\n"); ! 401: } ! 402: Filing4_UnifyAccessLists(connected, NULL, dirhandle, session); ! 403: } ! 404: ! 405: if ( logfile ) { ! 406: if ( (lfile= fopen(logfile, "w")) != NULL ) { ! 407: typeseq.length = 2; typeseq.sequence = tsvals; ! 408: typeseq.sequence[0] = Filing4_pathname; ! 409: typeseq.sequence[1] = Filing4_isDirectory; ! 410: ! 411: is_a_directory= FALSE; ! 412: ! 413: ProcEachSeq = isdirproc; ! 414: Filing4_List(connected, GetAttributeSequences, dirhandle, ! 415: typeseq, scopeseq, ! 416: BulkData1_immediateSink, session); ! 417: ! 418: /* ! 419: * for a directory, we list all files... ! 420: * for non-directory, just list it... ! 421: */ ! 422: if ( is_a_directory ) { ! 423: copyhandle(listhandle, remotehandle); ! 424: lscopeseq.length= 1; ! 425: lscope.designator= Filing4_depth; ! 426: lscope.Filing4_depth_case= Filing4_allDescendants; ! 427: } else { ! 428: copyhandle(listhandle, dirhandle); ! 429: lscopeseq.length= 1; ! 430: lscope.designator= Filing4_filter; ! 431: lscope.Filing4_filter_case.designator= Filing4_matches; ! 432: lscope.Filing4_filter_case.Filing4_matches_case.attribute.type= Filing4_name; ! 433: StringToAttr(cur_name,&lscope.Filing4_filter_case.Filing4_matches_case.attribute); ! 434: } ! 435: ! 436: typeseq.length = 4; ! 437: typeseq.sequence[0] = Filing4_pathname; ! 438: typeseq.sequence[1] = Filing4_type; ! 439: typeseq.sequence[2] = Filing4_createdOn; ! 440: typeseq.sequence[3] = Filing4_modifiedOn; ! 441: ! 442: date= time(0); ! 443: fprintf(lfile, "\n\n\tArchive of %s\n\tPerformed on %s\n\n\n", cur_pathname, ctime(&date)); ! 444: fprintf(lfile, "\tContents of archive file follows:\n\n"); ! 445: fprintf(lfile, " Create date\t\t Modification Date\t Type\t\t\t\t\tName\n\n"); ! 446: ! 447: ProcEachSeq = listproc; ! 448: Filing4_List(connected, GetAttributeSequences, listhandle, ! 449: typeseq, lscopeseq, ! 450: BulkData1_immediateSink, session); ! 451: fclose(lfile); ! 452: } ! 453: } ! 454: ! 455: ProcEachSeq = GetAllAttributes; ! 456: Filing4_List(connected, GetAttributeSequences, dirhandle, ! 457: Filing4_allAttributeTypes, scopeseq, ! 458: BulkData1_immediateSink, session); ! 459: ! 460: if ( verbose ) { ! 461: fprintf(stderr, " Serializing %s\n", cur_pathname); ! 462: } ! 463: ! 464: Filing4_Serialize(connected, retrieveproc, remotehandle, ! 465: BulkData1_immediateSink, session); ! 466: ! 467: freefilehandle(remotehandle); ! 468: freefilehandle(dirhandle); ! 469: } ! 470: ! 471: listproc(attr) ! 472: Filing4_AttributeSequence attr; ! 473: { ! 474: int i; ! 475: char *thisname, *typetostring(); ! 476: char createstr[30], modstr[30]; ! 477: LongCardinal thistype, createdate, moddate; ! 478: Filing4_AttributeType t; ! 479: ! 480: files_found= TRUE; ! 481: createdate= moddate= time(0); ! 482: ! 483: for (i = 0; i < attr.length; i++) { ! 484: t = attr.sequence[i].type; ! 485: if (t == Filing4_pathname) { ! 486: thisname = AttrToString(&attr.sequence[i]); ! 487: } else if (t == Filing4_type) { ! 488: thistype = AttrToLongCardinal(&attr.sequence[i]); ! 489: } else if (t == Filing4_createdOn) { ! 490: createdate= AttrToLongCardinal(&attr.sequence[i]); ! 491: createdate= createdate - XNS_TIME_DIFFERENCE; ! 492: strcpy(createstr, ctime(&createdate)); ! 493: createstr[24]= '\0'; ! 494: } else if (t == Filing4_modifiedOn) { ! 495: moddate= AttrToLongCardinal(&attr.sequence[i]); ! 496: moddate= moddate - XNS_TIME_DIFFERENCE; ! 497: strcpy(modstr, ctime(&moddate)); ! 498: modstr[24]= '\0'; ! 499: } ! 500: } ! 501: ! 502: fprintf(lfile, "%s\t%s\t%-16s\t%s\n", createstr+4, modstr+4, typetostring(thistype), thisname); ! 503: clear_String(&thisname); ! 504: } ! 505: ! 506: isdirproc(attr) ! 507: Filing4_AttributeSequence attr; ! 508: { ! 509: int i; ! 510: Filing4_AttributeType t; ! 511: ! 512: files_found= TRUE; ! 513: ! 514: for (i = 0; i < attr.length; i++) { ! 515: t = attr.sequence[i].type; ! 516: if (t == Filing4_isDirectory) { ! 517: is_a_directory = AttrToBoolean(&attr.sequence[i]); ! 518: } ! 519: } ! 520: ! 521: } ! 522: ! 523: GetAllAttributes(attr) ! 524: Filing4_AttributeSequence attr; ! 525: { ! 526: SaveExtendedAttributes(fout, attr); ! 527: ! 528: } ! 529: ! 530: #define MAXPACKS 20 ! 531: static ! 532: GetAttributeSequences(conn) ! 533: CourierConnection *conn; ! 534: { ! 535: int count, i; ! 536: Unspecified buffer[MAXWORDS*MAXPACKS], *bp, *bufend; ! 537: Filing4_StreamOfAttributeSequence attrs; ! 538: ! 539: files_found= FALSE; ! 540: ! 541: bufend = buffer; ! 542: bp = buffer+((MAXWORDS-1)*MAXPACKS); /* end of available space */ ! 543: while ((count = BDTread(conn, (char*)bufend, ! 544: MAXWORDS*sizeof(Unspecified))) > 0) { ! 545: bufend += count/sizeof(Unspecified); ! 546: if (bufend > bp) { ! 547: fprintf(stderr,"BDT read too big to fit\n"); ! 548: BDTabort(conn); ! 549: /* should clear out stuff here if we knew how much */ ! 550: } ! 551: } ! 552: bp = buffer; ! 553: while (bp < bufend) { ! 554: bp += internalize_Filing4_StreamOfAttributeSequence(&attrs,bp); ! 555: if (0 == (int) attrs.designator) { ! 556: for (i=0; i < attrs.nextSegment_case.segment.length; i++) { ! 557: (*ProcEachSeq)( ! 558: attrs.nextSegment_case.segment.sequence[i]); ! 559: } ! 560: free(attrs.nextSegment_case.segment.sequence); ! 561: } else { ! 562: for (i = 0; i < attrs.lastSegment_case.length; i++) { ! 563: (*ProcEachSeq)( ! 564: attrs.lastSegment_case.sequence[i]); ! 565: } ! 566: free(attrs.lastSegment_case.sequence); ! 567: return; ! 568: } ! 569: } ! 570: } ! 571: ! 572: retrieveproc(conn) ! 573: CourierConnection *conn; ! 574: { ! 575: int count, ocount, ch, fd; ! 576: char buffer[SPPMAXDATA]; ! 577: char *bp; ! 578: ! 579: errno = ocount = 0; ! 580: fflush(fout); ! 581: fd= fileno(fout); ! 582: ! 583: while ((count = BDTread(conn, buffer, sizeof(buffer))) > 0) { ! 584: if ((ocount = write (fd, buffer, count)) < 0) { ! 585: perror("write"); ! 586: BDTabort(conn); ! 587: break; ! 588: } ! 589: } ! 590: if (count < 0) perror("netin"); ! 591: } ! 592:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.