Documentation

Generated on Thu Aug 31 00:02:37 2006

 

Configuration Class Reference

#include <Configuration.h>

Collaboration diagram for Configuration:

Collaboration graph
[legend]
List of all members.

Public Member Functions

bool parse_config_file ()
bool parse_command_line (int argc, char **argv)
 Configuration (void)
users_struget_user (string)
 ~Configuration (void)

Public Attributes

string conf_file
log_stru logger
general_stru general
users_stru general_user

Private Member Functions

int count_users (vector< string >, string &)
bool fill_buff (vector< string > &, string)
string get_variables (vector< string > &, const char *, int)
bool set_structs (string, enum sect, void *)

Private Attributes

vector< users_struusers
int num_users
bool parsed

Detailed Description

Definition at line 77 of file Configuration.h.


Constructor & Destructor Documentation

Configuration::Configuration ( void   ) 

Definition at line 17 of file Configuration.cpp.

References A_DISABLE, general_stru::admin_email, ALLOW, general_stru::anonymous, conf_file, general_stru::connection_limit, general_stru::data_port, general_stru::dh_regenerate, users_stru::encryption, general, general_user, general_stru::group, users_stru::id, users_stru::idle, general_stru::lifebeat_tick, log_stru::log_level, logger, general_stru::no_daemon, users_stru::noftp, users_stru::only_home, users_stru::only_passive, general_stru::os, parsed, general_stru::port, general_stru::readonly, users_stru::sim_data, log_stru::thread_id, log_stru::time_format, general_stru::tls_ca, general_stru::tls_cert, general_stru::tls_crl, general_stru::tls_key, general_stru::user, users_stru::user_limit, general_stru::verify_client, general_stru::welcome_msg, log_stru::xferlog, and log_stru::xferlog_file.

00018 {
00019   conf_file = "babyftpd.conf";
00020   parsed = false;
00021 
00022   general.connection_limit = INT_MAX; // ain't this a bit high?
00023   general.port = 21; // default port
00024   general.data_port = 20; // default outgoing data port
00025   general.no_daemon = false; // daemon mode or not?
00026   general.os = "UNIX"; // what OS is this?
00027   general.admin_email = ""; // admin email?
00028   general.lifebeat_tick = 300; // run the lifebeat() function every this
00029   char tmp[20];
00030   gethostname(tmp, 20);
00031   general.welcome_msg = "BabyFTPd ";
00032   general.welcome_msg += VERSION;
00033   general.welcome_msg += " Server [";
00034   general.welcome_msg += tmp;
00035   general.welcome_msg += "]";
00036   general.user = 0; // by default when run all as root
00037   general.group = 0;
00038   general.readonly = false;
00039   general.anonymous = A_DISABLE;
00040 #ifdef USE_TLS
00041   general.tls_key = "/etc/babyftpd/tls_key.pem";
00042   general.tls_cert = "/etc/babyftpd/tls_cert.pem";
00043   general.tls_ca = "/etc/babyftpd/tls_ca.pem";
00044   general.tls_crl = "/etc/babyftpd/tls_crl.pem";
00045   general.dh_regenerate = 3600; // seconds between diffie-hellman regenerations
00046   general.verify_client = "/etc/babyftpd/verify_client.pl";
00047 
00048   general_user.encryption = ALLOW;
00049 #endif
00050   logger.log_level = 3; // 3 is probably a sensible default?
00051   logger.xferlog = true; // by default all transfers are logged
00052   logger.xferlog_file = "/var/log/xferlog"; // here
00053   logger.thread_id = false; // we don't want thread ids all over the logs
00054   logger.time_format = "%b %e %H:%M:%S "; // time format
00055 
00056   // these options end up as default for all users, that is,
00057   //  those that don't occur in the conf file get these values
00058   general_user.id = "user_general";
00059   general_user.sim_data = INT_MAX;
00060   general_user.idle = 900; // idle timeout after how long?
00061   general_user.noftp = false; // can this user login with ftp or not?
00062   general_user.only_home = false; // false chroot in homedir?
00063   general_user.only_passive = false;
00064   general_user.user_limit = INT_MAX; // maximum control connections
00065 }

Configuration::~Configuration ( void   ) 

Definition at line 67 of file Configuration.cpp.

00068 {
00069 }


Member Function Documentation

int Configuration::count_users ( vector< string >  ,
string &   
) [private]

Definition at line 425 of file Configuration.cpp.

Referenced by parse_config_file().

00426 {
00427   int ant = 0;
00428   int deep = 1, curr_deep = 0;
00429   string name = "user", section = "";
00430   for(vector<string>::iterator buff_it = buff.begin(); buff_it != buff.end();
00431       buff_it++)
00432   {
00433     if(*buff_it == "{")
00434     {
00435       if(curr_deep == deep && section == name)
00436       {
00437         ant++;
00438         users += *(buff_it - 1) + ",";
00439       }
00440       curr_deep++;
00441       if(curr_deep == deep)
00442         section = *(buff_it - 1);
00443     }
00444     else if(*buff_it == "}")
00445     {
00446       if(curr_deep == deep && section == name)
00447         return ant;
00448       curr_deep--;
00449     }
00450   }
00451   return ant;
00452 }

bool Configuration::fill_buff ( vector< string > &  ,
string   
) [private]

Definition at line 487 of file Configuration.cpp.

References Utilities::clean_string(), and util.

Referenced by parse_config_file().

00488 {
00489   ifstream fin;
00490   fin.open(filename.c_str(), ifstream::in);
00491 
00492   while(fin.good())
00493   {
00494     string buffer;
00495     getline(fin, buffer);
00496     util.clean_string(buffer);
00497     if(!fin.good() || buffer.empty())
00498       continue;
00499     buff.push_back(buffer);
00500   }
00501 
00502   fin.close();
00503   if(buff.empty())
00504     return(false);
00505   else
00506     return(true);
00507 }

Here is the call graph for this function:

struct users_stru & Configuration::get_user ( string   ) 

Definition at line 416 of file Configuration.cpp.

References general_user, and users.

Referenced by Commands::auth(), User::data_vec_full(), User::login(), User::operator>>(), Commands::port(), and Commands::user().

00417 {
00418   for(vector<users_stru>::iterator use_it = users.begin();
00419       use_it != users.end(); use_it++)
00420     if((*use_it).id == name && name != "")
00421       return(*use_it);
00422   return general_user;
00423 }

string Configuration::get_variables ( vector< string > &  ,
const char *  ,
int   
) [private]

Definition at line 455 of file Configuration.cpp.

Referenced by parse_config_file().

00457 {
00458   int curr_deep = 0;
00459   string section, str;
00460   for(vector<string>::iterator buff_it = buff.begin(); buff_it != buff.end();
00461       buff_it++)
00462   {
00463     if((*buff_it).empty())
00464       continue;
00465     size_t comment = (*buff_it).find_first_of('#');
00466     if(comment != string::npos)
00467       (*buff_it).erase(comment);
00468     if(*buff_it == "{")
00469     {
00470       section = *(buff_it - 1);
00471       curr_deep++;
00472       if(curr_deep == deep)
00473         str = section + "\n";
00474     }
00475     else if(*buff_it == "}")
00476     {
00477       if(curr_deep == deep && section == key)
00478         break;
00479       curr_deep--;
00480     }
00481     else if(curr_deep == deep && section == key)
00482       str += *buff_it + "\n";
00483   }
00484   return(str);
00485 }

bool Configuration::parse_command_line ( int  argc,
char **  argv 
)

Definition at line 510 of file Configuration.cpp.

References conf_file, config, exit_baby(), EXIT_EARLY, general, log_stru::log_level, logger, general_stru::no_daemon, general_stru::pid_file, and general_stru::port.

Referenced by main().

00511 {
00512   int opt = 0;
00513   const char *cmdopts = "hc:nVl:p:P:";
00514 
00515   // struct for the long options... neat, huh?
00516   struct option longopts[] =
00517   {
00518     { "help",      0, 0, 'h' },
00519     { "conf-file", 1, 0, 'c' },
00520     { "no-daemon", 0, 0, 'd' },
00521     { "version",   0, 0, 'V' },
00522     { "log-level", 1, 0, 'l' },
00523     { "port",      1, 0, 'p' },
00524     { "pid_file",  1, 0, 'P' },
00525     { 0,           0, 0, 0   }
00526   };
00527 
00528   while((opt = getopt_long(argc, argv, cmdopts, longopts, NULL)) != -1)
00529   {
00530     switch(opt)
00531     {
00532       case 'h':
00533         cout << "Usage: " << argv[0] << " [OPTION]...\n\n"
00534           << "  -h, --help            display this help and exit\n"
00535           << "  -c, --conf-file=FILE  supply another conf file instead "
00536           << "of the default\n"
00537           << "  -n, --no-daemon       do not fork into the background\n"
00538           << "  -V, --version         display version information and exit\n"
00539           << "  -l, --log-level=LEVEL set the log level, 1-10, default is 5\n"
00540           << "  -p, --port=PORT       specify an alternate port\n"
00541           << "  -P, --pid_file=FILE   a file to write our pid in\n\n"
00542           << "Please, report bugs, either directly to the developers\n"
00543           << "or via sourceforge (http://www.sf.net/projects/babyftpd).\n";
00544 
00545           exit_baby(0, EXIT_EARLY);
00546 
00547       case 'c':
00548         config->conf_file = optarg;
00549         break;
00550 
00551       case 'n':
00552         config->general.no_daemon = true;
00553         break;
00554 
00555       case 'V':
00556         cout << "BabyFTPd version " << VERSION << "\nBuilt on " << __DATE__
00557           << " " << " " << __TIME__ << endl;
00558         exit_baby(0, EXIT_EARLY);
00559 
00560       case 'l':
00561         // Log level code...
00562         if(atoi(optarg) > 10)
00563           logger.log_level = 10;
00564         else if(atoi(optarg) < 0)
00565           logger.log_level = 0;
00566         else
00567           logger.log_level = atoi(optarg);
00568         break;
00569 
00570       case 'p':
00571         // alternate port...
00572         config->general.port = atoi(optarg);
00573         break;
00574 
00575       case 'P':
00576         // pid_file
00577         config->general.pid_file = optarg;
00578     }
00579   }
00580   return true;
00581 }

Here is the call graph for this function:

bool Configuration::parse_config_file (  ) 

Definition at line 71 of file Configuration.cpp.

References conf_file, count_users(), fill_buff(), general, GENERAL, general_user, get_variables(), LOG, logger, StringTokenizer::nextToken(), num_users, parsed, set_structs(), StringTokenizer::StringTokenizer(), USER, and users.

Referenced by main(), and sig_handler().

00072 {
00073   vector<string> file_buff;
00074   if(!fill_buff(file_buff, conf_file))
00075     return(false);
00076 
00077   set_structs(get_variables(file_buff, "general", 1), GENERAL, &general);
00078   set_structs(get_variables(file_buff, "general", 2), USER, &general_user);
00079   set_structs(get_variables(file_buff, "log", 1), LOG, &logger);
00080 
00081   string user_names;
00082   num_users = count_users(file_buff, user_names) - 1; // first user is 0.
00083 
00084   class StringTokenizer *names = new StringTokenizer(user_names, ",", false);
00085   names->nextToken(); // not nice, but nicer.
00086 
00087   if(!users.empty()) // that is, on SIGHUP
00088     users.clear();
00089 
00090   users.reserve(num_users + 1);
00091   for(int i = 0; i < num_users; i++)
00092   {
00093     struct users_stru user_tmp = general_user;
00094     set_structs(get_variables(file_buff, names->nextToken().c_str(), 2),
00095         USER, &user_tmp);
00096     users.push_back(user_tmp);
00097   }
00098 
00099   parsed = true;
00100   delete names;
00101   return true;
00102 }

Here is the call graph for this function:

bool Configuration::set_structs ( string  ,
enum  sect,
void *   
) [private]

Definition at line 104 of file Configuration.cpp.

References A_DISABLE, A_ENABLE, A_ONLY, general_stru::admin_email, ALLOW, general_stru::anonymous, log_stru::authlog, CONF_ANON, CONF_BOOL, CONF_ENC, CONF_INT, CONF_LOGF, CONF_STRING, CONF_TIME, CONF_TIMEF, CONF_USER, general_stru::connection_limit, general_stru::data_port, log_stru::debuglog, DENY, general_stru::dh_regenerate, users_stru::encryption, FORCE, FORCE_CERT, general, GENERAL, general_stru::group, StringTokenizer::hasMoreTokens(), users_stru::id, users_stru::idle, log_stru::infolog, Utilities::itos(), general_stru::lifebeat_tick, LOG, log_stru::log_level, Log::log_this(), logging, StringTokenizer::nextToken(), general_stru::no_daemon, users_stru::noftp, users_stru::only_home, users_stru::only_passive, general_stru::pid_file, general_stru::port, PWBUF_SIZE, general_stru::readonly, StringTokenizer::restTokens(), users_stru::sim_data, StringTokenizer::StringTokenizer(), log_stru::thread_id, log_stru::time_format, general_stru::tls_ca, general_stru::tls_cert, general_stru::tls_crl, general_stru::tls_key, TYPE_INFO, general_stru::user, USER, users_stru::user_limit, util, general_stru::verify_client, general_stru::welcome_msg, log_stru::xferlog, and log_stru::xferlog_file.

Referenced by parse_config_file().

00106 {
00107   struct users_stru *usr_tmp = NULL;
00108   struct general_stru *gen_tmp = NULL;
00109   struct log_stru *log_tmp = NULL;
00110   vector<config_entry> this_entry;
00111   string for_log = "Configuration for ";
00112 
00113   switch(section)
00114   {
00115     case USER:
00116       {
00117         usr_tmp = (static_cast<struct users_stru*>(this_struct));
00118 
00119         this_entry.push_back(config_entry(
00120               "id", CONF_STRING, &usr_tmp->id));
00121         this_entry.push_back(config_entry(
00122               "sim_data", CONF_INT, &usr_tmp->sim_data));
00123         this_entry.push_back(config_entry(
00124               "idle", CONF_TIME, &usr_tmp->idle));
00125         this_entry.push_back(config_entry(
00126               "noftp", CONF_BOOL, &usr_tmp->noftp));
00127         this_entry.push_back(config_entry(
00128               "only_home", CONF_BOOL, &usr_tmp->only_home));
00129         this_entry.push_back(config_entry(
00130               "only_passive", CONF_BOOL, &usr_tmp->only_passive));
00131         this_entry.push_back(config_entry(
00132               "user_limit", CONF_INT, &usr_tmp->user_limit));
00133 #ifdef USE_TLS
00134         this_entry.push_back(config_entry(
00135               "encryption", CONF_ENC, &usr_tmp->encryption));
00136 #endif // USE_TLS
00137         for_log += "user section ";
00138       }
00139       break;
00140 
00141     case LOG:
00142 
00143       {
00144         log_tmp = (static_cast<struct log_stru*>(this_struct));
00145 
00146         this_entry.push_back(config_entry(
00147               "log_level", CONF_INT, &log_tmp->log_level));
00148         this_entry.push_back(config_entry(
00149               "xferlog", CONF_BOOL, &log_tmp->xferlog));
00150         this_entry.push_back(config_entry(
00151               "xferlog_file", CONF_LOGF, &log_tmp->xferlog_file));
00152         this_entry.push_back(config_entry(
00153               "authlog", CONF_LOGF, &log_tmp->authlog));
00154         this_entry.push_back(config_entry(
00155               "infolog", CONF_LOGF, &log_tmp->infolog));
00156         this_entry.push_back(config_entry(
00157               "debuglog", CONF_LOGF, &log_tmp->debuglog));
00158         this_entry.push_back(config_entry(
00159               "thread_id", CONF_BOOL, &log_tmp->thread_id));
00160         this_entry.push_back(config_entry(
00161               "time_format", CONF_TIMEF, &log_tmp->time_format));
00162         for_log += "log section ";
00163       }
00164       break;
00165 
00166     case GENERAL:
00167       {
00168         gen_tmp = (static_cast<struct general_stru*>(this_struct));
00169 
00170         this_entry.push_back(config_entry(
00171               "connection_limit", CONF_INT, &gen_tmp->connection_limit));
00172         this_entry.push_back(config_entry(
00173               "port", CONF_INT, &gen_tmp->port));
00174         this_entry.push_back(config_entry(
00175               "data_port", CONF_INT, &gen_tmp->data_port));
00176         this_entry.push_back(config_entry(
00177               "no_daemon", CONF_BOOL, &gen_tmp->no_daemon));
00178         this_entry.push_back(config_entry(
00179               "admin_email", CONF_STRING, &gen_tmp->admin_email));
00180         this_entry.push_back(config_entry(
00181               "welcome_msg", CONF_STRING, &gen_tmp->welcome_msg));
00182         this_entry.push_back(config_entry(
00183               "lifebeat_tick", CONF_TIME, &gen_tmp->lifebeat_tick));
00184         this_entry.push_back(config_entry(
00185               "user", CONF_USER, NULL));
00186         this_entry.push_back(config_entry(
00187               "pid_file", CONF_STRING, &gen_tmp->pid_file));
00188         this_entry.push_back(config_entry(
00189               "readonly", CONF_BOOL, &gen_tmp->readonly));
00190         this_entry.push_back(config_entry(
00191               "anonymous", CONF_ANON, &gen_tmp->anonymous));
00192 #ifdef USE_TLS
00193         this_entry.push_back(config_entry(
00194               "tls_key", CONF_STRING, &gen_tmp->tls_key));
00195         this_entry.push_back(config_entry(
00196               "tls_cert", CONF_STRING, &gen_tmp->tls_cert));
00197         this_entry.push_back(config_entry(
00198               "tls_ca", CONF_STRING, &gen_tmp->tls_ca));
00199         this_entry.push_back(config_entry(
00200               "tls_crl", CONF_STRING, &gen_tmp->tls_crl));
00201         this_entry.push_back(config_entry(
00202               "dh_regenerate", CONF_TIME, &gen_tmp->dh_regenerate));
00203         this_entry.push_back(config_entry(
00204               "verify_client", CONF_STRING, &gen_tmp->verify_client));
00205 #endif // USE_TLS
00206         for_log += "general section ";
00207       }
00208       break;
00209   }
00210   class StringTokenizer *var = new StringTokenizer(variables, "\n", false);
00211   string id = var->nextToken();
00212   if(section == USER)
00213   {
00214     *(string*)this_entry[0].variabel = id;
00215     for_log += "for " + id + " ";
00216   }
00217 
00218   while(var->hasMoreTokens())
00219   {
00220     string log_me, str = var->nextToken();
00221     class StringTokenizer *st = new StringTokenizer(str, " ", false);
00222     string op = st->nextToken();
00223     string arg = st->restTokens();
00224     vector<config_entry>::iterator this_it = this_entry.begin();
00225 
00226     for(; this_it != this_entry.end(); this_it++)
00227       if(op == (*this_it).name)
00228         break;
00229 
00230     if(this_it == this_entry.end())
00231       log_me = "Parameter " + op + " doesn't exist, check your spelling.";
00232     else
00233     {
00234       switch((*this_it).type)
00235       {
00236         case CONF_TIME:
00237         case CONF_ANON:
00238 #ifdef USE_TLS
00239         case CONF_ENC:
00240           if((*this_it).type == CONF_ENC)
00241           {
00242             if(arg == "allow")
00243               arg = util.itos(ALLOW);
00244             else if(arg == "deny")
00245               arg = util.itos(DENY);
00246             else if(arg == "force")
00247               arg = util.itos(FORCE);
00248             else if(arg == "force_cert")
00249               arg = util.itos(FORCE_CERT);
00250             else
00251               log_me = "only allow, force, foce_cert and deny are legal "
00252                 "parameters to encryption, " + arg + " isn't one of them.";
00253           }
00254           else
00255 #endif // USE_TLS
00256             if((*this_it).type == CONF_TIME)
00257             {
00258               int multi = 1;
00259               string::iterator st_it = arg.begin();
00260               for(; st_it != arg.end(); st_it++)
00261               {
00262                 if(isdigit(*st_it) || isspace(*st_it))
00263                   continue;
00264                 else
00265                   break;
00266               }
00267               if(st_it != arg.end())
00268               {
00269                 switch(*st_it)
00270                 {
00271                   case 's':
00272                     multi = 1;
00273                     break;
00274                   case 'm':
00275                     multi = 60;
00276                     break;
00277                   case 'h':
00278                     multi = 3600;
00279                     break;
00280                   case 'd':
00281                     multi = 86400;
00282                     break;
00283                   default:
00284                     log_me = "I don't understand your time unit \'";
00285                     log_me += *st_it;
00286                     log_me += "\' to paramater " + op + " I will ignore it.";
00287                 }
00288                 if(!log_me.empty())
00289                   break;
00290 
00291                 arg.erase(st_it, arg.end());
00292                 int temp_num = atoi(arg.c_str()) * multi;
00293                 arg = util.itos(temp_num);
00294               }
00295             }
00296             else if((*this_it).type == CONF_ANON)
00297             {
00298               if(arg == "enable")
00299                 arg = util.itos(A_ENABLE);
00300               else if(arg == "disable")
00301                 arg = util.itos(A_DISABLE);
00302               else if(arg == "only")
00303                 arg = util.itos(A_ONLY);
00304               else
00305                 log_me = "only enable, disable and only are legal "
00306                   "parameters to anonymous, " + arg + " isn't one of them.";
00307             }
00308         case CONF_INT:
00309           {
00310             int i_value = 0;
00311             bool error = false;
00312             for(string::iterator it = arg.begin(); it != arg.end(); it++)
00313               if(!isdigit(*it))
00314               {
00315                 error = true;
00316                 break;
00317               }
00318             if(!error)
00319               i_value = atoi(arg.c_str());
00320             else
00321               if(log_me.empty())
00322                 log_me = "Non int value supplied to " + op +
00323                   " value supplied was " + arg + ".";
00324 
00325             if(log_me.empty())
00326             {
00327               *(static_cast<int*>((*this_it).variabel)) = i_value;
00328               for_log += (*this_it).name + "=" + util.itos(i_value) + "; ";
00329             }
00330           }
00331           break;
00332 
00333         case CONF_BOOL:
00334           {
00335             bool b_value = true;
00336             if(arg == "true" || arg == "t" || arg == "1" || arg == "y")
00337               b_value = true;
00338             else if(arg == "false" || arg == "f" || arg == "0" || arg == "n")
00339               b_value = false;
00340             else
00341               log_me = arg + " not recognised as a boolean value supplied to "
00342                 + op + ".";
00343 
00344             if(log_me.empty())
00345             {
00346               *(static_cast<bool*>((*this_it).variabel)) = b_value;
00347               for_log += (*this_it).name + (b_value ? "=true; " : "=false; ");
00348             }
00349           }
00350           break;
00351 
00352         case CONF_USER:
00353           {
00354             struct passwd pwd, *pwd_ptr;
00355             struct group grp, *grp_ptr;
00356             char pwdata[PWBUF_SIZE], grpdata[PWBUF_SIZE];
00357             int delim = arg.find_first_of(':');
00358             getpwnam_r(arg.substr(0, delim).c_str(),
00359                 &pwd, pwdata, sizeof(pwdata), &pwd_ptr);
00360             getgrnam_r(arg.substr(delim + 1).c_str(),
00361                 &grp, grpdata, sizeof(grpdata), &grp_ptr);
00362             if(pwd_ptr == NULL)
00363             {
00364               log_me = "Tried to use nonexistent user " + arg.substr(0,
00365                   delim) + " to run the daemon under. using root instead.";
00366               pwd.pw_uid = 0;
00367               grp.gr_gid = 0;
00368             }
00369             else if(grp_ptr == NULL)
00370             {
00371               log_me = "Tried to use nonexistent group " + arg.substr(delim +1)
00372                 + " to run the daemon under. using root instead.";
00373               grp.gr_gid = 0;
00374             }
00375             general.user = pwd.pw_uid;
00376             general.group = grp.gr_gid;
00377             for_log += (*this_it).name + "=" +
00378               util.itos(pwd.pw_uid) + ":" + util.itos(grp.gr_gid) + "; ";
00379           }
00380           break;
00381 
00382         case CONF_LOGF:
00383           if(arg == "syslog")
00384             arg.clear();
00385         case CONF_TIMEF:
00386           if((*this_it).type == CONF_TIMEF)
00387             arg += " ";
00388         case CONF_STRING:
00389           *(static_cast<string*>((*this_it).variabel)) = arg;
00390           for_log += (*this_it).name + "=" + arg + "; ";
00391           break;
00392 
00393         default:
00394           log_me = "Parameter " + op + " doesn't exist, check your spelling.";
00395           break;
00396       }
00397     }
00398     delete st;
00399     if(!log_me.empty())
00400       logging->log_this(2, TYPE_INFO, log_me);
00401   }
00402 
00403   if(this->general.anonymous >= A_ENABLE && this->general.user == 0)
00404   {
00405     this->general.anonymous = A_DISABLE;
00406     logging->log_this(2, TYPE_INFO,
00407         "you enabled anonymous logins but you don't have a configured user."
00408         " anonymous logins disabled.");
00409   }
00410 
00411   logging->log_this(3, TYPE_INFO, for_log);
00412   delete var;
00413   return true;
00414 }

Here is the call graph for this function:


Member Data Documentation

int Configuration::num_users [private]

Definition at line 81 of file Configuration.h.

Referenced by parse_config_file().

bool Configuration::parsed [private]

Definition at line 82 of file Configuration.h.

Referenced by Configuration(), and parse_config_file().

vector<users_stru> Configuration::users [private]

Definition at line 80 of file Configuration.h.

Referenced by get_user(), and parse_config_file().


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