1
0
mirror of https://github.com/haiwen/ccnet-server.git synced 2025-05-09 07:36:20 +00:00
ccnet-server/net/server/ccnet-server.c
Xiangyue Cai 9a1858aea5 support python3 ()
* use searpc-named-pipe-transport

* delete unused files

* remove not threaded rpc

* use NamedPipeClient

* remove not threaded rpc

* remove unused code

* remove unused rpc function

* remove unused code and source files

* Add name of rpc named pipe to ccent.h.
2019-07-25 11:59:28 +08:00

374 lines
9.3 KiB
C

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
#include "common.h"
#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#include <event2/dns.h>
#else
#include <evdns.h>
#endif
#include "server-session.h"
#include "user-mgr.h"
#include "rpc-service.h"
#include "log.h"
char *pidfile = NULL;
CcnetSession *session;
#ifndef WIN32
struct event sigint;
struct event sigterm;
struct event sigusr1;
static void sigintHandler (int fd, short event, void *user_data)
{
ccnet_session_on_exit (session);
exit (1);
}
static void sigusr1Handler (int fd, short event, void *user_data)
{
ccnet_log_reopen ();
}
static void setSigHandlers ()
{
signal (SIGPIPE, SIG_IGN);
event_set(&sigint, SIGINT, EV_SIGNAL, sigintHandler, NULL);
event_add(&sigint, NULL);
/* same as sigint */
event_set(&sigterm, SIGTERM, EV_SIGNAL, sigintHandler, NULL);
event_add(&sigterm, NULL);
/* redesign as reopen log */
event_set(&sigusr1, SIGUSR1, EV_SIGNAL | EV_PERSIST, sigusr1Handler, NULL);
event_add(&sigusr1, NULL);
}
#endif
static void
remove_pidfile (const char *pidfile)
{
if (pidfile) {
g_unlink (pidfile);
}
}
static int
write_pidfile (const char *pidfile_path)
{
if (!pidfile_path)
return -1;
pid_t pid = getpid();
FILE *pidfile = fopen(pidfile_path, "w");
if (!pidfile) {
ccnet_warning ("Failed to fopen() pidfile %s: %s\n",
pidfile_path, strerror(errno));
return -1;
}
char buf[32];
snprintf (buf, sizeof(buf), "%d\n", pid);
if (fputs(buf, pidfile) < 0) {
ccnet_warning ("Failed to write pidfile %s: %s\n",
pidfile_path, strerror(errno));
return -1;
}
fflush (pidfile);
fclose (pidfile);
return 0;
}
static void
on_ccnet_exit(void)
{
if (pidfile)
remove_pidfile (pidfile);
}
static const char *short_options = "hvdta:c:D:f:P:M:F:";
static struct option long_options[] = {
{ "help", no_argument, NULL, 'h', },
{ "version", no_argument, NULL, 'v', },
{ "config-dir", required_argument, NULL, 'c' },
{ "add-admin", required_argument, NULL, 'a' },
{ "central-config-dir", required_argument, NULL, 'F' },
{ "logfile", required_argument, NULL, 'f' },
{ "debug", required_argument, NULL, 'D' },
{ "daemon", no_argument, NULL, 'd' },
{ "pidfile", required_argument, NULL, 'P' },
{ "max-users", required_argument, NULL, 'M' },
{ "test-config", required_argument, NULL, 't' },
{ NULL, 0, NULL, 0, },
};
static void usage()
{
fputs(
"usage: ccnet-server [OPTIONS]\n\n"
"Supported OPTIONS are:\n"
" -c CONFDIR\n"
" Specify the ccnet configuration directory. Default is ~/.ccnet\n"
" -d\n"
" Run ccnet as a daemon\n"
" -D FLAGS\n"
" Specify debug flags for logging, for example\n"
" Peer,Processor\n"
" supported flags are\n"
" Peer,Processor,Netio,\n"
" Message,Connection,Other\n"
" or ALL to enable all debug flags\n"
" -f LOG_FILE\n"
" Log file path\n"
" -P PIDFILE\n"
" Specify the file to store pid\n"
" -M MAX_USERS\n"
" Specify the max users for login\n"
" -t\n"
" test ccnet configuration and exit\n",
stdout);
}
int test_ccnet_config(const char *central_config_dir, const char *config_dir, int max_users)
{
#if !GLIB_CHECK_VERSION(2, 36, 0)
g_type_init ();
#endif
config_dir = ccnet_expand_path (config_dir);
if (central_config_dir) {
central_config_dir = ccnet_expand_path (central_config_dir);
}
if (ccnet_log_init ("-", "debug") < 0) {
fprintf (stderr, "ccnet_log_init error: %s\n", strerror(errno));
return -1;
}
srand (time(NULL));
session = (CcnetSession *)ccnet_server_session_new ();
if (!session) {
fprintf (stderr, "Error: failed to create ccnet session\n");
return -1;
}
event_init ();
evdns_init ();
ccnet_user_manager_set_max_users (((struct CcnetServerSession *)session)->user_mgr, max_users);
if (ccnet_session_prepare(session, central_config_dir, config_dir, TRUE) < 0) {
return -1;
}
return 0;
}
int
main (int argc, char **argv)
{
int c;
char *config_dir;
char *admin_passwd = NULL;
char *central_config_dir = NULL;
char *log_file = 0;
const char *debug_str = 0;
int daemon_mode = 0;
int max_users = 0;
const char *log_level_str = "debug";
gboolean test_config = FALSE;
config_dir = DEFAULT_CONFIG_DIR;
#ifdef WIN32
argv = get_argv_utf8 (&argc);
#endif
while ((c = getopt_long (argc, argv, short_options,
long_options, NULL)) != EOF) {
switch (c) {
case 'h':
usage();
exit(0);
break;
case 'v':
exit (1);
break;
case 'c':
config_dir = optarg;
break;
case 'F':
central_config_dir = optarg;
break;
case 'f':
log_file = optarg;
break;
case 'D':
debug_str = optarg;
break;
case 'd':
daemon_mode = 1;
break;
case 'P':
pidfile = optarg;
break;
case 'M':
max_users = atoi(optarg);
break;
case 't':
test_config = TRUE;
break;
case 'a':
admin_passwd = optarg;
break;
default:
fprintf (stderr, "unknown option \"-%c\"\n", (char)c);
usage();
exit (1);
}
}
argc -= optind;
argv += optind;
if (config_dir == NULL) {
fprintf (stderr, "Missing config dir\n");
exit (1);
}
if (test_config) {
/* test ccnet configuration and exit */
return test_ccnet_config (central_config_dir, config_dir, max_users);
}
#ifndef WIN32
if (daemon_mode) {
#ifndef __APPLE__
daemon (1, 0);
#else /* __APPLE */
/* daemon is deprecated under APPLE
* use fork() instead
* */
switch (fork ()) {
case -1:
ccnet_warning ("Failed to daemonize");
exit (-1);
break;
case 0:
/* all good*/
break;
default:
/* kill origin process */
exit (0);
}
#endif /* __APPLE */
}
#else /* WIN32 */
WSADATA wsadata;
WSAStartup(0x0101, &wsadata);
#endif
#if !GLIB_CHECK_VERSION(2, 36, 0)
g_type_init ();
#endif
/* log */
if (!debug_str)
debug_str = g_getenv("CCNET_DEBUG");
ccnet_debug_set_flags_string (debug_str);
config_dir = ccnet_expand_path (config_dir);
if (!log_file) {
char *logdir = g_build_filename (config_dir, "logs", NULL);
checkdir_with_mkdir (logdir);
g_free (logdir);
log_file = g_build_filename (config_dir, "logs", "ccnet.log", NULL);
}
if (ccnet_log_init (log_file, log_level_str) < 0) {
fprintf (stderr, "ccnet_log_init error: %s, %s\n", strerror(errno),
log_file);
exit (1);
}
srand (time(NULL));
session = (CcnetSession *)ccnet_server_session_new ();
if (!session) {
fputs ("Error: failed to start ccnet session, "
"see log file for the detail.\n", stderr);
return -1;
}
event_init ();
evdns_init ();
ccnet_user_manager_set_max_users (((struct CcnetServerSession *)session)->user_mgr, max_users);
if (ccnet_session_prepare(session, central_config_dir, config_dir, FALSE) < 0) {
fputs ("Error: failed to start ccnet session, "
"see log file for the detail.\n", stderr);
return -1;
}
if (admin_passwd) {
int ret = 0;
char **admin_pass = g_strsplit(admin_passwd, "/", 2);
if (g_strv_length (admin_pass) < 2 ) {
fprintf (stderr, "Error: Missing parameter, failed to add admin\n");
ret = -1;
} else if (!strcmp(admin_pass[0], "") || !strcmp(admin_pass[1], "")) {
fprintf (stderr, "Error: Username or password can't be null, failed to add admin\n");
ret = -1;
} else if (ccnet_user_manager_add_emailuser (((struct CcnetServerSession *)session)->user_mgr,
admin_pass[0],
admin_pass[1],
1, 1)) {
fprintf (stderr, "Error: Failed to add admin\n");
ret = -1;
}
g_strfreev (admin_pass);
return ret;
}
/* write pidfile after session_prepare success, if there is
* another instance of ccnet session_prepare will failed.
*/
if (pidfile) {
if (write_pidfile (pidfile) < 0) {
ccnet_message ("Failed to write pidfile\n");
return -1;
}
}
atexit (on_ccnet_exit);
#ifndef WIN32
setSigHandlers();
#endif
ccnet_session_start (session);
if(ccnet_start_rpc(session) < 0) {
ccnet_warning ("Failed to start ccnet rpc server.\n");
exit (-1);
}
/* actually enter the event loop */
event_dispatch ();
return 0;
}