📄 xnftp.c
字号:
#ifndef lintstatic char *rcsid = "$Header: xnftp.c,v 2.5 87/03/08 07:09:53 jqj Exp $";#endif lint/* $Log: xnftp.c,v $ * Revision 2.5 87/03/08 07:09:53 jqj * work around "schain botch" 4.3BSD VAX compiler bug (from Scooter Morris). * * 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 <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/CH.h>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;int continuetime;int remoteprocpending;Filing4_Handle wdHandle; /* the current remote working dir */static Filing4_ControlSequence nullControls = {0,0};static Filing4_ScopeSequence nullScope = {0,0};/* global data used to communicate with BDT procedures */extern GetAttributeSequences(), listproc(), nlistproc(), storeproc(), retrieveproc();static (*ProcEachSeq)();static long bytessent;static FILE *fout, *fin;copyhandle(dest,src) Filing4_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];}StringToAttr(str, attr) char *str; Filing4_Attribute *attr;{ Unspecified buf[2049], *bp; Cardinal len; bp = buf + sizeof_Cardinal(len); len = externalize_String(&str, bp); (void) externalize_Cardinal(&len, buf); internalize_Clearinghouse2_Item(&(attr->value), buf); return;}char *AttrToString(attr) Filing4_Attribute *attr;{ Unspecified buf[2049], *bp; Cardinal len; char *strval; externalize_Clearinghouse2_Item(&(attr->value), buf); bp = buf; bp += internalize_Cardinal(&len, bp); bp += internalize_String(&strval, bp); return(strval);}UserToAttr(id, attr) Clearinghouse2_Name id; Filing4_Attribute *attr;{ Unspecified buf[2049], *bp; Cardinal len; bp = buf + sizeof_Cardinal(len); len = externalize_Clearinghouse2_Name(&id, bp); (void) externalize_Cardinal(&len, buf); internalize_Clearinghouse2_Item(&(attr->value), buf); return;}LongCardinalToAttr(val, attr) LongCardinal val; Filing4_Attribute *attr;{ Unspecified buf[3], *bp; Cardinal len; bp = buf + sizeof_Cardinal(len); len = externalize_LongCardinal(&val, bp); (void) externalize_Cardinal(&len, buf); internalize_Clearinghouse2_Item(&(attr->value), buf); return;}BooleanToAttr(val, attr) int val; Filing4_Attribute *attr;{ Boolean boolval; Unspecified buf[3], *bp; Cardinal len; boolval = (Boolean) val; bp = buf + sizeof_Cardinal(len); len = externalize_Boolean(&boolval, bp); (void) externalize_Cardinal(&len, buf); internalize_Clearinghouse2_Item(&(attr->value), buf); return;}intAttrToBoolean(attr) Filing4_Attribute *attr;{ Unspecified buf[1]; Boolean result; (void) externalize_Unspecified(attr->value.sequence, buf); (void) internalize_Boolean(&result, buf); return(result);}LongCardinalAttrToLongCardinal(attr) Filing4_Attribute *attr;{ Unspecified buf[2]; LongCardinal result; (void) externalize_Unspecified(attr->value.sequence, buf); (void) externalize_Unspecified((attr->value.sequence)+1, buf+1); (void) internalize_LongCardinal(&result, buf); return(result);}getfilehandle(filename, handle) char *filename; Filing4_Handle handle;{ Filing4_Attribute pathattr[1]; Filing4_AttributeSequence attrseq; Filing4_OpenResults openresult; if (filename == (char *)0 || *filename == '\000') { copyhandle(handle,wdHandle); return; } attrseq.length = 1; attrseq.sequence = pathattr; pathattr[0].type = Filing4_pathname; copyhandle(handle, Filing4_nullHandle); if (*filename != '/') { /* relative pathname specified */ StringToAttr(filename, &pathattr[0]); copyhandle(handle, wdHandle); } else if (filename[1] == '\000') { /* root specified */ attrseq.length = 0; } else { /* absolute pathname specified */ StringToAttr(filename+1, &pathattr[0]); } alarm(0); openresult = Filing4_Open(connected, NULL, attrseq, handle, nullControls, session); alarm(continuetime); copyhandle(handle, openresult.file);}freefilehandle(handle) Filing4_Handle handle;{ if (handle[0] == Filing4_nullHandle[0] && handle[1] == Filing4_nullHandle[1]) return; /* don't free nullHandle */ if (handle[0] == wdHandle[0] && handle[1] == wdHandle[1]) return; /* don't free working directory */ alarm(0); 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(){ Filing4_ContinueResults cresult; alarm(0); /* cancel previous alarms */ cresult = Filing4_Continue(connected, NULL, session); continuetime = cresult.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(); 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(IDPPORT_COURIER); /* ?? */ cconn = CourierOpen(hostaddr); /* reset objname to flush wildcards */ /* clear_Clearinghouse2_ThreePartName(&hostobjname); */ hostobjname = CH_StringToName(hnamebuf, &defaultobjname); hostname = hnamebuf; if (cconn == (CourierConnection*) 0) printf("%s: connection failed\n", hnamebuf); else if (verbose) printf("Connected to %s\n", hnamebuf); } else { printf("%s: unknown host\n", name); cconn = (CourierConnection*)0; } return(cconn);}login(name,pwd) char *pwd; char *name;{ Authentication2_Credentials credentials; Filing4_LogonResults logonresult; username = CH_StringToName(name,&hostobjname); MakeSimpleCredsAndVerifier(&username,pwd, &credentials, &verifier); logonresult = Filing4_Logon(connected, NULL, hostobjname, credentials, verifier); session = logonresult.session; copyhandle(wdHandle, Filing4_nullHandle); if (verbose) printf("User %s:%s:%s logged on\n", username.object, username.domain, username.organization); alarm(0); signal(SIGALRM, probe); probe();}logout(){ signal(SIGALRM, SIG_IGN); Filing4_Logoff(connected, NULL, session); clear_Filing4_Session(&session); copyhandle(wdHandle, Filing4_nullHandle);}domakedir(dest) char *dest;{ sendrequest("MKDIR", "-", dest);}doremovedir(src) char *src;{ dodelete(src);}dostore(src, dest) char *src, *dest;{ sendrequest("STOR", src, dest);}doappend(src, dest) char *src, *dest;{ NYI();}dorename(src, dest) char *src, *dest;{ NYI();}recvrequest(cmd, local, remote, mode) char *cmd, *local, *remote, *mode;{ FILE *popen(); int (*closefunc)(), pclose(), fclose(); struct timeval start, stop; Filing4_Handle remotehandle; /* note: an array */ Filing4_AttributeTypeSequence typeseq; Filing4_AttributeType tsvals[10]; char *dir; closefunc = NULL; fout = stdout; typeseq.length = 0; typeseq.sequence = tsvals; if (strcmp(local, "-") && *local != '|') if (access(local, 2) < 0) { dir = rindex(local, '/'); /* get a good error message */ if (dir != NULL) *dir = '\0'; if (access(dir ? local : ".", 2) < 0) { perror(local); goto bad; } if (dir != NULL) *dir = '/'; } if (strcmp(local, "-") == 0) fout = stdout; else if (*local == '|') { fout = popen(local + 1, "w"); if (fout == NULL) { perror(local + 1); goto bad; } closefunc = pclose; } else { fout = fopen(local, mode); if (fout == NULL) { perror(local); goto bad; } closefunc = fclose; } bytessent = 0; gettimeofday(&start, (struct timezone *)0); getfilehandle(remote, remotehandle); alarm(0); if (strcmp(cmd,"NLST") == 0) { typeseq.length = 1; typeseq.sequence[0] = Filing4_pathname; ProcEachSeq = nlistproc; Filing4_List(connected, GetAttributeSequences, remotehandle, typeseq, nullScope, BulkData1_immediateSink, session); } else if (strcmp(cmd,"LIST") == 0) { typeseq.length = 5; typeseq.sequence[0] = Filing4_name; typeseq.sequence[1] = Filing4_dataSize; typeseq.sequence[2] = Filing4_isDirectory; typeseq.sequence[3] = Filing4_isTemporary; typeseq.sequence[4] = Filing4_type; ProcEachSeq = listproc; Filing4_List(connected, GetAttributeSequences, remotehandle, typeseq, nullScope, BulkData1_immediateSink, session); } else if (strcmp(cmd,"RETR") == 0) { Filing4_Retrieve(connected, retrieveproc, remotehandle, BulkData1_immediateSink, session); } else printf("unrecognized command %s\n",cmd); alarm(continuetime); gettimeofday(&stop, (struct timezone *)0); freefilehandle(remotehandle); if (bytessent > 0 && verbose) ptransfer("received", bytessent, &start, &stop); bad: if (closefunc != NULL && fout != NULL) (*closefunc)(fout); fout = NULL;}sendrequest(cmd, local, remote) char *cmd, *local, *remote;{ FILE *popen(); int (*closefunc)(), pclose(), fclose(); struct stat st; struct timeval start, stop; Filing4_StoreResults storeresults; Filing4_CreateResults createresults; Filing4_Handle remotehandle; Filing4_AttributeSequence attrseq; Filing4_Attribute attrvals[5]; closefunc = NULL; if (strcmp(local, "-") == 0) { fin = stdin; closefunc = NULL; } else if (*local == '|') { fin = popen(local + 1, "r"); if (fin == NULL) { perror(local + 1); goto bad; } closefunc = pclose; } else { fin = fopen(local, "r"); if (fin == NULL) { perror(local); goto bad; } closefunc = fclose; if (fstat(fileno(fin), &st) < 0 || (st.st_mode&S_IFMT) != S_IFREG) { fprintf(stderr, "%s: not a plain file.", local); goto bad; } } if (remote) { char *dir = rindex(remote,'/'); if (dir != NULL) { *dir = '\000'; getfilehandle(remote, remotehandle);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -