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