📄 ftpdlib.c
字号:
/* ftpdLib.c - File Transfer Protocol (FTP) server *//* Copyright 1990 - 1998 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------03d,03dec98,lrn added default home dir control (SPR#23554) removed dependency on usrLib (SPR#23536)03c,29sep98,lrn creqated DosFs 2.0 branch for T2.0, verified fix for SPR#2082803b,14jul98,lrn SPR#6647: adding notes on text file to description03a,25may98,lrn anonymous access with root dir and upload dir connection timeout, default mode Binary enhance transfer rate: bufSize now same as winSize mget "*" support with wildcards, rework directory travel standardized directory listing to work with GUI clients simplified error handling in main loop, to make code smaller fixed: ASCII transfer of binary files breaks connection02n,17may98,lrn merged previous additions with SENS source added support for delete, rename, mkdir and rmdir, added non-standard service port02m,05dec97,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. XCWD | - Change working directory. CDUP | - Change to parent directory. XCUP | - Change to parent directory. TYPE | - Change the data representation type. PORT | - Change the port number. PWD | - Get the name of current working directory. XPWD | - 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 MKD | - Make a directory XMKD | - Make a directory RMD | - Remove a directory XRMD | - Remove a directory RNFR | - File to rename RNTO | - a new name for a file that is being renamed SIZE | - get file size in bytes MDTM | - get file modification date and time SYST | - report type of operating system.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.This FTP server optionally offers client login via loginLib, or anyother custom user and password verification mechanism, which isintroduced to the FTP server by calling ftpdLoginInstall(). Also,"anonymous" guest access may be optionally enabled withftpdAnonymousAllow(), which imposes certain access restrictions on theguest client, namely access may be restriced to a certain subdirectoryon the disk, and the access is restirected to read-only, except aspecified directory which is allowed for read-write access.Please note that if ftpdLoginInstall() is not called, the FTP server willaccept any client, which may potentially cause a security problem, hence ifthere is no user login mechanism used, then at least "anonymous" access shouldbe enabled, so at least some access restrictions can be imposed on the client,which can not be authenticated.Therefore, if anonymous access has been enabled but no other authenticationmechanism was installed with ftpdLoginInstall(), no other user then"anonymous" will be allowed to access the FTP service.NOTE ON TEXT FILESAlthough the dominant file system on VxWorksis MS-DOS compatible, this does not imply that Text Files on VxWorks aretreated as in MS-DOS.Essentially, VxWorks does not treat Text Files in any special way, all filestext or binary are treated in a transparrent manner by the I/O and stdiolibraries, resulting in handling of Text Files similar to UNIX.Therefore, the FTP server will treat ASCII-mode file transfers in the same wayas on UNIX, whence the text lines are delimited with the Line Feed characteronly. Transferring a Text File from an MS-DOS or Windows system to VxWorkswill thus result in all CR-LF sequences converted to LF only.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.CEKnown Problems:Work task name are not guaranteed to be unique.All file sizes are done in 32-bit, hence 3 GB max file size limitation.Should log every anonymous access to logMsg or log file.INCLUDE 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"#include "fioLib.h"#include "dosFsLib.h" /* for attributes definition *//* 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_ANONYMOUS 0x2000#define FTPD_PASSIVE 0x10000/* Macros to obtain correct parts of the status code */#define FTPD_REPRESENTATION(slot) ( (slot)->status & 0xff)#ifdef _unused_#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)#endif/* 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#define FTPD_CONN_TIMEOUT 200/* 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#define FTPD_ANONYMOUS_USER_1 "anonymous"#define FTPD_ANONYMOUS_USER_2 "ftp"#define FTPD_ANONYMOUS_USER_3 "guest"/* globals */int ftpdDebug = FALSE; /* TRUE: debugging messages */int ftpdTaskPriority = 56;int ftpdTaskOptions = VX_SUPERVISOR_MODE | VX_UNBREAKABLE;int ftpdWorkTaskPriority = 152;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;/* 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 */ caddr_t buf; /* multi-purpose buffer per session */ int bufSize; /* size of the above buffer */ time_t timeUsed; /* last time session was active */ char curDirName /* active directory */ [MAX_FILENAME_LENGTH+1]; char curUserName /* current user */ [MAX_LOGIN_NAME_LEN+1]; } 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;LOCAL FUNCPTR pLoginVrfyFunc = NULL ;LOCAL char defaultHomeDir /* default root directory */ [MAX_FILENAME_LENGTH+1] = {0};LOCAL char guestHomeDir /* anonymous root directory */ [MAX_FILENAME_LENGTH+1] = {0};LOCAL char writeDirName /* anonymous upload directory */ [MAX_FILENAME_LENGTH+1] = {0};/* Various messages to be told to the clients */LOCAL const char *messages [] = { "Can't open passive connection", "Parameter not accepted", "Data connection error", "Directory non existent or syntax error", "Local resource failure: %s", "VxWorks FTP server (VxWorks %s) 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.", "File exists, ready for destination name.", "File renamed successfuly.", "\"%s\" directory created", "Directory %s removed", "%s: not a plain file", "UNIX Type: L8 Version: VxWorks",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -