root/src/stratcond.c

Revision 6210da7ee0e2ed143d71a8e00b709f16e71059f8, 4.2 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 6 years ago)

various changes to avoid dereferencing type-punned pointers and breaking strict-aliasing rules, refs #34

  • Property mode set to 100644
Line 
1 #include "noit_defines.h"
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <errno.h>
7 #include <sys/ioctl.h>
8 #include <fcntl.h>
9
10 #include "eventer/eventer.h"
11 #include "utils/noit_log.h"
12 #include "utils/noit_hash.h"
13 #include "utils/noit_security.h"
14 #include "noit_listener.h"
15 #include "noit_console.h"
16 #include "noit_module.h"
17 #include "noit_conf.h"
18 #include "stratcon_jlog_streamer.h"
19 #include "stratcon_datastore.h"
20 #include "stratcon_realtime_http.h"
21
22 #define APPNAME "stratcon"
23 static char *config_file = ETC_DIR "/" APPNAME ".conf";
24 static const char *droptouser = NULL;
25 static const char *droptogroup = NULL;
26 static const char *chrootpath = NULL;
27 static int foreground = 0;
28 static int debug = 0;
29
30 #include "man/stratcond.usage.h"
31 static void usage(const char *progname) {
32   printf("Usage for %s:\n", progname);
33 #ifdef STRATCOND_USAGE
34   write(STDOUT_FILENO, STRATCOND_USAGE, sizeof(STRATCOND_USAGE)-1);
35 #else
36   printf("\nError in usage, build problem.\n");
37 #endif
38   return;
39 }
40
41 void parse_clargs(int argc, char **argv) {
42   int c;
43   while((c = getopt(argc, argv, "hc:dDu:g:t:")) != EOF) {
44     switch(c) {
45       case 'h':
46         usage(argv[0]);
47         exit(1);
48         break;
49       case 'u':
50         droptouser = strdup(optarg);
51         break;
52       case 'g':
53         droptogroup = strdup(optarg);
54         break;
55       case 't':
56         chrootpath = strdup(optarg);
57         break;
58       case 'c':
59         config_file = strdup(optarg);
60         break;
61       case 'd':
62         debug++;
63         break;
64       case 'D':
65         foreground = 1;
66         break;
67       default:
68         break;
69     }
70   }
71 }
72
73 static
74 int configure_eventer() {
75   int rv = 0;
76   noit_hash_table *table;
77   table = noit_conf_get_hash(NULL, "/" APPNAME "/eventer/config");
78   if(table) {
79     noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
80     const char *key, *value;
81     int klen;
82     while(noit_hash_next_str(table, &iter, &key, &klen, &value)) {
83       int subrv;
84       if((subrv = eventer_propset(key, value)) != 0)
85         rv = subrv;
86     }
87     noit_hash_destroy(table, free, free);
88     free(table);
89   }
90   return rv;
91 }
92
93 int main(int argc, char **argv) {
94   char conf_str[1024];
95
96   parse_clargs(argc, argv);
97
98   chdir("/");
99   if(!foreground) {
100     close(STDIN_FILENO);
101     close(STDOUT_FILENO);
102     close(STDERR_FILENO);
103     if(fork()) exit(0);
104     setsid();
105     if(fork()) exit(0);
106   }
107
108   /* First initialize logging, so we can log errors */
109   noit_log_init();
110   noit_log_stream_add_stream(noit_debug, noit_stderr);
111   noit_log_stream_add_stream(noit_error, noit_stderr);
112
113   /* Next load the configs */
114   noit_conf_init(APPNAME);
115   if(noit_conf_load(config_file) == -1) {
116     fprintf(stderr, "Cannot load config: '%s'\n", config_file);
117     exit(2);
118   }
119
120   /* Reinitialize the logging system now that we have a config */
121   noit_conf_log_init(APPNAME);
122   if(debug)
123     noit_debug->enabled = 1;
124
125   /* Lastly, run through all other system inits */
126   if(!noit_conf_get_stringbuf(NULL, "/" APPNAME "/eventer/@implementation",
127                               conf_str, sizeof(conf_str))) {
128     noitL(noit_stderr, "Cannot find '%s' in configuration\n",
129           "/" APPNAME "/eventer/@implementation");
130     exit(-1);
131   }
132   if(eventer_choose(conf_str) == -1) {
133     noitL(noit_stderr, "Cannot choose eventer %s\n", conf_str);
134     exit(-1);
135   }
136   if(configure_eventer() != 0) {
137     noitL(noit_stderr, "Cannot configure eventer\n");
138     exit(-1);
139   }
140   if(eventer_init() == -1) {
141     noitL(noit_stderr, "Cannot init eventer %s\n", conf_str);
142     exit(-1);
143   }
144   noit_console_init();
145   stratcon_realtime_http_init(APPNAME);
146   noit_listener_init(APPNAME);
147
148   /* Drop privileges */
149   if(chrootpath && noit_security_chroot(chrootpath)) {
150     noitL(noit_stderr, "Failed to chroot(), exiting.\n");
151     exit(-1);
152   }
153   if(noit_security_usergroup(droptouser, droptogroup)) {
154     noitL(noit_stderr, "Failed to drop privileges, exiting.\n");
155     exit(-1);
156   }
157
158   stratcon_jlog_streamer_init(APPNAME);
159
160   /* Write our log out, and setup a watchdog to write it out on change. */
161   stratcon_datastore_saveconfig(NULL);
162   noit_conf_coalesce_changes(10); /* 10 seconds of no changes before we write */
163   noit_conf_watch_and_journal_watchdog(stratcon_datastore_saveconfig, NULL);
164
165   eventer_loop();
166   return 0;
167 }
Note: See TracBrowser for help on using the browser.