예제 #1
0
파일: server.c 프로젝트: Dim-ka/countctl
int main(int argc, char *argv[]){

	struct srv_connection conn;
	int cli_ct;

	FILE *fin;

	if (argc!=3) {
		printf("Bad param\n");
		return 1;
	}

	cli_ct = atoi(argv[2]);

	fin = fopen(argv[1], "r");
	if (fin == NULL) {
		printf("err file");
		return 1;
	}

	make_daemon(argv[1]);

	create_workers(cli_ct);
	
	init_connection(&conn, cli_ct);

	process_file(fin, &conn);

	fclose(fin);

	close_connection(&conn);

	return 0;
}
gint
main (gint                argc,
      const gchar * const argv[])
{
  EmerDaemon *daemon = make_daemon (argc, argv);
  if (daemon == NULL)
    return EXIT_FAILURE;

  GMainLoop *main_loop = g_main_loop_new (NULL, TRUE);

  // Shut down on any of these signals.
  g_unix_signal_add (SIGHUP, (GSourceFunc) quit_main_loop, main_loop);
  g_unix_signal_add (SIGINT, (GSourceFunc) quit_main_loop, main_loop);
  g_unix_signal_add (SIGTERM, (GSourceFunc) quit_main_loop, main_loop);
  g_unix_signal_add (SIGUSR1, (GSourceFunc) quit_main_loop, main_loop);
  g_unix_signal_add (SIGUSR2, (GSourceFunc) quit_main_loop, main_loop);

  guint name_id = g_bus_own_name (G_BUS_TYPE_SYSTEM, "com.endlessm.Metrics",
                                  G_BUS_NAME_OWNER_FLAGS_NONE,
                                  on_bus_acquired,
                                  NULL /* name_acquired_callback */,
                                  on_name_lost,
                                  daemon, NULL /* user data free func */);

  g_main_loop_run (main_loop);

  g_object_unref (daemon);
  g_bus_unown_name (name_id);
  g_main_loop_unref (main_loop);

  return EXIT_SUCCESS;
}
예제 #3
0
파일: cnat.c 프로젝트: millken/zhuxianB30
/*******************************************************************************
 函数名称  : main
 功能描述  : 程序的入口
 输入参数  :argc : 命令参数的个数
 			    argv : 命令参数
 输出参数  : 无
 返 回 值      : ERROR_SUCCESS
------------------------------------------------------------
 最近一次修改记录 :
 修改作者   : 阮春博
 修改目的   : 新增函数
 修改日期   : 2012年3 月21 日
*******************************************************************************/
s32 main(int argc, char **argv)
{
	s32 ret;
	s32 opt;
	s32 daemon_flag = 1;
	struct cnat_global_data data;

	while(-1 != (opt = getopt(argc, argv, "n")))
	{
		switch(opt)
		{
			case 'n':
				daemon_flag = 0;
			default:
			{
			}
		}
	}

	
	/*	如果有-n选项,则不构造daemon	*/
	if (daemon_flag)
	{
		ret = make_daemon(CNAT_PID_FILE);
		if (ERROR_SUCCESS != ret)
		{
			return ERROR_FAIL;
		}
	}


	memset(&data, 0, sizeof(struct cnat_global_data));

	dloop_init();

	/*注册SIGHUP SIGTERM 信号*/
	dloop_register_signal(SIGHUP, sig_hup_handle, &data);
	dloop_register_signal(SIGTERM, sig_term_handle, NULL);

	/*添加连接服务器,循环直到连接成功。*/
    cnat_server_connect_suc(&data);

	dloop_run();

	dloop_destroy();

	return ERROR_SUCCESS;
	
}
예제 #4
0
int main ( int argc, char** argv )
{
	int sock, rc, one = 1;
	struct pollfd pfd;
	struct _socket_handle_data* handle;
	pthread_t ptt;
	struct sockaddr_in local_addr;
	// make us a daemon process
	if (argc > 1 && !strcmp(argv[1], "--foreground"))
	{
	}
	else
	{
		make_daemon();
	}
	// set up listener socket
	sock = socket(AF_INET, SOCK_STREAM, 0);
	// bind
	local_addr.sin_len = sizeof(local_addr);
	local_addr.sin_family = AF_INET;
	local_addr.sin_port = htons(33940);
	local_addr.sin_addr.s_addr = INADDR_ANY;
	bind(sock, (struct sockaddr*)&local_addr, sizeof(local_addr));
	// make it listen
	listen(sock, 5);
	// prepare to poll
	while (1)
	{
		pfd.fd = sock;
		pfd.events = POLLIN;
		pfd.revents = 0;
		// poll for input
		rc = poll(&pfd, 1, -1);
		// we got some!
		if (rc > 0)
		{
			// create the new handle, fill it with data
			handle = malloc(sizeof(struct _socket_handle_data));
			handle->fd = accept(sock, (struct sockaddr*)&(handle->remote_address), &(handle->remote_address_len));
			printf("Handling new connection, fd=%d\n", handle->fd);
			// set SO_LINGER
			setsockopt(handle->fd, 6, SO_LINGER, &one, sizeof(one));
			// dispatch in another thread
			pthread_create(&ptt, NULL, socket_handle, handle);
			pthread_detach(ptt);
		}
	}
	return 0;
}
예제 #5
0
/*******************************************************************************
 函数名称  : main
 功能描述  : hotb入口
 输入参数  : argc ---- 命令参数个数
                               argv ---- 命令参数
 输出参数  : 无
 返 回 值      : ERROR_SUCCESS ----  成功
                           其它错误码
------------------------------------------------------------
 最近一次修改记录 :
 修改作者   : 王群
 修改目的   : 新增函数
 修改日期   : 2011年12月12日
*******************************************************************************/
int main(s32 argc, s8 *argv[])
{
	s32 opt;
	s32 daemon_flag = 1;
	s32 retcode = ERROR_FAIL;
	struct hotb_global_data data;
	
	memset(&data, 0, sizeof(struct hotb_global_data));
	while(-1 != (opt = getopt(argc, argv, "n")))
	{
		switch(opt)
		{
			case 'n':
				daemon_flag = 0;
			default:
			{
			}
		}
	}
	/*如果有-n选项,则不构造daemon*/
	if (daemon_flag)
	{
		retcode = make_daemon(HOTB_PID_FILE_PATH);
		if (ERROR_SUCCESS != retcode)
		{
			return ERROR_FAIL;
		}
	}
	dloop_init();
	//双机热备客户端初始化
	retcode = hotb_client_init(&data);
	if (ERROR_SUCCESS != retcode)
	{
		goto out;
	}
	//连接服务端
	hotb_client_connect_handle(&data);
	//注册socket,信号处理函数
	dloop_register_signal_terminate(hotb_terminate_handle, NULL);
	dloop_register_read_sock(data.if_sock, hotb_if_change_handle, &data, NULL);
	dloop_register_read_sock(data.l_sock, hotb_local_socket_handle, &data, NULL);
	dloop_run();

out:
	dloop_destroy();
	exit(1);
	return retcode;
}
예제 #6
0
파일: ocamlmerlin.c 프로젝트: dra27/merlin
static void start_server(const char *socketname, const char* ignored, const char *exec_path)
{
  int sock = socket(PF_UNIX, SOCK_STREAM, 0);
  if (sock == -1)
    failwith_perror("socket");

  int err;

  BEGIN_PROTECTCWD
    struct sockaddr_un address;
    int address_len;

    chdir(path_socketdir());
    address.sun_family = AF_UNIX;
    snprintf(address.sun_path, 104, "./%s", socketname);
    address_len = strlen(address.sun_path) + sizeof(address.sun_family) + 1;
    unlink(address.sun_path);

    NO_EINTR(err, bind(sock, (struct sockaddr*)&address, address_len));
  END_PROTECTCWD

  if (err == -1)
    failwith_perror("bind");

  if (listen(sock, 5) == -1)
    failwith_perror("listen");

  pid_t child = fork();

  if (child == -1)
    failwith_perror("fork");

  if (child == 0)
  {
    make_daemon(sock);

    char socket_fd[50], socket_path[PATHSZ];
    sprintf(socket_fd, "%d", sock);
    snprintf(socket_path, PATHSZ, "%s/%s", path_socketdir(), socketname);
    //execlp("nohup", "nohup", exec_path, "server", socket_path, socket_fd, NULL);
    execlp(exec_path, exec_path, "server", socket_path, socket_fd, NULL);
    failwith_perror("execlp");
  }

  close(sock);
  wait(NULL);
}
예제 #7
0
int main(int argc, char **argv) {
	int alive, kill, live;

	openlog("angeld",LOG_PID | LOG_CONS,LOG_USER);

	/* Set defaults */
	kill = 0;
	live = 0;

	/* Parse arguments */
	if(argc <= 1) goto help;

	if(strcmp(argv[1],"start") == 0) live = 1;
	else if(strcmp(argv[1],"restart") == 0) kill = live = 1;
	else if(strcmp(argv[1],"stop") == 0) kill = 1;
	else { /* Fools! */
help:
		puts("usage: angeld (start|restart|stop)");
		exit(EXIT_SUCCESS);
	}

	/* Check PID file */
	if(kill || live) {
		alive = is_alive();

		if(kill && !alive) syslog(LOG_INFO,"nothing to kill");
		kill &= alive;

		if(!kill && live && alive)
			syslog(LOG_INFO,"angeld already alive");
		live &= kill || !alive;
	}

	/* To be or not to be... */
	if(kill) kill_daemon();

	if(live) {
		make_daemon();
		init_com();
		monitor();
	}

	closelog();

	return !(kill || live);
}
예제 #8
0
파일: sntpd.c 프로젝트: millken/zhuxianB30
int main(int argc, char* argv[])
{
    s8  pServer[16] = {0};
    int c;
    int interval = SNTP_DEFAULT_POLL;
    s32 ret;

    for (;;)
    {
        c = getopt(argc, argv, "hi:[c:s]");
        if (c < 0)
        {
            break;
        }
        switch (c)
        {
        case 'c':   /* Client */
            strncpy(pServer, optarg, sizeof(pServer) - 1);
            pServer[sizeof(pServer) - 1] = '\0';
            break;
		case 'h':   /* Help */
			sntp_help();
			break;
		case 'i':   /* synchronization Interval */
			interval = atoi(optarg);
			break;
		case 's':   /* Server */
            pServer[0] = '\0';
			break;
        default:
            sntp_help();
            break;
        }
    }
#define SNTPD_PID_FILE   "/var/run/sntpd.pid"
    ret = make_daemon(SNTPD_PID_FILE);
    if (ERROR_SUCCESS != ret)
    {
        return ERROR_FAIL;
    }

    SntpService(pServer, interval);
    return 0;
}
예제 #9
0
파일: main.cpp 프로젝트: Kurkin/OS-HW
int main(int argc, const char * argv[]) {
    
    if (argc == 1) {
        std::cout << "Usage: rshd [port]" << std::endl;
        return 0;
    }
        
    try {
        make_daemon();
        io_queue queue;
        sshd_daemon deamon(queue, std::stoi(argv[1]));
        queue.watch_loop();
    }  catch (std::runtime_error const& error) {
        std::cout << error.what() << std::endl;
    }
    
    return 0;
    
}
예제 #10
0
int initDaemon()
{
    int ret = make_daemon(true);
    if (ret)
        return ret;
    struct sigaction act;
    sigset_t blockset;
    sigemptyset(&blockset);
    act.sa_mask = blockset;
    act.sa_handler = SIG_IGN;
    act.sa_flags = 0;
    sigaction(SIGHUP, &act, NULL);

    act.sa_flags = SA_SIGINFO;
    act.sa_sigaction = &sighandler; 
    sigaction(SIGTERM, &act, NULL);
    sigaction(SIGINT, &act, NULL);
    return 0;
}
예제 #11
0
파일: monit.c 프로젝트: millken/zhuxianB30
s32 main(s32 argc, s8 *argv[])
{
	monit_pass_data_s data;
	monit_init(&data);
	make_daemon(NULL);

	/* 
	* 采用dloop定时器实现周期监控
	*/
    dloop_init();
	dloop_register_timeout(data.interval, 0, monit_timeout, &data);
	dloop_run();
	
	/*
	*销毁dloop资源
	*/
	dloop_destroy();
	free(data.process_table);
	return TRUE;
}
예제 #12
0
int main(int argc, char *argv[])
{
#ifndef _WIN32
  if (geteuid() == 0)
  {
    fprintf(stderr, "Running IRC services is root is not recommended.");
    return 1;
  }
  setup_corefile();
#endif
  memset(&ServicesInfo, 0, sizeof(ServicesInfo));
  memset(&ServicesState, 0, sizeof(ServicesState));

  ServicesState.configfile = CPATH; 
  ServicesState.logfile    = LPATH;
  ServicesState.pidfile    = PPATH;
  ServicesState.fully_connected = 0;

  parseargs(&argc, &argv, myopts);

  if(ServicesState.printversion)
  {
    printf("oftc-ircservices: version: %s\n", VERSION);
    exit(EXIT_SUCCESS);
  }

  if(chdir(DPATH))
  {
    perror("chdir");
    exit(EXIT_FAILURE);
  }

#ifndef _WIN32
  if(!ServicesState.foreground)
    make_daemon();
  else
    print_startup(getpid());
#endif

  setup_signals();
  memset(&me, 0, sizeof(me));

  libio_init(!ServicesState.foreground);
  init_events();
  iorecv_cb = register_callback("iorecv", iorecv_default);
  connected_cb = register_callback("server connected", server_connected);
  iosend_cb = register_callback("iosend", iosend_default);

  OpenSSL_add_all_digests();
 
  init_interface();
  check_pidfile(ServicesState.pidfile);
  init_log(ServicesState.logfile);

#ifdef HAVE_RUBY
  init_ruby();
  signal(SIGSEGV, SIG_DFL);
#endif

  init_channel();
  init_conf();
  init_client();
  init_parser();
  init_channel_modes();
  init_mqueue();
  init_tor();

  me.from = me.servptr = &me;
  SetServer(&me);
  SetMe(&me);
  dlinkAdd(&me, &me.node, &global_client_list);
  
  read_services_conf(TRUE);
  init_db();
  init_uid();
 
#ifdef HAVE_PYTHON
  init_python();
#endif

  init_kill();

  write_pidfile(ServicesState.pidfile);
  ilog(L_NOTICE, "Services Ready");

  db_load_driver();
#ifdef USE_SHARED_MODULES
  if(chdir(MODPATH))
  {
    ilog(L_ERROR, "Could not load core modules from %s: %s",
         MODPATH, strerror(errno));
    exit(EXIT_FAILURE);
  }

  /* Go back to DPATH after checking to see if we can chdir to MODPATH */
  chdir(DPATH);
#else
  load_all_modules(1);
#endif

  boot_modules(1);
  
  connect_server();

  for(;;)
  {
    while (eventNextTime() <= CurrentTime)
      eventRun();

    execute_callback(do_event_cb);

    if(events_loop() == -1)
    {
      ilog(L_CRIT, "libevent returned error %d", errno);
      services_die("Libevent returned some sort of error", NO);
      break;
    }

    comm_select();
    send_queued_all();

    if(dorehash)
    {
      ilog(L_INFO, "Got SIGHUP, reloading configuration");
      read_services_conf(NO);
      dorehash = 0;
    }
  }

  return 0;
}
예제 #13
0
int
main(int argc, char *argv[])
{
	/* Check to see if the user is running us as root, which is a nono */
	if(geteuid() == 0)
	{
		fprintf(stderr, "Don't run ircd as root!!!\n");
		return -1;
	}

	/*
	 * save server boot time right away, so getrusage works correctly
	 */
	set_time();
	/*
	 * Setup corefile size immediately after boot -kre
	 */
	setup_corefile();

	/*
	 * set initialVMTop before we allocate any memory
	 */
	initialVMTop = get_vm_top();

	ServerRunning = 0;
	/* It ain't random, but it ought to be a little harder to guess */
	srand(SystemTime.tv_sec ^ (SystemTime.tv_usec | (getpid() << 20)));
	memset(&me, 0, sizeof(me));
	memset(&meLocalUser, 0, sizeof(meLocalUser));
	me.localClient = &meLocalUser;

	/* Make sure all lists are zeroed */
	memset(&unknown_list, 0, sizeof(unknown_list));
	memset(&lclient_list, 0, sizeof(lclient_list));
	memset(&serv_list, 0, sizeof(serv_list));
	memset(&global_serv_list, 0, sizeof(global_serv_list));
	memset(&oper_list, 0, sizeof(oper_list));

	dlinkAddTail(&me, &me.node, &global_client_list);

	memset((void *) &Count, 0, sizeof(Count));
	memset((void *) &ServerInfo, 0, sizeof(ServerInfo));
	memset((void *) &AdminInfo, 0, sizeof(AdminInfo));

	/* Initialise the channel capability usage counts... */
	init_chcap_usage_counts();

	ConfigFileEntry.dpath = DPATH;
	ConfigFileEntry.configfile = CPATH;	/* Server configuration file */
	ConfigFileEntry.klinefile = KPATH;	/* Server kline file */
	ConfigFileEntry.dlinefile = DLPATH;	/* dline file */
	ConfigFileEntry.xlinefile = XPATH;
	ConfigFileEntry.resvfile = RESVPATH;
	ConfigFileEntry.connect_timeout = 30;	/* Default to 30 */
	myargv = argv;
	umask(077);		/* better safe than sorry --SRB */

	parseargs(&argc, &argv, myopts);

	if(printVersion)
	{
		printf("ircd: version %s\n", ircd_version);
		exit(EXIT_SUCCESS);
	}

	if(chdir(ConfigFileEntry.dpath))
	{
		fprintf(stderr, "Unable to chdir to %s: %s\n", ConfigFileEntry.dpath, strerror(errno));
		exit(EXIT_FAILURE);
	}

	setup_signals();

#ifdef __CYGWIN__
	server_state_foreground = 1;
#endif

	if (testing_conf)
		server_state_foreground = 1;

	/* We need this to initialise the fd array before anything else */
	fdlist_init();
	if(!server_state_foreground)
	{
		comm_close_all();
	}


	/* Check if there is pidfile and daemon already running */
	if(!testing_conf)
	{
		check_pidfile(pidFileName);

		if(!server_state_foreground)
			make_daemon();
		else
			print_startup(getpid());
	}

	init_netio();		/* This needs to be setup early ! -- adrian */

	/* Init the event subsystem */
	eventInit();
	init_sys();

	init_main_logfile();
	initBlockHeap();
	init_dlink_nodes();
	init_patricia();
	newconf_init();
	init_s_conf();
	init_s_newconf();
	linebuf_init();		/* set up some linebuf stuff to control paging */
	init_hash();
	clear_scache_hash_table();	/* server cache name table */
	init_host_hash();
	clear_hash_parse();
	init_client();
	initUser();
	init_channels();
	initclass();
	initwhowas();
	init_stats();
	init_hook();
	init_reject();
	init_cache();
	init_monitor();
	load_all_modules(1);
#ifndef STATIC_MODULES
	load_core_modules(1);
#endif
	init_auth();		/* Initialise the auth code */
	init_resolver();	/* Needs to be setup before the io loop */

	if (testing_conf)
		fprintf(stderr, "\nBeginning config test\n");
	read_conf_files(YES);	/* cold start init conf files */
	rehash_bans(0);
#ifndef STATIC_MODULES

	mod_add_path(MODULE_DIR); 
	mod_add_path(MODULE_DIR "/autoload"); 
#endif

	initialize_server_capabs();	/* Set up default_server_capabs */
	initialize_global_set_options();

	if(ServerInfo.name == NULL)
	{
		fprintf(stderr, "ERROR: No server name specified in serverinfo block.\n");
		ilog(L_MAIN, "No server name specified in serverinfo block.");
		exit(EXIT_FAILURE);
	}
	strlcpy(me.name, ServerInfo.name, sizeof(me.name));

	if(ServerInfo.sid[0] == '\0')
	{
		fprintf(stderr, "ERROR: No server sid specified in serverinfo block.\n");
		ilog(L_MAIN, "No server sid specified in serverinfo block.");
		exit(EXIT_FAILURE);
	}
	strcpy(me.id, ServerInfo.sid);
	init_uid();

	/* serverinfo{} description must exist.  If not, error out. */
	if(ServerInfo.description == NULL)
	{
		fprintf(stderr, "ERROR: No server description specified in serverinfo block.\n");
		ilog(L_MAIN, "ERROR: No server description specified in serverinfo block.");
		exit(EXIT_FAILURE);
	}
	strlcpy(me.info, ServerInfo.description, sizeof(me.info));

	if (testing_conf)
	{
		fprintf(stderr, "\nConfig testing complete.\n");
		fflush(stderr);
		exit(EXIT_SUCCESS);
	}

	me.from = &me;
	me.servptr = &me;
	SetMe(&me);
	make_server(&me);
	me.serv->up = me.name;
	startup_time = CurrentTime;
	add_to_client_hash(me.name, &me);
	add_to_id_hash(me.id, &me);

	dlinkAddAlloc(&me, &global_serv_list);

	check_class();
	write_pidfile(pidFileName);
	load_help();
	open_logfiles();

	ilog(L_MAIN, "Server Ready");

	eventAddIsh("cleanup_glines", cleanup_glines, NULL, CLEANUP_GLINES_TIME);

	/* We want try_connections to be called as soon as possible now! -- adrian */
	/* No, 'cause after a restart it would cause all sorts of nick collides */
	/* um.  by waiting even longer, that just means we have even *more*
	 * nick collisions.  what a stupid idea. set an event for the IO loop --fl
	 */
	eventAddIsh("try_connections", try_connections, NULL, STARTUP_CONNECTIONS_TIME);
	eventAddOnce("try_connections_startup", try_connections, NULL, 0);

	eventAddIsh("collect_zipstats", collect_zipstats, NULL, ZIPSTATS_TIME);

	/* Setup the timeout check. I'll shift it later :)  -- adrian */
	eventAddIsh("comm_checktimeouts", comm_checktimeouts, NULL, 1);

	if(ConfigServerHide.links_delay > 0)
		eventAddIsh("cache_links", cache_links, NULL,
			    ConfigServerHide.links_delay);
	else
		ConfigServerHide.links_disabled = 1;

	if(splitmode)
		eventAdd("check_splitmode", check_splitmode, NULL, 2);

	ServerRunning = 1;

	io_loop();
	return 0;
}
예제 #14
0
파일: main.c 프로젝트: bochf/testing
/* ========================================================================= */
int main(int argc, char *argv[])
{
   struct options *clo;            /* Command line options                   */
   struct proot *p;                /* Base of all provider/pitem data        */
   struct config *cfg;             /* Config file input (parsed to struct)   */
   struct prov_name *pn;
   struct thread_root *tr;
   struct provider *hot_provider;
   struct provider *this_provider; /* Used to walk the provider list */
   struct sighandler_arg *timerc;  /* This is the timer cond variable */

   int first_iteration;
   int sdivisor;      /* Divisor calculated for per-second averaging         */
   int stemp;         /* Temp variable used for sdivisor calculations        */
   int mfail; /* Used in multiple error/fail situations */

   /* Used for simple stat notification (if verbose) */
   int provcnt;
   int apcnt; /* Active provider count */
   int prrv; /* provider registration rv (used to check registrations) */

   /* Used to print (reformat) parts of error messages */
   char errstr[80];

   /* Used for the writer */
   int (*writer_finish)(void *data_handle);
   void *writer_data;
   int writer_state;

   /* Times used for the run_for config file option */
   time_t stop_at;
   time_t time_now;


   int tc;
   /* Used for $ARG substitution */
   int ascount; /* Used as basic stats on substitution counts - for reporting */
   char *argsub; 
   char *argval;
   int   argnum;
   char *before_arg;
   char *after_arg;
   char *rebuilt_arg;
   int i, j;

   /* Set default error message destination to stderr */
   errorto = ERROR_MSG_STDERR;

   if ( NULL == (clo = ReadOptions(argc, argv)) )
      return(1);

   if ( clo->bHelp )
      return(help());

   if ( clo->bAbout )
      return(about());

   if ( clo->bError )
      return(1);

   /* Initialize our provider root */
   p = Providers();

   /* Register the provider(s) */
   prrv =  CoreRegister(p); 
   prrv += AllOSRegister(p);
   prrv += CmnPRegister(p);

   if ( prrv )
   {
      error_msg("ERROR: Failed to register a provider.");
      return(1);
   }

   /* Handle all the potential list options (-l,-p,-d) */
   /* Dump providers (if asked) */
   if ( clo->bListProv )
   {
      this_provider = p->prov_list;
      while( this_provider )
      {
         printf("%s\n", this_provider->name);
         this_provider = this_provider->next;
      }
      fflush(stdout);
      return(0);
   }

   /* Dump data items for a provider (if asked) */
   if ( clo->bListPD )
   {
      this_provider = p->prov_list;
      while( this_provider )
      {
         if ( 0 == strcmp(this_provider->name, clo->provider) )
         {
            /* Match found */
            printf("%s\n", this_provider->name);
            this_provider->listavail(clo->bListTypes);
            fflush(stdout);
            return(0);
         }
         this_provider = this_provider->next;
      }
      error_msg("ERROR: No provider matches \"%s\".", clo->provider);
      fflush(stdout);
      return(1);
   }

   /* Lis all data items from all providers (if asked) */
   if ( clo->bListAllD )
   {
      DumpPItemList(p, clo->bListTypes);
      return(0);
   }

   /* We are in it for the long haul - set go to true */
   go = 1;
   tt = 0; /* No ticks at this time */

   if ( NULL == clo->confile )
   {
      error_msg("ERROR: No config file was specified. Unable to continue.");
      return(1);
   }

   /* Read in the config file */
   if ( NULL == (cfg = ReadConfigFile(clo->confile)) )
      return(1);

   /* Validate some DANGER! conditions */
   mfail = 0;
   if (( 0 == clo->bDanger ) && ( DANGER_NACK == cfg->danger_mode ))
   {
#ifdef MIN_RUN_EVERY
      /* Test for *slightly* less than a second for those trying to
         introduce skew */
      if ( cfg->run_every < MIN_RUN_EVERY )
      {
         error_msg("DANGER: A sampling period of less than a second was specified without -D!");
         mfail = 1;
      }
#endif

#ifdef MAX_QUAD_COUNT
      /* This really should be for the number of providers, not quads */
      if ( cfg->quad_count >= MAX_QUAD_COUNT )
      {
         error_msg("DANGER: Exceeded safe registered quad count. Acknowledge the danger with -D!");
         mfail = 1;
      }
#endif
   }


   /* Do some substitutions ($ARGx for arg item)
      Note - this is not exceptionally strong but it is what is supported
      at this time.

      What is supported:
      - Only ONE $ARGx per line
      - Only $ARG1 (really 0) through $ARG9
      - Only in a quad string
   */
   ascount = 0;
   pn = cfg->pnlist;
   while ( pn )
   {
      if ( NULL != ( argsub = strstr(pn->quad, "$ARG") ) )
      {
         /* Good news! This is supported */

         /* quad is a string, not a quad! So all insertions are "complex" */
         /* First - Save the leading part (if any) */
         before_arg = NULL;
         if ( argsub != pn->quad )
            before_arg = pn->quad;

         argnum = -1;
         if (( argsub[4] >= '0' ) && ( argsub[4] <= '9' ))
            argnum = argsub[4] - '0';

         after_arg = NULL;
         if (( argsub[5] != 0 ) && ( argnum >= 0 ))
            after_arg = argsub + 5;

         /* Validate that things are correct */
         if ( argnum >= 0 )
         {
            if ( NULL == (argval = GetConfArgument(clo, argnum)) )
            {
               error_msg("ERROR: Argument not supplied for \"$ARG%d\".", argnum);
               mfail = 1;
            }      
            else
            {
               if ( NULL == (rebuilt_arg = (char *)malloc(strlen(pn->quad) + strlen(argval) + 1)) )
               {
                  /* Shine this noise - just exit on the extreme rare case of failrue */
                  error_msg("ERROR: Failed to allocate memory for arg replacement string.");
                  return(1);
               }

               rebuilt_arg[0] = 0;

               i = 0;
               j = 0;
               if ( before_arg )
               {
                  while(before_arg[j] != '$')
                     rebuilt_arg[i++] = before_arg[j++];
               }

               j = 0;
               while(argval[j] != 0)
                  rebuilt_arg[i++] = argval[j++];

               if ( after_arg )
               {
                  j = 0;
                  while(after_arg[j] != 0)
                     rebuilt_arg[i++] = after_arg[j++];
               }

               rebuilt_arg[i] = 0;

               free(pn->quad);
               pn->quad = rebuilt_arg;

               ascount++; /* Keep track of how many successful substitutions done */
            }
         }
         else
         {
            dotdotdot_string(errstr, pn->quad, 35);
            error_msg("ERROR: Failed to parse argument in quad \"%s\".", errstr);
            mfail = 1;
         }
      }

      pn = pn->next;
   }

   /* Activate the data points (but not threads) */
   pn = cfg->pnlist;
   while ( pn )
   {
      if(EnableDataPoint(p, pn))
      {
         dotdotdot_string(errstr, pn->quad, 45);
         error_msg("ERROR: Unable to register \"%s\".", errstr);
         mfail = 1;
      }

      pn = pn->next;
   }

   /* mfail lets errors build up (a bit) before the app bails. This way the
      user can (potentially) diagnose more than one error at a time. */
   if ( mfail )
      return(1);
   
   /* Count the number of active providers */
   if ( 1 > (apcnt = GetActiveProviderCount(p)) )
   {
      error_msg("ERROR: No providers are registered for updates.");
      return(1);
   }

   /* See "danger.h" */
#ifdef MAX_ACTIVE_PROVIDERS
   /* Check again for danger conditions */
   if (( 0 == clo->bDanger ) && ( DANGER_NACK == cfg->danger_mode ))
   {
      if ( apcnt >= MAX_ACTIVE_PROVIDERS )
      {
         error_msg("DANGER: Exceeded safe max provider count. Acknowledge the danger with -D!");
         return(1);
      }      
   }
#endif

   /* Calculate the divisior for per-second averaging */

   if ( cfg->run_every < 950 )
   {
      /* 950 shall be considered 1 second - for those looking to 
         introduce drift. Anything less than that, then no averaging
         is going to happen. (although... concievably.... we could 
         go negative and consider this a multiplier.).    */
      sdivisor = 1;
   }
   else
   {
      stemp = cfg->run_every % 1000;

      if ( stemp >= 950 )
      {
         sdivisor = cfg->run_every + ( 1000 - stemp );
         sdivisor = sdivisor / 1000;
      }
      else if ( stemp <= 50 )
      {
         sdivisor = cfg->run_every - stemp;
         sdivisor = sdivisor / 1000;
      }
      else
      {
         /* Not going to average */
         sdivisor = 1;
      }
   }

   if ( clo->bVerbose )
   {
      provcnt = 0;
      this_provider = p->prov_list;
      while( this_provider )
      {
         provcnt++;
         this_provider = this_provider->next;
      }

      /* This MUST go to stderr - because someone might be capturing stdout */
      fprintf(stderr, "Registered %d providers, %d active.\n", provcnt, apcnt);
      fprintf(stderr, "Requested (pre-enabled) %d quads.\n", cfg->quad_count);
      fprintf(stderr, "Per-Second averaging factor is %d.\n", sdivisor);
      fprintf(stderr, "Completed %d $ARGx substitutions to the config file.\n", ascount);
   }



   /* Set up our thread structures (but not the threads themselves) */
   if ( NULL == ( tr = InitThreadRoot(apcnt, sdivisor) ) )
      return(1);

   /* Commentary: The "hooks" to install the writer modules are not as
         simple as a "point registration". The init must be called, the
         write() must be registered (and then called by a thread) and the
         finish() method must be called on exit - after likely being 
         registered. So the three interfaces are well defined... the 
         problem is that they are defined in very different places/ways.
         Additionally, the idea of calling init() inline is not so brilliant
         as the data then has to be fished out of some struct later in
         main() (as it is about to exit) to call the finish() method.
   */
   /* Start with bad values */
   writer_state = -1;
   writer_data = NULL;

   /* Make the bad values good */
   switch ( cfg->send_to )
   {
   case WM_STDOUT_TYPE:
      writer_data = InitStdoutWM(p, cfg);
      writer_state = SetWriterData(tr, writer_data, StdoutWMWrite, StdoutWMFinish);
      writer_finish = StdoutWMFinish;
      break;
   case WM_FILE_TYPE:
      writer_data = InitFileWM(p, cfg);
      writer_state = SetWriterData(tr, writer_data, WriteFileWM, FinishFileWM);
      writer_finish = FinishFileWM;
      break;
   case WM_ALARM_TYPE:
      writer_data = InitAlarmWM(p, cfg);
      writer_state = SetWriterData(tr, writer_data, WriteAlarmWM, FinishAlarmWM);
      writer_finish = FinishAlarmWM;
      break;
   case WM_BCD_TYPE:
      writer_data = InitBCDWM(p, cfg);
      writer_state = SetWriterData(tr, writer_data, WriteBCDWM, FinishBCDWM);
      writer_finish = FinishBCDWM;
      break;
   default:
      error_msg("ERROR: Internal error send_to type %d unknown.", cfg->send_to);
      break;
   }

   /* Look for bad values */
   if ( NULL == writer_data )
   {
      error_msg("ERROR: Failed to initialize writer module data.");
      return(1);
   }

   if ( 0 != writer_state )
   {
      error_msg("ERROR: Failed to set writer module data.");
      return(1);
   }

   /* This is where we will daemonize. Because:
      - The command line has been parsed (checked for errors)
      - The config file has been parsed (checked for errors)
      - The providers have been registered / validated (checked for errors)
      - The writer has looked at all the options (checked for errors)
      - Only after all of this can we fork() with clarity
      > Also note - we MUST fork() before the thread creation or they will
        be stripped away in the fork().
   */
   if ( cfg->run_method == RM_DAEMON )
   {
      make_daemon();
      /* Set default error message destination to syslog */
      errorto = ERROR_MSG_SYSLOG;
   }

   /* ========== NOW POTENTIALLY A DAEMON ========== */

   /* Lock this - makes the timer hang until the worker is ready */
   pthread_mutex_lock(&tr->wrarg->readygo);

   /* ========== JUST ONE THREAD, ABOUT TO BE MANY ========== */

   /* Spawn the timer thread first - because the launch code also sets
      the signal handling settings that all threads will inherit. If
      this is going to be moved, then the signal handling mask needs
      to be removed from this function. */
   if ( NULL == (timerc = SpawnTimerThread(cfg->run_every)) )
      return(1);

   /* Spawn worker threads */
   hot_provider = GetNextActiveProvider(p, NULL);
   while ( hot_provider )
   {
      if ( SpawnWorkerThread(tr, hot_provider) )
         return(1);

      hot_provider = GetNextActiveProvider(p, hot_provider);
   }

   /* Spawn writer thread LAST - It will release readygo */
   /* The point here is to give te workers every chance to get started
      and wait until the very last minute to spawn the writer thread.
      Because it is the writer thread that will release the readygo
      lock and let things start. While this is not *perfect* (the
      workers *could* be still starting - but that is exceptionally
      unlikely), it is fairly solid (as witnessed in practice). */
   if ( SpawnWriterThread(tr) )
      return(1);

   /* If the user said run for x time, then set that up here */
   stop_at = time(NULL);
   stop_at--;            /* Effectively an assert(), but more about
                            making the compiler happy. */

   if ( 0 < cfg->run_for )
   {
      stop_at = time(NULL);
      stop_at += cfg->run_for;
   }


   /* This is the timer loop that activates all the other threads */
   first_iteration = 1;
   while(go)
   {
      /* Check for run_for time expiration */
      if ( 0 < cfg->run_for )
      {
         time_now = time(NULL);
         if ( time_now >= stop_at )
         {
            go = 0;
            continue;
         }
      }

      /* The first iteration is used to avoid printing data on start
         that is typically incomplete anyways. (Incomplete = the diff
         values are not properly timed) Also, the first printing is
         timed VERY CLOSE to the second iteration. So it is ok to 
         skip this. Unfortunately, the way the loop is structured the
         timer (event) has to happen at the BOTTOM so that we can exit
         out (without some kind of break) when we get our event. The
         break *may* have been the more elegant answer here....
      */
      if ( first_iteration )
         first_iteration = 0;
      else
      {
         pthread_mutex_lock(&tr->wrarg->readygo); /* Gotta take lock to go */

         tc = 0;
         while ( tc < apcnt )
         {
            pthread_cond_signal(&tr->wkalist[tc].runcond);
            tc++;
         }

         pthread_cond_signal(&tr->wrarg->writecond);
      }

      /* What is going on here:
         - There is a mutex/cond semaphore that we block on waiting
           for some sort of signal. Typically this will be a simple
           alarm timer, but it may be a Ctrl-C or similarly induced
           signal. The key difference will be what the value of the
           global "go" is. If it is a timer, then go will be 1. If
           it is an exit-inducing event, then go will be 0. Either
           way, go will be evaluated at the top of the loop.
         - No, go is not protected by a mutex. No, this is not seen
           as a problem.
         - The mutex here is only for access to the cond variable.
           It protects nothing (other than the cond).
         - The cond here is about responding to the signal induced
           event loop. And as expressed earlier... there are really
           only two events we care about - a timer tick and a quit
           signal.
       */

      /* Standard cond wait block */
      pthread_mutex_lock(&timerc->mutex);
      while( tt == 0 ) /* Use tt because timer may have already fired */
         pthread_cond_wait(&timerc->cond, &timerc->mutex);
      tt = 0; /* Immediately clear */
      pthread_mutex_unlock(&timerc->mutex);
   }

   /* Take the writer lock (to insure that it is done writing)
      and then finish up the write - whatever that may be. The
      writer_finish() method was registered at about the same time the
      write() method.
   */
   pthread_mutex_lock(&tr->wrarg->writelock);
   writer_finish(tr->wrarg->writer_data);
   return(0);
}
예제 #15
0
파일: Monitor.c 프로젝트: Distrotech/mdadm
int Monitor(struct mddev_dev *devlist,
	    char *mailaddr, char *alert_cmd,
	    struct context *c,
	    int daemonise, int oneshot,
	    int dosyslog, char *pidfile, int increments,
	    int share)
{
	/*
	 * Every few seconds, scan every md device looking for changes
	 * When a change is found, log it, possibly run the alert command,
	 * and possibly send Email
	 *
	 * For each array, we record:
	 *   Update time
	 *   active/working/failed/spare drives
	 *   State of each device.
	 *   %rebuilt if rebuilding
	 *
	 * If the update time changes, check out all the data again
	 * It is possible that we cannot get the state of each device
	 * due to bugs in the md kernel module.
	 * We also read /proc/mdstat to get rebuild percent,
	 * and to get state on all active devices incase of kernel bug.
	 *
	 * Events are:
	 *    Fail
	 *	An active device had Faulty set or Active/Sync removed
	 *    FailSpare
	 *      A spare device had Faulty set
	 *    SpareActive
	 *      An active device had a reverse transition
	 *    RebuildStarted
	 *      percent went from -1 to +ve
	 *    RebuildNN
	 *      percent went from below to not-below NN%
	 *    DeviceDisappeared
	 *      Couldn't access a device which was previously visible
	 *
	 * if we detect an array with active<raid and spare==0
	 * we look at other arrays that have same spare-group
	 * If we find one with active==raid and spare>0,
	 *  and if we can get_disk_info and find a name
	 *  Then we hot-remove and hot-add to the other array
	 *
	 * If devlist is NULL, then we can monitor everything because --scan
	 * was given.  We get an initial list from config file and add anything
	 * that appears in /proc/mdstat
	 */

	struct state *statelist = NULL;
	struct state *st2;
	int finished = 0;
	struct mdstat_ent *mdstat = NULL;
	char *mailfrom = NULL;
	struct alert_info info;

	if (!mailaddr) {
		mailaddr = conf_get_mailaddr();
		if (mailaddr && ! c->scan)
			pr_err("Monitor using email address \"%s\" from config file\n",
			       mailaddr);
	}
	mailfrom = conf_get_mailfrom();

	if (!alert_cmd) {
		alert_cmd = conf_get_program();
		if (alert_cmd && ! c->scan)
			pr_err("Monitor using program \"%s\" from config file\n",
			       alert_cmd);
	}
	if (c->scan && !mailaddr && !alert_cmd && !dosyslog) {
		pr_err("No mail address or alert command - not monitoring.\n");
		return 1;
	}
	info.alert_cmd = alert_cmd;
	info.mailaddr = mailaddr;
	info.mailfrom = mailfrom;
	info.dosyslog = dosyslog;

	if (daemonise) {
		int rv = make_daemon(pidfile);
		if (rv >= 0)
			return rv;
	}

	if (share)
		if (check_one_sharer(c->scan))
			return 1;

	if (devlist == NULL) {
		struct mddev_ident *mdlist = conf_get_ident(NULL);
		for (; mdlist; mdlist=mdlist->next) {
			struct state *st;
			if (mdlist->devname == NULL)
				continue;
			if (strcasecmp(mdlist->devname, "<ignore>") == 0)
				continue;
			st = xcalloc(1, sizeof *st);
			if (mdlist->devname[0] == '/')
				st->devname = xstrdup(mdlist->devname);
			else {
				st->devname = xmalloc(8+strlen(mdlist->devname)+1);
				strcpy(strcpy(st->devname, "/dev/md/"),
				       mdlist->devname);
			}
			st->next = statelist;
			st->devnm[0] = 0;
			st->percent = RESYNC_UNKNOWN;
			st->from_config = 1;
			st->expected_spares = mdlist->spare_disks;
			if (mdlist->spare_group)
				st->spare_group = xstrdup(mdlist->spare_group);
			statelist = st;
		}
	} else {
		struct mddev_dev *dv;
		for (dv=devlist ; dv; dv=dv->next) {
			struct mddev_ident *mdlist = conf_get_ident(dv->devname);
			struct state *st = xcalloc(1, sizeof *st);
			st->devname = xstrdup(dv->devname);
			st->next = statelist;
			st->devnm[0] = 0;
			st->percent = RESYNC_UNKNOWN;
			st->expected_spares = -1;
			if (mdlist) {
				st->expected_spares = mdlist->spare_disks;
				if (mdlist->spare_group)
					st->spare_group = xstrdup(mdlist->spare_group);
			}
			statelist = st;
		}
	}

	while (! finished) {
		int new_found = 0;
		struct state *st, **stp;
		int anydegraded = 0;

		if (mdstat)
			free_mdstat(mdstat);
		mdstat = mdstat_read(oneshot?0:1, 0);

		for (st=statelist; st; st=st->next)
			if (check_array(st, mdstat, c->test, &info,
					increments, c->prefer))
				anydegraded = 1;

		/* now check if there are any new devices found in mdstat */
		if (c->scan)
			new_found = add_new_arrays(mdstat, &statelist, c->test,
						   &info);

		/* If an array has active < raid && spare == 0 && spare_group != NULL
		 * Look for another array with spare > 0 and active == raid and same spare_group
		 *  if found, choose a device and hotremove/hotadd
		 */
		if (share && anydegraded)
			try_spare_migration(statelist, &info);
		if (!new_found) {
			if (oneshot)
				break;
			else
				mdstat_wait(c->delay);
		}
		c->test = 0;

		for (stp = &statelist; (st = *stp) != NULL; ) {
			if (st->from_auto && st->err > 5) {
				*stp = st->next;
				free(st->devname);
				free(st->spare_group);
				free(st);
			} else
				stp = &st->next;
		}
	}
	for (st2 = statelist; st2; st2 = statelist) {
		statelist = st2->next;
		free(st2);
	}

	if (pidfile)
		unlink(pidfile);
	return 0;
}
예제 #16
0
파일: main.c 프로젝트: timekpr/clepsydrad
int main(void)
{
   return make_daemon ();
}
예제 #17
0
파일: main.c 프로젝트: gitter-badger/knot
int main(int argc, char **argv)
{
	/* Parse command line arguments. */
	int c = 0, li = 0;
	int daemonize = 0;
	const char *config_fn = CONF_DEFAULT_FILE;
	const char *config_db = NULL;
	const char *daemon_root = "/";

	/* Long options. */
	struct option opts[] = {
		{"config",    required_argument, 0, 'c' },
		{"confdb",    required_argument, 0, 'C' },
		{"daemonize", optional_argument, 0, 'd'},
		{"version",   no_argument,       0, 'V'},
		{"help",      no_argument,       0, 'h'},
		{0, 0, 0, 0}
	};

	while ((c = getopt_long(argc, argv, "c:C:dVh", opts, &li)) != -1) {
		switch (c) {
		case 'c':
			config_fn = optarg;
			break;
		case 'C':
			config_db = optarg;
			break;
		case 'd':
			daemonize = 1;
			if (optarg) {
				daemon_root = optarg;
			}
			break;
		case 'V':
			printf("%s, version %s\n", "Knot DNS", PACKAGE_VERSION);
			return EXIT_SUCCESS;
		case 'h':
		case '?':
			help();
			return EXIT_SUCCESS;
		default:
			help();
			return EXIT_FAILURE;
		}
	}

	/* Check for non-option parameters. */
	if (argc - optind > 0) {
		help();
		return EXIT_FAILURE;
	}

	/* Now check if we want to daemonize. */
	if (daemonize) {
		if (make_daemon(1, 0) != 0) {
			fprintf(stderr, "Daemonization failed, shutting down...\n");
			return EXIT_FAILURE;
		}
	}

	/* Clear file creation mask. */
	umask(0);

	/* Setup base signal handling. */
	setup_signals();

	/* Initialize cryptographic backend. */
	dnssec_crypto_init();
	atexit(dnssec_crypto_cleanup);

	/* Initialize pseudorandom number generator. */
	srand(time(NULL));

	/* POSIX 1003.1e capabilities. */
	setup_capabilities();

	/* Default logging to std out/err. */
	log_init();

	/* Open configuration. */
	conf_t *new_conf = NULL;
	if (config_db == NULL) {
		int ret = conf_new(&new_conf, conf_scheme, NULL);
		if (ret != KNOT_EOK) {
			log_fatal("failed to initialize configuration database "
			          "(%s)", knot_strerror(ret));
			log_close();
			return EXIT_FAILURE;
		}

		/* Import the configuration file. */
		ret = conf_import(new_conf, config_fn, true);
		if (ret != KNOT_EOK) {
			log_fatal("failed to load configuration file (%s)",
			          knot_strerror(ret));
			conf_free(new_conf, false);
			log_close();
			return EXIT_FAILURE;
		}

		new_conf->filename = strdup(config_fn);
	} else {
		/* Open configuration database. */
		int ret = conf_new(&new_conf, conf_scheme, config_db);
		if (ret != KNOT_EOK) {
			log_fatal("failed to open configuration database '%s' "
			          "(%s)", config_db, knot_strerror(ret));
			log_close();
			return EXIT_FAILURE;
		}
	}

	/* Run post-open config operations. */
	int res = conf_post_open(new_conf);
	if (res != KNOT_EOK) {
		log_fatal("failed to use configuration (%s)", knot_strerror(res));
		conf_free(new_conf, false);
		log_close();
		return EXIT_FAILURE;
	}

	conf_update(new_conf);

	/* Initialize logging subsystem. */
	log_reconfigure(conf(), NULL);

	/* Initialize server. */
	server_t server;
	res = server_init(&server, conf_bg_threads(conf()));
	if (res != KNOT_EOK) {
		log_fatal("failed to initialize server (%s)", knot_strerror(res));
		conf_free(conf(), false);
		log_close();
		return EXIT_FAILURE;
	}

	/* Reconfigure server interfaces.
	 * @note This MUST be done before we drop privileges. */
	server_reconfigure(conf(), &server);
	log_info("configured %zu zones", conf_id_count(conf(), C_ZONE));

	/* Alter privileges. */
	int uid, gid;
	if (conf_user(conf(), &uid, &gid) != KNOT_EOK ||
	    log_update_privileges(uid, gid) != KNOT_EOK ||
	    proc_update_privileges(uid, gid) != KNOT_EOK) {
		log_fatal("failed to drop privileges");
		server_deinit(&server);
		conf_free(conf(), false);
		log_close();
		return EXIT_FAILURE;
	}

	/* Check and create PID file. */
	long pid = (long)getpid();
	char *pidfile = NULL;
	if (daemonize) {
		pidfile = pid_check_and_create();
		if (pidfile == NULL) {
			server_deinit(&server);
			conf_free(conf(), false);
			log_close();
			return EXIT_FAILURE;
		}

		log_info("PID stored in '%s'", pidfile);
		if (chdir(daemon_root) != 0) {
			log_warning("failed to change working directory to %s",
			            daemon_root);
		} else {
			log_info("changed directory to %s", daemon_root);
		}
	}

	/* Now we're going multithreaded. */
	rcu_register_thread();

	/* Populate zone database. */
	log_info("loading zones");
	server_update_zones(conf(), &server);

	/* Check number of loaded zones. */
	if (knot_zonedb_size(server.zone_db) == 0) {
		log_warning("no zones loaded");
	}

	/* Start it up. */
	log_info("starting server");
	conf_val_t async_val = conf_get(conf(), C_SRV, C_ASYNC_START);
	res = server_start(&server, conf_bool(&async_val));
	if (res != KNOT_EOK) {
		log_fatal("failed to start server (%s)", knot_strerror(res));
		server_deinit(&server);
		rcu_unregister_thread();
		pid_cleanup(pidfile);
		log_close();
		conf_free(conf(), false);
		return EXIT_FAILURE;
	}

	if (daemonize) {
		log_info("server started as a daemon, PID %ld", pid);
	} else {
		log_info("server started in the foreground, PID %ld", pid);
		init_signal_started();
	}

	/* Start the event loop. */
	event_loop(&server);

	/* Teardown server and configuration. */
	server_deinit(&server);

	/* Free configuration. */
	conf_free(conf(), false);

	/* Unhook from RCU. */
	rcu_unregister_thread();

	/* Cleanup PID file. */
	pid_cleanup(pidfile);

	log_info("shutting down");
	log_close();

	return EXIT_SUCCESS;
}
예제 #18
0
int main(int argc, char* argv[])
{
    pre_log("test server now start\n");

    bool is_daemon = false;
    const char* config_file = NULL;

    Test_server test_server;
    test_server.set_version("v1.0.0");
    test_server.set_name("test_server");

    //指定默认配置文件
    config_file = "../conf/config.ini";

    pre_log("read command line parameter\n");
    // 命令行解释
    int optch = 0;

    while ((optch=getopt(argc , argv , "c:dhv"))  != -1)
    {
        switch (optch)
        {
            case 'c':
                config_file = optarg;
                continue;

            case 'd':
                is_daemon = true;
                continue;

            case 'v':
                test_server.print_version();
                return 0;

            case 'h':
            default:
                test_server.print_usage();
                return 0;
        }
    }

    if (NULL == config_file)
    {
        test_server.print_usage();
        return 0;
    }

    // 允许没有配置文件,但指定了配置文件却没权限读取则退出失败返回
    if ((config_file[0] != '\0') && (access(config_file, R_OK) != 0))
    {
        pre_log("No access config file: (%s)\n", config_file);
        test_server.print_usage();
        return 1;
    }

    test_server.set_config_file(config_file);

    // 变成daemon进程
    if (is_daemon)
    {
        make_daemon();
    }

    test_server.start();

    return 0;
}
예제 #19
0
int
main(int argc, char *argv[])
{
  /* Check to see if the user is running us as root, which is a nono */
  if (!geteuid())
  {
    fprintf(stderr, "ERROR: This server won't run as root/superuser\n");
    return -1;
  }

  /* Setup corefile size immediately after boot -kre */
  setup_corefile();

  /* Save server boot time right away, so getrusage works correctly */
  set_time();

  /* It's not random, but it ought to be a little harder to guess */
  init_genrand(SystemTime.tv_sec ^ (SystemTime.tv_usec | (getpid() << 20)));

  dlinkAdd(&me, &me.node, &global_client_list);

  ConfigGeneral.dpath      = DPATH;
  ConfigGeneral.spath      = SPATH;
  ConfigGeneral.mpath      = MPATH;
  ConfigGeneral.configfile = CPATH;    /* Server configuration file */
  ConfigGeneral.klinefile  = KPATH;    /* Server kline file         */
  ConfigGeneral.glinefile  = GPATH;    /* Server gline file         */
  ConfigGeneral.xlinefile  = XPATH;    /* Server xline file         */
  ConfigGeneral.dlinefile  = DLPATH;   /* dline file                */
  ConfigGeneral.resvfile   = RESVPATH; /* resv file                 */

  myargv = argv;
  umask(077);  /* umask 077: u=rwx,g=,o= */

  parseargs(&argc, &argv, myopts);

  if (printVersion)
  {
    printf("ircd: version %s(%s)\n", ircd_version, serno);
    exit(EXIT_SUCCESS);
  }

  if (chdir(ConfigGeneral.dpath))
  {
    perror("chdir");
    exit(EXIT_FAILURE);
  }

  ssl_init();

  if (!server_state.foreground)
  {
    make_daemon();
    close_standard_fds(); /* this needs to be before init_netio()! */
  }
  else
    print_startup(getpid());

  setup_signals();

  /* We need this to initialise the fd array before anything else */
  fdlist_init();
  log_set_file(LOG_TYPE_IRCD, 0, logFileName);

  init_netio();         /* This needs to be setup early ! -- adrian */

  /* Check if there is pidfile and daemon already running */
  check_pidfile(pidFileName);

  mp_pool_init();
  init_dlink_nodes();
  init_isupport();
  dbuf_init();
  hash_init();
  ipcache_init();
  client_init();
  class_init();
  whowas_init();
  watch_init();
  auth_init();          /* Initialise the auth code */
  init_resolver();      /* Needs to be setup before the io loop */
  modules_init();
  read_conf_files(1);   /* cold start init conf files */
  init_uid();
  initialize_server_capabs();   /* Set up default_server_capabs */
  initialize_global_set_options();  /* Has to be called after read_conf_files() */
  channel_init();
  read_links_file();
  motd_init();
  user_usermodes_init();
#ifdef HAVE_LIBGEOIP
  geoip_ctx = GeoIP_new(GEOIP_MEMORY_CACHE);
#endif

  if (EmptyString(ConfigServerInfo.sid))
  {
    ilog(LOG_TYPE_IRCD, "ERROR: No server id specified in serverinfo block.");
    exit(EXIT_FAILURE);
  }

  strlcpy(me.id, ConfigServerInfo.sid, sizeof(me.id));

  if (EmptyString(ConfigServerInfo.name))
  {
    ilog(LOG_TYPE_IRCD, "ERROR: No server name specified in serverinfo block.");
    exit(EXIT_FAILURE);
  }

  strlcpy(me.name, ConfigServerInfo.name, sizeof(me.name));

  /* serverinfo{} description must exist.  If not, error out.*/
  if (EmptyString(ConfigServerInfo.description))
  {
    ilog(LOG_TYPE_IRCD, "ERROR: No server description specified in serverinfo block.");
    exit(EXIT_FAILURE);
  }

  strlcpy(me.info, ConfigServerInfo.description, sizeof(me.info));

  me.from = &me;
  me.servptr = &me;
  me.connection->lasttime = CurrentTime;
  me.connection->since = CurrentTime;
  me.connection->firsttime = CurrentTime;

  SetMe(&me);
  make_server(&me);

  hash_add_id(&me);
  hash_add_client(&me);

  dlinkAdd(&me, make_dlink_node(), &global_server_list);

  load_kline_database();
  load_dline_database();
  load_gline_database();
  load_xline_database();
  load_resv_database();

  load_all_modules(1);
  load_conf_modules();
  load_core_modules(1);

  write_pidfile(pidFileName);

  ilog(LOG_TYPE_IRCD, "Server Ready");

  event_addish(&event_cleanup_glines, NULL);
  event_addish(&event_cleanup_tklines, NULL);

  /* We want try_connections to be called as soon as possible now! -- adrian */
  /* No, 'cause after a restart it would cause all sorts of nick collides */
  event_addish(&event_try_connections, NULL);

  /* Setup the timeout check. I'll shift it later :)  -- adrian */
  event_add(&event_comm_checktimeouts, NULL);

  event_addish(&event_save_all_databases, NULL);

  if (ConfigServerHide.links_delay > 0)
  {
    event_write_links_file.when = ConfigServerHide.links_delay;
    event_addish(&event_write_links_file, NULL);
  }
  else
    ConfigServerHide.links_disabled = 1;

  if (splitmode)
    event_addish(&splitmode_event, NULL);

  io_loop();
  return 0;
}
예제 #20
0
s32 main(s32 argc, s8 **argv)
{
    s32 recode = ERROR_SUCCESS;
    struct timeval tv;
    fd_set rfds;
    s32 fd;
    struct sockaddr_in addr;
	socklen_t addrlen = sizeof(struct sockaddr);
    s32 retcode;

     /*全局初始化*/
	retcode = auth_linkage_global_init();
    if (ERROR_SUCCESS != retcode)
	{
		return retcode;
	}

    /*配置恢复*/
    auth_linkage_restore(MAIN_BOARD);
    retcode = make_daemon(AUTH_LINKAGE_PATH);
	if (ERROR_SUCCESS != retcode)
	{
		return ERROR_FAIL;
	}

    signal (SIGTERM, auth_linkage_sigexit_handle);	/*KILL HANDLE*/
	signal (SIGUSR2, auth_linkage_sigexit_handle);	/*OUR OWN EXIT*/
    signal (SIGHUP,  auth_linkage_change_cfg);

    /*创建本地UNIX socket 监听*/
	fd = auth_linkage_start_socket ();
    do
	{

		tv.tv_sec = AUTH_LINKAGE_TIMEOUT;
		tv.tv_usec = 0;

		FD_ZERO (&rfds);
		FD_SET (fd, &rfds);

		retcode = select(fd + 1, &rfds, NULL, NULL, &tv);
        if(g_auth_linkage_cfg.auth_linkage_switch != AUTH_LINKAGE_ENABLE)
        {
            continue;
        }
		if (EINTR == errno)
		{
			errno = 0;
			retcode = 0;
		}

        
		if (-1 == retcode)
		{
			return ERROR_FAIL;
		}
        
		if (0 < retcode)
		{
			int client;
            memset(&addr, 0, sizeof(struct sockaddr_in));
			client = accept(fd, (struct sockaddr *)&addr, &addrlen);
			recode = auth_linkage_receive_proc (client, &addr);
			close (client);
		}
    }while(1);

    return recode;
}
예제 #21
0
파일: crm_mon.c 프로젝트: sipwise/heartbeat
int
main(int argc, char **argv)
{
	int argerr = 0;
	int flag;

#ifdef HAVE_GETOPT_H
	int option_index = 0;
	static struct option long_options[] = {
		/* Top-level Options */
		{"verbose", 0, 0, 'V'},
		{"help", 0, 0, '?'},
		{"interval", 1, 0, 'i'},
		{"group-by-node", 0, 0, 'n'},
		{"inactive", 0, 0, 'r'},
		{"as-html", 1, 0, 'h'},		
		{"web-cgi", 0, 0, 'w'},
		{"simple-status", 0, 0, 's'},
		{"as-console", 0, 0, 'c'},		
		{"one-shot", 0, 0, '1'},		
		{"daemonize", 0, 0, 'd'},		
		{"pid-file", 0, 0, 'p'},		
		{"xml-file", 1, 0, 'X'},		

		{0, 0, 0, 0}
	};
#endif
	pid_file = crm_strdup("/tmp/ClusterMon.pid");
	crm_system_name = basename(argv[0]);
	crm_log_init(crm_system_name, LOG_ERR-1, FALSE, FALSE, 0, NULL);

	if (strcmp(crm_system_name, "crm_mon.cgi")==0) {
		web_cgi = TRUE;
		one_shot = TRUE;
	}
	
	while (1) {
#ifdef HAVE_GETOPT_H
		flag = getopt_long(argc, argv, OPTARGS,
				   long_options, &option_index);
#else
		flag = getopt(argc, argv, OPTARGS);
#endif
		if (flag == -1)
			break;

		switch(flag) {
			case 'V':
				cl_log_enable_stderr(TRUE);
				alter_debug(DEBUG_INC);
				break;
			case 'i':
				interval = crm_get_msec(optarg);
				break;
			case 'n':
				group_by_node = TRUE;
				break;
			case 'r':
				inactive_resources = TRUE;
				break;
			case 'd':
				daemonize = TRUE;
				break;
			case 'p':
				pid_file = crm_strdup(optarg);
				break;
			case 'X':
				xml_file = crm_strdup(optarg);
				one_shot = TRUE;
				break;
			case 'h':
				as_html_file = crm_strdup(optarg);
				break;
			case 'w':
			        web_cgi = TRUE;
				one_shot = TRUE;
				break;
			case 'c':
#if CURSES_ENABLED
				as_console = TRUE;
#else
				printf("You need to have curses available at compile time to enable console mode\n");
				argerr++;
#endif
				break;
			case 's':
			        simple_status = TRUE;
				one_shot = TRUE;
				break;
			case '1':
				one_shot = TRUE;
				break;
			default:
				printf("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag);
				++argerr;
				break;
		}
	}

	if (optind < argc) {
		printf("non-option ARGV-elements: ");
		while (optind < argc)
			printf("%s ", argv[optind++]);
		printf("\n");
	}
	if (argerr) {
		usage(crm_system_name, LSB_EXIT_GENERIC);
	}

	if(as_html_file == NULL && !web_cgi && !simple_status) {
#if CURSES_ENABLED
		as_console = TRUE;
#else
		printf("Defaulting to one-shot mode\n");
		printf("You need to have curses available at compile time to enable console mode\n");
		one_shot = TRUE;
#endif
	}

	if(daemonize) {
		as_console = FALSE;
	}

	if(one_shot) {
		daemonize = FALSE;
		as_console = FALSE;
	}
	
	if(daemonize && as_html_file == NULL) {
		usage(crm_system_name, LSB_EXIT_GENERIC);
	}
	
	make_daemon(daemonize, pid_file);

#if CURSES_ENABLED
	if(as_console) {
		initscr();
		cbreak();
		noecho();
	}
#endif
	
	crm_info("Starting %s", crm_system_name);
	mainloop = g_main_new(FALSE);

	if(one_shot == FALSE) {
		timer_id = Gmain_timeout_add(
			interval, mon_timer_popped, NULL);

	} else if(xml_file != NULL) {
		FILE *xml_strm = fopen(xml_file, "r");
		crm_data_t *cib_object = NULL;			
		if(strstr(xml_file, ".bz2") != NULL) {
			cib_object = file2xml(xml_strm, TRUE);
		} else {
			cib_object = file2xml(xml_strm, FALSE);
		}
		if(xml_strm != NULL) {
			fclose(xml_strm);
		}
		one_shot = TRUE;
		mon_update(NULL, 0, cib_ok, cib_object, NULL);
	}

	mon_timer_popped(NULL);
	g_main_run(mainloop);
	return_to_orig_privs();
	
	crm_info("Exiting %s", crm_system_name);	
	
#if CURSES_ENABLED
	if(as_console) {
		echo();
		nocbreak();
		endwin();
	}
#endif
	return 0;
}
예제 #22
0
파일: sidc.c 프로젝트: sorki/sidc
int main( int argc, char *argv[])
{
   while( 1)
   {
      int c = getopt( argc, argv, "vfmic:p:");

      if( c == 'v') VFLAG++;
      else
      if( c == 'f') background = 0;
      else
      if( c == 'c') config_file = optarg;
      else
      if( c == 'p') pid_file = optarg;
      else
      if( c == -1) break;
      else bailout( "unknown option [%c]", c);
   }

   setup_signal_handling();
   load_config();

   if( CF_output_policy != OP_SPECTRUM)
   {
      int i;
      struct BAND *b;

      for( i=0, b=bands; i<nbands; i++, b++)
         report( 1, "band %s %d %d %s",
            b->ident, b->start, b->end, b->side->name);
   }

   if( background && !logfile)
      report( -1, "warning: no logfile specified for daemon");

   if( background) make_daemon();

   setup_input_stream();

   DF = (double) CF_sample_rate/(double) FFTWID;
   report( 1, "resolution: bins=%d fftwid=%d df=%f", CF_bins, FFTWID, DF);

   if( CF_uspec_file)
   {
      // Convert CF_uspec_secs seconds to uspec_max frames
      uspec_max = rint( CF_uspec_secs * CF_sample_rate / FFTWID);
      report( 2, "utility spectrum interval: %d frames", uspec_max);
      report( 2, "utility spectrum file: %s", CF_uspec_file); 
   }

   // Convert CF_output_interval seconds to output_int frames
   output_int = rint( CF_output_interval * CF_sample_rate / FFTWID);
   if( output_int == 0) output_int = 1;
   report( 2, "output interval: %d frames", output_int);

   if( CF_output_policy == OP_SPECTRUM)
   {
      // Convert range variables Hertz to bins
      cuton = CF_range1 / DF;
      cutoff = CF_range2 / DF;
      report( 2, "output bins: %d to %d", cuton, cutoff);
   }   

   // Both sets of channel data structures are initialised, even if mono
   initialise_channel( &left);
   initialise_channel( &right);

   setup_hamming_window();

   if( CF_card_delay) sleep( CF_card_delay);
   report( 0, "sidc version %s %s: starting work",
      PACKAGE_VERSION, soundsystem);
   alert_on = 1;
   if( CF_priority) set_scheduling();   // Setup real time scheduling

   process_signal();

   if( CF_output_policy != OP_SPECTRUM)
   {
      int i;
      struct BAND *b;

      for( i=0, b=bands; i<nbands; i++, b++)
         free( b->ident);
   }
   if( CF_uspec_file)
      free( CF_uspec_file);
   if( CF_mailaddr)
      free( CF_mailaddr);
   if( out_prefix)
      free( out_prefix);
   return 0;
}
예제 #23
0
int
main (int argc, char *argv[])
{
  /* Check to see if the user is running
   * us as root, which is a nono
   */
  if (geteuid () == 0)
    {
      fprintf (stderr, "Don't run ircd as root!!!\n");
      return (-1);
    }

  /* save server boot time right away, so getrusage works correctly */
  set_time ();

  /* Setup corefile size immediately after boot -kre */
  setup_corefile ();

  /* set initialVMTop before we allocate any memory */
  initialVMTop = get_vm_top ();

  ServerRunning = 0;

  /* It ain't random, but it ought to be a little harder to guess */
  srand (SystemTime.tv_sec ^ (SystemTime.tv_usec | (getpid () << 20)));
  memset (&me, 0, sizeof (me));
  memset (&meLocalUser, 0, sizeof (meLocalUser));
  me.localClient = &meLocalUser;
  dlinkAdd (&me, &me.node, &global_client_list);	/* Pointer to beginning
							   of Client list */

  memset (&ServerInfo, 0, sizeof (ServerInfo));

  /* Initialise the channel capability usage counts... */
  init_chcap_usage_counts ();

  ConfigFileEntry.dpath = DPATH;
  ConfigFileEntry.configfile = CPATH;	/* Server configuration file */
  ConfigFileEntry.klinefile = KPATH;	/* Server kline file         */
  ConfigFileEntry.xlinefile = XPATH;	/* Server xline file         */
  ConfigFileEntry.dlinefile = DLPATH;	/* dline file                */
  ConfigFileEntry.cresvfile = CRESVPATH;	/* channel resv file      */
  ConfigFileEntry.nresvfile = NRESVPATH;	/* nick resv file         */
  myargv = argv;
  umask (077);			/* better safe than sorry --SRB */

  parseargs (&argc, &argv, myopts);

  build_version ();

  if (printVersion)
    {
      printf ("ircd: version %s\n", ircd_version);
      exit (EXIT_SUCCESS);
    }

  if (chdir (ConfigFileEntry.dpath))
    {
      perror ("chdir");
      exit (EXIT_FAILURE);
    }

  if (!server_state.foreground)
    make_daemon ();
  else
    print_startup (getpid ());

#ifdef HAVE_LIBCRYPTO
  dh_init();
  fprintf(stderr, "SSL: Initialize\n");

  SSL_load_error_strings();
  SSLeay_add_ssl_algorithms();
  ServerInfo.ctx = SSL_CTX_new(SSLv23_server_method());

  if (!ServerInfo.ctx) {
       ERR_print_errors_fp(stderr);
       return 0;
  }

  fprintf(stderr, "SSL: Client based SSL connections are enabled.\n");
#endif

  setup_signals ();
  /* We need this to initialise the fd array before anything else */
  fdlist_init ();

  if (!server_state.foreground)
    close_all_connections ();	/* this needs to be before init_netio()! */
  else
    check_can_use_v6 ();	/* Done in close_all_connections normally */

  init_log (logFileName);
  init_netio ();		/* This needs to be setup early ! -- adrian */
  /* Check if there is pidfile and daemon already running */
  check_pidfile (pidFileName);
  /* Init the event subsystem */
  eventInit ();
  init_sys ();

#ifndef NOBALLOC
  initBlockHeap ();
#endif
  init_dlink_nodes ();
  init_slink_nodes ();
  initialize_message_files ();
  dbuf_init ();
  init_hash ();
  init_ip_hash_table ();	/* client host ip hash table */
  init_host_hash ();		/* Host-hashtable. */
  clear_hash_parse ();
  init_client ();
  init_user ();
  init_channels ();
  init_class ();
  init_whowas ();
  init_stats ();
  init_hooks ();
  read_conf_files (1);		/* cold start init conf files */
  initServerMask ();
  init_uid ();
  init_auth ();			/* Initialise the auth code */
  init_resolver ();		/* Needs to be setup before the io loop */
  init_reject ();               /* Set up the reject code. */
  init_umodes ();               /* Set up the usermode system. */

  initialize_foundation_signals(); /* register things that modules need */

#ifdef HAVE_LIBCRYPTO
  bio_spare_fd = save_spare_fd ("SSL private key validation");
#endif /* HAVE_LIBCRYPTO */

  initialize_server_capabs ();	/* Set up default_server_capabs */
  initialize_global_set_options ();

  if (ServerInfo.name == NULL)
    {
      fprintf (stderr,
	       "ERROR: No server name specified in serverinfo block.\n");
      ilog (L_CRIT, "No server name specified in serverinfo block.");
      exit (EXIT_FAILURE);
    }
  strlcpy (me.name, ServerInfo.name, sizeof (me.name));

  /* serverinfo{} description must exist.  If not, error out. */
  if (ServerInfo.description == NULL)
    {
      fprintf (stderr,
	       "ERROR: No server description specified in serverinfo block.\n");
      ilog (L_CRIT,
	    "ERROR: No server description specified in serverinfo block.");
      exit (EXIT_FAILURE);
    }
  strlcpy (me.info, ServerInfo.description, sizeof (me.info));

  me.from = &me;
  me.servptr = &me;

  SetMe (&me);
  make_server (&me);

  strlcpy (me.serv->up, me.name, sizeof (me.serv->up));
  me.lasttime = me.since = me.firsttime = CurrentTime;
  hash_add_client (&me);

  /* add ourselves to global_serv_list */
  dlinkAdd (&me, make_dlink_node (), &global_serv_list);

  check_class ();

#ifndef STATIC_MODULES
  if (chdir (MODPATH))
    {
      ilog (L_CRIT, "Could not load core modules. Terminating!");
      exit (EXIT_FAILURE);
    }
  mod_set_base ();
  load_all_modules (1);
  load_core_modules (1);
  /* Go back to DPATH after checking to see if we can chdir to MODPATH */
  chdir (ConfigFileEntry.dpath);
#else
  load_all_modules (1);
#endif

  write_pidfile (pidFileName);

  ilog (L_NOTICE, "Server Ready");

  eventAddIsh ("cleanup_tklines", cleanup_tklines, NULL,
	       CLEANUP_TKLINES_TIME);

  /* We want try_connections to be called as soon as possible now! -- adrian */
  /* No, 'cause after a restart it would cause all sorts of nick collides */
  eventAddIsh ("try_connections", try_connections, NULL,
	       STARTUP_CONNECTIONS_TIME);

  eventAddIsh ("collect_zipstats", collect_zipstats, NULL, ZIPSTATS_TIME);

  /* Setup the timeout check. I'll shift it later :)  -- adrian */
  eventAddIsh ("comm_checktimeouts", comm_checktimeouts, NULL, 1);

  if (splitmode)
    eventAddIsh ("check_splitmode", check_splitmode, NULL, 60);

  ServerRunning = 1;
  io_loop ();
  return (0);
}