📄 ftpdlib.c
字号:
/* ftpdLib.c - File Transfer Protocol (FTP) server *//* Copyright 1990 - 1999 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02r,13oct00,cn fixed memory leak (SPR# 25954).02q,16mar99,spm recovered orphaned code from tor2_0_x branch (SPR #25770)02p,01dec98,spm changed reply code for successful DELE command (SPR #20554)02o,27mar98,spm corrected byte-ordering problem in PASV command (SPR #20828)02n,27mar98,spm merged from recovered version 02m of tor1_0_x branch02m,10dec97,spm upgraded server shutdown routine to terminate active sessions (SPR #9906); corrected response for PASV command to include valid IP address (SPR #1318); modified syntax of PASV command (SPR #5627); corrected handling of PORT command to support multiple interfaces (SPR #3500); added support for maximum number of connections (SPR #2032); applied changes for configurable password authentication from SENS branch (SPR #8602); removed incorrect note from man page concerning user/password verification, which was actually performed (SPR #7672); general cleanup (reorganized code, added FTP responses for error conditions, replaced "static" with LOCAL keyword in function declarations)02l,09jul97,dgp doc: add note on UID and password per SPR 767202k,06feb97,jdi made drawing internal.02j,30sep96,spm partial fix for spr #7227. Added support for deleting files and using relative pathnames when listing directories.02i,05aug96,sgv fix for spr #3583 and spr #5920. Provide login security for VxWorks login02h,21may96,sgv Added global variable ftpdWindowSize which can be set by the user. the server would set the window size after the connection is established.02g,29mar95,kdl changed ftpdDirListGet() to use ANSI time format in stat.02f,11feb95,jdi doc format tweak.02e,20aug93,jag Fixed memory leak by calling fclose (SPR #2194) Changed ftpdWorkTask Command Read Logic, Added error checking on write calls to the network and file operations. Added case-conversion changes (SPR #2035)02d,20aug93,jmm Changed ioctl.h and socket.h to sys/ioctl.h and sys/socket.h02c,27feb93,kdl Removed 01z case-conversion changes (SPR #2035).02b,05feb93,jag Changed call to inet_ntoa to inet_ntoa_b. SPR# 181402a,20jan93,jdi documentation cleanup for 5.1.01z,09sep92,jmm fixed spr 1568, ftpd now recognizes lower case commands changed errnoGet() to errno to get rid of warning message01y,19aug92,smb Changed systime.h to sys/times.h.01x,16jun92,kdl increased slot buffer to hold null terminator; use calloc() to allocate slot struct (SPR #1509).01w,26may92,rrr the tree shuffle -changed includes to have absolute path from h/01v,08apr92,jmm cleaned up some ansi warnings01u,18dec91,rrr removed a recursive macro (killed the mips compiler)01t,10dec91,gae ANSI cleanup. Changed ftpdSlotSem to an Id so that internal routine semTerminate() not used.01s,19nov91,rrr shut up some ansi warnings.01r,14nov91,rrr shut up some warnings01q,12nov91,wmd fixed bug in ftpdDataStreamSend() and ftpdDataStreamReceive(), EOF is cast to type char to prevent endless looping.01p,04oct91,rrr passed through the ansification filter -changed functions to ansi style -changed includes to have absolute path from h/ -changed VOID to void -changed copyright notice01o,10jul91,gae i960 fixes: non-varargs usage, added ntohs(). added HELP command, changed listing to support NFS/DOS not old style.01n,30apr91,jdi documentation tweaks.01m,05apr91,jdi documentation -- removed header parens and x-ref numbers; doc review by dnw.01l,12feb91,jaa documentation.01k,08oct90,hjb included "inetLib.h".01j,05oct90,dnw made ftpdWorkTask() be LOCAL. documentation tweaks.01i,02oct90,hjb deleted "inet.h". added more doc to ftpdInit(). added a call to htons() where needed.01h,18sep90,kdl removed erroneous forward declaration of "ftpDataStreamRecv()".01g,10aug90,dnw added forward declaration of ftpdDataStreamReceive().01f,10aug90,kdl added forward declarations for functions returning void.01e,26jun90,jcf changed ftpd semaphore to static mutex.01d,07may90,hjb various bug fixes -- too numerous to mention.01c,17apr90,jcf changed ftpd work task name to tFtpd...01b,11apr90,hjb de-linted01a,01mar90,hjb written*//*DESCRIPTIONThis library implements the server side of the File Transfer Protocol (FTP),which provides remote access to the file systems available on a target.The protocol is defined in RFC 959. This implementation supports all commandsrequired by that specification, as well as several additional commands.USER INTERFACEDuring system startup, the ftpdInit() routine creates a control connectionat the predefined FTP server port which is monitored by the primary FTPtask. Each FTP session established is handled by a secondary server taskcreated as necessary. The server accepts the following commands:.TStab(|);l1 l. HELP | - List supported commands. USER | - Verify user name. PASS | - Verify password for the user. QUIT | - Quit the session. LIST | - List out contents of a directory. NLST | - List directory contents using a concise format. RETR | - Retrieve a file. STOR | - Store a file. CWD | - Change working directory. TYPE | - Change the data representation type. PORT | - Change the port number. PWD | - Get the name of current working directory. STRU | - Change file structure settings. MODE | - Change file transfer mode. ALLO | - Reserver sufficient storage. ACCT | - Identify the user's account. PASV | - Make the server listen on a port for data connection. NOOP | - Do nothing. DELE | - Delete a file.TEThe ftpdDelete() routine will disable the FTP server until restarted. It reclaims all system resources used by the server tasks and cleanly terminates all active sessions.INTERNALThe ftpdInit() routine spawns the primary server task ('ftpdTask') to handlemultiple FTP sessions. That task creates a separate task ('ftpdWorkTask') foreach active control connection.The diagram below defines the structure chart of ftpdLib..CS ftpdDelete ftpdInit | \ | | \ | | \ ftpdTask | \ / | \____________ | \ / | \ | | ftpdSessionAdd ftpdWorkTask ftpdSessionDelete | | ______________________/ | \ | | / / | | \ ftpdSlotDelete | ftpdDirListGet / ftpdDataStreamReceive | ftpdDataStreamSend | | / | \ | / / \ | __________/ | \ | / / \ | / | ftpdDataConnGet / \ | | | | ___________/ \ | | | | / ftpdSockFree ftpdDataCmdSend.CEINCLUDE FILES: ftpdLib.hSEE ALSO:ftpLib, netDrv, .I "RFC-959 File Transfer Protocol"*/#include "vxWorks.h"#include "ioLib.h"#include "taskLib.h"#include "lstLib.h"#include "stdio.h"#include "sys/socket.h"#include "netinet/in.h"#include "errno.h"#include "version.h"#include "string.h"#include "stdlib.h"#include "iosLib.h"#include "inetLib.h"#include "dirent.h"#include "sys/stat.h"#include "sys/times.h"#include "sockLib.h"#include "logLib.h"#include "unistd.h"#include "pathLib.h"#include "sysLib.h"#include "ftpdLib.h"#include "ctype.h"#include "time.h"#include "loginLib.h"/* Representation Type */#define FTPD_BINARY_TYPE 0x1#define FTPD_ASCII_TYPE 0x2#define FTPD_EBCDIC_TYPE 0x4#define FTPD_LOCAL_BYTE_TYPE 0x8/* Transfer mode */#define FTPD_STREAM_MODE 0x10#define FTPD_BLOCK_MODE 0x20#define FTPD_COMPRESSED_MODE 0x40/* File structure */#define FTPD_NO_RECORD_STRU 0x100#define FTPD_RECORD_STRU 0x200#define FTPD_PAGE_STRU 0x400/* Session Status */#define FTPD_USER_OK 0x1000#define FTPD_PASSIVE 0x2000/* Macros to obtain correct parts of the status code */#define FTPD_REPRESENTATION(slot) ( (slot)->status & 0xff)#define FTPD_TRANS_MODE(slot) (((slot)->status >> 8) & 0xff)#define FTPD_FILE_STRUCTURE(slot) (((slot)->status >> 16) & 0xff)#define FTPD_STATUS(slot) (((slot)->status >> 24) & 0xff)/* Well known port definitions -- someday we'll have getservbyname */#define FTP_DATA_PORT 20#define FTP_DAEMON_PORT 21/* Free socket indicative */#define FTPD_SOCK_FREE -1/* Arbitrary limits for the size of the FTPD work task name */#define FTPD_WORK_TASK_NAME_LEN 40/* Arbitrary limits hinted by Unix FTPD in waing for a new data connection */#define FTPD_WAIT_MAX 90#define FTPD_WAIT_INTERVAL 5/* Macro to get the byte out of an int */#define FTPD_UC(ch) (((int) (ch)) & 0xff)/* Bit set in FTP reply code to indicate multi-line reply. * Used internally by ftpdCmdSend() where codes are less than * 1024 but are 32-bit integers. [Admittedly a hack, see * ftpdCmdSend().] */#define FTPD_MULTI_LINE 0x10000000#define FTPD_WINDOW_SIZE 10240/* globals */int ftpdDebug = FALSE; /* TRUE: debugging messages */int ftpdTaskPriority = 56;int ftpdTaskOptions = VX_SUPERVISOR_MODE | VX_UNBREAKABLE;int ftpdWorkTaskPriority = 252;int ftpdWorkTaskOptions = VX_SUPERVISOR_MODE | VX_UNBREAKABLE; int ftpdWorkTaskStackSize = 12000;int ftpdWindowSize = FTPD_WINDOW_SIZE;int ftpsMaxClients = 4; /* Default max. for simultaneous connections */int ftpsCurrentClients;FUNCPTR loginVerifyRtn;/* locals */LOCAL BOOL ftpsActive = FALSE; /* Server started? */LOCAL BOOL ftpsShutdownFlag; /* Server halt requested? *//* * The FTP server keeps track of active client sessions in a linked list * of the following FTPD_SESSION_DATA data structures. That structure * contains all the variables which must be maintained separately * for each client so that the code shared by every secondary * task will function correctly. */typedef struct { NODE node; /* for link-listing */ int status; /* see various status bits above */ int byteCount; /* bytes transferred */ int cmdSock; /* command socket */ STATUS cmdSockError; /* Set to ERROR on write error */ int dataSock; /* data socket */ struct sockaddr_in peerAddr; /* address of control connection */ struct sockaddr_in dataAddr; /* address of data connection */ char buf [BUFSIZE]; /* multi-purpose buffer per session */ char curDirName [MAX_FILENAME_LENGTH]; /* active directory */ char user [MAX_LOGIN_NAME_LEN+1]; /* current user */ } FTPD_SESSION_DATA;LOCAL int ftpdTaskId = -1;LOCAL int ftpdServerSock = FTPD_SOCK_FREE;LOCAL LIST ftpsSessionList;LOCAL SEM_ID ftpsMutexSem;LOCAL SEM_ID ftpsSignalSem;LOCAL char ftpdWorkTaskName [FTPD_WORK_TASK_NAME_LEN];LOCAL int ftpdNumTasks;/* Various messages to be told to the clients */LOCAL char *messages [] = { "Can't open passive connection", "Parameter not accepted", "Data connection error", "Directory non existent or syntax error", "Local resource failure: %s", "VxWorks (%s) FTP server ready", "Password required", "User logged in", "Bye...see you later", "USER and PASS required", "No files found or invalid directory or permission problem", "Transfer complete", "File \"%s\" not found or permission problem", "Cannot create file \"%s\" or permission problem", "Changed directory to \"%s\"", "Type set to I, binary mode", "Type set to A, ASCII mode", "Port set okay", "Current directory is \"%s\"", "File structure set to NO RECORD", "Stream mode okay", "Allocate and Account not required", "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", "NOOP -- did nothing as requested...hah!", "Command not recognized", "Error in input file", "Unimplemented TYPE %d", "You could at least say goodbye.", "The following commands are recognized:", "End of command list.", "File deleted successfully.", "Login failed.", };/* Indexes to the messages [] array */#define MSG_PASSIVE_ERROR 0#define MSG_PARAM_BAD 1#define MSG_DATA_CONN_ERROR 2#define MSG_DIR_NOT_PRESENT 3#define MSG_LOCAL_RESOURCE_FAIL 4#define MSG_SERVER_READY 5#define MSG_PASSWORD_REQUIRED 6#define MSG_USER_LOGGED_IN 7#define MSG_SEE_YOU_LATER 8#define MSG_USER_PASS_REQ 9#define MSG_DIR_ERROR 10#define MSG_TRANS_COMPLETE 11#define MSG_FILE_ERROR 12#define MSG_CREATE_ERROR 13#define MSG_CHANGED_DIR 14#define MSG_TYPE_BINARY 15#define MSG_TYPE_ASCII 16#define MSG_PORT_SET 17#define MSG_CUR_DIR 18#define MSG_FILE_STRU 19#define MSG_STREAM_MODE 20#define MSG_ALLOC_ACCOUNT 21#define MSG_PASSIVE_MODE 22#define MSG_NOOP_OKAY 23#define MSG_BAD_COMMAND 24#define MSG_INPUT_FILE_ERROR 25#define MSG_TYPE_ERROR 26#define MSG_NO_GOOD_BYE 27#define MSG_COMMAND_LIST_BEGIN 28#define MSG_COMMAND_LIST_END 29#define MSG_DELE_OKAY 30#define MSG_USER_LOGIN_FAILED 31LOCAL char *ftpdCommandList ="HELP USER PASS QUIT LIST NLST\n\RETR STOR CWD TYPE PORT PWD\n\STRU MODE ALLO ACCT PASV NOOP\n\DELE\n";/* forward declarations */LOCAL FTPD_SESSION_DATA *ftpdSessionAdd (void);LOCAL void ftpdSessionDelete (FTPD_SESSION_DATA *);LOCAL STATUS ftpdWorkTask (FTPD_SESSION_DATA *);LOCAL STATUS ftpdCmdSend (FTPD_SESSION_DATA *, int, int, char *, int, int, int, int, int, int);LOCAL STATUS ftpdDataConnGet (FTPD_SESSION_DATA *);LOCAL void ftpdDataStreamSend (FTPD_SESSION_DATA *, FILE *);LOCAL void ftpdDataStreamReceive (FTPD_SESSION_DATA *, FILE *outStream);LOCAL void ftpdSockFree (int *);LOCAL STATUS ftpdDirListGet (int, char *, BOOL);LOCAL void ftpdDebugMsg (char *, int, int, int, int);LOCAL void unImplementedType (FTPD_SESSION_DATA *pSlot);LOCAL void dataError (FTPD_SESSION_DATA *pSlot);LOCAL void fileError (FTPD_SESSION_DATA *pSlot);LOCAL void transferOkay (FTPD_SESSION_DATA *pSlot);/********************************************************************************* ftpdTask - FTP server daemon task** This routine monitors the FTP control port for incoming requests from clients* and processes each request by spawning a secondary server task after * establishing the control connection. If the maximum number of connections is* reached, it returns the appropriate error to the requesting client. The * routine is the entry point for the primary FTP server task and should only* be called internally.** RETURNS: N/A** ERRNO: N/A** INTERNAL:* The server task is deleted by the server shutdown routine. Adding a newly* created client session to the list of active clients is performed atomically* with respect to the shutdown routine. However, accepting control connections* is not a critical section, since closing the initial socket used in the* listen() call also closes any later connections which are still open.** NOMANUAL*/LOCAL void ftpdTask (void) { int newSock; FAST FTPD_SESSION_DATA *pSlot; int on = 1; int addrLen; struct sockaddr_in addr; char a_ip_addr [INET_ADDR_LEN]; /* ascii ip address of client */ ftpdNumTasks = 0; /* The following loop halts if this task is deleted. */ FOREVER { /* Wait for a new incoming connection. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -