Logo Search packages:      
Sourcecode: netams version File versions  Download package

main.c

/*************************************************************************
***   Authentication, authorization, accounting + firewalling package
***   Copyright 1998-2002 Anton Vinokurov <anton@netams.com>
***   Copyright 2002-2008 NeTAMS Development Team
***   This code is GPL v3
***   For latest version and more info, visit this project web page
***   located at http://www.netams.com
***
*************************************************************************/
/* $Id: main.c,v 1.106 2009-07-21 12:53:06 jura Exp $ */

#include "netams.h"

/////////////////////////////////////////////////////////////
void aMainInit();
void aMainRelease();
/////////////////////////////////////////////////////////////
Service *sMain;
extern Service *sSched;
int global_return_code=0;
int is_running=0;
language lang=LANG_EN;

int flag_nodaemon=0, flag_log=0, flag_quiet=0, flag_pid=0, flag_nopid=0, flag_syslog=0;
FILE *LOGFILE;
FILE *configfile;
char *config_file_name=NULL;
char *pid_file_name=NULL;
struct timeval program_start;
time_t start_t;

struct timeval when_config_changed;
int is_autosave=0;

/////////////////////////////////////////////////////////////
extern void CalibrateClock();
void InitVersion();
/////////////////////////////////////////////////////////////
int main(int argc, char **argv){
      int op;
      char buf[32];

      gettimeofday(&program_start, NULL);
      start_t     = program_start.tv_sec;

      when_config_changed.tv_sec=0; // never changed yet

      while((op=getopt(argc, argv, "qdlLPsf:p:")) != EOF){
            switch(op){
                  case 'q':
                        flag_quiet = 1;
                        break;
                  case 'd': flag_nodaemon = 1;
                        break;
                  case 'l':
                        flag_log = 1;
                        flag_pid = 1;
                        break;
                  case 'L':
                        flag_syslog = 1;
                        flag_pid = 1;
                        break;
                  case 'P':
                        flag_nopid = 1;
                        break;
                  case 'p':
                        pid_file_name=strdup(optarg);
                        flag_pid = 1;
                        break;
                  case 'f':
                        config_file_name=strdup(optarg);
                        break;
                  default:
                        break;
            }
      }

      // umask(026) for logs, config, storage
      //  umask(S_IWGRP | S_IROTH | S_IWOTH );

      // We should close all available file descriptors except LOGFILE and syslog's fd.
      // daemon(...) closes only stdin, stdout, stderr, but there may be others.
      // We have to do this here, because later (near daemon(...)) we'll need to do some tricks to avoid syslog's fd closing.
      if (flag_quiet&&!flag_nodaemon) {
            int maxfd, fd;
            maxfd = sysconf(_SC_OPEN_MAX);
            for (fd = 3; fd < maxfd; ++fd)
                  close(fd);
      }

      if (flag_log) {
            LOGFILE = fopen(path_to_log, "at");
            if (LOGFILE==NULL) {
                  fprintf(stderr, "LOGFILE %s opening: %s\n", path_to_log, strerror(errno));
                  aMainRelease();
                  exit(-1);
            }
            setvbuf(LOGFILE, NULL, _IOLBF, 0);
      }

      aMainInit();

      if (flag_syslog) openlog("netams", 0, LOG_DAEMON);
      if (!flag_quiet) puts(SHOW_VERSION);
      if (flag_log) aShowVersion(LOGFILE);

      if (config_file_name==NULL)
            config_file_name=set_string((char*)path_to_config);

      if (!flag_nodaemon) {
            if(chdir(RUN_PATH)<0) {
                  mkdir(RUN_PATH,S_IRWXU);
            }
            if(chdir(RUN_PATH)<0)
                  aLog(D_CRIT, "Cannot chdir to directory %s: %s\n",RUN_PATH,strerror(errno));

            aLog(D_INFO, "Becoming a daemon...\n");
            daemon(1, !flag_quiet);
      } else {
            CLI->client=stdout;
            aLog(D_INFO, "Stay in debug mode...\n");
      }

      if (flag_pid && !flag_nopid) {
            if (pid_file_name==NULL) pid_file_name=set_string("/var/run/netams.pid");
            FILE *pidfile = fopen(pid_file_name, "wt");

            if (pidfile!=NULL) {
                  fprintf(pidfile, "%u\n", getpid());
                  fclose(pidfile);
            } else {
                  fprintf(stderr, "Can't create pid-file: %s\n", strerror(errno));
            }
      }

      CalibrateClock();

      // handling signals
      signal(SIGHUP, (sig_t)logrotate);
      signal(SIGUSR1, (sig_t)logrotate);
      signal(SIGQUIT, (sig_t)termination);
      signal(SIGINT, (sig_t)termination);
      signal(SIGTERM, (sig_t)termination);

      aPermissionsInit();

      aDebugAdd(&debug, "none");
      sMain=new Service(SERVICE_MAIN);
      Services->Insert(sMain);
      pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
      sMain->t_id=pthread_self();

      {
            FILE *file = fopen( config_file_name, "rt");
            if(!file) {
                  aLog(D_CRIT, "main/configfile opening: %s\n", strerror(errno));
                  aMainRelease();
                  exit(-1);
            }
            //read for new commands
            cli_file(CLI, file, PRIVILEGE_PRIVILEGED, MODE_CONFIG);
            fclose(file);
      }

      if (!Services->getService(SERVICE_SCHEDULER, 0)) {
            sSched=InitSchedulerService();
            sSched->serv_flags|=SERVICE_FLAG_VISIBLE;
            Services->Insert(sSched);
            sSched->cli_mode = MODE_SCHEDULER;
            sSched->id = Services->num_objects; //workaround for List hash
      }

      Services->StartAll();

      sMain->Sleep(1); //we must sleep to be sure all services started

      if (!flag_quiet)
            printf("%s is now operational, %s\n", aaa_fw_software_name, timeU2T(time(NULL), buf));

      LogEvent(SYSTEM, 0, 0, 0, "NeTAMS Startup %s %s", SHOW_VERSION, config_file_name);

      is_running=1;

      sMain->Sleep();

      // the last actual action
      is_running=0;

      /////////////////////////////////////////////////////////////
      // exit point
      if (!flag_quiet)
            printf("\n%s signal received at %s\n", signal_name[global_return_code], timeU2T(time(NULL), buf));
      aLog(D_INFO, "%s signal received at %s\n", signal_name[global_return_code], timeU2T(time(NULL), buf));
      LogEvent(SYSTEM, 0, 0, 0, "NeTAMS Shutdown");

      if(global_return_code!=KILL)
            Services->ShutdownAll();

      free(config_file_name); //we need this for "save"

      if (flag_pid && !flag_nopid && (pid_file_name!=NULL)) {
            unlink(pid_file_name);
            free(pid_file_name);
      }

      aMainRelease();

      aLog(D_INFO, "%s exiting with code %d\n", aaa_fw_software_name, global_return_code);
      if (!flag_quiet)
            printf("%s exiting at %s\n", aaa_fw_software_name, timeU2T(time(NULL), buf));

      if (flag_log) fclose(LOGFILE);

      if (flag_syslog) closelog();

      if( global_return_code == RELOAD )
            if (-1==execvp(argv[0],argv)) perror("reload failed");

      return global_return_code;
}
///////////////////////////////////////////////////////////////////////////////////
void InitVersion() {
      print_to_string(&SHOW_VERSION, "%s %u.%u.%u (%u",
            aaa_fw_software_name, aaa_fw_major_version,
            aaa_fw_minor_version, aaa_fw_subversion, aaa_fw_build_version);
      if (aaa_fw_build_version_local)
            print_to_string(&SHOW_VERSION, ".%u", aaa_fw_build_version_local);
      if (buildforstring)
            print_to_string(&SHOW_VERSION, "-%s", buildforstring);
      print_to_string(&SHOW_VERSION, ") %s / %s", aaa_fw_build_person, aaa_fw_build_time);
}
////////////////////////////////////////////////////////////////////////////////////
void aMainInit() {
      aInitCli();
      aDebugInit();

      aMutexDebugInit();
      aMemoryDebugInit();

      aOidsInit();

      MsgMgr            = new MessageManager();
      PolicyL           = new PolicyList();
    Units         = new NetUnitsList();
      Users             = new UsersList();

      Services        = new ServicesList();
      Connections     = new ConnectionsList();

      InitVersion();
}

void aMainRelease() {
      delete Services;  Services=NULL;
      delete Connections;     Connections=NULL;
      aFree(SHOW_VERSION);

      delete Users;     Users=NULL;
      delete Units;     Units=NULL;
      delete PolicyL;   PolicyL=NULL;
      delete MsgMgr;  MsgMgr=NULL;

      aMemoryDebugRelease();
      aMutexDebugRelease();

      aReleaseCli();
}
/////////////////////////////////////////////////////////////

Generated by  Doxygen 1.6.0   Back to index