|
|
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.