1 #define WITH_C99 /* For ul_gsa.h iterators */
11 #include <forb/forb-internal.h>
13 #include <forb/server_id.h>
15 static struct option long_opts[] = {
16 { "daemon", optional_argument, NULL, 'd' },
17 { "id", required_argument, NULL, 'i' },
18 { "loglevel", required_argument, NULL, 'l' },
19 { "port", required_argument, NULL, 'p' },
20 { "serverid", required_argument, NULL, 's' },
27 printf("usage: forbrun [ options ] -- <forb-server>.so [ options for forb_main() ] [-- ...]\n");
28 printf(" -d, --daemon [pid-file] go to background after initialization of servers\n");
29 printf(" -i, --id <textual orb id>\n");
30 printf(" -l, --loglevel <number>|<domain>=<number>,...\n");
31 printf(" -p, --port <number> listen on a fixed port number\n");
32 printf(" -s, --serverid <serverid> fixed server id of this server\n");
35 int print_log_domain(ul_log_domain_t *domain, void *context)
37 printf("%s = %d\n", domain->name, domain->level);
41 struct forb_main_data {
44 int (*forb_main)(forb_orb orb, int argc, char *argv[]);
49 void *forb_main_thread(void *arg)
51 struct forb_main_data *data = arg;
54 ret = data->forb_main(data->orb, data->argc, data->argv);
60 int main(int argc, char *argv[])
62 unsigned libs_loaded_cnt = 0;
64 bool opt_daemon = false;
65 char *opt_pidfile = NULL;
67 forb_server_id *server_id;
68 forb_init_attr_t attr = {
70 .peer_discovery_callback = NULL, /* TODO */
71 .peer_dead_callback = NULL, /* TODO */
73 #ifdef CONFIG_FORB_PROTO_INET_DEFAULT
74 .fixed_server_id = 0, /* TODO */
75 .redistribute_hellos = false , /* TODO */
80 while ((opt = getopt_long(argc, argv, "d::hi:l:p:s:", &long_opts[0], NULL)) != EOF) {
84 ul_logreg_for_each_domain(print_log_domain, NULL);
88 ret = ul_log_domain_arg2levels(optarg);
90 error(1, EINVAL, "Error parsing -l argument at char %d\n", ret);
103 exit(opt == 'h' ? 0 : 1);
106 attr.fixed_tcp_port = atol(optarg);
109 server_id = forb_server_id_from_string(&attr.fixed_server_id, optarg);
111 error(1, 0, "Invalid server id: '%s'\n", optarg);
117 forb_daemon_prepare(opt_pidfile); /* == fork() */
119 orb = forb_init(&argc, &argv, &attr);
120 if (!orb) error(1, errno, "FORB initialization failed");
123 #if CONFIG_FCB_INET && !CONFIG_FORB_PROTO_INET_DEFAULT
124 ret = register_inet_port(orb);
125 if (ret) error(0, errno, "INET port registration failed");
128 for (i = optind; i < argc; i++) {
130 fosa_thread_id_t tid;
131 struct forb_main_data *data = malloc(sizeof(*data));
133 data->filename = argv[i];
134 handle = dlopen(data->filename, RTLD_LOCAL|RTLD_LAZY);
136 error(1, errno, "dlopen(\"%s\") failed", data->filename);
137 data->forb_main = dlsym(handle, "forb_main");
138 if (!data->forb_main)
139 error(1, errno, "Cannot find forb_main() in %s", data->filename);
143 // prepare forb_main() parameters
145 data->argv = &argv[i];
146 while (i < argc && strcmp(argv[i], "--")) {
151 fosa_thread_create(&tid, NULL, forb_main_thread, data);
154 ret = forb_wait_for_server_ready(orb);
156 error(1, errno, "forb_wait_for_server_ready");
162 /* Allow other threads to continue execution, but exit
163 * ourselves (without exit()ing the whole process. */
164 if (libs_loaded_cnt > 0)