From 85e24a32379f2345ecb95f8420fb4c3f2ff51741 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 2 Apr 1999 14:39:19 +0000 Subject: Patch from Emmanuel Rauget (raguet@crf.canon.fr) to add a htons on the sin_port. --- cpukit/ftpd/ftpd.c | 425 +++++++++++++++++++++++++++-------------------------- cpukit/ftpd/ftpd.h | 20 ++- 2 files changed, 233 insertions(+), 212 deletions(-) (limited to 'cpukit/ftpd') diff --git a/cpukit/ftpd/ftpd.c b/cpukit/ftpd/ftpd.c index 121a5b7762..25b1f3c4e4 100644 --- a/cpukit/ftpd/ftpd.c +++ b/cpukit/ftpd/ftpd.c @@ -1,39 +1,26 @@ -/* - * FTP Server Daemon +/* FIXME: 1. Parse command is a hack. We can do better. + * 2. chdir is a hack. We can do better. + * 3. PWD doesn't work. + * 4. Some sort of access control? + * + * FTP Server Daemon * * Submitted by: Jake Janovetz * * $Id$ */ -/* - * Current state: - * To untar, put as "untar" - * CWD uses chdir - * This is bad due to global setting of chdir. - * - * Stored files come into RAM and are saved later. This is an artifact - * of a previous implementation (no filesystem -- had to do stuff with - * the "files" later). This can be eliminated once all of Jake's stuff - * is moved to devices/filesystems. - * - * CLOSE(S) doesn't seem to work. This causes problems in - * several areas. It lets too many file descriptors pile up - * and it doesn't seem to flush the stream. - * - * Is 'recv' what I want to use to get commands from the control port? - * - */ - /************************************************************************** * ftpd.c * ************************************************************************** * Description: * * * * This file contains the daemon which services requests that appear * - * on the 'FTP' port. This server is compatible with FTP, but it * - * also provides services specific to the Erithacus system. * - * This server is started at boot-time and runs forever. * + * on the FTP port. This server is compatible with FTP, but it * + * also provides 'hooks' to make it usable in situations where files * + * are not used/necessary. Once the server is started, it runs * + * forever. * + * * * * * Organization: * * * @@ -44,12 +31,6 @@ * is complete, the session task deletes itself. The daemon still * * runs, however. * * * - * Implementation Notes: * - * * - * The 'current working directory' implementation utilizes the * - * RTEMS filesystem cwd. This is no good since other processes * - * inherit the same cwd. * - * * * * * Supported commands are: * * * @@ -70,51 +51,34 @@ * and port (x*256 + y). * * * * * - * * * The public routines contained in this file are: * * * - * FTPD_Start - Starts the server daemon, then returns to its caller. * + * rtems_initialize_ftpd_start - Starts the server daemon, then * + * returns to its caller. * * * * * * The private routines contained in this file are: * * * - * FTPD_SendReply - Sends a reply code and text through the control * - * port. * - * FTPD_CommandStore - Performs the "STOR" command. * - * FTPD_CommandList - Performs the "LIST" command. * - * FTPD_CommandPort - Opens a data port (the "PORT" command). * - * FTPD_ParseCommand - Parses an incoming command. * - * FTPD_Session - Begins a service session. * - * FTPD_Daemon - Listens on the FTP port for service requests. * - * * - * * + * rtems_ftpd_send_reply - Sends a reply code and text through the * + * control port. * + * rtems_ftpd_command_retrieve - Performs to "RETR" command. * + * rtems_ftpd_command_store - Performs the "STOR" command. * + * rtems_ftpd_command_list - Performs the "LIST" command. * + * rtems_ftpd_command_port - Opens a data port (the "PORT" command). * + * rtems_ftpd_parse_command - Parses an incoming command. * + * rtmes_ftpd_session - Begins a service session. * + * rtems_ftpd_daemon - Listens on the FTP port for service * + * requests. * *------------------------------------------------------------------------* - * * * Jake Janovetz * * University of Illinois * * 1406 West Green Street * * Urbana IL 61801 * - * * ************************************************************************** * Change History: * * 12/01/97 - Creation (JWJ) * *************************************************************************/ -/* Revision Control Information: - * - * $Source$ - * $Id$ - * $Log$ - * Revision 1.3 1998/05/19 21:28:17 erithacus - * Update control socket to file I/O. - * - * Revision 1.2 1998/05/19 20:13:50 erithacus - * Remodeled to be entirely reentrant. - * - * - */ - - #include #include #include @@ -133,9 +97,10 @@ #include #include "ftpd.h" -#include "untar.h" +extern struct rtems_ftpd_configuration rtems_ftpd_configuration; + /************************************************************************** * Meanings of first and second digits of reply codes: * @@ -163,14 +128,6 @@ *************************************************************************/ -/************************************************************************** - * Maximum buffer size for use by the transfer protocol. - * This will be eliminated when the filesystem is complete enough that - * we don't have to store the received data until we have something to - * do with it. - *************************************************************************/ -#define FTPD_MAX_RECEIVESIZE (512*1024) - /************************************************************************** * SessionInfo structure. * @@ -180,13 +137,14 @@ typedef struct { struct sockaddr_in data_addr; /* Data address for PORT commands */ - int ctrl_sock; /* Control connection socker */ + FILE *ctrl_fp; /* File pointer for control connection */ char cwd[255]; /* Current working directory */ /* Login -- future use -- */ int xfer_mode; /* Transfer mode (ASCII/binary) */ } FTPD_SessionInfo_t; +#define FTPD_SERVER_MESSAGE "RTEMS FTP server (Version 1.0-JWJ) ready." #define FTPD_WELCOME_MESSAGE \ "Welcome to the RTEMS FTP server.\n" \ "\n" \ @@ -194,7 +152,7 @@ typedef struct /************************************************************************** - * Function: FTPD_SendReply * + * Function: rtems_ftpd_send_reply * ************************************************************************** * Description: * * * @@ -216,7 +174,7 @@ typedef struct * 12/01/97 - Creation (JWJ) * *************************************************************************/ static void -FTPD_SendReply(int code, char *text) +rtems_ftpd_send_reply(int code, char *text) { rtems_status_code sc; FTPD_SessionInfo_t *info = NULL; @@ -241,17 +199,19 @@ FTPD_SendReply(int code, char *text) if (text != NULL) { sprintf(str, "%d %.70s\r\n", code, text); + fprintf(info->ctrl_fp, "%d %.70s\r\n", code, text); } else { sprintf(str, "%d\r\n", code); + fprintf(info->ctrl_fp, "%d\r\n", code); } - send(info->ctrl_sock, str, strlen(str), 0); + fflush(info->ctrl_fp); } /************************************************************************** - * Function: FTPD_CommandRetrieve * + * Function: rtems_ftpd_command_retrieve * ************************************************************************** * Description: * * * @@ -274,12 +234,11 @@ FTPD_SendReply(int code, char *text) * 04/29/98 - Creation (JWJ) * *************************************************************************/ static int -FTPD_CommandRetrieve(char *filename) +rtems_ftpd_command_retrieve(char *filename) { int s; int n; - - FILE *fp; + int fd; unsigned char *bufr; rtems_status_code sc; FTPD_SessionInfo_t *info = NULL; @@ -288,32 +247,31 @@ FTPD_CommandRetrieve(char *filename) sc = rtems_task_get_note(RTEMS_SELF, RTEMS_NOTEPAD_0, (rtems_unsigned32 *)&info); - - if ((fp = fopen(filename, "r")) == NULL) + if ((fd = open(filename, O_RDONLY)) == -1) { - FTPD_SendReply(450, "Error opening file."); + rtems_ftpd_send_reply(450, "Error opening file."); return(0); } bufr = (unsigned char *)malloc(BUFSIZ); if (bufr == NULL) { - FTPD_SendReply(440, "Server error - malloc fail."); - fclose(fp); + rtems_ftpd_send_reply(440, "Server error - malloc fail."); + close(fd); return(0); } /*********************************************************************** * Connect to the data connection (PORT made in an earlier PORT call). **********************************************************************/ - FTPD_SendReply(150, "BINARY data connection."); + rtems_ftpd_send_reply(150, "BINARY data connection."); s = socket(AF_INET, SOCK_STREAM, 0); if (connect(s, (struct sockaddr *)&info->data_addr, sizeof(struct sockaddr)) < 0) { - FTPD_SendReply(420, "Server error - could not connect socket."); + rtems_ftpd_send_reply(420, "Server error - could not connect socket."); free(bufr); - fclose(fp); + close(fd); close(s); return(1); } @@ -321,18 +279,19 @@ FTPD_CommandRetrieve(char *filename) /*********************************************************************** * Send the data over the ether. **********************************************************************/ - while ((n = fread(bufr, 1, BUFSIZ, fp)) != 0) + while ((n = read(fd, bufr, BUFSIZ)) > 0) { send(s, bufr, n, 0); + bufr[n-1] = '\0'; } - if (feof(fp)) + if (n == 0) { - FTPD_SendReply(210, "File sent successfully."); + rtems_ftpd_send_reply(210, "File sent successfully."); } else { - FTPD_SendReply(450, "Retrieve failed."); + rtems_ftpd_send_reply(450, "Retrieve failed."); } if (close(s) != 0) @@ -341,13 +300,13 @@ FTPD_CommandRetrieve(char *filename) } free(bufr); - fclose(fp); + close(fd); return(0); } /************************************************************************** - * Function: FTPD_CommandStore * + * Function: rtems_ftpd_command_store * ************************************************************************** * Description: * * * @@ -370,15 +329,15 @@ FTPD_CommandRetrieve(char *filename) * 12/01/97 - Creation (JWJ) * *************************************************************************/ static int -FTPD_CommandStore(char *filename) +rtems_ftpd_command_store(char *filename) { - char *bufr; - char *bigBufr; - int s; - int n; - unsigned long size = 0; - rtems_status_code sc; - FTPD_SessionInfo_t *info = NULL; + char *bufr; + int s; + int n; + unsigned long size = 0; + rtems_status_code sc; + FTPD_SessionInfo_t *info = NULL; + struct rtems_ftpd_hook *usehook = NULL; sc = rtems_task_get_note(RTEMS_SELF, RTEMS_NOTEPAD_0, @@ -387,26 +346,17 @@ FTPD_CommandStore(char *filename) bufr = (char *)malloc(BUFSIZ * sizeof(char)); if (bufr == NULL) { - FTPD_SendReply(440, "Server error - malloc fail."); - return(1); - } - - bigBufr = (char *)malloc(FTPD_MAX_RECEIVESIZE * sizeof(char)); - if (bigBufr == NULL) - { - FTPD_SendReply(440, "Server error - malloc fail."); - free(bufr); + rtems_ftpd_send_reply(440, "Server error - malloc fail."); return(1); } - FTPD_SendReply(150, "BINARY data connection."); + rtems_ftpd_send_reply(150, "BINARY data connection."); s = socket(AF_INET, SOCK_STREAM, 0); if (connect(s, (struct sockaddr *)&info->data_addr, sizeof(struct sockaddr)) < 0) { free(bufr); - free(bigBufr); close(s); return(1); } @@ -414,22 +364,57 @@ FTPD_CommandStore(char *filename) /*********************************************************************** * File: "/dev/null" just throws the data away. + * Otherwise, search our list of hooks to see if we need to do something + * special. **********************************************************************/ if (!strncmp("/dev/null", filename, 9)) { while ((n = read(s, bufr, BUFSIZ)) > 0); } - else + else if (rtems_ftpd_configuration.hooks != NULL) { + struct rtems_ftpd_hook *hook; + int i; + + i = 0; + hook = &rtems_ftpd_configuration.hooks[i++]; + while (hook->filename != NULL) + { + if (!strcmp(hook->filename, filename)) + { + usehook = hook; + break; + } + hook = &rtems_ftpd_configuration.hooks[i++]; + } + } + + if (usehook != NULL) + { + char *bigBufr; + + /*********************************************************************** + * Allocate space for our "file". + **********************************************************************/ + bigBufr = (char *)malloc( + rtems_ftpd_configuration.max_hook_filesize * sizeof(char)); + if (bigBufr == NULL) + { + rtems_ftpd_send_reply(440, "Server error - malloc fail."); + free(bufr); + return(1); + } + /*********************************************************************** * Retrieve the file into our buffer space. **********************************************************************/ size = 0; while ((n = read(s, bufr, BUFSIZ)) > 0) { - if (size + n > FTPD_MAX_RECEIVESIZE) + if (size + n > + rtems_ftpd_configuration.max_hook_filesize * sizeof(char)) { - FTPD_SendReply(440, "Server error - Buffer size exceeded."); + rtems_ftpd_send_reply(440, "Server error - Buffer size exceeded."); free(bufr); free(bigBufr); close(s); @@ -438,66 +423,60 @@ FTPD_CommandStore(char *filename) memcpy(&bigBufr[size], bufr, n); size += n; } - } - free(bufr); - close(s); - + close(s); - /*********************************************************************** - * Figure out what to do with the data we just received. - **********************************************************************/ - if (!strncmp("untar", filename, 5)) - { - Untar_FromMemory(bigBufr, size); - FTPD_SendReply(210, "Untar successful."); + /*********************************************************************** + * Call our hook. + **********************************************************************/ + if ((usehook->hook_function)(bigBufr, size) == 0) + { + rtems_ftpd_send_reply(210, "File transferred successfully."); + } + else + { + rtems_ftpd_send_reply(440, "File transfer failed."); + } + free(bigBufr); } else { - FILE *fp; - size_t len; + int fd; size_t written; - fp = fopen(filename, "w"); - if (fp == NULL) + fd = creat(filename, S_IRUSR | S_IWUSR | + S_IRGRP | S_IWGRP | + S_IROTH | S_IWOTH); + if (fd == -1) { - FTPD_SendReply(440, "Could not open file."); - free(bigBufr); + rtems_ftpd_send_reply(450, "Could not open file."); + close(s); + free(bufr); return(1); } - - n = 0; - written = 0; - while (n 0) { - len = ((size-n>BUFSIZ)?(BUFSIZ):(size-n)); - written = fwrite(&bigBufr[n], 1, len, fp); - n += written; - if (written != len) + written = write(fd, bufr, n); + if (written == -1) { - break; + rtems_ftpd_send_reply(450, "Error during write."); + close(fd); + close(s); + free(bufr); + return(1); } } - fclose(fp); - - if (n == size) - { - FTPD_SendReply(226, "Transfer complete."); - } - else - { - FTPD_SendReply(440, "Error during write."); - free(bigBufr); - return(1); - } + close(fd); + close(s); + rtems_ftpd_send_reply(226, "Transfer complete."); } - free(bigBufr); + free(bufr); return(0); } /************************************************************************** - * Function: FTPD_CommandList * + * Function: rtems_ftpd_command_list * ************************************************************************** * Description: * * * @@ -518,7 +497,7 @@ FTPD_CommandStore(char *filename) * 12/01/97 - Creation (JWJ) * *************************************************************************/ static void -FTPD_CommandList(char *fname) +rtems_ftpd_command_list(char *fname) { int s; rtems_status_code sc; @@ -532,7 +511,7 @@ FTPD_CommandList(char *fname) sc = rtems_task_get_note(RTEMS_SELF, RTEMS_NOTEPAD_0, (rtems_unsigned32 *)&info); - FTPD_SendReply(150, "ASCII data connection for LIST."); + rtems_ftpd_send_reply(150, "ASCII data connection for LIST."); s = socket(AF_INET, SOCK_STREAM, 0); if (connect(s, (struct sockaddr *)&info->data_addr, @@ -548,7 +527,7 @@ FTPD_CommandList(char *fname) fname, (info->xfer_mode==TYPE_A)?("\r"):("")); send(s, dirline, strlen(dirline), 0); close(s); - FTPD_SendReply(226, "Transfer complete."); + rtems_ftpd_send_reply(226, "Transfer complete."); return; } while ((dp = readdir(dirp)) != NULL) @@ -578,7 +557,7 @@ FTPD_CommandList(char *fname) closedir(dirp); close(s); - FTPD_SendReply(226, "Transfer complete."); + rtems_ftpd_send_reply(226, "Transfer complete."); } @@ -586,7 +565,7 @@ FTPD_CommandList(char *fname) * Cheesy way to change directories */ static void -FTPD_CWD(char *dir) +rtems_ftpd_CWD(char *dir) { rtems_status_code sc; FTPD_SessionInfo_t *info = NULL; @@ -597,17 +576,17 @@ FTPD_CWD(char *dir) if (chdir(dir) == 0) { - FTPD_SendReply(250, "CWD command successful."); + rtems_ftpd_send_reply(250, "CWD command successful."); } else { - FTPD_SendReply(550, "CWD command failed."); + rtems_ftpd_send_reply(550, "CWD command failed."); } } /************************************************************************** - * Function: FTPD_CommandPort * + * Function: rtems_ftpd_command_port * ************************************************************************** * Description: * * * @@ -630,7 +609,7 @@ FTPD_CWD(char *dir) * 12/01/97 - Creation (JWJ) * *************************************************************************/ static void -FTPD_CommandPort(char *bufr) +rtems_ftpd_command_port(char *bufr) { char *ip; char *port; @@ -656,13 +635,15 @@ FTPD_CommandPort(char *bufr) /************************************************************************** - * Function: FTPD_ParseCommand * + * Function: rtems_ftpd_parse_command * ************************************************************************** * Description: * * * * Here, we parse the commands that have come through the control * * connection. * * * + * FIXME: This section is somewhat of a hack. We should have a better * + * way to parse commands. * * * * Inputs: * * * @@ -678,7 +659,7 @@ FTPD_CommandPort(char *bufr) * 12/01/97 - Creation (JWJ) * *************************************************************************/ static void -FTPD_ParseCommand(char *bufr) +rtems_ftpd_parse_command(char *bufr) { char fname[255]; rtems_status_code sc; @@ -690,71 +671,71 @@ FTPD_ParseCommand(char *bufr) if (!strncmp("PORT", bufr, 4)) { - FTPD_SendReply(200, "PORT command successful."); - FTPD_CommandPort(&bufr[5]); + rtems_ftpd_send_reply(200, "PORT command successful."); + rtems_ftpd_command_port(&bufr[5]); } else if (!strncmp("RETR", bufr, 4)) { sscanf(&bufr[5], "%254s", fname); - FTPD_CommandRetrieve(fname); + rtems_ftpd_command_retrieve(fname); } else if (!strncmp("STOR", bufr, 4)) { sscanf(&bufr[5], "%254s", fname); - FTPD_CommandStore(fname); + rtems_ftpd_command_store(fname); } else if (!strncmp("LIST", bufr, 4)) { if (bufr[5] == '\n') { - FTPD_CommandList("."); + rtems_ftpd_command_list("."); } else { sscanf(&bufr[5], "%254s", fname); - FTPD_CommandList(fname); + rtems_ftpd_command_list(fname); } } else if (!strncmp("USER", bufr, 4)) { - FTPD_SendReply(230, "User logged in."); + rtems_ftpd_send_reply(230, "User logged in."); } else if (!strncmp("SYST", bufr, 4)) { - FTPD_SendReply(240, "RTEMS"); + rtems_ftpd_send_reply(240, "RTEMS"); } else if (!strncmp("TYPE", bufr, 4)) { if (bufr[5] == 'I') { info->xfer_mode = TYPE_I; - FTPD_SendReply(200, "Type set to I."); + rtems_ftpd_send_reply(200, "Type set to I."); } else if (bufr[5] == 'A') { info->xfer_mode = TYPE_A; - FTPD_SendReply(200, "Type set to A."); + rtems_ftpd_send_reply(200, "Type set to A."); } else { info->xfer_mode = TYPE_I; - FTPD_SendReply(504, "Type not implemented. Set to I."); + rtems_ftpd_send_reply(504, "Type not implemented. Set to I."); } } else if (!strncmp("PASS", bufr, 4)) { - FTPD_SendReply(230, "User logged in."); + rtems_ftpd_send_reply(230, "User logged in."); } else if (!strncmp("DELE", bufr, 4)) { sscanf(&bufr[4], "%254s", fname); if (unlink(fname) == 0) { - FTPD_SendReply(257, "DELE successful."); + rtems_ftpd_send_reply(257, "DELE successful."); } else { - FTPD_SendReply(550, "DELE failed."); + rtems_ftpd_send_reply(550, "DELE failed."); } } else if (!strncmp("SITE CHMOD", bufr, 10)) @@ -764,11 +745,11 @@ FTPD_ParseCommand(char *bufr) sscanf(&bufr[11], "%o %254s", &mask, fname); if (chmod(fname, (mode_t)mask) == 0) { - FTPD_SendReply(257, "CHMOD successful."); + rtems_ftpd_send_reply(257, "CHMOD successful."); } else { - FTPD_SendReply(550, "CHMOD failed."); + rtems_ftpd_send_reply(550, "CHMOD failed."); } } else if (!strncmp("RMD", bufr, 3)) @@ -776,11 +757,11 @@ FTPD_ParseCommand(char *bufr) sscanf(&bufr[4], "%254s", fname); if (rmdir(fname) == 0) { - FTPD_SendReply(257, "RMD successful."); + rtems_ftpd_send_reply(257, "RMD successful."); } else { - FTPD_SendReply(550, "RMD failed."); + rtems_ftpd_send_reply(550, "RMD failed."); } } else if (!strncmp("MKD", bufr, 3)) @@ -788,33 +769,34 @@ FTPD_ParseCommand(char *bufr) sscanf(&bufr[4], "%254s", fname); if (mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO) == 0) { - FTPD_SendReply(257, "MKD successful."); + rtems_ftpd_send_reply(257, "MKD successful."); } else { - FTPD_SendReply(550, "MKD failed."); + rtems_ftpd_send_reply(550, "MKD failed."); } } else if (!strncmp("CWD", bufr, 3)) { sscanf(&bufr[4], "%254s", fname); - FTPD_CWD(fname); + rtems_ftpd_CWD(fname); } else if (!strncmp("PWD", bufr, 3)) { char *cwd = getcwd(0, 0); sprintf(bufr, "\"%s\" is the current directory.", cwd); - FTPD_SendReply(250, bufr); + rtems_ftpd_send_reply(250, bufr); free(cwd); } else { - FTPD_SendReply(500, "Unrecognized/unsupported command."); + rtems_ftpd_send_reply(500, "Unrecognized/unsupported command."); } } + /************************************************************************** - * Function: FTPD_Session * + * Function: rtems_ftpd_session * ************************************************************************** * Description: * * * @@ -827,7 +809,7 @@ FTPD_ParseCommand(char *bufr) * * * Inputs: * * * - * rtems_task_argument arg - The FTPD_Daemon task passes the socket * + * rtems_task_argument arg - The daemon task passes the socket * * which serves as the control connection. * * * * Output: * @@ -839,7 +821,7 @@ FTPD_ParseCommand(char *bufr) * 12/01/97 - Creation (JWJ) * *************************************************************************/ static void -FTPD_Session(rtems_task_argument arg) +rtems_ftpd_session(rtems_task_argument arg) { char cmd[256]; rtems_status_code sc; @@ -849,7 +831,7 @@ FTPD_Session(rtems_task_argument arg) sc = rtems_task_get_note(RTEMS_SELF, RTEMS_NOTEPAD_0, (rtems_unsigned32 *)&info); - FTPD_SendReply(220, "Erithacus FTP server (Version 1.0) ready."); + rtems_ftpd_send_reply(220, FTPD_SERVER_MESSAGE); /*********************************************************************** * Set initial directory to "/". @@ -858,7 +840,7 @@ FTPD_Session(rtems_task_argument arg) info->xfer_mode = TYPE_A; while (1) { - if (recv(info->ctrl_sock, cmd, 256, 0) == -1) + if (fgets(cmd, 256, info->ctrl_fp) == NULL) { syslog(LOG_INFO, "ftpd: Connection aborted."); break; @@ -866,16 +848,16 @@ FTPD_Session(rtems_task_argument arg) if (!strncmp("QUIT", cmd, 4)) { - FTPD_SendReply(221, "Goodbye."); + rtems_ftpd_send_reply(221, "Goodbye."); break; } else { - FTPD_ParseCommand(cmd); + rtems_ftpd_parse_command(cmd); } } - if (close(info->ctrl_sock) < 0) + if (fclose(info->ctrl_fp) != 0) { syslog(LOG_ERR, "ftpd: Could not close session."); } @@ -895,7 +877,7 @@ FTPD_Session(rtems_task_argument arg) /************************************************************************** - * Function: FTPD_Daemon * + * Function: rtems_ftpd_daemon * ************************************************************************** * Description: * * * @@ -918,7 +900,7 @@ FTPD_Session(rtems_task_argument arg) * 12/01/97 - Creation (JWJ) * *************************************************************************/ static void -FTPD_Daemon() +rtems_ftpd_daemon() { int s; int s1; @@ -941,7 +923,7 @@ FTPD_Daemon() } localAddr.sin_family = AF_INET; - localAddr.sin_port = FTPD_CONTROL_PORT; + localAddr.sin_port = htons(rtems_ftpd_configuration.port); localAddr.sin_addr.s_addr = INADDR_ANY; memset(localAddr.sin_zero, '\0', sizeof(localAddr.sin_zero)); if (bind(s, (struct sockaddr *)&localAddr, @@ -1002,21 +984,28 @@ FTPD_Daemon() /******************************************************************** * Send the socket on to the new session. *******************************************************************/ - info->ctrl_sock = s1; - sc = rtems_task_set_note(tid, RTEMS_NOTEPAD_0, - (rtems_unsigned32)info); - sc = rtems_task_start(tid, FTPD_Session, 0); - if (sc != RTEMS_SUCCESSFUL) + if ((info->ctrl_fp = fdopen(s1, "r+")) == NULL) { - syslog(LOG_ERR, "ftpd: Could not start FTPD session: %s", - rtems_status_text(sc)); + syslog(LOG_ERR, "ftpd: fdopen() on socket failed."); + close(s1); + } + else + { + sc = rtems_task_set_note(tid, RTEMS_NOTEPAD_0, + (rtems_unsigned32)info); + sc = rtems_task_start(tid, rtems_ftpd_session, 0); + if (sc != RTEMS_SUCCESSFUL) + { + syslog(LOG_ERR, "ftpd: Could not start FTPD session: %s", + rtems_status_text(sc)); + } } } } /************************************************************************** - * Function: FTPD_Start * + * Function: rtems_ftpd_start * ************************************************************************** * Description: * * * @@ -1031,21 +1020,33 @@ FTPD_Daemon() * * * Output: * * * - * none * + * int - RTEMS_SUCCESSFUL on successful start of the daemon. * * * ************************************************************************** * Change History: * * 12/01/97 - Creation (JWJ) * *************************************************************************/ -void -FTPD_Start(rtems_task_priority priority) +int +rtems_initialize_ftpd() { rtems_status_code sc; rtems_id tid; + if (rtems_ftpd_configuration.port == 0) + { + rtems_ftpd_configuration.port = FTPD_CONTROL_PORT; + } + + /*********************************************************************** + * Default FTPD priority. + **********************************************************************/ + if (rtems_ftpd_configuration.priority == 0) + { + rtems_ftpd_configuration.priority = 40; + } sc = rtems_task_create(rtems_build_name('F', 'T', 'P', 'D'), - priority, 8*1024, + rtems_ftpd_configuration.priority, 8*1024, RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_NO_ASR | RTEMS_INTERRUPT_LEVEL(0), RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL, @@ -1054,14 +1055,18 @@ FTPD_Start(rtems_task_priority priority) { syslog(LOG_ERR, "ftpd: Could not create FTP daemon: %s", rtems_status_text(sc)); + return(RTEMS_UNSATISFIED); } - sc = rtems_task_start(tid, FTPD_Daemon, 0); + sc = rtems_task_start(tid, rtems_ftpd_daemon, 0); if (sc != RTEMS_SUCCESSFUL) { syslog(LOG_ERR, "ftpd: Could not start FTP daemon: %s", rtems_status_text(sc)); + return(RTEMS_UNSATISFIED); } syslog(LOG_INFO, "ftpd: FTP daemon started."); + return(RTEMS_SUCCESSFUL); } + diff --git a/cpukit/ftpd/ftpd.h b/cpukit/ftpd/ftpd.h index 56bae5a043..6daaaf4d51 100644 --- a/cpukit/ftpd/ftpd.h +++ b/cpukit/ftpd/ftpd.h @@ -10,17 +10,33 @@ #define FTPD_CONTROL_PORT 21 +typedef int (*rtems_ftpd_hookfunction)(unsigned char *, unsigned long); + +struct rtems_ftpd_hook +{ + char *filename; + rtems_ftpd_hookfunction hook_function; +}; + +struct rtems_ftpd_configuration +{ + rtems_task_priority priority; /* FTPD task priority */ + unsigned long max_hook_filesize; /* Maximum buffersize */ + /* for hooks */ + int port; /* Well-known port */ + struct rtems_ftpd_hook *hooks; /* List of hooks */ +}; + /* * Reply codes. */ - #define PRELIM 1 /* positive preliminary */ #define COMPLETE 2 /* positive completion */ #define CONTINUE 3 /* positive intermediate */ #define TRANSIENT 4 /* transient negative completion */ #define ERROR 5 /* permanent negative completion */ -void rtems_ftpd_sTart(rtems_task_priority priority); +int rtems_initialize_ftpd(); #endif /* __FTPD_H__ */ -- cgit v1.2.3