]> rtime.felk.cvut.cz Git - frescor/forb.git/blob - src/forbrun/forbrun.c
forb: Update forbrun usage help
[frescor/forb.git] / src / forbrun / forbrun.c
1 #define WITH_C99                /* For ul_gsa.h iterators */
2 #include <getopt.h>
3 #include <forb.h>
4 #include <error.h>
5 #include <errno.h>
6 #include <stdio.h>
7 #include <ul_log.h>
8 #include <stdbool.h>
9 #include <dlfcn.h>
10 #include <forb/forb-internal.h>
11 #include <pthread.h>
12
13 static struct option long_opts[] = {
14     { "daemon",   optional_argument, NULL, 'd' },
15     { "id",       required_argument, NULL, 'i' },
16 /*     { "loglevel", required_argument, NULL, 'l' }, */
17     { "port",     required_argument, NULL, 'p' },
18     { 0, 0, 0, 0}
19 };
20
21 static void
22 usage(void)
23 {
24         printf("usage: forbrun [ options ] -- <forb-server>.so [ options for forb_main() ] [-- ...]\n");
25         printf("  -d, --daemon [pid-file]   go to background after initialization of servers\n");
26         printf("  -i, --id <orb id>         \n");
27 /*      printf("  -l, --loglevel <number>|<domain>=<number>,...\n"); */
28         printf("  -p, --port <number>       listen on a fixed port number\n");
29 }
30
31 int print_log_domain(ul_log_domain_t *domain, void *context)
32 {
33         printf("%s = %d\n", domain->name, domain->level);
34         return 0;
35 }
36
37 struct forb_main_data {
38         char *filename;
39         forb_orb orb;
40         int (*forb_main)(forb_orb orb, int argc, char *argv[]);
41         int argc;
42         char **argv;
43 };
44
45 void *forb_main_thread(void *arg)
46 {
47         struct forb_main_data *data = arg;
48         int ret;
49         ret = data->forb_main(data->orb, data->argc, data->argv);
50         exit(ret);
51         return NULL;
52 }
53
54 int main(int argc, char *argv[])
55 {
56         unsigned libs_loaded_cnt = 0;
57         forb_orb orb;
58         bool opt_daemon = false;
59         char *opt_pidfile = NULL;
60         int i;
61         forb_init_attr_t attr = {
62                 .orb_id = "org.frescor.fcb",
63                 .peer_discovery_callback = NULL, /* TODO */
64                 .peer_dead_callback = NULL,      /* TODO */
65                 .fixed_tcp_port = 0,
66 #ifdef CONFIG_FORB_PROTO_INET_DEFAULT           
67                 .fixed_server_id = 0, /* TODO */
68                 .redistribute_hellos = false , /* TODO */
69 #endif
70         };
71         int  opt;
72
73         while ((opt = getopt_long(argc, argv, "d::hil:p:x", &long_opts[0], NULL)) != EOF) {
74                 switch (opt) {
75 #if 0                   
76                         case 'l':
77                                 if (*optarg == '?') {
78                                         ul_logreg_for_each_domain(print_log_domain, NULL);
79                                         exit(0);
80                                 }
81                                 {
82                                         int ret;
83                                         ret = ul_log_domain_arg2levels(optarg);
84                                         if (ret) 
85                                                 error(1, EINVAL, "Error parsing -l argument at char %d\n", ret);
86                                 }
87                                 break;
88 #endif
89                         case 'd':
90                                 opt_daemon = true;
91                                 opt_pidfile = optarg;
92                                 break;
93                         case 'i':
94                                 attr.orb_id = optarg;
95                                 break;
96                         case 'h':
97                         /*default:*/
98                                 usage();
99                                 exit(opt == 'h' ? 0 : 1);
100                                 break;
101                         case 'p':
102                                 attr.fixed_tcp_port = atol(optarg);
103                                 break;
104                 }
105         }
106
107         if (opt_daemon)
108                 forb_daemon_prepare(opt_pidfile); /* == fork() */
109
110         orb = forb_init(&argc, &argv, &attr);
111         if (!orb) error(1, errno, "FORB initialization failed");
112
113
114 #if CONFIG_FCB_INET && !CONFIG_FORB_PROTO_INET_DEFAULT
115         ret = register_inet_port(orb);
116         if (ret) error(0, errno, "INET port registration failed");
117 #endif
118
119         for (i = optind; i < argc; i++) {
120                 void *handle;
121                 fosa_thread_id_t tid;
122                 struct forb_main_data data;
123
124                 data.filename = argv[i];
125                 handle = dlopen(data.filename, RTLD_LOCAL|RTLD_LAZY);
126                 if (!handle)
127                         error(1, errno, "dlopen(\"%s\") failed", data.filename);
128                 data.forb_main = dlsym(handle, "forb_main");
129                 if (!data.forb_main)
130                         error(1, errno, "Cannot find forb_main() in %s", data.filename);
131
132                 data.orb = orb;
133                 
134                 // parse forb parameters
135                 data.argc = 1;
136                 data.argv = &argv[i];
137                 while (i+1 < argc) {
138                         i++;
139                         if (!strcmp(argv[i], "--")) 
140                                 break;
141                         else
142                                 data.argc++;
143                 }
144                 fosa_thread_create(&tid, NULL, forb_main_thread, &data);
145                 libs_loaded_cnt++;
146
147                 forb_wait_for_server_ready(orb);
148         }
149
150         if (opt_daemon)
151                 forb_daemon_ready();
152
153         /* Allow other threads to continue execution, but exit
154          * ourselves (without exit()ing the whole process. */
155         if (libs_loaded_cnt > 0)
156                 pthread_exit(NULL);     
157
158         return 0;
159 }