static char *rcsid
= "$Header: xnsrestore.c,v 1.1 87/03/17 16:27:26 ed Exp $";
* Copyright (c) 1986, 1987 Xerox Corporation.
/* $Log: xnsrestore.c,v $
* Revision 1.1 87/03/17 16:27:26 ed
#include <xnscourier/Filing4.h>
#include <xnscourier/except.h>
#include <xnscourier/CH.h>
#include <xnscourier/filetypes.h>
#define XNS_TIME_DIFFERENCE 2177452800 /* [(1970-1901) years * 365 days/year + 17 leap days */
/* * 24 hours/day * 60 minutes/hour * 60 seconds/minute */
#define ROOT_DIRECTORY "/"
CourierConnection
*connected
;
Clearinghouse2_ObjectName hostobjname
;
Authentication2_Verifier verifier
;
/* the following 3 items make up the current session */
Filing4_Session session
; /* the current session */
Clearinghouse2_ObjectName username
;
Filing4_Handle rootHandle
;
char cur_pathname
[512]= 0;
static Filing4_ControlSequence nullControls
= {0,0};
/* global data used to communicate with BDT procedures
extern GetAttributeSequences(),
listproc(), isdirproc(), storeproc();
LongCardinal
AttrToLongCardinal();
Cardinal
AttrToCardinal();
Boolean files_found
= FALSE
;
Boolean is_a_directory
= FALSE
;
CourierConnection
*hookup();
static char *options
= "vl:";
static char *usage
= "Usage: %s [-v] [-l log-file] local-file remote-file\n";
fprintf(stderr
, usage
, argv
[0]);
while ((opt
= getopt(argc
, argv
, options
)) != EOF
)
fprintf(stderr
, "Invalid command option -%c\n", opt
);
if ( getserviceandfile(argv
[optind
], &service
, &remotefile
) == 0 ) {
fprintf(stderr
, "Invalid name %s\n", argv
[optind
]);
if ( (connected
= hookup(service
)) == (CourierConnection
*)0 ) {
fprintf(stderr
, "\nCan't connect to %s\n", service
);
deserializefile(localfile
, remotefile
);
FilingErrMsg(Exception
.Code
, Exception
.Message
);
getserviceandfile(name
, srvcptr
, fileptr
)
char **srvcptr
, **fileptr
;
char *index(), *rindex();
* look for Xerox forms first:
if ( (sptr
= index(name
, '[')) != 0 ) {
if ( (fptr
= index(sptr
, ']')) != 0 ) {
if ( (sptr
= index(name
, '(')) != 0 ) {
if ( (fptr
= index(sptr
, ')')) != 0 ) {
* look for XNS style with trailing : delimiter
* (assumes no : in file name, use alternate spec instead)
* object:domain:organization:filename
* domain & organization are optional
if ( (fptr
= rindex(name
, ':')) != 0 ) {
if (dest
== (Unspecified
*) 0) {
fprintf(stderr
,"Oops. dest is null in copyhandle\n");
getfilehandle(filename
, handle
)
Filing4_Attribute pathattr
[1];
Filing4_AttributeSequence attrseq
;
Filing4_OpenResults openresult
;
Filing4_OpenResults openresult2
;
if (filename
== (char *)0 || *filename
== '\000' || (strcmp(filename
, "/") == 0) ) {
copyhandle(handle
,rootHandle
);
attrseq
.sequence
= pathattr
;
pathattr
[0].type
= Filing4_pathname
;
copyhandle(handle
, Filing4_nullHandle
);
#ifdef XEROXFSCOMPATIBILITY
StringToAttr(filename
+1, &pathattr
[0]);
StringToAttr(filename
, &pathattr
[0]);
#else XEROXFSCOMPATIBILITY
StringToAttr(filename
, &pathattr
[0]);
#endif XEROXFSCOMPATIBILITY
openresult2
= Filing4_Open(connected
, NULL
, attrseq
,
copyhandle(handle
, openresult2
.file
);
getdirhandle(filename
, handle
)
Filing4_Attribute pathattr
[1];
Filing4_AttributeSequence attrseq
;
Filing4_OpenResults openresult
;
Filing4_OpenResults openresult2
;
if (filename
== (char *)0 || *filename
== '\000' || (strcmp(filename
, "/") == 0) ) {
strcpy(cur_pathname
, "/");
copyhandle(handle
,rootHandle
);
} else if ( filename
[0] == '/' ) {
strcpy(cur_pathname
, filename
);
strcpy(cur_pathname
, cur_dir
);
if ( strcmp(cur_pathname
, "/") != 0 )
strcat(cur_pathname
, "/");
strcat(cur_pathname
, filename
);
if ( (slash
= rindex(cur_pathname
,'/')) == NULL
)
strcpy(cur_name
, cur_pathname
);
strcpy(cur_name
, slash
+1);
if ( slash
== cur_pathname
) {
copyhandle(handle
, rootHandle
);
attrseq
.sequence
= pathattr
;
pathattr
[0].type
= Filing4_pathname
;
copyhandle(handle
, Filing4_nullHandle
);
*slash
= '\0'; /* separate pathname from name */
#ifdef XEROXFSCOMPATIBILITY
if ( cur_pathname
[0] == '/' )
StringToAttr(cur_pathname
+1, &pathattr
[0]);
StringToAttr(cur_pathname
, &pathattr
[0]);
#else XEROXFSCOMPATIBILITY
StringToAttr(cur_pathname
, &pathattr
[0]);
#endif XEROXFSCOMPATIBILITY
*slash
= '/'; /* and put back */
openresult2
= Filing4_Open(connected
, NULL
, attrseq
,
handle
, nullControls
, session
);
copyhandle(handle
, openresult2
.file
);
if (handle
[0] == Filing4_nullHandle
[0] &&
handle
[1] == Filing4_nullHandle
[1])
return; /* don't free nullHandle */
if (handle
[0] == rootHandle
[0] &&
handle
[1] == rootHandle
[1])
return; /* don't free root directory */
Filing4_Close(connected
, NULL
, handle
, session
);
register struct ns_addr
*hostaddr
;
extern struct ns_addr
*getXNSaddr();
Clearinghouse2_ObjectName defaultobjname
;
static char hnamebuf
[128];
CourierConnection
*cconn
;
CH_NameDefault(&defaultobjname
);
hostobjname
= CH_StringToName(name
, &defaultobjname
);
if ((hostaddr
= CH_LookupAddrDN( hostobjname
, 0, hnamebuf
, 128))) {
/* should check here to be sure host is a file service */
hostaddr
->x_port
= htons(5); /* ?? */
cconn
= CourierOpen(hostaddr
);
/* reset objname to flush wildcards */
/* clear_Clearinghouse2_ThreePartName(&hostobjname); */
hostobjname
= CH_StringToName(hnamebuf
, &defaultobjname
);
Filing4_Credentials credentials
;
Filing4_LogonResults logonresult
;
Filing4_AttributeSequence attrseq
;
Filing4_OpenResults openresult
;
username
= CH_StringToName(name
,&hostobjname
);
if ( name
== 0 && pwd
== 0 ) {
GetSimpleCredsAndVerifier(&username
, 0,
&credentials
, &verifier
);
MakeSimpleCredsAndVerifier(&username
,pwd
,
&credentials
, &verifier
);
logonresult
= Filing4_Logon(connected
, NULL
, hostobjname
,
session
= logonresult
.session
;
openresult
= Filing4_Open(connected
, NULL
, attrseq
,
Filing4_nullHandle
, nullControls
,
copyhandle(rootHandle
, openresult
.file
);
strcpy(cur_dir
, ROOT_DIRECTORY
);
Filing4_Logoff(connected
, NULL
, session
);
clear_Filing4_Session(&session
);
deserializefile(local
, remote
)
Filing4_Handle remotehandle
; /* note: an array */
Filing4_Handle dirhandle
; /* note: an array */
Filing4_Handle listhandle
; /* note: an array */
Filing4_DeserializeResults results
;
Filing4_AttributeSequence attrseq
;
Filing4_Attribute attrvals
[50];
Filing4_AttributeTypeSequence typeseq
;
Filing4_AttributeType tsvals
[10];
Filing4_ScopeSequence scopeseq
;
Filing4_ScopeSequence lscopeseq
;
scopeseq
.sequence
= &scope
; lscopeseq
.sequence
= &lscope
;
attrseq
.sequence
= attrvals
;
if ( strcmp(local
, "-") == 0 ) {
if ( (fin
= fopen(local
, "r")) == NULL
) {
perror("Cannot open local file ");
if ( (name
= rindex(local
, '/')) == 0 ) {
getdirhandle(remote
, dirhandle
);
scope
.designator
= Filing4_filter
;
scope
.Filing4_filter_case
.designator
= Filing4_matches
;
scope
.Filing4_filter_case
.Filing4_matches_case
.attribute
.type
= Filing4_name
;
StringToAttr(cur_name
,&scope
.Filing4_filter_case
.Filing4_matches_case
.attribute
);
typeseq
.length
= 2; typeseq
.sequence
= tsvals
;
typeseq
.sequence
[0] = Filing4_name
;
typeseq
.sequence
[1] = Filing4_isDirectory
;
Filing4_List(connected
, GetAttributeSequences
, dirhandle
,
BulkData1_immediateSink
, session
);
fprintf(stderr
, "Must specify file name when pinput is from stdin\n");
freefilehandle(dirhandle
);
getfilehandle(remote
, dirhandle
);
strcat(cur_pathname
, "/");
strcat(cur_pathname
, name
);
attrvals
[0].type
= Filing4_name
;
StringToAttr(name
, &attrvals
[0]);
if ( AddExtendedDeserializeAttributes(fin
, &attrseq
) != -1 ) {
fprintf(stderr
, "Cannot determine extended attributes\n");
fprintf(stdout
, " Restoring %s\n", cur_pathname
);
results
= Filing4_Deserialize(connected
, storeproc
, dirhandle
,
BulkData1_immediateSink
, session
);
if ( (lfile
= fopen(logfile
, "w")) != NULL
) {
scope
.designator
= Filing4_filter
;
scope
.Filing4_filter_case
.designator
= Filing4_matches
;
scope
.Filing4_filter_case
.Filing4_matches_case
.attribute
.type
= Filing4_name
;
StringToAttr(name
,&scope
.Filing4_filter_case
.Filing4_matches_case
.attribute
);
typeseq
.length
= 2; typeseq
.sequence
= tsvals
;
typeseq
.sequence
[0] = Filing4_pathname
;
typeseq
.sequence
[1] = Filing4_isDirectory
;
Filing4_List(connected
, GetAttributeSequences
, dirhandle
,
BulkData1_immediateSink
, session
);
* for a directory, we list all files...
* for non-directory, just list it...
copyhandle(listhandle
, results
.file
);
lscope
.designator
= Filing4_depth
;
lscope
.Filing4_depth_case
= Filing4_allDescendants
;
copyhandle(listhandle
, dirhandle
);
lscope
.designator
= Filing4_filter
;
lscope
.Filing4_filter_case
.designator
= Filing4_matches
;
lscope
.Filing4_filter_case
.Filing4_matches_case
.attribute
.type
= Filing4_name
;
StringToAttr(name
,&lscope
.Filing4_filter_case
.Filing4_matches_case
.attribute
);
typeseq
.sequence
[0] = Filing4_pathname
;
typeseq
.sequence
[1] = Filing4_type
;
typeseq
.sequence
[2] = Filing4_createdOn
;
typeseq
.sequence
[3] = Filing4_modifiedOn
;
fprintf(lfile
, "\n\n\tRestore of %s\n\tPerformed on %s\n\n\n", cur_pathname
, ctime(&date
));
fprintf(lfile
, "\tFiles restored as follows:\n\n");
fprintf(lfile
, " Create Date\t\t Modification Date\t Type\t\t\t\t\t\tName\n\n");
Filing4_List(connected
, GetAttributeSequences
, listhandle
,
BulkData1_immediateSink
, session
);
freefilehandle(results
.file
);
freefilehandle(dirhandle
);
Filing4_AttributeSequence attr
;
char *thisname
, *typetostring();
char createstr
[30], modstr
[30];
LongCardinal thistype
, createdate
, moddate
;
createdate
= moddate
= time(0);
for (i
= 0; i
< attr
.length
; i
++) {
t
= attr
.sequence
[i
].type
;
if (t
== Filing4_pathname
) {
thisname
= AttrToString(&attr
.sequence
[i
]);
} else if (t
== Filing4_type
) {
thistype
= AttrToLongCardinal(&attr
.sequence
[i
]);
} else if (t
== Filing4_createdOn
) {
createdate
= AttrToLongCardinal(&attr
.sequence
[i
]);
createdate
= createdate
- XNS_TIME_DIFFERENCE
;
strcpy(createstr
, ctime(&createdate
));
} else if (t
== Filing4_modifiedOn
) {
moddate
= AttrToLongCardinal(&attr
.sequence
[i
]);
moddate
= moddate
- XNS_TIME_DIFFERENCE
;
strcpy(modstr
, ctime(&moddate
));
fprintf(lfile
, "%s\t%s\t%-16s\t%s\n", createstr
+4, modstr
+4, typetostring(thistype
), thisname
);
Filing4_AttributeSequence attr
;
for (i
= 0; i
< attr
.length
; i
++) {
t
= attr
.sequence
[i
].type
;
if (t
== Filing4_isDirectory
) {
is_a_directory
= AttrToBoolean(&attr
.sequence
[i
]);
} else if (t
== Filing4_name
) {
thisname
= AttrToString(&attr
.sequence
[i
]);
strcpy(cur_name
, thisname
);
GetAttributeSequences(conn
)
Unspecified buffer
[MAXWORDS
*MAXPACKS
], *bp
, *bufend
;
Filing4_StreamOfAttributeSequence attrs
;
bp
= buffer
+((MAXWORDS
-1)*MAXPACKS
); /* end of available space */
while ((count
= BDTread(conn
, (char*)bufend
,
MAXWORDS
*sizeof(Unspecified
))) > 0) {
bufend
+= count
/sizeof(Unspecified
);
fprintf(stderr
,"BDT read too big to fit\n");
/* should clear out stuff here if we knew how much */
bp
+= internalize_Filing4_StreamOfAttributeSequence(&attrs
,bp
);
if (0 == (int) attrs
.designator
) {
for (i
=0; i
< attrs
.nextSegment_case
.segment
.length
; i
++) {
attrs
.nextSegment_case
.segment
.sequence
[i
]);
free(attrs
.nextSegment_case
.segment
.sequence
);
for (i
= 0; i
< attrs
.lastSegment_case
.length
; i
++) {
attrs
.lastSegment_case
.sequence
[i
]);
free(attrs
.lastSegment_case
.sequence
);
while ( ((count
= fread(buffer
, sizeof(char), SPPMAXDATA
, fin
)) != 0)
&& (ocount
= BDTwrite (conn
, buffer
, count
)) > 0) {
} else if ( ferror(fin
) ) {