Ejemplo n.º 1
0
int main(int argc, char *argv[])
{
   int ret_value = 0;
   libettercap_init(PROGRAM, EC_VERSION);
   ef_globals_alloc();
   select_text_interface();
   libettercap_ui_init();
   /* etterfilter copyright */
   USER_MSG("\n" EC_COLOR_BOLD "%s %s" EC_COLOR_END " copyright %s %s\n\n", 
                      PROGRAM, EC_VERSION, EC_COPYRIGHT, EC_AUTHORS);
 
   /* initialize the line number */
   EF_GBL->lineno = 1;
  
   /* getopt related parsing...  */
   parse_options(argc, argv);

   /* set the input for source file */
   if (EF_GBL_OPTIONS->source_file) {
      yyin = fopen(EF_GBL_OPTIONS->source_file, "r");
      if (yyin == NULL)
         FATAL_ERROR("Input file not found !");
   } else {
      FATAL_ERROR("No source file.");
   }

   /* no buffering */
   setbuf(yyin, NULL);
   setbuf(stdout, NULL);
   setbuf(stderr, NULL);

   
   /* load the tables in etterfilter.tbl */
   load_tables();
   /* load the constants in etterfilter.cnt */
   load_constants();

   /* print the message */
   USER_MSG("\n Parsing source file \'%s\' ", EF_GBL_OPTIONS->source_file);

   ef_debug(1, "\n");

   /* begin the parsing */
   if (yyparse() == 0)
      USER_MSG(" done.\n\n");
   else
      USER_MSG("\n\nThe script contains errors...\n\n");
  
   /* write to file */
   ret_value = write_output();
   if (ret_value == -E_NOTHANDLED)
      FATAL_ERROR("Cannot write output file (%s): the filter is not correctly handled.", EF_GBL_OPTIONS->output_file);
   else if (ret_value == -E_INVALID)
      FATAL_ERROR("Cannot write output file (%s): the filter format is not correct. ", EF_GBL_OPTIONS->output_file);

   ef_exit(0);
}
Ejemplo n.º 2
0
/* This is the C kernel entry point */
void kmain(struct multiboot *mboot_header, addr_t initial_stack)
{
	/* Store passed values, and initiate some early things
	 * We want serial log output as early as possible */
	kernel_state_flags=0;
	mtboot = mboot_header;
	i_stack = initial_stack;
	parse_kernel_elf(mboot_header, &kernel_elf);
#if CONFIG_MODULES
	init_kernel_symbols();
#endif
	init_serial();
	console_init_stage1();
	load_tables();
	puts("~ SeaOS Version ");	
	char ver[32];
	get_kernel_version(ver);
	puts(ver);
	puts(" Booting Up ~\n\r");
#if CONFIG_MODULES
	init_module_system();
#endif
	init_syscalls();
	load_initrd(mtboot);
	install_timer(1000);
	pm_init(placement, mtboot);
	init_main_cpu_1();

	/* Now get the management stuff going */
	printk(1, "[kernel]: Starting system management\n");
	init_memory(mtboot);
	init_main_cpu_2();
	console_init_stage2();
	parse_kernel_cmd((char *)(addr_t)mtboot->cmdline);
	init_multitasking();
	init_cache();
	init_dm();
	init_vfs();
	/* Load the rest... */
	process_initrd();
	init_kern_task();
	get_timed(&kernel_start_time);
	printk(KERN_MILE, "[kernel]: Kernel is setup (%2.2d:%2.2d:%2.2d, %s, kv=%d, ts=%d bytes: ok)\n", 
	       kernel_start_time.tm_hour, kernel_start_time.tm_min, 
	       kernel_start_time.tm_sec, kernel_name, KVERSION, sizeof(task_t));
	assert(!set_int(1));
	if(!fork())
		init();
	sys_setsid();
	enter_system(255);
	kernel_idle_task();
}
Ejemplo n.º 3
0
int main(int argc, char *argv[])
{

   /* etterfilter copyright */
   fprintf(stdout, "\n" EC_COLOR_BOLD "%s %s" EC_COLOR_END " copyright %s %s\n\n", 
                      GBL_PROGRAM, EC_VERSION, EC_COPYRIGHT, EC_AUTHORS);
 
   /* initialize the line number */
   GBL.lineno = 1;
  
   /* getopt related parsing...  */
   parse_options(argc, argv);

   /* set the input for source file */
   if (GBL_OPTIONS.source_file) {
      yyin = fopen(GBL_OPTIONS.source_file, "r");
      if (yyin == NULL)
         FATAL_ERROR("Input file not found !");
   } else {
      FATAL_ERROR("No source file.");
   }

   /* no buffering */
   setbuf(yyin, NULL);
   setbuf(stdout, NULL);
   setbuf(stderr, NULL);

   
   /* load the tables in etterfilter.tbl */
   load_tables();
   /* load the constants in etterfilter.cnt */
   load_constants();

   /* print the message */
   fprintf(stdout, "\n Parsing source file \'%s\' ", GBL_OPTIONS.source_file);
   fflush(stdout);

   ef_debug(1, "\n");

   /* begin the parsing */
   if (yyparse() == 0)
      fprintf(stdout, " done.\n\n");
   else
      fprintf(stdout, "\n\nThe script contains errors...\n\n");
  
   /* write to file */
   if (write_output() != ESUCCESS)
      FATAL_ERROR("Cannot write output file (%s)", GBL_OPTIONS.output_file);

   return 0;
}
Ejemplo n.º 4
0
ErrorStack TpccLoadTask::run(thread::Thread* context) {
  context_ = context;
  engine_ = context->get_engine();
  xct_manager_ = engine_->get_xct_manager();
  load_threads_ = engine_->get_options().thread_.get_total_thread_count();
  thread_ordinal_ = context->get_thread_global_ordinal();
  ASSERT_ND(thread_ordinal_ < load_threads_);
  LOG(INFO) << "Load Thread-" << thread_ordinal_ << " start";
  debugging::StopWatch watch;
  CHECK_ERROR(load_tables());
  watch.stop();
  LOG(INFO) << "Load-Thread-" << thread_ordinal_ << " done in " << watch.elapsed_sec() << "sec";
  return kRetOk;
}
Ejemplo n.º 5
0
void do_load( char_data* ch, char* argument )
{
  if( *argument == '\0' ) {
    send( ch, "Which file do you wish to load?\r\n" );
    return;
    }

  if( matches( argument, "tables" ) ) {
    load_tables( );
    return;
    }

  send( ch, "Unknown file.\r\n" );
  return;
}
Ejemplo n.º 6
0
ElfFile::ElfFile(const char* filepath) {
  assert(filepath, "null file path");
  memset(&m_elfHdr, 0, sizeof(m_elfHdr));
  m_string_tables = NULL;
  m_symbol_tables = NULL;
  m_next = NULL;
  m_status = NullDecoder::no_error;

  int len = strlen(filepath) + 1;
  m_filepath = (const char*)os::malloc(len * sizeof(char));
  if (m_filepath != NULL) {
    strcpy((char*)m_filepath, filepath);
    m_file = fopen(filepath, "r");
    if (m_file != NULL) {
      load_tables();
    } else {
      m_status = NullDecoder::file_not_found;
    }
  } else {
    m_status = NullDecoder::out_of_memory;
  }
}
Ejemplo n.º 7
0
bool
NdbInfo::check_tables()
{
  if (unlikely(m_connection->get_connect_count() != m_connect_count ||
               m_connection->get_min_db_version() != m_min_db_version))
  {
    // Connect count or min db version of cluster has changed
    //  -> flush the cached table definitions
    flush_tables();
  }
  if (unlikely(m_tables.entries() <= NUM_HARDCODED_TABLES))
  {
    // Global table cache is not loaded yet or has been
    // flushed, try to load it
    if (!load_tables())
    {
      return false;
    }
  }
  // Make sure that some dynamic tables have been loaded
  assert(m_tables.entries() > NUM_HARDCODED_TABLES);
  return true;
}
Ejemplo n.º 8
0
int main(int argc, char** argv)
{

  int i, j, k, n;
  int rl, p , nwl;
  int al;

  FILE * wrdlst;
  FILE * afflst;

  char *nword, *wf, *af;
  char as[(MAX_PREFIXES + MAX_SUFFIXES)];
  char * ap;

  struct hentry * ep;
  struct hentry * ep1;
  struct affent * pfxp;
  struct affent * sfxp;

  /* first parse the command line options */
  /* arg1 - wordlist, arg2 - affix file */

  if (argv[1]) {
       wf = mystrdup(argv[1]);
  } else {
    fprintf(stderr,"correct syntax is:\n"); 
    fprintf(stderr,"munch word_list_file affix_file\n");
    exit(1);
  }
  if (argv[2]) {
       af = mystrdup(argv[2]);
  } else {
    fprintf(stderr,"correct syntax is:\n"); 
    fprintf(stderr,"munch word_list_file affix_file\n");
    exit(1);
  }

  /* open the affix file */
  afflst = fopen(af,"r");
  if (!afflst) {
    fprintf(stderr,"Error - could not open affix description file\n");
    exit(1);
  }

  /* step one is to parse the affix file building up the internal
     affix data structures */

  numpfx = 0;
  numsfx = 0;

  parse_aff_file(afflst);
  fclose(afflst);

  fprintf(stderr,"parsed in %d prefixes and %d suffixes\n",numpfx,numsfx);

  /* affix file is now parsed so create hash table of wordlist on the fly */

  /* open the wordlist */
  wrdlst = fopen(wf,"r");
  if (!wrdlst) {
    fprintf(stderr,"Error - could not open word list file\n");
    exit(1);
  }

  if (load_tables(wrdlst)) {
    fprintf(stderr,"Error building hash tables\n");
    exit(1);
  }
  fclose(wrdlst);

  for (i=0; i< tablesize; i++) {
    ep = &tableptr[i];
    if (ep->word == NULL) continue;
    for (  ;  ep != NULL;  ep = ep->next) {
      numroots = 0;
      aff_chk(ep->word,strlen(ep->word));
      if (numroots) {
            /* now there might be a number of combinations */
            /* of prefixes and suffixes that might match this */
            /* word.  So how to choose?  As a first shot look */
            /* for the shortest remaining root word to */
            /* to maximize the combinatorial power */

	    /* but be careful, do not REQUIRE a specific combination */
            /* of a prefix and a suffix to generate the word since */
            /* that violates the rule that the root word with just */
            /* the prefix or just the suffix must also exist in the */
            /* wordlist as well */

	    /* in fact because of the cross product issue, this not a  */
	    /* simple choice since some combinations of previous */ 
	    /* prefixes and new suffixes may not be valid. */
	    /*  The only way to know is to simply try them all */
  
            rl = 1000;
            p = -1;

            for (j = 0; j < numroots; j++){

	      /* first collect the root word info and build up */
              /* the potential new affix string */
               nword = (roots[j].hashent)->word;
               nwl = strlen(nword);
               *as = '\0';
               al = 0;
               ap = as;
               if (roots[j].prefix) *ap++ = (roots[j].prefix)->achar;
               if (roots[j].suffix) *ap++ = (roots[j].suffix)->achar;
               if ((roots[j].hashent)->affstr) {
		   strcpy(ap,(roots[j].hashent)->affstr);
               } else {
		 *ap = '\0';
               }
               al =strlen(as);

               /* now expand the potential affix string to generate */
               /* all legal words and make sure they all exist in the */
               /* word list */
               numwords = 0;
               wlist[numwords].word = mystrdup(nword);
               wlist[numwords].pallow = 0;
               numwords++;
               n = 0;
               if (al)
		 expand_rootword(nword,nwl,as,al);
               for (k=0; k<numwords; k++) {
		 if (lookup(wlist[k].word)) n++;
                 free(wlist[k].word);
                 wlist[k].word = NULL;
                 wlist[k].pallow = 0;
               }

               /* if all exist in word list then okay */
               if (n == numwords) {               
                  if (nwl < rl) {
                     rl = nwl;
                     p = j;
                  }
               }
            }
            if (p != -1) {
               ep1 = roots[p].hashent;
               pfxp = roots[p].prefix;
               sfxp = roots[p].suffix;
               ep1->keep = 1;
               if (pfxp != NULL) add_affix_char(ep1,pfxp->achar);
               if (sfxp != NULL) add_affix_char(ep1,sfxp->achar);
            } else {
	      ep->keep = 1;
            }
      } else {
            ep->keep = 1;
      }
    }
  }

  /* now output only the words to keep along with affixes info */
  /* first count how many words that is */
  k = 0;
  for (i=0; i< tablesize; i++) {
    ep = &tableptr[i];
    if (ep->word == NULL) continue;
    for (  ;  ep != NULL;  ep = ep->next) {
       if (ep->keep > 0) k++;
    }
  }
  fprintf(stdout,"%d\n",k);

  for (i=0; i< tablesize; i++) {
    ep = &tableptr[i];
    if (ep->word == NULL) continue;
    for (  ;  ep != NULL;  ep = ep->next) {
      if (ep->keep > 0) {
        if (ep->affstr != NULL) { 
	  fprintf(stdout,"%s/%s\n",ep->word,ep->affstr);
	} else {
          fprintf(stdout,"%s\n",ep->word);
        }
      }
    }
  }
  return 0;
}
Ejemplo n.º 9
0
void arch_cpu_early_init(void)
{
	load_tables();
}
Ejemplo n.º 10
0
/**
 * \param[in] argc argument count
 * \param[in] argv argument array
 * \return 0 on success, 1 on error
 * 
 * \attention In daemon mode, it finishes immediately.
 */
int main(int argc, char** argv)
{
  openlog(INCRON_DAEMON_NAME, INCRON_LOG_OPTS, INCRON_LOG_FACIL);
  
  syslog(LOG_NOTICE, "starting service (version %s, built on %s %s)", INCRON_VERSION, __DATE__, __TIME__);
  
  try {
    Inotify in;
    in.SetNonBlock(true);
    
    EventDispatcher ed(&in);
    
    try {
      load_tables(&in, &ed);
    } catch (InotifyException e) {
      int err = e.GetErrorNumber();
      syslog(LOG_CRIT, "%s: (%i) %s", e.GetMessage().c_str(), err, strerror(err));
      syslog(LOG_NOTICE, "stopping service");
      closelog();
      return 1;
    }
    
    signal(SIGTERM, on_signal);
    signal(SIGINT, on_signal);
    signal(SIGCHLD, on_signal);
    
    if (DAEMON)
      daemon(0, 0);
    
    uint32_t wm = IN_CLOSE_WRITE | IN_DELETE | IN_MOVE | IN_DELETE_SELF | IN_UNMOUNT;
    InotifyWatch watch(INCRON_TABLE_BASE, wm);
    in.Add(watch);
    
    syslog(LOG_NOTICE, "ready to process filesystem events");
    
    InotifyEvent e;
    
    struct pollfd pfd;
    pfd.fd = in.GetDescriptor();
    pfd.events = (short) POLLIN;
    pfd.revents = (short) 0;
    
    while (!g_fFinish) {
      
      int res = poll(&pfd, 1, -1);
      if (res > 0) {
        in.WaitForEvents(true);
      }
      else if (res < 0) {
        if (errno != EINTR)
          throw InotifyException("polling failed", errno, NULL);
      }
      
      UserTable::FinishDone();
      
      while (in.GetEvent(e)) {
        
        if (e.GetWatch() == &watch) {
          if (e.IsType(IN_DELETE_SELF) || e.IsType(IN_UNMOUNT)) {
            syslog(LOG_CRIT, "base directory destroyed, exitting");
            g_fFinish = true;
          }
          else if (!e.GetName().empty()) {
            SUT_MAP::iterator it = g_ut.find(e.GetName());
            if (it != g_ut.end()) {
              UserTable* pUt = (*it).second;
              if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) {
                syslog(LOG_INFO, "table for user %s changed, reloading", e.GetName().c_str());
                pUt->Dispose();
                pUt->Load();
              }
              else if (e.IsType(IN_MOVED_FROM) || e.IsType(IN_DELETE)) {
                syslog(LOG_INFO, "table for user %s destroyed, removing", e.GetName().c_str());
                delete pUt;
                g_ut.erase(it);
              }
            }
            else if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) {
              if (check_user(e.GetName().c_str())) {
                syslog(LOG_INFO, "table for user %s created, loading", e.GetName().c_str());
                UserTable* pUt = new UserTable(&in, &ed, e.GetName());
                g_ut.insert(SUT_MAP::value_type(e.GetName(), pUt));
                pUt->Load();
              }
            }
          }
        }
        else {
          ed.DispatchEvent(e);
        }
      }
    }
  } catch (InotifyException e) {
    int err = e.GetErrorNumber();
    syslog(LOG_CRIT, "*** unhandled exception occurred ***");
    syslog(LOG_CRIT, "  %s", e.GetMessage().c_str());
    syslog(LOG_CRIT, "  error: (%i) %s", err, strerror(err));
  }

  syslog(LOG_NOTICE, "stopping service");
  
  closelog();
  
  return 0;
}
Ejemplo n.º 11
0
/**
 * \param[in] argc argument count
 * \param[in] argv argument array
 * \return 0 on success, 1 on error
 * 
 * \attention In daemon mode, it finishes immediately.
 */
int main(int argc, char** argv)
{
  AppArgs::Init();

  if (!(  AppArgs::AddOption("about",       '?', AAT_NO_VALUE, false)
      &&  AppArgs::AddOption("help",        'h', AAT_NO_VALUE, false)
      &&  AppArgs::AddOption("foreground",  'n', AAT_NO_VALUE, false)
      &&  AppArgs::AddOption("kill",        'k', AAT_NO_VALUE, false)
      &&  AppArgs::AddOption("config",      'f', AAT_MANDATORY_VALUE, false)
      &&  AppArgs::AddOption("version",     'V', AAT_NO_VALUE, false)))
  {
    fprintf(stderr, "error while initializing application");
    return 1;
  }
  
  AppArgs::Parse(argc, argv);
  
  if (AppArgs::ExistsOption("help")) {
    fprintf(stderr, "%s\n", INCROND_HELP);
    return 0;
  }
  
  if (AppArgs::ExistsOption("about")) {
    fprintf(stderr, "%s\n", INCROND_DESCRIPTION);
    return 0;
  }
  
  if (AppArgs::ExistsOption("version")) {
    fprintf(stderr, "%s\n", INCROND_VERSION);
    return 0;
  }
  
  IncronCfg::Init();
  
  std::string cfg;
  if (!AppArgs::GetOption("config", cfg))
    cfg = INCRON_CONFIG;
  IncronCfg::Load(cfg);
  
  std::string lckdir;
  IncronCfg::GetValue("lockfile_dir", lckdir);
  std::string lckfile;
  IncronCfg::GetValue("lockfile_name", lckfile);
  AppInstance app(lckfile, lckdir);
  
  if (AppArgs::ExistsOption("kill")) {
    fprintf(stderr, "attempting to terminate a running instance of incrond...\n");
    if (app.Terminate()) {
      fprintf(stderr, "the instance notified, going down\n");
      return 0;
    }
    else { 
      fprintf(stderr, "error - incrond probably not running\n");
      return 1;
    }
  }
  
  if (AppArgs::ExistsOption("foreground"))
    g_daemon = false;
  
  
  openlog(INCROND_NAME, INCRON_LOG_OPTS, INCRON_LOG_FACIL);
  
  syslog(LOG_NOTICE, "starting service (version %s, built on %s %s)", INCRON_VERSION, __DATE__, __TIME__);
  
  AppArgs::Destroy();
  
  int ret = 0;
  
  std::string sysBase;
  std::string userBase;
  
  if (!IncronCfg::GetValue("system_table_dir", sysBase))
    throw InotifyException("configuration is corrupted", EINVAL);
  
  if (access(sysBase.c_str(), R_OK) != 0) {
    syslog(LOG_CRIT, "cannot read directory for system tables (%s): (%i) %s", sysBase.c_str(), errno, strerror(errno));
    if (!g_daemon)
        fprintf(stderr, "cannot read directory for system tables (%s): (%i) %s", sysBase.c_str(), errno, strerror(errno));
    ret = 1;
    goto error;
  }
  
  if (!IncronCfg::GetValue("user_table_dir", userBase))
    throw InotifyException("configuration is corrupted", EINVAL);
  
  if (access(userBase.c_str(), R_OK) != 0) {
    syslog(LOG_CRIT, "cannot read directory for user tables (%s): (%i) %s", userBase.c_str(), errno, strerror(errno));
    if (!g_daemon)
        fprintf(stderr, "cannot read directory for user tables (%s): (%i) %s", userBase.c_str(), errno, strerror(errno));
    ret = 1;
    goto error;
  }
  
  try {
    if (g_daemon)
      if (daemon(0, 0) == -1) {
        syslog(LOG_CRIT, "daemonizing failed: (%i) %s", errno, strerror(errno));
        fprintf(stderr, "daemonizing failed: (%i) %s\n", errno, strerror(errno));
        ret = 1;
        goto error;
      }
  
    try {
    if (!app.Lock()) {
      syslog(LOG_CRIT, "another instance of incrond already running");
      if (!g_daemon)
        fprintf(stderr, "another instance of incrond already running\n");
      ret = 1;
      goto error;
      }
    } catch (AppInstException e) {
      syslog(LOG_CRIT, "instance lookup failed: (%i) %s", e.GetErrorNumber(), strerror(e.GetErrorNumber()));
      if (!g_daemon)
        fprintf(stderr, "instance lookup failed: (%i) %s\n", e.GetErrorNumber(), strerror(e.GetErrorNumber()));
      ret = 1;
      goto error;
    }
    
    prepare_pipe();
    
    Inotify in;
    in.SetNonBlock(true);
    in.SetCloseOnExec(true);
    
    uint32_t wm = IN_CREATE | IN_CLOSE_WRITE | IN_DELETE | IN_MOVE | IN_DELETE_SELF | IN_UNMOUNT;
    InotifyWatch stw(sysBase, wm);
    in.Add(stw);
    InotifyWatch utw(userBase, wm);
    in.Add(utw);
    
    EventDispatcher ed(g_cldPipe[0], &in, &stw, &utw);
    
    try {
      load_tables(&ed);
    } catch (InotifyException e) {
      int err = e.GetErrorNumber();
      syslog(LOG_CRIT, "%s: (%i) %s", e.GetMessage().c_str(), err, strerror(err));
      ret = 1;
      goto error;
    }
    
    ed.Rebuild(); // not too efficient, but simple 
    
    signal(SIGTERM, on_signal);
    signal(SIGINT, on_signal);
    signal(SIGCHLD, on_signal);
    
    syslog(LOG_NOTICE, "ready to process filesystem events");
    
    while (!g_fFinish) {
      
      int res = poll(ed.GetPollData(), ed.GetSize(), -1);
      
      if (res > 0) {
        if (ed.ProcessEvents())
          UserTable::FinishDone();
      }
      else if (res < 0) {
        switch (errno) {
          case EINTR:   // syscall interrupted - continue polling
            break;
          case EAGAIN:  // not enough resources - wait a moment and try again
            syslog(LOG_WARNING, "polling failed due to resource shortage, retrying later...");
            sleep(POLL_EAGAIN_WAIT);
            break;
          default:
            throw InotifyException("polling failed", errno, NULL);
        } 
      }
      
    }
    
    free_tables(&ed);
    
    if (g_cldPipe[0] != -1)
      close(g_cldPipe[0]);
    if (g_cldPipe[1] != -1)
      close(g_cldPipe[1]);
  } catch (InotifyException e) {
    int err = e.GetErrorNumber();
    syslog(LOG_CRIT, "*** unhandled exception occurred ***");
    syslog(LOG_CRIT, "  %s", e.GetMessage().c_str());
    syslog(LOG_CRIT, "  error: (%i) %s", err, strerror(err));
    ret = 1;
  }

error:

  syslog(LOG_NOTICE, "stopping service");
  
  closelog();
  
  return ret;
}
Ejemplo n.º 12
0
int startup(int argc, char* argv[])
{
  const char* tmp;
  const char* end;
  const char* cwdstr;
  char* ptr;
  unsigned long session_timeout;
  unsigned startup_code;

  if ((tmp = getenv("TCPLOCALIP")) == 0) FAIL("Missing $TCPLOCALIP.");
  if (!parse_localip(tmp)) FAIL("Could not parse $TCPLOCALIP.");
  if ((tmp = getenv("TCPREMOTEIP")) == 0) FAIL("Missing $TCPREMOTEIP.");
  if (!parse_remoteip(tmp)) FAIL("Could not parse $TCPREMOTEIP.");
  if ((tmp = getenv("UID")) == 0) FAIL("Missing $UID.");
  if (!(uid = strtou(tmp, &end)) || *end) FAIL("Invalid $UID.");
  if ((tmp = getenv("GID")) == 0) FAIL("Missing $GID.");
  if (!(gid = strtou(tmp, &end)) || *end) FAIL("Invalid $GID.");
  if ((home = getenv("HOME")) == 0) FAIL("Missing $HOME.");
  if ((tmp = getenv("GIDS")) != 0 && !parse_gids(tmp))
    FAIL("Could not parse or set supplementary group IDs.");

  /* Strip off trailing slashes in $HOME */
  ptr = (char*)home + strlen(home)-1;
  while (ptr > home && *ptr == '/') *ptr-- = 0;

  if ((user = getenv("USER")) == 0) FAIL("Missing $USER.");
  if ((group = getenv("GROUP")) == 0) group = "mygroup";
  if (chdir(home)) FAIL("Could not chdir to $HOME.");
  if (!load_tables()) FAIL("Loading startup tables failed.");
  if (getenv("CHROOT") != 0) {
    cwdstr = "/";
    if (chroot(".")) FAIL("Could not chroot.");
  }
  else if (getenv("SOFTCHROOT") != 0) {
    cwdstr = "/";
  }
  else {
    cwdstr = home;
    if (chdir("/")) FAIL("Could not chdir to '/'.");
  }
  if (!str_copys(&cwd, cwdstr)) FAIL("Could not set CWD string");
  if (setgid(gid)) FAIL("Could not set GID.");
  if (setuid(uid)) FAIL("Could not set UID.");
  if ((user_len = strlen(user)) > MAX_NAME_LEN) {
    user_len = MAX_NAME_LEN;
    ((char*)user)[MAX_NAME_LEN] = 0;
  }
  if ((group_len = strlen(group)) > MAX_NAME_LEN) {
    group_len = MAX_NAME_LEN;
    ((char*)group)[MAX_NAME_LEN] = 0;
  }

  lockhome = (getenv("LOCKHOME") != 0);
  nodotfiles = (getenv("NODOTFILES") != 0);
  list_options = (nodotfiles ? 0 : PATH_MATCH_DOTFILES);

  session_timeout = 0;
  if ((tmp = getenv("SESSION_TIMEOUT")) != 0)
    session_timeout = strtou(tmp, &tmp);
  alarm(session_timeout);
  connect_timeout = timeout;
  if ((tmp = getenv("CONNECT_TIMEOUT")) != 0)
    connect_timeout = strtou(tmp, &tmp);

  if ((tmp = getenv("TWOFTPD_BIND_PORT_FD")) != 0) {
    if ((bind_port_fd = strtou(tmp, &end)) == 0 || *end != 0)
      FAIL("Invalid $TWOFTPD_BIND_PORT_FD");
  }
  else
    bind_port_fd = -1;

  startup_code = (getenv("AUTHENTICATED") != 0) ? 230 : 220;
  if ((tmp = getenv("BANNER")) != 0) show_banner(startup_code, tmp);
  message_file = getenv("MESSAGEFILE");
  show_message_file(startup_code);
  return respond(startup_code, 1, "Ready to transfer files.");
  (void)argc;
  (void)argv;
}