📄 ccache_ftp.c
字号:
static char rcsid[] = "ccache_ftp.c,v 1.17 1996/01/04 04:12:23 duane Exp";/****************************************************************************** * * FILE * ftp.c * * DESCRIPTION * Contains code for ftp client, these calls are used by processes * desiring ftp services * Contains functions for communicating with FTP server (i.e. socket * level control of data transfer and request) * * FUNCTIONS * FTPInit() * Login() * Disconnect() * Retrieve() * * InitSocket() * ReadServReply() * SendMessage() * ReadOutText() * CheckServReply() * PrepareDataConnect() * RetrieveFile() * WriteToSocket() * * David Merkel & Mark Peterson, University of Colorado - Boulder, July 1994 * * ---------------------------------------------------------------------- * Copyright (c) 1994, 1995. All rights reserved. * * The Harvest software was developed by the Internet Research Task * Force Research Group on Resource Discovery (IRTF-RD): * * Mic Bowman of Transarc Corporation. * Peter Danzig of the University of Southern California. * Darren R. Hardy of the University of Colorado at Boulder. * Udi Manber of the University of Arizona. * Michael F. Schwartz of the University of Colorado at Boulder. * Duane Wessels of the University of Colorado at Boulder. * * This copyright notice applies to software in the Harvest * ``src/'' directory only. Users should consult the individual * copyright notices in the ``components/'' subdirectories for * copyright information about other software bundled with the * Harvest source code distribution. * * TERMS OF USE * * The Harvest software may be used and re-distributed without * charge, provided that the software origin and research team are * cited in any use of the system. Most commonly this is * accomplished by including a link to the Harvest Home Page * (http://harvest.cs.colorado.edu/) from the query page of any * Broker you deploy, as well as in the query result pages. These * links are generated automatically by the standard Broker * software distribution. * * The Harvest software is provided ``as is'', without express or * implied warranty, and with no support nor obligation to assist * in its use, correction, modification or enhancement. We assume * no liability with respect to the infringement of copyrights, * trade secrets, or any patents, and are not responsible for * consequential damages. Proper use of the Harvest software is * entirely the responsibility of the user. * * DERIVATIVE WORKS * * Users may make derivative works from the Harvest software, subject * to the following constraints: * * - You must include the above copyright notice and these * accompanying paragraphs in all forms of derivative works, * and any documentation and other materials related to such * distribution and use acknowledge that the software was * developed at the above institutions. * * - You must notify IRTF-RD regarding your distribution of * the derivative work. * * - You must clearly notify users that your are distributing * a modified version and not the original Harvest software. * * - Any derivative product is also subject to these copyright * and use restrictions. * * Note that the Harvest software is NOT in the public domain. We * retain copyright, as specified above. * * HISTORY OF FREE SOFTWARE STATUS * * Originally we required sites to license the software in cases * where they were going to build commercial products/services * around Harvest. In June 1995 we changed this policy. We now * allow people to use the core Harvest software (the code found in * the Harvest ``src/'' directory) for free. We made this change * in the interest of encouraging the widest possible deployment of * the technology. The Harvest software is really a reference * implementation of a set of protocols and formats, some of which * we intend to standardize. We encourage commercial * re-implementations of code complying to this set of standards. * ******************************************************************************/#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <fcntl.h>#include <sys/types.h>#include <sys/time.h>#include <sys/stat.h>#include <sys/socket.h>#include <netdb.h>#include <netinet/in.h>#include "ccache.h"extern int select(); /* UNIX sys call *//******************************************************************************** function name: FTPInit()**** preconditions: hostAddr should be a valid IP address. portNum is a TCP** port to connect to. errorReply has been allocated by caller.**** postconditions: On success a socket descriptor is returned to caller** that is connect to hostAddr, portNum. The value is a negative** error otherwise.**** author/credits: David Merkel, 4/94********************************************************************************/int FTPInit(hostAddr, portNum, errorReply) u_long hostAddr; /* address to connect to */ int portNum; /* TCP port */ char *errorReply; /* string for returning FTP server reply */{ int theSocket; /* socket descriptor to return */ int error; /* string to get FTP server reply */ char servReply[SERV_REPLY_LENGTH]; /* initialize socket by connecting to hostAddr, portNum */ theSocket = InitSocket(hostAddr, portNum); if (theSocket < 0) return (INIT_SOCKET_ERR); /* read FTP server reply */ error = ReadServReply(theSocket, servReply); if (error != NO_ERROR) return (error); /* check to see if we can continue */ error = CheckServReply(CONNECT_CHK, servReply); /* error found, return to caller */ if (error != NO_ERROR) { memcpy(errorReply, servReply, SERV_REPLY_LENGTH); return (error); } /* no errors, return socket descriptor */ return (theSocket);}/******************************************************************************** function name: Login()**** preconditions: userName and password are valid (i.e. allocated), theSocket** is a socket descriptor that has been connected to an FTP server,** firstUse indicates if this is the first login attempted on theSocket,** and errorReply is preallocated by caller**** postconditions: on success userName has been logged in to FTP server and** may begin FTP operations. A negative error value is returned** on failure. If success, the mode is STREAM, and the type** is IMAGE (see rfc959).**** author/credits: David Merkel, 4/94********************************************************************************/int Login(userName, password, theSocket, firstUse, errorReply) char *userName; /* user to log into FTP server */ char *password; /* password of user */ int theSocket; /* socket descriptor to use for communication */ Boolean firstUse; /* is this the first login on theSocket? */ char *errorReply; /* for returning server replies */{ int error; char servReply[SERV_REPLY_LENGTH]; /* for storing server replies */ char modeCode[2], typeCode[2]; /* for setting mode and type */#if DEBUG > 4 printf("Login: '%s' @ '%s' %s\n", userName, password, firstUse ? "TRUE" : "FALSE");#endif /* we've already used this socket before */ if (!firstUse) { /* must send 'REIN' message to reset state of login on * FTP server */ error = SendMessage(REINIT, NULL, theSocket); if (error != NO_ERROR) return (error); /* read reply for REIN command */ error = ReadServReply(theSocket, servReply); if (error != NO_ERROR) return (error); /* check reply for REIN command */ error = CheckServReply(CONNECT_CHK, servReply); if (error != NO_ERROR) { memcpy(errorReply, servReply, SERV_REPLY_LENGTH); return (error); } } /* send USER command */ error = SendMessage(USER, userName, theSocket); if (error != NO_ERROR) return (error); error = ReadServReply(theSocket, servReply); if (error != NO_ERROR) return (error); /* check for errors on USER reply */ error = CheckServReply(USER_CHK, servReply); if (error == NO_PASS_REQ) return (NO_ERROR); else if (error != NO_ERROR) { memcpy(errorReply, servReply, SERV_REPLY_LENGTH); return (error); } /* finish login sequence with PASS */ error = SendMessage(PASSWD, password, theSocket); if (error != NO_ERROR) return (error); error = ReadServReply(theSocket, servReply); if (error != NO_ERROR) return (error); /* check for errors */ error = CheckServReply(PASSWD_CHK, servReply); if (error != NO_ERROR) { memcpy(errorReply, servReply, SERV_REPLY_LENGTH); return (error); } /* if this is first use, setup STREAM mode, IMAGE data type */ if (firstUse) { modeCode[0] = STREAM; modeCode[1] = '\0'; /* send MODE message */ error = SendMessage(MODE, modeCode, theSocket); if (error != NO_ERROR) return (error); error = ReadServReply(theSocket, servReply); if (error != NO_ERROR) return (error); /* check MODE reply */ error = CheckServReply(MODE_CHK, servReply); if (error != NO_ERROR) { memcpy(errorReply, servReply, SERV_REPLY_LENGTH); return (error); } typeCode[0] = IMAGE; typeCode[1] = '\0'; /* send TYPE message */ error = SendMessage(TYPE, typeCode, theSocket); if (error != NO_ERROR) return (error); error = ReadServReply(theSocket, servReply); if (error != NO_ERROR) return (error); /* check TYPE reply */ error = CheckServReply(TYPE_CHK, servReply); if (error != NO_ERROR) { memcpy(errorReply, servReply, SERV_REPLY_LENGTH); return (error); } } return (NO_ERROR);}/******************************************************************************** function name: Disconnect()**** preconditions: errorReply is preallocated for return of FTP server errors,** theSocket is connected to an FTP server.**** postconditions: theSocket has been disconnected from the FTP server. If** an error occurred the result code is returned in errorReply**** author/credits: David Merkel, 4/94********************************************************************************/int Disconnect(theSocket, errorReply) int theSocket; /* socket identifier */ char *errorReply; /* string for return of reply codes */{ char servReply[SERV_REPLY_LENGTH]; /* to check reply codes */ int error; /* Tell FTP server we're disconnecting */ error = SendMessage(DISCONNECT, NULL, theSocket); if (error != NO_ERROR) { close(theSocket); return (error); } /* read its reply */ error = ReadServReply(theSocket, errorReply); /* if no reply, continue disconnect anyway */ if (error == NO_REPLY_PRESENT) { close(theSocket); return (NO_ERROR); } /* return error code to caller */ memcpy(errorReply, servReply, SERV_REPLY_LENGTH); close(theSocket); return (SERV_REPLY_ERROR);}/******************************************************************************** function name: Retrieve()**** preconditions: fileName is name of file to retrieve, theSocket is ** the control connection, dataSocket is a socket for data retrieval,** isListening tells us if theSocket is already listening for a** data connection, sendPort indicates whether or not to use FTP port ** command, errorReply is preallocated for return of FTP error codes,** data is the returns the retrieved data (preallocated by caller)**** postconditions: ** File returned inside of data.**** author/credits: Dave Merkel, 4/94********************************************************************************/int Retrieve(fileName, theSocket, dataSocket, isListening, sendPort, errorReply, data) char *fileName; /* name of file to retrieve */ int theSocket; /* control connection */ int dataSocket; /* data connection (not required) */ Boolean isListening; /* theSocket is already listening */ Boolean sendPort; /* use PORT command */ char *errorReply; /* return error codes */ DataReturn *data; /* data storage struct */{ extern int gethostname(); /* unix system call */ struct sockaddr_in theAddr; /* for use in PORT */ struct hostent *theEntry = NULL; /* for use in PORT */ /* return strings for error codes and send strings for FTP PORT * command */ char servReply[SERV_REPLY_LENGTH]; char portMessage[PORT_MESSAGE_LENGTH]; char hostName[HOST_NAME_LENGTH]; char *port, *host; /* for use in PORT */ int error; int newSocket; /* new data socket */ int addrLen = sizeof(theAddr); /* if using port command or default method with no listen, prepare * a new data connection
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -