|
|
BSD 4.3tahoe
#ifndef lint
static char *rcsid = "$Header: /var/lib/cvsd/repos/CSRG/43BSDTahoe/new/xns/examples/remotetool/xnsremote.c,v 1.1.1.1 2018/04/24 16:12:58 root Exp $";
#endif lint
/*
* Copyright (c) 1986, 1987 Xerox Corporation.
*/
/* $Log: xnsremote.c,v $
/* Revision 1.1.1.1 2018/04/24 16:12:58 root
/* BSD 4.3tahoe
/*
* Revision 1.3 87/04/01 08:23:53 ed
* Changed for new MakeSecondaryCreds call.
*
* Revision 1.2 87/03/25 10:55:53 ed
* Don't reset usefiling in login.
*
* Revision 1.1 87/03/17 16:29:19 ed
* Initial revision
*
*
*/
#include <stdio.h>
#include <sys/time.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <netns/ns.h>
#include <netns/sp.h>
#include <xnscourier/FilingSubset1.h>
#include <xnscourier/Filing4.h>
#include <xnscourier/except.h>
#undef __Clearinghouse2 /* Filing4.h defs this */
#include <xnscourier/CH.h>
#include <xnscourier/filetypes.h>
#ifdef PRINTOPTION
#ifndef XNSPRINT
#define XNSPRINT "/usr/new/xnsprint"
#endif XNSPRINT
#ifndef MAHA
#define MAHA "/usr/new/maha"
#endif MAHA
#endif PRINTOPTION
#define ROOT_DIRECTORY "/"
CourierConnection *connected;
Clearinghouse3_ObjectName hostobjname;
Authentication3_Verifier verifier;
/* the following 3 items make up the current session */
FilingSubset1_Session session; /* the current session */
Clearinghouse3_ObjectName username;
FilingSubset1_Handle rootHandle;
char cur_dir[512]= 0;
char cur_pathname[512]= 0;
char cur_name[512]= 0;
static FilingSubset1_ControlSequence nullControls = {0,0};
static FilingSubset1_ScopeSequence nullScope = {0,0};
/* global data used to communicate with BDT procedures
*/
extern GetAttributeSequences(),
listproc(), retrieveproc();
char *AttrToString();
Boolean AttrToBoolean();
LongCardinal AttrToLongCardinal();
Cardinal AttrToCardinal();
static (*ProcEachSeq)();
static FILE *fout= stdout;
Boolean files_found= FALSE;
Boolean filing_subset= TRUE;
Boolean usefiling= TRUE;
Boolean verbose= FALSE;
LongCardinal typevalue= 0;
char *service, *pager;
extern int errno;
char thru_options[512];
struct name_entry {
char *pathname;
LongCardinal type;
} ;
static struct name_entry *name_list= 0;
static int name_count= 0;
static int name_size= 0;
#define MAX_NAMES 10
main(argc, argv)
int argc;
char *argv[];
{
char *file, *rightbrkt;
char oldservice[100];
char *index(), *getenv();
int i;
CourierConnection *hookup();
int opt;
extern int optind;
extern char *optarg;
#ifdef PRINTOPTION
static char *options= "fvP:";
static char *usage= "Usage: %s [-f] [-v] [-P printer] file1 ... filen\n";
#else PRINTOPTION
static char *options= "fvs";
static char *usage= "Usage: %s [-f] [-v] [-s] file1 ... filen\n";
#endif PRINTOPTION
if ( argc < 1 ) {
fprintf(stderr, usage, argv[0]);
exit(1);
}
#ifndef PRINTOPTION
pager= getenv("PAGER");
#endif PRINTOPTION
strcpy(thru_options, "");
while ((opt= getopt(argc, argv, options)) != EOF)
switch (opt) {
case 'v':
verbose++;
break;
case 'f':
usefiling= 0;
break;
#ifdef PRINTOPTION
case 'P' :
strcat(thru_options, " -P ");
strcat(thru_options, optarg);
break;
#else PRINTOPTION
case 's' :
pager= '\0'; /* override pager */
break;
#endif PRINTOPTION
default:
fprintf(stderr, "Invalid command option -%c\n", opt);
exit(1);
}
for ( ; optind < argc ; optind++ ) {
if ( getserviceandfile(argv[optind], &service, &file) == 0 ) {
fprintf(stderr, "Invalid name %s\n", argv[optind]);
exit(1);
}
DURING {
if ( strcmp(oldservice, service) != 0 ) {
if ( (connected= hookup(service)) == (CourierConnection *)0 ) {
fprintf(stderr, "\nCan't connect to %s\n", service);
continue;
}
login(0,0);
strcpy(oldservice, service);
}
getfile(file);
} HANDLER {
FilingErrMsg(Exception.Code, Exception.Message);
#ifndef PRINTOPTION
if ( fout != stdout )
pclose(fout);
#endif PRINTOPTION
} END_HANDLER;
}
return(0);
}
getserviceandfile(name, srvcptr, fileptr)
char *name;
char **srvcptr, **fileptr;
{
char *sptr, *fptr;
char *index(), *rindex();
/*
* look for Xerox forms first:
* [host]filename
*/
if ( (sptr= index(name, '[')) != 0 ) {
if ( (fptr= index(sptr, ']')) != 0 ) {
*fptr= '\0';
*srvcptr= sptr + 1;
*fileptr= fptr + 1;
return(1);
} else
return(0);
}
/*
* (host)filename
*/
if ( (sptr= index(name, '(')) != 0 ) {
if ( (fptr= index(sptr, ')')) != 0 ) {
*fptr= '\0';
*srvcptr= sptr + 1;
*fileptr= fptr + 1;
return(1);
} else
return(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 ) {
*fptr= '\0';
*srvcptr= name;
*fileptr= fptr + 1;
return(1);
} else
return(0);
}
copyhandle(dest,src)
FilingSubset1_Handle dest,src;
{
if (dest == (Unspecified *) 0) {
fprintf(stderr,"Oops. dest is null in copyhandle\n");
exit(1);
}
dest[0] = src[0];
dest[1] = src[1];
}
getfilehandle(filename, handle)
char *filename;
FilingSubset1_Handle handle;
{
FilingSubset1_Attribute pathattr[1];
FilingSubset1_AttributeSequence attrseq;
FilingSubset1_OpenResults openresult;
Filing4_OpenResults openresult2;
if (filename == (char *)0 || *filename == '\000' || (strcmp(filename, "/") == 0) ) {
if ( filing_subset )
copyhandle(handle,FilingSubset1_nullHandle);
else
copyhandle(handle,rootHandle);
return;
}
attrseq.length = 1;
attrseq.sequence = pathattr;
pathattr[0].type = FilingSubset1_pathname;
copyhandle(handle, FilingSubset1_nullHandle);
#ifdef XEROXFSCOMPATIBILITY
if ( filename[0] == '/')
StringToAttr(filename+1, &pathattr[0]);
else
StringToAttr(filename, &pathattr[0]);
#else XEROXFSCOMPATIBILITY
StringToAttr(filename, &pathattr[0]);
#endif XEROXFSCOMPATIBILITY
alarm(0);
if ( filing_subset ) {
openresult = FilingSubset1_Open(connected, NULL, attrseq,
handle, nullControls,
session);
copyhandle(handle, openresult.file);
} else {
openresult2 = Filing4_Open(connected, NULL, attrseq,
handle, nullControls,
session);
copyhandle(handle, openresult2.file);
}
}
getdirhandle(filename, handle)
char *filename;
FilingSubset1_Handle handle;
{
FilingSubset1_Attribute pathattr[1];
FilingSubset1_AttributeSequence attrseq;
FilingSubset1_OpenResults openresult;
Filing4_OpenResults openresult2;
char *rindex();
char *slash;
if (filename == (char *)0 || *filename == '\000' || (strcmp(filename, "/") == 0) ) {
strcpy(cur_pathname, "/");
strcpy(cur_name, "/");
if ( filing_subset )
copyhandle(handle,FilingSubset1_nullHandle);
else
copyhandle(handle,rootHandle);
return;
} else if ( filename[0] == '/' ) {
strcpy(cur_pathname, filename);
} else {
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);
else
strcpy(cur_name, slash+1);
if ( filing_subset ) {
copyhandle(handle, FilingSubset1_nullHandle);
} else {
if ( slash == cur_pathname) {
copyhandle(handle, rootHandle);
return;
}
attrseq.length = 1;
attrseq.sequence = pathattr;
pathattr[0].type = FilingSubset1_pathname;
copyhandle(handle, FilingSubset1_nullHandle);
*slash= '\0'; /* separate pathname from name */
#ifdef XEROXFSCOMPATIBILITY
if ( cur_pathname[0] == '/' )
StringToAttr(cur_pathname+1, &pathattr[0]);
else
StringToAttr(cur_pathname, &pathattr[0]);
#else XEROXFSCOMPATIBILITY
StringToAttr(cur_pathname, &pathattr[0]);
#endif XEROXFSCOMPATIBILITY
*slash= '/'; /* and put back */
alarm(0);
if ( filing_subset ) {
openresult = FilingSubset1_Open(connected, NULL, attrseq,
handle, nullControls,
session);
copyhandle(handle, openresult.file);
} else {
openresult2 = Filing4_Open(connected, NULL, attrseq,
handle, nullControls,
session);
copyhandle(handle, openresult2.file);
}
}
}
freefilehandle(handle)
FilingSubset1_Handle handle;
{
if (handle[0] == FilingSubset1_nullHandle[0] &&
handle[1] == FilingSubset1_nullHandle[1])
return; /* don't free nullHandle */
if (handle[0] == rootHandle[0] &&
handle[1] == rootHandle[1])
return; /* don't free root directory */
alarm(0);
if ( filing_subset )
FilingSubset1_Close(connected, NULL, handle, session);
else
Filing4_Close(connected, NULL, handle, session);
}
CourierConnection *
hookup(name)
char *name;
{
register struct ns_addr *hostaddr;
extern struct ns_addr *getXNSaddr();
Clearinghouse3_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_Clearinghouse3_ThreePartName(&hostobjname); */
hostobjname = CH_StringToName(hnamebuf, &defaultobjname);
}
return(cconn);
}
login(name,pwd)
char *pwd;
char *name;
{
FilingSubset1_Credentials credentials;
FilingSubset1_LogonResults logonresult;
FilingSubset1_LogonResults *resultptr= &logonresult;
Filing4_LogonResults logonresult2;
FilingSubset1_AttributeSequence attrseq;
FilingSubset1_OpenResults openresult;
Filing4_OpenResults openresult2;
if ( name != 0 )
username = CH_StringToName(name,&hostobjname);
if ( usefiling ) {
filing_subset= FALSE;
if ( name == 0 && pwd == 0 ) {
GetSimpleCredsAndVerifier(&username, 0,
&credentials.primary, &verifier);
} else {
MakeSimpleCredsAndVerifier(&username,pwd,
&credentials.primary, &verifier);
}
logonresult2= Filing4_Logon(connected, NULL, hostobjname,
credentials.primary, verifier);
resultptr= (FilingSubset1_LogonResults *) &logonresult2;
} else {
if ( name == 0 && pwd == 0 ) {
GetSimpleCredsAndVerifier(&username, 0, &credentials.primary, &verifier);
MakeSecondaryCreds(hostobjname.object, 0, 0, &credentials.secondary);
} else {
MakeSimpleCredsAndVerifier(0, pwd, &credentials.primary, &verifier);
MakeSecondaryCreds(hostobjname.object, name, pwd, &credentials.secondary);
}
filing_subset= TRUE;
DURING
logonresult = FilingSubset1_Logon(connected, NULL, hostobjname,
credentials, verifier);
HANDLER {
switch (Exception.Code) {
case REJECT_ERROR:
filing_subset= FALSE;
logonresult2= Filing4_Logon(connected, NULL, hostobjname,
credentials.primary, verifier);
resultptr= (FilingSubset1_LogonResults *) &logonresult2;
break;
default:
RERAISE;
}
} END_HANDLER;
}
if ( filing_subset )
session = resultptr->session;
else
session = resultptr->session;
attrseq.length= 0;
attrseq.sequence= 0;
if ( filing_subset ) {
openresult= FilingSubset1_Open(connected, NULL, attrseq,
FilingSubset1_nullHandle, nullControls,
session);
copyhandle(rootHandle, openresult.file);
} else {
openresult2= Filing4_Open(connected, NULL, attrseq,
FilingSubset1_nullHandle, nullControls,
session);
copyhandle(rootHandle, openresult2.file);
}
strcpy(cur_dir, ROOT_DIRECTORY);
}
logout()
{
if ( filing_subset )
FilingSubset1_Logoff(connected, NULL, session);
else
Filing4_Logoff(connected, NULL, session);
clear_FilingSubset1_Session(&session);
}
getfile(remote)
char *remote;
{
FILE *popen();
FilingSubset1_Handle remotehandle; /* note: an array */
FilingSubset1_Handle dirhandle; /* note: an array */
FilingSubset1_AttributeTypeSequence typeseq;
FilingSubset1_AttributeType tsvals[10];
FilingSubset1_ScopeSequence scopeseq;
FilingSubset1_Scope scope;
char pcmd[500];
int i;
register struct name_entry *entry;
name_count= 0;
name_size= MAX_NAMES;
if ( (name_list= (struct name_entry *) malloc(sizeof(struct name_entry) * name_size)) == 0 ) {
perror("getfile: ");
return;
}
typeseq.length = 0; typeseq.sequence = tsvals;
scopeseq.length= 1; scopeseq.sequence= &scope;
scope.designator= FilingSubset1_filter;
scope.FilingSubset1_filter_case.designator= FilingSubset1_matches;
if ( filing_subset )
scope.FilingSubset1_filter_case.FilingSubset1_matches_case.attribute.type= FilingSubset1_pathname;
else
scope.FilingSubset1_filter_case.FilingSubset1_matches_case.attribute.type= FilingSubset1_name;
copyhandle(remotehandle, FilingSubset1_nullHandle);
getdirhandle(remote, dirhandle);
if ( filing_subset )
StringToAttr(cur_pathname,&scope.FilingSubset1_filter_case.FilingSubset1_matches_case.attribute);
else
StringToAttr(cur_name,&scope.FilingSubset1_filter_case.FilingSubset1_matches_case.attribute);
typeseq.length = 2;
typeseq.sequence[0] = FilingSubset1_pathname;
typeseq.sequence[1] = FilingSubset1_type;
ProcEachSeq = listproc;
if ( filing_subset )
FilingSubset1_List(connected, GetAttributeSequences, dirhandle,
typeseq, scopeseq,
BulkData1_immediateSink, session);
else
Filing4_List(connected, GetAttributeSequences, dirhandle,
typeseq, scopeseq,
BulkData1_immediateSink, session);
if ( !files_found ) {
fprintf(stderr, "\n(%s)%s not found\n", service, remote);
} else {
for ( i= 0 ; i < name_count ; i++ ) {
entry= &name_list[i];
#ifdef PRINTOPTION
if ( (entry->type != FilingSubset1_tText) && (entry->type != TYPE_VPMailNote) &&
(entry->type != TYPE_Interpress) ) {
fprintf(stderr, "\n\n\n\nInvalid file type (%d)\n\n\n\n", entry->type);
clear_String(&entry->pathname);
continue;
}
if ( entry->type == TYPE_Interpress ) {
sprintf(pcmd, "%s -q -b \"(%s)%s\"%s -", XNSPRINT, service, entry->pathname, thru_options);
} else {
sprintf(pcmd, "%s -b \"(%s)%s\"%s", MAHA, service, entry->pathname, thru_options);
}
if ( (fout= popen(pcmd, "w")) == NULL ) {
perror("popen: ");
exit(1);
}
if (verbose) {
fprintf(stderr, "\n\printing (%s)%s...\n\n",service,entry->pathname);
}
#else PRINTOPTION
if ( entry->type != FilingSubset1_tText ) {
fprintf(stderr, "\n\n\nCan only view text files.\n\n\n");
clear_String(&entry->pathname);
continue;
}
if ( pager == NULL || *pager == '\0' ) {
fout= stdout;
} else {
sprintf(pcmd, "%s%s", pager, thru_options);
if ( (fout= popen(pcmd, "w")) == NULL )
fout= stdout;
}
if (verbose) {
fprintf(stderr, "\n\n\n\nretrieving (%s)%s...\n\n\n\n",service,entry->pathname);
}
#endif PRINTOPTION
typevalue= entry->type;
getfilehandle(entry->pathname, remotehandle); /* get file handle */
if ( filing_subset ) {
FilingSubset1_Retrieve(connected, retrieveproc, remotehandle,
BulkData1_immediateSink, session);
} else {
Filing4_Retrieve(connected, retrieveproc, remotehandle,
BulkData1_immediateSink, session);
}
freefilehandle(remotehandle);
#ifdef PRINTOPTION
pclose(fout);
#else PRINTOPTION
if ( fout != stdout )
pclose(fout);
#endif PRINTOPTION
clear_String(&entry->pathname);
}
}
free(name_list);
freefilehandle(dirhandle);
}
listproc(attr)
FilingSubset1_AttributeSequence attr;
{
int i;
FilingSubset1_AttributeType t;
struct name_entry *entry;
files_found= TRUE;
/*
* Xerox file servers will return all versions of the requested file in
* ascending version order. We assume that the last version will be the
* highest and remember that name so that the retrieve will pull the
* highest version of the file. If we request just the file with no
* version, the server will return the oldest version (not what I would
* expect...)
*/
if ( name_count > name_size ) {
name_size += MAX_NAMES;
name_list= (struct name_entry *) realloc(name_list,
sizeof(struct name_entry) * name_size);
}
entry= &name_list[name_count];
for (i = 0; i < attr.length; i++) {
t = attr.sequence[i].type;
if (t == FilingSubset1_name || t == FilingSubset1_pathname) {
entry->pathname = AttrToString(&attr.sequence[i]);
} else if (t == FilingSubset1_type) {
entry->type = AttrToLongCardinal(&attr.sequence[i]);
}
}
name_count++;
}
#define MAXPACKS 20
static
GetAttributeSequences(conn)
CourierConnection *conn;
{
int count, i;
Unspecified buffer[MAXWORDS*MAXPACKS], *bp, *bufend;
FilingSubset1_StreamOfAttributeSequence attrs;
files_found= FALSE;
bufend = buffer;
bp = buffer+((MAXWORDS-1)*MAXPACKS); /* end of available space */
while ((count = BDTread(conn, (char*)bufend,
MAXWORDS*sizeof(Unspecified))) > 0) {
bufend += count/sizeof(Unspecified);
if (bufend > bp) {
fprintf(stderr,"BDT read too big to fit\n");
BDTabort(conn);
/* should clear out stuff here if we knew how much */
}
}
bp = buffer;
while (bp < bufend) {
bp += internalize_FilingSubset1_StreamOfAttributeSequence(&attrs,bp);
if (0 == (int) attrs.designator) {
for (i=0; i < attrs.nextSegment_case.segment.length; i++) {
(*ProcEachSeq)(
attrs.nextSegment_case.segment.sequence[i]);
}
free(attrs.nextSegment_case.segment.sequence);
} else {
for (i = 0; i < attrs.lastSegment_case.length; i++) {
(*ProcEachSeq)(
attrs.lastSegment_case.sequence[i]);
}
free(attrs.lastSegment_case.sequence);
return;
}
}
}
int
getBDTch(conn,bpp)
CourierConnection *conn;
u_char **bpp;
{
static u_char buffer[SPPMAXDATA];
static int count;
if (*bpp == NULL) {*bpp = buffer; count = 0;}
if (*bpp >= buffer+count) {
count=BDTread(conn,buffer,sizeof(buffer));
*bpp = buffer;
}
if (count <= 0) return(EOF);
else return(*((*bpp)++));
}
retrieveproc(conn)
CourierConnection *conn;
{
int count, ocount, ch;
char buffer[SPPMAXDATA];
int charset, charset16;
char *bp;
errno = ocount = 0;
fflush(fout);
switch (typevalue) {
default :
fprintf(stderr, "Unsupported file type\n");
BDTabort(conn);
break;
case TYPE_Interpress :
while ((count = BDTread(conn, buffer, sizeof(buffer))) > 0) {
if ((ocount = write (fileno(fout), buffer, count)) < 0) {
perror("write");
BDTabort(conn);
break;
}
}
if (count < 0) perror("netin");
break;
case TYPE_VPMailNote :
case TYPE_A :
charset = 0; charset16 = 0; bp = NULL;
while ((ch = getBDTch(conn,&bp)) != EOF) {
if (ch == '\377') {
ch = getBDTch(conn,&bp);
if (ch == '\377') charset16 = 1;
else charset = ch;
continue;
}
if (charset16) {
charset = ch;
ch = getBDTch(conn,&bp);
}
switch (charset) {
case 0: /* normal character set -- minimal xlation */
if (ch == '\r') {
int nextch;
putc('\n',fout);
if ( (nextch = getBDTch(conn,&bp)) != '\n'){
if (nextch == '\r')
putc('\n',fout);
else if ( nextch != EOF )
putc(nextch,fout);
else
continue;
}
break;
}
else if (ch == ','+0200) ch = '_';
/* more mapping here */
putc(ch,fout);
break;
default:
break; /* ignore */
}
}
/* if (count < 0) perror("netin"); */
break;
}
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.