📄 xnftp.c
字号:
#ifndef lintstatic char *rcsid = "$Header: xnftp.c,v 2.13 87/05/28 14:17:14 ed Exp $";#endif lint/* $Log: xnftp.c,v $ * Revision 2.13 87/05/28 14:17:14 ed * I botched the compiler bug fix... * * Revision 2.12 87/05/14 11:37:34 ed * Raise error from hookup if connection not established. * Better handling of truncated bulk data stream when it overflows buffer. * * Revision 2.11 87/05/11 14:40:12 ed * Incorporated changes from JQ's 4.3e version. * * Revision 2.11 87/03/08 07:09:53 jqj * work around "schain botch" 4.3BSD VAX compiler bug (from Scooter Morris). * * Revision 2.10 87/05/05 14:49:00 ed * Move alarm setting/resetting closer to actual procedure calls. * * Revision 2.9 87/04/16 15:23:47 ed * Fixed lingering bugs in Subset pathname usage. * * Revision 2.8 87/04/01 09:33:36 ed * Changed for new MakeSecondaryCreds call. * Reset connection on login failure. * * Revision 2.7 87/03/27 15:19:19 ed * Don't assume secondary username is primary name. * Additional check for underscore translation on text files. * * Revision 2.6 87/03/23 12:32:12 ed * allow round-trip transfer of Viewpoint files, retain/specify uninterpreted * attributes. * Serialization/Deserialization of directories from server. * Wildcard deletion. * Compatibility with XDE MFileServer. * New commands: Archive, Restore, Unify. * * Revision 2.5 87/01/14 15:59:29 ed * Use FilingSubset, if rejected attempt Filing * Allows user override with -F switch * Maintain FilingSubset mandatory attributes * User niceties: echo file name/type on transfer commands * prompt on delete * guess type which will determine file type implied by content * New commands: (type related) Guess, Whatis * (file transfer) Copy, Move, Rename * * Revision 2.4 86/12/15 11:41:16 jqj * Added support for more ViewPoint file types (no other attributes, though) * * Revision 2.3 86/12/11 06:12:22 jqj * Eliminated form, mode, and struct commands. Started adding support for * more file types. * * Revision 2.2 86/09/07 07:43:40 jqj * Cope with failure return from CourierOpen. * * Revision 2.1 86/06/30 12:19:39 jqj * convert to Authentication v. 2 for compatibility with official spec. * * Revision 2.0 85/11/21 07:22:51 jqj * 4.3BSD standard release * * Revision 1.5 85/09/24 14:45:10 jqj * fix bug in alarm() handling that caused aborts during large file transfers. * * Revision 1.4 85/09/17 07:49:47 jqj * 4.3 changes. Use more routines from CHlookup * * Revision 1.1 85/05/27 06:31:07 jqj * Initial revision * */#include <stdio.h>#include <ctype.h>#include <sys/time.h>#include <sys/param.h>#include <sys/stat.h>#include <netns/ns.h>#include <netns/sp.h>#include "ftp_var.h"#include <xnscourier/Filing4.h>#include <xnscourier/except.h>#undef __Clearinghouse2 /* Filing4.h defs this */#include <xnscourier/CH.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 "/"#define MAXNAMES 10CourierConnection *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;int continuetime;int remoteprocpending;FilingSubset1_Handle rootHandle;char cur_dir[512]= 0;char cur_pathname[512]= 0;char cur_name[512]= 0;struct name_entry { char *pathname; LongCardinal type;} ;static struct name_entry *name_list= 0;static int name_count= 0;static int name_size= 0;static FilingSubset1_ControlSequence nullControls = {0,0};static FilingSubset1_ScopeSequence nullScope = {0,0};/* global data used to communicate with BDT procedures */extern GetAttributeSequences(), GetAllAttributes(), listproc(), nlistproc(), storeproc(), retrieveproc(), rlistproc(), mkdirproc(), cdproc(), isdirproc(), deleteproc();char *malloc();char *AttrToString();Boolean AttrToBoolean();LongCardinal AttrToLongCardinal();Cardinal AttrToCardinal();char *typetostring();static (*ProcEachSeq)();static long bytessent;static FILE *fout, *fin;LongCardinal filetypevalue; /* real transfer type */struct timeval timbuf[2];Boolean is_a_directory= FALSE;Boolean files_found= FALSE;Boolean filing_subset= TRUE;Boolean isdir= FALSE;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); } alarm(continuetime);}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, *bang; 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 ( (bang= rindex(cur_name, '!')) != NULL ) *bang= '\0'; 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); } alarm(continuetime); }}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); alarm(continuetime);}/* * do a continue to make sure that the session doesn't time out. * Note that this is usually called by an ALARM interrupt */probe(){ FilingSubset1_ContinueResults cresult; Filing4_ContinueResults cresult2; alarm(0); /* cancel previous alarms */ if ( filing_subset ) { cresult = FilingSubset1_Continue(connected, NULL, session); continuetime = cresult.continuance / 5; /* seconds */ } else { cresult2 = Filing4_Continue(connected, NULL, session); continuetime = cresult2.continuance / 5; /* seconds */ } alarm(continuetime); /* reset for another 2 min. or so */}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); if ( cconn == (CourierConnection *) 0 ) { Cardinal problem; problem= FilingSubset1_noResponse; raise(FilingSubset1_ConnectionError, &problem); } /* reset objname to flush wildcards */ /* clear_Clearinghouse3_ThreePartName(&hostobjname); */ hostobjname = CH_StringToName(hnamebuf, &defaultobjname); hostname = hnamebuf; if (verbose) printf("Connected to %s\n", hnamebuf); } else { printf("%s: unknown host\n", name); usefiling= 0; cconn = (CourierConnection*)0; } 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 ) { usefiling= 0; 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 { usefiling= 0; 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: connected= (CourierConnection *)0; /* reset */ RERAISE; } } END_HANDLER; } if ( filing_subset ) session = resultptr->session; else session = resultptr->session; if (verbose) printf("User %s:%s:%s logged on\n", username.object, username.domain, username.organization); 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); alarm(0); signal(SIGALRM, probe); probe();}logout(){ signal(SIGALRM, SIG_IGN); if ( filing_subset ) FilingSubset1_Logoff(connected, NULL, session); else Filing4_Logoff(connected, NULL, session); clear_FilingSubset1_Session(&session);}domakedir(dest) char *dest;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -