Documentation

Generated on Thu Aug 31 00:02:39 2006

 

Handler Class Reference

#include <Handler.h>

List of all members.


Public Member Functions

 Handler ()
 ~Handler ()
bool init (User *)
Userinitializer (int)

Public Attributes

hash_map< const char *, struct
command_info, hash< const
char * >, Utilities::eqstr
cmd_info

Private Member Functions

bool interpreter (User *, string)

Detailed Description

Definition at line 44 of file Handler.h.


Constructor & Destructor Documentation

Handler::Handler (  ) 

Definition at line 19 of file Handler.cpp.

References Commands::abor(), Commands::auth(), BEFORE_USER, cmd_info, COM_APPE, COM_CCC, COM_CDUP, COM_CONF, COM_CWD, COM_ENC, COM_EPRT, COM_EPSV, COM_FEAT, COM_FROM, COM_LONG, COM_MDTM, COM_MIC, COM_MLSD, COM_MLST, COM_MODE, COM_NOOP, COM_PASV, COM_PBSZ, COM_PORT, COM_PROT, COM_PWD, COM_SHORT, COM_SIZE, COM_STOR, COM_STRU, COM_SYST, COM_TO, COM_TYPE, config, Commands::cwd(), Commands::dele(), Configuration::general, Commands::help(), HLP_ABOR, HLP_APPE, HLP_AUTH, HLP_CCC, HLP_CDUP, HLP_CWD, HLP_DELE, HLP_EPRT, HLP_EPSV, HLP_FEAT, HLP_HELP, HLP_LIST, HLP_MDTM, HLP_MKD, HLP_MLSD, HLP_MLST, HLP_MODE, HLP_NLST, HLP_NOOP, HLP_OPTS, HLP_PASS, HLP_PASV, HLP_PBSZ, HLP_PORT, HLP_PROT, HLP_PWD, HLP_QUIT, HLP_REST, HLP_RETR, HLP_RMD, HLP_RNFR, HLP_RNTO, HLP_SIZE, HLP_STOR, HLP_STRU, HLP_SYST, HLP_TYPE, HLP_USER, Commands::list(), Commands::mkd(), Commands::opts(), Commands::pass(), Commands::pasv(), Commands::port(), Commands::quit(), general_stru::readonly, Commands::rest(), Commands::retr(), Commands::rmd(), Commands::rname(), Commands::sim1(), Commands::sim2(), Commands::stor(), and Commands::user().

00020 {
00021   // first argument is number of arguments to the command, they should
00022   //  be self explaining except the negative ones. -1 means any number,
00023   //  -2 means anything but 0.
00024   // An empty hlp field means no help will be displayed about the command
00025   cmd_info["SYST"] = command_info(0, &Commands::sim1, COM_SYST, HLP_SYST);
00026   cmd_info["HELP"] = command_info(-1, &Commands::help, BEFORE_USER, HLP_HELP);
00027   cmd_info["RETR"] = command_info(-2, &Commands::retr, 0, HLP_RETR);
00028   // these commands are disabled if the conf variable readonly in general
00029   //  sector is enabled.
00030   if(!config->general.readonly)
00031   {
00032     cmd_info["STOR"] = command_info(-2, &Commands::stor, COM_STOR, HLP_STOR);
00033     cmd_info["APPE"] = command_info(-2, &Commands::stor, COM_APPE, HLP_APPE);
00034     cmd_info["DELE"] = command_info(-2, &Commands::dele, 0, HLP_DELE);
00035     cmd_info["RNFR"] = command_info(-2, &Commands::rname, COM_FROM, HLP_RNFR);
00036     cmd_info["RNTO"] = command_info(-2, &Commands::rname, COM_TO, HLP_RNTO);
00037     cmd_info["MKD"] = command_info(-2, &Commands::mkd, 0, HLP_MKD);
00038     cmd_info["RMD"] = command_info(-2, &Commands::rmd, 0, HLP_RMD);
00039     cmd_info["XMKD"] = command_info(-2, &Commands::mkd, 0, HLP_MKD);
00040     cmd_info["XRMD"] = command_info(-2, &Commands::rmd, 0, HLP_RMD);
00041   }
00042   cmd_info["PORT"] = command_info(1, &Commands::port, COM_PORT, HLP_PORT);
00043   cmd_info["EPRT"] = command_info(1, &Commands::port, COM_EPRT, HLP_EPRT);
00044   cmd_info["PASV"] = command_info(0, &Commands::pasv, COM_PASV, HLP_PASV);
00045   cmd_info["EPSV"] = command_info(-1, &Commands::pasv, COM_EPSV, HLP_EPSV);
00046   cmd_info["PWD"] = command_info(0, &Commands::sim1, COM_PWD, HLP_PWD);
00047   cmd_info["CWD"] = command_info(-2, &Commands::cwd,  COM_CWD, HLP_CWD);
00048   cmd_info["CDUP"] = command_info(0, &Commands::cwd,  COM_CDUP, HLP_CDUP);
00049   cmd_info["LIST"] = command_info(-1, &Commands::list, COM_LONG, HLP_LIST);
00050   cmd_info["NLST"] = command_info(-1, &Commands::list, COM_SHORT, HLP_NLST);
00051   cmd_info["TYPE"] = command_info(-2, &Commands::sim1, COM_TYPE, HLP_TYPE);
00052   cmd_info["MODE"] = command_info(1, &Commands::sim1, COM_MODE, HLP_MODE);
00053   cmd_info["STRU"] = command_info(1, &Commands::sim1, COM_STRU, HLP_STRU);
00054   cmd_info["SIZE"] = command_info(-2, &Commands::sim2, COM_SIZE, HLP_SIZE);
00055   cmd_info["USER"] = command_info(1, &Commands::user, BEFORE_USER, HLP_USER);
00056   cmd_info["PASS"] = command_info(-2, &Commands::pass, BEFORE_USER, HLP_PASS);
00057   cmd_info["QUIT"] = command_info(-1, &Commands::quit, BEFORE_USER, HLP_QUIT);
00058   cmd_info["NOOP"] = command_info(0, &Commands::sim1, COM_NOOP, HLP_NOOP);
00059   cmd_info["MDTM"] = command_info(-2, &Commands::sim2, COM_MDTM, HLP_MDTM);
00060   cmd_info["FEAT"] =
00061     command_info(0, &Commands::sim1, COM_FEAT | BEFORE_USER, HLP_FEAT);
00062   cmd_info["MLST"] = command_info(-2, &Commands::sim2, COM_MLST, HLP_MLST);
00063   cmd_info["MLSD"] = command_info(-1, &Commands::list, COM_MLSD, HLP_MLSD);
00064   cmd_info["OPTS"] = command_info(-1, &Commands::opts, 0, HLP_OPTS);
00065   cmd_info["REST"] = command_info(1, &Commands::rest, 0, HLP_REST);
00066   cmd_info["XCWD"] = command_info(-2, &Commands::cwd, COM_CWD, HLP_CWD);
00067   cmd_info["XPWD"] = command_info(0, &Commands::sim1, COM_PWD, HLP_PWD);
00068   cmd_info["XCUP"] = command_info(0, &Commands::sim1, COM_CDUP, HLP_CDUP);
00069 #ifdef USE_TLS
00070   cmd_info["AUTH"] = command_info(1, &Commands::auth, BEFORE_USER, HLP_AUTH);
00071   cmd_info["PBSZ"] =
00072     command_info(1, &Commands::sim1, COM_PBSZ | BEFORE_USER, HLP_PBSZ);
00073   cmd_info["PROT"] =
00074     command_info(1, &Commands::sim1, COM_PROT | BEFORE_USER, HLP_PROT);
00075   cmd_info["CCC"] = command_info(0, &Commands::sim1, COM_CCC, HLP_CCC);
00076   // these commands are required to be understood by rfc2228, even if
00077   // we don't use them.
00078   cmd_info["CONF"] =
00079     command_info(-1, &Commands::sim1, COM_CONF | BEFORE_USER, "");
00080   cmd_info["MIC"] =
00081     command_info(-1, &Commands::sim1, COM_MIC | BEFORE_USER, "");
00082   cmd_info["ENC"] =
00083     command_info(-1, &Commands::sim1, COM_ENC | BEFORE_USER, "");
00084 #endif // USE_TLS
00085   cmd_info["ABOR"] = command_info(0, &Commands::abor, 0, HLP_ABOR);
00086 }

Here is the call graph for this function:

Handler::~Handler (  ) 

Definition at line 88 of file Handler.cpp.

References cmd_info.

00089 {
00090   cmd_info.clear();
00091 }


Member Function Documentation

bool Handler::init ( User  ) 

Definition at line 129 of file Handler.cpp.

References Utilities::clean_string(), FAILURE, Connection::settings(), and util.

Referenced by user_wrapper().

00130 {
00131   while(true)
00132   {
00133     string command;
00134     if(user->settings(FAILURE))
00135       break;
00136     *user >> command;
00137     util.clean_string(command);
00138     if(!command.empty())
00139       this->interpreter(user, command);
00140   }
00141   return(true); // we're returning to wrapper for exit.
00142 }

Here is the call graph for this function:

class User * Handler::initializer ( int   ) 

Definition at line 93 of file Handler.cpp.

References B_SET, config, general_stru::connection_limit, FAILURE, Configuration::general, Log::log_this(), logging, Connection::settings(), TYPE_INFO, User::User(), user_list, user_list_lock, and general_stru::welcome_msg.

Referenced by user_wrapper().

00094 {
00095   struct sockaddr_in addr;
00096   socklen_t len = sizeof(sockaddr_in);
00097 
00098   getpeername(socket_id, reinterpret_cast<struct sockaddr*>(&addr), &len);
00099   class User *user = new User(socket_id, addr);
00100 
00101   string log = "new connection from: ";
00102   log += inet_ntoa(addr.sin_addr);
00103   logging->log_this(3, TYPE_INFO, log);
00104 
00105   pthread_rwlock_wrlock(&user_list_lock);
00106   user_list.push_back(user);
00107   pthread_rwlock_unlock(&user_list_lock);
00108 
00109   string message;
00110   pthread_rwlock_rdlock(&user_list_lock);
00111   if(static_cast<int>(user_list.size()) > config->general.connection_limit)
00112   {
00113     // reached maximum number of connections...
00114     message =
00115       "421 Maximum number of connections reached, please try again later.";
00116     user->settings(FAILURE, B_SET);
00117   }
00118   else
00119   {
00120     // dns lookup should go here.. find a nice way of doing it.
00121     message = "220 " + config->general.welcome_msg;
00122   }
00123   pthread_rwlock_unlock(&user_list_lock);
00124   *user << message << "\r\n";
00125 
00126   return(user);
00127 }

Here is the call graph for this function:

bool Handler::interpreter ( User ,
string   
) [private]

Definition at line 144 of file Handler.cpp.

References BEFORE_USER, cmd_info, comm, StringTokenizer::countTokens(), Utilities::is_set(), Log::log_this(), LOGGED_IN, logging, StringTokenizer::nextToken(), StringTokenizer::restTokens(), StringTokenizer::StringTokenizer(), TYPE_DEBUG, and util.

00145 {
00146   string argument, message;
00147   class StringTokenizer *st = NULL;
00148 
00149   st = new StringTokenizer(command, " ", false);
00150   int words = st->countTokens() - 1;
00151   command = st->nextToken();
00152 
00153   transform(command.begin(), command.end(), command.begin(),
00154       (int(*)(int))toupper);
00155 
00156   if(command == "SITE")
00157   {
00158     st->nextToken();
00159     command += " " + st->nextToken();
00160     transform(command.begin() + 4, command.end(), command.begin() + 4,
00161         (int(*)(int))toupper);
00162     words--;
00163   }
00164   argument = st->restTokens();
00165   delete(st);
00166 
00167   if(command != "PASS")
00168     logging->log_this(5, TYPE_DEBUG, command + "-" + argument);
00169   else
00170     logging->log_this(5, TYPE_DEBUG, "PASS-**********");
00171 
00172   hash_map<const char*, struct command_info, hash<const char*>,
00173     Utilities::eqstr>::iterator cmd_it = cmd_info.find(command.c_str());
00174 
00175   if(cmd_it == cmd_info.end())
00176     message = "500 '" + command + "' not understood.";
00177   else
00178   {
00179     if(user->logged_in() < LOGGED_IN &&
00180         !util.is_set((*(cmd_it)).second.extra_flag,BEFORE_USER))
00181       message = "530 Login with 'USER' and 'PASS' first.";
00182     else
00183     {
00184       if((!user->temp_buf().empty()) && command != "RNTO")
00185         user->temp_buf(""); // we don't want this hanging around forever.
00186 
00187       if(words == 0 && (((*(cmd_it)).second.ant_arg == -2) ||
00188             (words < (*(cmd_it)).second.ant_arg)))
00189         message = "501 '" + command + "': requires an argument.";
00190       else if((*(cmd_it)).second.ant_arg >= 0 &&
00191           words > (*(cmd_it)).second.ant_arg)
00192         message = "501 '" + command + "': to many arguments to command.";
00193       else
00194         ((comm.*(*(cmd_it)).second.pf)
00195          (user, argument, (*(cmd_it)).second.extra_flag));
00196     }
00197   }
00198   if(!message.empty())
00199     *user << message << "\r\n";
00200   return(true);
00201 }

Here is the call graph for this function:


Member Data Documentation

hash_map<const char*, struct command_info, hash<const char*>, Utilities::eqstr> Handler::cmd_info

Definition at line 54 of file Handler.h.

Referenced by Handler(), Commands::help(), interpreter(), and ~Handler().


The documentation for this class was generated from the following files: