diff options
Diffstat (limited to 'c/src/lib/libnetworking/rtems_servers/ftpd.c')
-rw-r--r-- | c/src/lib/libnetworking/rtems_servers/ftpd.c | 1072 |
1 files changed, 0 insertions, 1072 deletions
diff --git a/c/src/lib/libnetworking/rtems_servers/ftpd.c b/c/src/lib/libnetworking/rtems_servers/ftpd.c deleted file mode 100644 index 25b1f3c4e4..0000000000 --- a/c/src/lib/libnetworking/rtems_servers/ftpd.c +++ /dev/null @@ -1,1072 +0,0 @@ -/* 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 <janovetz@tempest.ece.uiuc.edu> - * - * $Id$ - */ - -/************************************************************************** - * 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 'hooks' to make it usable in situations where files * - * are not used/necessary. Once the server is started, it runs * - * forever. * - * * - * * - * Organization: * - * * - * The FTP daemon is started upon boot. It runs all the time * - * and waits for connections on the known FTP port (21). When * - * a connection is made, it starts a 'session' task. That * - * session then interacts with the remote host. When the session * - * is complete, the session task deletes itself. The daemon still * - * runs, however. * - * * - * * - * Supported commands are: * - * * - * RETR xxx - Sends a file from the client. * - * STOR xxx - Receives a file from the client. xxx = filename. * - * LIST xxx - Sends a file list to the client. * - * (LIST xxx isn't working yet...) * - * USER - Does nothing. * - * PASS - Does nothing. * - * SYST - Replies with the system type (`RTEMS'). * - * DELE xxx - Delete file xxx. * - * MKD xxx - Create directory xxx. * - * RMD xxx - Remove directory xxx. * - * PWD - Print working directory. * - * CWD xxx - Change working directory. * - * SITE CHMOD xxx yyy - Change permissions on file yyy to xxx. * - * PORT a,b,c,d,x,y - Setup for a data port to IP address a.b.c.d * - * and port (x*256 + y). * - * * - * * - * The public routines contained in this file are: * - * * - * rtems_initialize_ftpd_start - Starts the server daemon, then * - * returns to its caller. * - * * - * * - * The private routines contained in this file are: * - * * - * 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) * - *************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <dirent.h> - -#include <rtems.h> -#include <rtems/rtems_bsdnet.h> -#include <rtems/error.h> -#include <syslog.h> - -#include <sys/types.h> -#include <sys/socket.h> -#include <arpa/ftp.h> -#include <netinet/in.h> - -#include "ftpd.h" - - -extern struct rtems_ftpd_configuration rtems_ftpd_configuration; - -/************************************************************************** - * Meanings of first and second digits of reply codes: - * - * Reply: Description: - *-------- -------------- - * 1yz Positive preliminary reply. The action is being started but - * expect another reply before sending another command. - * 2yz Positive completion reply. A new command can be sent. - * 3yz Positive intermediate reply. The command has been accpeted - * but another command must be sent. - * 4yz Transient negative completion reply. The requested action did - * not take place, but the error condition is temporary so the - * command can be reissued later. - * 5yz Permanent negative completion reply. The command was not - * accepted and should not be retried. - *------------------------------------------------------------------------- - * x0z Syntax errors. - * x1z Information. - * x2z Connections. Replies referring to the control or data - * connections. - * x3z Authentication and accounting. Replies for the login or - * accounting commands. - * x4z Unspecified. - * x5z Filesystem status. - *************************************************************************/ - - -/************************************************************************** - * SessionInfo structure. - * - * The following structure is allocated for each session. The pointer - * to this structure is contained in the tasks notepad entry. - *************************************************************************/ -typedef struct -{ - struct sockaddr_in data_addr; /* Data address for PORT commands */ - 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" \ - "Login accepted.\n" - - -/************************************************************************** - * Function: rtems_ftpd_send_reply * - ************************************************************************** - * Description: * - * * - * This procedure sends a reply to the client via the control * - * connection. * - * * - * * - * Inputs: * - * * - * int code - The 3-digit reply code. * - * char *text - Reply text. * - * * - * Output: * - * * - * none * - * * - ************************************************************************** - * Change History: * - * 12/01/97 - Creation (JWJ) * - *************************************************************************/ -static void -rtems_ftpd_send_reply(int code, char *text) -{ - rtems_status_code sc; - FTPD_SessionInfo_t *info = NULL; - char str[80]; - - - sc = rtems_task_get_note(RTEMS_SELF, RTEMS_NOTEPAD_0, - (rtems_unsigned32 *)&info); - - /*********************************************************************** - * code must be a 3-digit number. - **********************************************************************/ - if ((code < 100) || (code > 999)) - { - syslog(LOG_ERR, "ftpd: Code not 3-digits."); - return; - } - - /*********************************************************************** - * If a text reply exists, add it to the reply data. - **********************************************************************/ - 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); - } - fflush(info->ctrl_fp); -} - - -/************************************************************************** - * Function: rtems_ftpd_command_retrieve * - ************************************************************************** - * Description: * - * * - * This performs the "RETR" command. A data connection must already * - * be open (via the "PORT" command.) Here, we send the data to the * - * connection. * - * * - * * - * Inputs: * - * * - * char *filename - Source filename. * - * * - * Output: * - * * - * int - 0 for reply sent. * - * 1 for no reply sent. * - * * - ************************************************************************** - * Change History: * - * 04/29/98 - Creation (JWJ) * - *************************************************************************/ -static int -rtems_ftpd_command_retrieve(char *filename) -{ - int s; - int n; - int fd; - unsigned char *bufr; - rtems_status_code sc; - FTPD_SessionInfo_t *info = NULL; - - - sc = rtems_task_get_note(RTEMS_SELF, RTEMS_NOTEPAD_0, - (rtems_unsigned32 *)&info); - - if ((fd = open(filename, O_RDONLY)) == -1) - { - rtems_ftpd_send_reply(450, "Error opening file."); - return(0); - } - - bufr = (unsigned char *)malloc(BUFSIZ); - if (bufr == NULL) - { - 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). - **********************************************************************/ - 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) - { - rtems_ftpd_send_reply(420, "Server error - could not connect socket."); - free(bufr); - close(fd); - close(s); - return(1); - } - - /*********************************************************************** - * Send the data over the ether. - **********************************************************************/ - while ((n = read(fd, bufr, BUFSIZ)) > 0) - { - send(s, bufr, n, 0); - bufr[n-1] = '\0'; - } - - if (n == 0) - { - rtems_ftpd_send_reply(210, "File sent successfully."); - } - else - { - rtems_ftpd_send_reply(450, "Retrieve failed."); - } - - if (close(s) != 0) - { - syslog(LOG_ERR, "ftpd: Error closing data socket"); - } - - free(bufr); - close(fd); - return(0); -} - - -/************************************************************************** - * Function: rtems_ftpd_command_store * - ************************************************************************** - * Description: * - * * - * This performs the "STOR" command. A data connection must already * - * be open (via the "PORT" command.) Here, we get the data from the * - * connection and figure out what to do with it. * - * * - * * - * Inputs: * - * * - * char *filename - Destination filename. * - * * - * Output: * - * * - * int - 0 for success. * - * 1 for failure. * - * * - ************************************************************************** - * Change History: * - * 12/01/97 - Creation (JWJ) * - *************************************************************************/ -static int -rtems_ftpd_command_store(char *filename) -{ - 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, - (rtems_unsigned32 *)&info); - - bufr = (char *)malloc(BUFSIZ * sizeof(char)); - if (bufr == NULL) - { - rtems_ftpd_send_reply(440, "Server error - malloc fail."); - return(1); - } - - 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); - close(s); - return(1); - } - - - /*********************************************************************** - * 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 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 > - rtems_ftpd_configuration.max_hook_filesize * sizeof(char)) - { - rtems_ftpd_send_reply(440, "Server error - Buffer size exceeded."); - free(bufr); - free(bigBufr); - close(s); - return(1); - } - memcpy(&bigBufr[size], bufr, n); - size += n; - } - close(s); - - /*********************************************************************** - * 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 - { - int fd; - size_t written; - - fd = creat(filename, S_IRUSR | S_IWUSR | - S_IRGRP | S_IWGRP | - S_IROTH | S_IWOTH); - if (fd == -1) - { - rtems_ftpd_send_reply(450, "Could not open file."); - close(s); - free(bufr); - return(1); - } - while ((n = read(s, bufr, BUFSIZ)) > 0) - { - written = write(fd, bufr, n); - if (written == -1) - { - rtems_ftpd_send_reply(450, "Error during write."); - close(fd); - close(s); - free(bufr); - return(1); - } - } - close(fd); - close(s); - rtems_ftpd_send_reply(226, "Transfer complete."); - } - - free(bufr); - return(0); -} - - -/************************************************************************** - * Function: rtems_ftpd_command_list * - ************************************************************************** - * Description: * - * * - * Sends a file list through a data connection. The data * - * connection must have already been opened with the "PORT" command. * - * * - * * - * Inputs: * - * * - * char *fname - File (or directory) to list. * - * * - * Output: * - * * - * none * - * * - ************************************************************************** - * Change History: * - * 12/01/97 - Creation (JWJ) * - *************************************************************************/ -static void -rtems_ftpd_command_list(char *fname) -{ - int s; - rtems_status_code sc; - FTPD_SessionInfo_t *info = NULL; - DIR *dirp; - struct dirent *dp; - char dirline[255]; - struct stat stat_buf; - - - sc = rtems_task_get_note(RTEMS_SELF, RTEMS_NOTEPAD_0, - (rtems_unsigned32 *)&info); - - 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, - sizeof(struct sockaddr)) < 0) - { - syslog(LOG_ERR, "ftpd: Error connecting to data socket."); - return; - } - - if ((dirp = opendir(fname)) == NULL) - { - sprintf(dirline, "%s: No such file or directory.%s\n", - fname, (info->xfer_mode==TYPE_A)?("\r"):("")); - send(s, dirline, strlen(dirline), 0); - close(s); - rtems_ftpd_send_reply(226, "Transfer complete."); - return; - } - while ((dp = readdir(dirp)) != NULL) - { - if (stat(dp->d_name, &stat_buf) == 0) - { - sprintf(dirline, "%c%c%c%c%c%c%c%c%c%c %5d %5d %11d %s%s\n", - (S_ISLNK(stat_buf.st_mode)?('l'): - (S_ISDIR(stat_buf.st_mode)?('d'):('-'))), - (stat_buf.st_mode & S_IRUSR)?('r'):('-'), - (stat_buf.st_mode & S_IWUSR)?('w'):('-'), - (stat_buf.st_mode & S_IXUSR)?('x'):('-'), - (stat_buf.st_mode & S_IRGRP)?('r'):('-'), - (stat_buf.st_mode & S_IWGRP)?('w'):('-'), - (stat_buf.st_mode & S_IXGRP)?('x'):('-'), - (stat_buf.st_mode & S_IROTH)?('r'):('-'), - (stat_buf.st_mode & S_IWOTH)?('w'):('-'), - (stat_buf.st_mode & S_IXOTH)?('x'):('-'), - (int)stat_buf.st_uid, - (int)stat_buf.st_gid, - (int)stat_buf.st_size, - dp->d_name, - (info->xfer_mode==TYPE_A)?("\r"):("")); - send(s, dirline, strlen(dirline), 0); - } - } - closedir(dirp); - - close(s); - rtems_ftpd_send_reply(226, "Transfer complete."); -} - - -/* - * Cheesy way to change directories - */ -static void -rtems_ftpd_CWD(char *dir) -{ - rtems_status_code sc; - FTPD_SessionInfo_t *info = NULL; - - - sc = rtems_task_get_note(RTEMS_SELF, RTEMS_NOTEPAD_0, - (rtems_unsigned32 *)&info); - - if (chdir(dir) == 0) - { - rtems_ftpd_send_reply(250, "CWD command successful."); - } - else - { - rtems_ftpd_send_reply(550, "CWD command failed."); - } -} - - -/************************************************************************** - * Function: rtems_ftpd_command_port * - ************************************************************************** - * Description: * - * * - * This procedure opens up a data port given the IP address of the * - * remote machine and the port on the remote machine. This connection * - * will then be used to transfer data between the hosts. * - * * - * * - * Inputs: * - * * - * char *bufr - Arguments to the "PORT" command. * - * * - * * - * Output: * - * * - * none * - * * - ************************************************************************** - * Change History: * - * 12/01/97 - Creation (JWJ) * - *************************************************************************/ -static void -rtems_ftpd_command_port(char *bufr) -{ - char *ip; - char *port; - int ip0, ip1, ip2, ip3, port0, port1; - rtems_status_code sc; - FTPD_SessionInfo_t *info = NULL; - - - sc = rtems_task_get_note(RTEMS_SELF, RTEMS_NOTEPAD_0, - (rtems_unsigned32 *)&info); - - sscanf(bufr, "%d,%d,%d,%d,%d,%d", &ip0, &ip1, &ip2, &ip3, &port0, &port1); - ip = (char *)&(info->data_addr.sin_addr); - ip[0] = ip0 & 0xff; - ip[1] = ip1 & 0xff; - ip[2] = ip2 & 0xff; - ip[3] = ip3 & 0xff; - port = (char *)&(info->data_addr.sin_port); - port[0] = port0 & 0xff; - port[1] = port1 & 0xff; - info->data_addr.sin_family = AF_INET; -} - - -/************************************************************************** - * 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: * - * * - * char *bufr - Pointer to the buffer which contains the command * - * text. * - * * - * Output: * - * * - * none * - * * - ************************************************************************** - * Change History: * - * 12/01/97 - Creation (JWJ) * - *************************************************************************/ -static void -rtems_ftpd_parse_command(char *bufr) -{ - char fname[255]; - rtems_status_code sc; - FTPD_SessionInfo_t *info = NULL; - - - sc = rtems_task_get_note(RTEMS_SELF, RTEMS_NOTEPAD_0, - (rtems_unsigned32 *)&info); - - if (!strncmp("PORT", bufr, 4)) - { - 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); - rtems_ftpd_command_retrieve(fname); - } - else if (!strncmp("STOR", bufr, 4)) - { - sscanf(&bufr[5], "%254s", fname); - rtems_ftpd_command_store(fname); - } - else if (!strncmp("LIST", bufr, 4)) - { - if (bufr[5] == '\n') - { - rtems_ftpd_command_list("."); - } - else - { - sscanf(&bufr[5], "%254s", fname); - rtems_ftpd_command_list(fname); - } - } - else if (!strncmp("USER", bufr, 4)) - { - rtems_ftpd_send_reply(230, "User logged in."); - } - else if (!strncmp("SYST", bufr, 4)) - { - rtems_ftpd_send_reply(240, "RTEMS"); - } - else if (!strncmp("TYPE", bufr, 4)) - { - if (bufr[5] == 'I') - { - info->xfer_mode = TYPE_I; - rtems_ftpd_send_reply(200, "Type set to I."); - } - else if (bufr[5] == 'A') - { - info->xfer_mode = TYPE_A; - rtems_ftpd_send_reply(200, "Type set to A."); - } - else - { - info->xfer_mode = TYPE_I; - rtems_ftpd_send_reply(504, "Type not implemented. Set to I."); - } - } - else if (!strncmp("PASS", bufr, 4)) - { - rtems_ftpd_send_reply(230, "User logged in."); - } - else if (!strncmp("DELE", bufr, 4)) - { - sscanf(&bufr[4], "%254s", fname); - if (unlink(fname) == 0) - { - rtems_ftpd_send_reply(257, "DELE successful."); - } - else - { - rtems_ftpd_send_reply(550, "DELE failed."); - } - } - else if (!strncmp("SITE CHMOD", bufr, 10)) - { - int mask; - - sscanf(&bufr[11], "%o %254s", &mask, fname); - if (chmod(fname, (mode_t)mask) == 0) - { - rtems_ftpd_send_reply(257, "CHMOD successful."); - } - else - { - rtems_ftpd_send_reply(550, "CHMOD failed."); - } - } - else if (!strncmp("RMD", bufr, 3)) - { - sscanf(&bufr[4], "%254s", fname); - if (rmdir(fname) == 0) - { - rtems_ftpd_send_reply(257, "RMD successful."); - } - else - { - rtems_ftpd_send_reply(550, "RMD failed."); - } - } - else if (!strncmp("MKD", bufr, 3)) - { - sscanf(&bufr[4], "%254s", fname); - if (mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO) == 0) - { - rtems_ftpd_send_reply(257, "MKD successful."); - } - else - { - rtems_ftpd_send_reply(550, "MKD failed."); - } - } - else if (!strncmp("CWD", bufr, 3)) - { - sscanf(&bufr[4], "%254s", fname); - rtems_ftpd_CWD(fname); - } - else if (!strncmp("PWD", bufr, 3)) - { - char *cwd = getcwd(0, 0); - sprintf(bufr, "\"%s\" is the current directory.", cwd); - rtems_ftpd_send_reply(250, bufr); - free(cwd); - } - else - { - rtems_ftpd_send_reply(500, "Unrecognized/unsupported command."); - } -} - - -/************************************************************************** - * Function: rtems_ftpd_session * - ************************************************************************** - * Description: * - * * - * This task is started when the FTP daemon gets a service request * - * from a remote machine. Here, we watch for commands that will * - * come through the "control" connection. These commands are then * - * parsed and executed until the connection is closed, either * - * unintentionally or intentionally with the "QUIT" command. * - * * - * * - * Inputs: * - * * - * rtems_task_argument arg - The daemon task passes the socket * - * which serves as the control connection. * - * * - * Output: * - * * - * none * - * * - ************************************************************************** - * Change History: * - * 12/01/97 - Creation (JWJ) * - *************************************************************************/ -static void -rtems_ftpd_session(rtems_task_argument arg) -{ - char cmd[256]; - rtems_status_code sc; - FTPD_SessionInfo_t *info = NULL; - - - sc = rtems_task_get_note(RTEMS_SELF, RTEMS_NOTEPAD_0, - (rtems_unsigned32 *)&info); - - rtems_ftpd_send_reply(220, FTPD_SERVER_MESSAGE); - - /*********************************************************************** - * Set initial directory to "/". - **********************************************************************/ - strcpy(info->cwd, "/"); - info->xfer_mode = TYPE_A; - while (1) - { - if (fgets(cmd, 256, info->ctrl_fp) == NULL) - { - syslog(LOG_INFO, "ftpd: Connection aborted."); - break; - } - - if (!strncmp("QUIT", cmd, 4)) - { - rtems_ftpd_send_reply(221, "Goodbye."); - break; - } - else - { - rtems_ftpd_parse_command(cmd); - } - } - - if (fclose(info->ctrl_fp) != 0) - { - syslog(LOG_ERR, "ftpd: Could not close session."); - } - - - /* Least we can do is put the CWD back to /. */ - chdir("/"); - - /*********************************************************************** - * Free up the allocated SessionInfo struct and exit. - **********************************************************************/ - free(info); - sc = rtems_task_delete(RTEMS_SELF); - syslog(LOG_ERR, "ftpd: Task deletion failed: %s", - rtems_status_text(sc)); -} - - -/************************************************************************** - * Function: rtems_ftpd_daemon * - ************************************************************************** - * Description: * - * * - * This task runs in the background forever. It waits for service * - * requests on the FTP port (port 21). When a request is received, * - * it opens a new session to handle those requests until the * - * connection is closed. * - * * - * * - * Inputs: * - * * - * none * - * * - * Output: * - * * - * none * - * * - ************************************************************************** - * Change History: * - * 12/01/97 - Creation (JWJ) * - *************************************************************************/ -static void -rtems_ftpd_daemon() -{ - int s; - int s1; - int addrLen; - struct sockaddr_in remoteAddr; - struct sockaddr_in localAddr; - char sessionID; - rtems_task_priority priority; - rtems_status_code sc; - rtems_id tid; - FTPD_SessionInfo_t *info = NULL; - - - sessionID = 'a'; - - s = socket(AF_INET, SOCK_STREAM, 0); - if (s < 0) - { - perror("Creating socket"); - } - - localAddr.sin_family = AF_INET; - 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, - sizeof(localAddr)) < 0) - { - perror("Binding control socket"); - } - - if (listen(s, 2) < 0) - { - perror("Listening on control socket"); - } - - while (1) - { - /******************************************************************** - * Allocate a SessionInfo structure for the session task. - *******************************************************************/ - info = (FTPD_SessionInfo_t *)malloc(sizeof(FTPD_SessionInfo_t)); - if (info == NULL) - { - syslog(LOG_ERR, "ftpd: Could not allocate session info struct."); - rtems_panic("Malloc fail."); - } - - /******************************************************************** - * Accept on the socket and start the session task. - *******************************************************************/ - addrLen = sizeof(remoteAddr); - s1 = accept(s, (struct sockaddr *)&remoteAddr, &addrLen); - if (s1 < 0) - { - perror("Accepting control connection"); - } - - rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &priority); - sc = rtems_task_create(rtems_build_name('F', 'T', 'P', sessionID), - priority, 8*1024, - RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | - RTEMS_NO_ASR | RTEMS_INTERRUPT_LEVEL(0), - RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL, - &tid); - if (sc != RTEMS_SUCCESSFUL) - { - syslog(LOG_ERR, "ftpd: Could not create FTPD session: %s", - rtems_status_text(sc)); - } - - if (sessionID == 'z') - { - sessionID = 'a'; - } - else - { - sessionID++; - } - - /******************************************************************** - * Send the socket on to the new session. - *******************************************************************/ - if ((info->ctrl_fp = fdopen(s1, "r+")) == NULL) - { - 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: rtems_ftpd_start * - ************************************************************************** - * Description: * - * * - * Here, we start the FTPD task which waits for FTP requests and * - * services them. This procedure returns to its caller once the * - * task is started. * - * * - * * - * Inputs: * - * * - * rtems_task_priority priority - Priority to assign to this task. * - * * - * Output: * - * * - * int - RTEMS_SUCCESSFUL on successful start of the daemon. * - * * - ************************************************************************** - * Change History: * - * 12/01/97 - Creation (JWJ) * - *************************************************************************/ -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'), - rtems_ftpd_configuration.priority, 8*1024, - RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_NO_ASR | - RTEMS_INTERRUPT_LEVEL(0), - RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL, - &tid); - if (sc != RTEMS_SUCCESSFUL) - { - syslog(LOG_ERR, "ftpd: Could not create FTP daemon: %s", - rtems_status_text(sc)); - return(RTEMS_UNSATISFIED); - } - - 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); -} - |