/* Copyright (C) 1999 Beau Kuiper This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ftpd.h" #include "ftpcmd.h" /* command, proc, needsparam, needlogin, dataportok */ FTPCMD siteftpcmd[] = { #ifdef DUMPCMD {"DUMP", ftpsite_dump, TRUE, TRUE, FALSE, "Display a file over control connection." }, */ #endif {"UMASK", ftpsite_umask, FALSE, TRUE, FALSE, "Change the umask." }, {"CHMOD", ftpsite_chmod, TRUE, TRUE, FALSE, "Change the permissions on a file." }, {"HELP", ftpsite_help, FALSE, TRUE, TRUE, "Get help on SITE commands." }, #ifdef ACCESSCMD {"ACCESS", ftpsite_access, FALSE, TRUE, TRUE, "Show access list that is enforced." }, */ #endif {"IDLE", ftpsite_idle, FALSE, TRUE, FALSE, "Change the current timeout." }, {"", NULL, FALSE, FALSE, FALSE, ""} }; FTPCMD mainftpcmd[] = { {"PORT", ftp_port, TRUE , TRUE , FALSE, "Specify data port connection." }, {"PASV", ftp_pasv, FALSE, TRUE , FALSE, "Specify a passive data port connection." }, {"RETR", ftp_retr, TRUE , TRUE , FALSE, "Download a file." }, {"STOR", ftp_stor, TRUE , TRUE , FALSE, "Upload a file." }, {"STOU", ftp_stou, TRUE , TRUE , FALSE, "Upload a file, storing it with a unique filename." }, {"APPE", ftp_appe, TRUE , TRUE , FALSE, "Append to a file on the server." }, {"TYPE", ftp_type, TRUE , TRUE , FALSE, "Specify type of file transfer." }, {"QUIT", ftp_quit, FALSE, FALSE, TRUE , "Quit control connection." }, {"PASS", ftp_pass, FALSE, FALSE, FALSE, "Specify password." }, {"USER", ftp_user, TRUE , FALSE, FALSE, "Specify username." }, {"HOST", ftp_host, TRUE , FALSE, FALSE, "Specify virtual host." }, {"SYST", ftp_syst, FALSE, FALSE, FALSE, "Return the system type." }, {"LIST", ftp_list, FALSE, TRUE , FALSE, "Do a long file list." }, {"NLST", ftp_nlst, FALSE, TRUE , FALSE, "Do a short file list." }, {"PWD" , ftp_pwd , FALSE, TRUE , FALSE, "Get the current directory." }, {"XPWD", ftp_pwd , FALSE, TRUE , FALSE, "Get the current directory." }, {"CWD" , ftp_cwd , TRUE , TRUE , FALSE, "Change the current directory." }, {"XCWD", ftp_cwd , TRUE , TRUE , FALSE, "Change the current directory." }, {"ABOR", ftp_abor, FALSE, TRUE , TRUE , "Abort a file transfer." }, {"CDUP", ftp_cdup, FALSE, TRUE , FALSE, "Change to parent directory." }, {"XCUP", ftp_cdup, FALSE, TRUE , FALSE, "Change to parent directory." }, {"STAT", ftp_stat, FALSE, TRUE , TRUE , "Get server status." }, {"NOOP", ftp_noop, FALSE, FALSE, TRUE , "No-operation." }, {"REIN", ftp_rein, FALSE, FALSE, TRUE , "Re-initialize server." }, {"REST", ftp_rest, TRUE , TRUE , FALSE, "Specify resume postion for file transfer." }, {"DELE", ftp_dele, TRUE , TRUE , FALSE, "Delete a file." }, {"MKD" , ftp_mkd , TRUE , TRUE , FALSE, "Make a new directory." }, {"XMKD", ftp_mkd , TRUE , TRUE , FALSE, "Make a new directory." }, {"XRMD", ftp_rmd , TRUE , TRUE , FALSE, "Remove a directory." }, {"RMD" , ftp_rmd , TRUE , TRUE , FALSE, "Remove a directory." }, {"RNFR", ftp_rnfr, TRUE , TRUE , FALSE, "Specify a file to rename from." }, {"RNTO", ftp_rnto, TRUE , TRUE , FALSE, "Specify a file to rename to." }, {"SIZE", ftp_size, TRUE , TRUE , FALSE, "Get the size of a file." }, {"MDTM", ftp_mdtm, TRUE , TRUE , FALSE, "Get the modified data of a file." }, {"HELP", ftp_help, FALSE, FALSE, TRUE , "Get help on commands." }, {"SITE", ftp_site, FALSE, TRUE , TRUE , "Site specific commands. See SITE HELP." }, {"ALLO", ftp_allo, FALSE, TRUE , FALSE, "Allocate space (redundant)." }, {"ACCT", ftp_acct, FALSE, TRUE , FALSE, "Specify account (redundant)." }, {"STRU", ftp_stru, FALSE, TRUE , FALSE, "Specify structure (redundant)."}, {"EPRT", ftp_eprt, TRUE , TRUE , FALSE, "Specify an extended data port connection."}, {"EPSV", ftp_epsv, FALSE, TRUE , FALSE, "Specify an extended passive port connection."}, {"", NULL , FALSE, FALSE, FALSE, ""} }; int *disableset_create(void) { int *set; int count = 0; while(mainftpcmd[count].ftpfunc != NULL) count++; count++; set = mallocwrapper(sizeof(int) * count); memset(set, 0, sizeof(int) * count); return(set); } void disableset_disablecmd(int *set, FTPCMD *ctable, char *cmd) { int count = 0; while((strcasecmp(ctable[count].command, cmd) != 0) && (ctable[count].ftpfunc != NULL)) count++; if (ctable[count].ftpfunc != NULL) set[count] = TRUE; else log_giveentry(MYLOG_INFO, NULL, safe_snprintf("Could not find command '%s' to disable.", cmd)); } char *getkeyword(char **iline) { char *data, *param; /* move to the first non-space stuff */ while ((**iline == ' ') || ((unsigned char)**iline > 128)) (*iline)++; data = strdupwrapper(*iline); param = strchr(data, ' '); if (param != NULL) *param = 0; *iline = strchr(*iline, ' '); if (*iline != NULL) (*iline)++; return(data); } void cmd_split(FTPSTATE *peer, INPUTLINE *cmd, char* inpline, FTPCMD *ctable, int log, int *disableset) { char *command; char *param = inpline; int counter; command = getkeyword(¶m); if (param != NULL) cmd->parameters = strdupwrapper(param); else cmd->parameters = NULL; counter = 0; /* while (command not found && not end of table) || command is disabled */ /* this causes the parser to drop past disabled commands */ while( ((strcasecmp(ctable[counter].command, command) != 0) && (ctable[counter].ftpfunc != NULL)) || ((disableset ? disableset[counter] : ctable[counter].needslogin))) { counter++; } cmd->command = &(ctable[counter]); if (log) if (cmd->command->ftpfunc != ftp_none) { if (cmd->command->ftpfunc == ftp_pass) log_addentry(MYLOG_COMMAND, peer, "PASS *"); else log_addentry(MYLOG_COMMAND, peer, inpline); } freewrapper(command); }