~ubuntu-branches/ubuntu/trusty/syslog-ng/trusty-proposed

« back to all changes in this revision

Viewing changes to syslog-ng/main.c

  • Committer: Package Import Robot
  • Author(s): Laszlo Boszormenyi (GCS), Gergely Nagy
  • Date: 2011-10-11 14:30:48 UTC
  • mfrom: (1.3.7)
  • Revision ID: package-import@ubuntu.com-20111011143048-r1iljux9xbvj3lwh
Tags: 3.3.1.dfsg-1
* New upstream release with important fixes from upstream git tree with
  non-free manpages removed.
* Drop syslog-ng.conf(5) (closes: #496521).
* syslog-ng(8) is generated, and does not mention -Q anymore
  (closes: #616069).
* Supports CAP_SYSLOG on recent kernels (closes: #630172).
* Does not use g_timeout_add_seconds anymore (closes: #609154).

[ Gergely Nagy <algernon@madhouse-project.org> ]
* Update debian/copyright to DEP-5 format.
* Simplified the logrotate file by merging identical entries.
* Include local configuration files from /etc/syslog-ng/conf.d/ (Closes:
  #609050).
* Update syslog-ng.conf to be fully 3.3 compliant.
* Compress both source and binaries (except the syslog-ng meta
  package) with xz, instead of gzip.
* Use dpkg triggers to restart syslog-ng when appropriate.
* Include DFSG-free manual pages for all binaries.
* Build with Hardening enabled.
* Mention syslog(3) in /etc/default/syslog-ng, instead of
  <linux/kernel.h> (Closes: #608605)
* Support 'status' in the init script.
  Patch from Peter Eisentraut <petere@debian.org> (Closes: #644458)
* Build-Depend on libevtlog-dev (>= 0.2.12-5~) for correct shlibs.
* Use [linux-any] in Build-Depends instead of hardcoded links.
  (Closes: #634715)
* Use $SYSLOGNG_OPTS in the init script when reloading syslog-ng.
  (Closes: #589081)

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
#include "control.h"
37
37
#include "timeutils.h"
38
38
#include "logsource.h"
39
 
 
40
 
#if ENABLE_SSL
41
 
#include <openssl/ssl.h>
42
 
#include <openssl/rand.h>
43
 
#endif
44
 
 
 
39
#include "mainloop.h"
 
40
#include "plugin.h"
45
41
 
46
42
#include <sys/types.h>
47
43
#include <stdio.h>
59
55
#include <getopt.h>
60
56
#endif
61
57
 
62
 
static gchar *cfgfilename = PATH_SYSLOG_NG_CONF;
 
58
#include <iv.h>
 
59
#include <iv_signal.h>
 
60
 
63
61
static gchar *install_dat_filename = PATH_INSTALL_DAT;
64
62
static gchar *installer_version = NULL;
65
 
static const gchar *persist_file = PATH_PERSIST_CONFIG;
66
 
static gboolean syntax_only = FALSE;
67
63
static gboolean display_version = FALSE;
68
 
static gchar *ctlfilename = PATH_CONTROL_SOCKET;
69
 
static gchar *preprocess_into = NULL;
70
 
 
71
 
static volatile sig_atomic_t sig_hup_received = FALSE;
72
 
static volatile sig_atomic_t sig_term_received = FALSE;
73
 
static volatile sig_atomic_t sig_child_received = FALSE;
74
 
 
75
 
static void 
76
 
sig_hup_handler(int signo)
77
 
{
78
 
  sig_hup_received = TRUE;
79
 
}
80
 
 
81
 
static void
82
 
sig_term_handler(int signo)
83
 
{
84
 
  sig_term_received = TRUE;
85
 
}
86
 
 
87
 
static void
88
 
sig_child_handler(int signo)
89
 
{
90
 
  sig_child_received = TRUE;
91
 
}
92
 
 
93
 
static void
94
 
setup_signals(void)
95
 
{
96
 
  struct sigaction sa;
97
 
  
98
 
  memset(&sa, 0, sizeof(sa));
99
 
  sa.sa_handler = SIG_IGN;
100
 
  sigaction(SIGPIPE, &sa, NULL);
101
 
  sa.sa_handler = sig_hup_handler;
102
 
  sigaction(SIGHUP, &sa, NULL);
103
 
  sa.sa_handler = sig_term_handler;
104
 
  sigaction(SIGTERM, &sa, NULL);
105
 
  sa.sa_handler = sig_term_handler;
106
 
  sigaction(SIGINT, &sa, NULL);
107
 
  sa.sa_handler = sig_child_handler;
108
 
  sigaction(SIGCHLD, &sa, NULL);
109
 
}
110
 
 
111
 
gboolean
112
 
stats_timer(gpointer st)
113
 
{
114
 
  stats_generate_log();
115
 
  return TRUE;
116
 
}
117
 
 
118
 
static GStaticMutex main_loop_lock = G_STATIC_MUTEX_INIT;
119
 
static GMainLoop *main_loop = NULL;
120
 
static GPollFunc system_poll_func = NULL;
121
 
 
122
 
void
123
 
main_loop_wakeup(void)
124
 
{
125
 
  g_static_mutex_lock(&main_loop_lock);
126
 
  if (main_loop)
127
 
    g_main_context_wakeup(g_main_loop_get_context(main_loop));
128
 
  g_static_mutex_unlock(&main_loop_lock);
129
 
}
130
 
 
131
 
gint
132
 
main_context_poll(GPollFD *ufds, guint nfsd, gint timeout_)
133
 
{
134
 
  gint ret = (*system_poll_func)(ufds, nfsd, timeout_);
135
 
  update_g_current_time();
136
 
  return ret;
137
 
}
138
 
 
139
 
int 
140
 
main_loop_run(GlobalConfig **cfg)
141
 
{
142
 
  gint iters;
143
 
  guint stats_timer_id = 0;
144
 
  sigset_t ss;
145
 
 
146
 
  log_source_set_wakeup_func(main_loop_wakeup);
147
 
 
148
 
  msg_notice("syslog-ng starting up", 
149
 
             evt_tag_str("version", VERSION),
150
 
             NULL);
151
 
  main_loop = g_main_loop_new(NULL, TRUE);
152
 
  if ((*cfg)->stats_freq > 0)
153
 
    stats_timer_id = g_timeout_add((*cfg)->stats_freq * 1000, stats_timer, NULL);
154
 
    
155
 
  control_init(ctlfilename, g_main_loop_get_context(main_loop));
156
 
 
157
 
  system_poll_func = g_main_context_get_poll_func(g_main_loop_get_context(main_loop));
158
 
  g_main_context_set_poll_func(g_main_loop_get_context(main_loop), main_context_poll);
159
 
  while (g_main_loop_is_running(main_loop))
160
 
    {
161
 
      if ((*cfg)->time_sleep > 0)
162
 
        {
163
 
          struct timespec ts;
164
 
          
165
 
          ts.tv_sec = (*cfg)->time_sleep / 1000;
166
 
          ts.tv_nsec = ((*cfg)->time_sleep % 1000) * 1E6;
167
 
          
168
 
          nanosleep(&ts, NULL);
169
 
        }
170
 
      g_main_context_iteration(g_main_loop_get_context(main_loop), TRUE);
171
 
      if (sig_hup_received)
172
 
        {
173
 
          sigemptyset(&ss);
174
 
          sigaddset(&ss, SIGHUP);
175
 
          sigprocmask(SIG_BLOCK, &ss, NULL);
176
 
          sig_hup_received = FALSE;
177
 
 
178
 
          /* this may handle multiple SIGHUP signals, however it doesn't
179
 
           * really matter if we received only a single or multiple SIGHUPs
180
 
           * until we make sure that we handle the last one.  Since we
181
 
           * blocked the SIGHUP signal and reset sig_hup_received to FALSE,
182
 
           * we can be sure that if we receive an additional SIGHUP during
183
 
           * signal processing we get the new one when we finished this, and
184
 
           * handle that one as well. */
185
 
 
186
 
          app_pre_config_loaded();
187
 
          (*cfg) = cfg_reload_config(cfgfilename, (*cfg));
188
 
          app_post_config_loaded();
189
 
          msg_notice("Configuration reload request received, reloading configuration", 
190
 
                       NULL);
191
 
          reset_cached_hostname();
192
 
          if ((*cfg)->stats_freq > 0)
193
 
            {
194
 
              if (stats_timer_id != 0)
195
 
                g_source_remove(stats_timer_id);
196
 
              stats_timer_id = g_timeout_add((*cfg)->stats_freq * 1000, stats_timer, NULL);
197
 
            }
198
 
          stats_cleanup_orphans();
199
 
          sigprocmask(SIG_UNBLOCK, &ss, NULL);
200
 
        }
201
 
      if (sig_term_received)
202
 
        {
203
 
          msg_info("Termination requested via signal, terminating", NULL);
204
 
          sig_term_received = FALSE;
205
 
          break;
206
 
        }
207
 
      if (sig_child_received)
208
 
        {
209
 
          pid_t pid;
210
 
          int status;
211
 
 
212
 
          sigemptyset(&ss);
213
 
          sigaddset(&ss, SIGCHLD);
214
 
          sigprocmask(SIG_BLOCK, &ss, NULL);
215
 
          sig_child_received = FALSE;
216
 
 
217
 
          /* this may handle multiple SIGCHLD signals, however it doesn't
218
 
           * matter if one or multiple SIGCHLD was received assuming that
219
 
           * all exited child process are waited for */
220
 
 
221
 
          do
222
 
            {
223
 
              pid = waitpid(-1, &status, WNOHANG);
224
 
              child_manager_sigchild(pid, status);
225
 
            }
226
 
          while (pid > 0);
227
 
          sigprocmask(SIG_UNBLOCK, &ss, NULL);
228
 
        }
229
 
    }
230
 
  control_destroy();
231
 
  msg_notice("syslog-ng shutting down", 
232
 
             evt_tag_str("version", VERSION),
233
 
             NULL);
234
 
  iters = 0;
235
 
  while (g_main_context_iteration(NULL, FALSE) && iters < 3)
236
 
    {
237
 
      iters++;
238
 
    }
239
 
  g_static_mutex_lock(&main_loop_lock);
240
 
  g_main_loop_unref(main_loop);
241
 
  main_loop = NULL;
242
 
  g_static_mutex_unlock(&main_loop_lock);
243
 
  return 0;
244
 
}
 
64
static gboolean display_module_registry = FALSE;
 
65
static gboolean dummy = FALSE;
245
66
 
246
67
#ifdef YYDEBUG
247
68
extern int cfg_parser_debug;
248
69
#endif
249
70
 
250
 
 
251
71
static GOptionEntry syslogng_options[] = 
252
72
{
253
 
  { "cfgfile",           'f',         0, G_OPTION_ARG_STRING, &cfgfilename, "Set config file name, default=" PATH_SYSLOG_NG_CONF, "<config>" },
254
 
  { "persist-file",      'R',         0, G_OPTION_ARG_STRING, &persist_file, "Set the name of the persistent configuration file, default=" PATH_PERSIST_CONFIG, "<fname>" },
255
 
  { "module-path",         0,         0, G_OPTION_ARG_STRING, &module_path, "Set the list of colon separated directories to search for modules, default=" PATH_MODULEDIR, "<path>" },
256
 
  { "syntax-only",       's',         0, G_OPTION_ARG_NONE, &syntax_only, "Only read and parse config file", NULL},
257
 
  { "preprocess-into",     0,         0, G_OPTION_ARG_STRING, &preprocess_into, "Write the preprocessed configuration file to the file specified", "output" },
258
73
  { "version",           'V',         0, G_OPTION_ARG_NONE, &display_version, "Display version number (" PACKAGE " " VERSION ")", NULL },
259
 
  { "seed",              'S',         0, G_OPTION_ARG_NONE, &seed_rng, "Seed the RNG using ~/.rnd or $RANDFILE", NULL},
260
 
  { "control",           'c',         0, G_OPTION_ARG_STRING, &ctlfilename, "Set syslog-ng control socket, default=" PATH_CONTROL_SOCKET, "<ctlpath>" },
 
74
  { "module-path",         0,         0, G_OPTION_ARG_STRING, &module_path, "Set the list of colon separated directories to search for modules, default=" MODULE_PATH, "<path>" },
 
75
  { "module-registry",     0,         0, G_OPTION_ARG_NONE, &display_module_registry, "Display module information", NULL },
 
76
  { "default-modules",     0,         0, G_OPTION_ARG_STRING, &default_modules, "Set the set of auto-loaded modules, default=" DEFAULT_MODULES, "<module-list>" },
 
77
  { "seed",              'S',         0, G_OPTION_ARG_NONE, &dummy, "Does nothing, the need to seed the random generator is autodetected", NULL},
261
78
#ifdef YYDEBUG
262
79
  { "yydebug",           'y',         0, G_OPTION_ARG_NONE, &cfg_parser_debug, "Enable configuration parser debugging", NULL },
263
80
#endif
264
81
  { NULL },
265
82
};
266
83
 
267
 
/* 
268
 
 * Returns: exit code to be returned to the calling process.
269
 
 */
270
 
int 
271
 
initial_init(GlobalConfig **cfg)
272
 
{
273
 
  app_startup();
274
 
  setup_signals();
275
 
 
276
 
  *cfg = cfg_new(0);
277
 
  if (!cfg_read_config(*cfg, cfgfilename, syntax_only, preprocess_into))
278
 
    {
279
 
      return 1;
280
 
    }
281
 
 
282
 
  if (syntax_only)
283
 
    {
284
 
      return 0;
285
 
    }
286
 
 
287
 
  if (!cfg_initial_init(*cfg, persist_file))
288
 
    {
289
 
      return 2;
290
 
    }
291
 
  return 0;
292
 
}
293
 
 
294
84
#define INSTALL_DAT_INSTALLER_VERSION "INSTALLER_VERSION"
295
85
 
296
86
gboolean
326
116
void
327
117
version(void)
328
118
{
329
 
  if (!get_installer_version(&installer_version) || installer_version==NULL)
 
119
  if (!get_installer_version(&installer_version) || installer_version == NULL)
330
120
    {
331
 
      installer_version=VERSION;
 
121
      installer_version = VERSION;
332
122
    }
333
123
  printf(PACKAGE " " VERSION "\n"
334
124
         "Installer-Version: %s\n"
335
125
         "Revision: " SOURCE_REVISION "\n"
 
126
#if WITH_COMPILE_DATE
336
127
         "Compile-Date: " __DATE__ " " __TIME__ "\n"
337
 
         "Enable-Threads: %s\n"
338
 
         "Enable-Debug: %s\n"
 
128
#endif
 
129
         "Default-Modules: %s\n"
 
130
         "Available-Modules: ",
 
131
         installer_version,
 
132
         default_modules);
 
133
 
 
134
  plugin_list_modules(stdout, FALSE);
 
135
 
 
136
  printf("Enable-Debug: %s\n"
339
137
         "Enable-GProf: %s\n"
340
138
         "Enable-Memtrace: %s\n"
341
 
         "Enable-Sun-STREAMS: %s\n"
342
139
         "Enable-IPv6: %s\n"
343
140
         "Enable-Spoof-Source: %s\n"
344
141
         "Enable-TCP-Wrapper: %s\n"
345
 
         "Enable-SSL: %s\n"
346
 
         "Enable-SQL: %s\n"
347
142
         "Enable-Linux-Caps: %s\n"
348
 
         "Enable-Pcre: %s\n"
349
 
         "Enable-Pacct: %s\n",
350
 
         installer_version,
351
 
         ON_OFF_STR(ENABLE_THREADS),
 
143
         "Enable-Pcre: %s\n",
352
144
         ON_OFF_STR(ENABLE_DEBUG),
353
145
         ON_OFF_STR(ENABLE_GPROF),
354
146
         ON_OFF_STR(ENABLE_MEMTRACE),
355
 
         ON_OFF_STR(ENABLE_SUN_STREAMS_MODULE),
356
147
         ON_OFF_STR(ENABLE_IPV6),
357
148
         ON_OFF_STR(ENABLE_SPOOF_SOURCE),
358
149
         ON_OFF_STR(ENABLE_TCP_WRAPPER),
359
 
         ON_OFF_STR(ENABLE_SSL_MODULE),
360
 
         ON_OFF_STR(ENABLE_SQL_MODULE),
361
150
         ON_OFF_STR(ENABLE_LINUX_CAPS),
362
 
         ON_OFF_STR(ENABLE_PCRE),
363
 
         ON_OFF_STR(ENABLE_PACCT_MODULE));
364
 
}
 
151
         ON_OFF_STR(ENABLE_PCRE));
 
152
 
 
153
}
 
154
 
 
155
#if ENABLE_LINUX_CAPS
 
156
#define BASE_CAPS "cap_net_bind_service,cap_net_broadcast,cap_net_raw," \
 
157
  "cap_dac_read_search,cap_dac_override,cap_chown,cap_fowner=p "
 
158
 
 
159
static void
 
160
setup_caps (void)
 
161
{
 
162
  static gchar *capsstr_syslog = BASE_CAPS "cap_syslog=ep";
 
163
  static gchar *capsstr_sys_admin = BASE_CAPS "cap_sys_admin=ep";
 
164
 
 
165
  /* Set up the minimal privilege we'll need
 
166
   *
 
167
   * NOTE: polling /proc/kmsg requires cap_sys_admin, otherwise it'll always
 
168
   * indicate readability. Enabling/disabling cap_sys_admin on every poll
 
169
   * invocation seems to be too expensive. So I enable it for now.
 
170
   */
 
171
  if (g_process_check_cap_syslog())
 
172
    g_process_set_caps(capsstr_syslog);
 
173
  else
 
174
    g_process_set_caps(capsstr_sys_admin);
 
175
}
 
176
#else
 
177
 
 
178
#define setup_caps()
 
179
 
 
180
#endif
365
181
 
366
182
int 
367
183
main(int argc, char *argv[])
368
184
{
369
 
  GlobalConfig *cfg;
370
185
  gint rc;
371
186
  GOptionContext *ctx;
372
187
  GError *error = NULL;
374
189
  z_mem_trace_init("syslog-ng.trace");
375
190
 
376
191
  g_process_set_argv_space(argc, (gchar **) argv);
377
 
  
378
 
  /* NOTE: polling /proc/kmsg requires cap_sys_admin, otherwise it'll always
379
 
   * indicate readability. Enabling/disabling cap_sys_admin on every poll
380
 
   * invocation seems to be too expensive. So I enable it for now. */
381
 
  
382
 
  g_process_set_caps("cap_net_bind_service,cap_net_broadcast,cap_net_raw,"
383
 
                     "cap_dac_read_search,cap_dac_override,cap_chown,cap_fowner=p "
384
 
                     "cap_sys_admin=ep");
 
192
 
 
193
  setup_caps();
 
194
 
385
195
  ctx = g_option_context_new("syslog-ng");
386
196
  g_process_add_option_group(ctx);
387
197
  msg_add_option_group(ctx);
388
198
  g_option_context_add_main_entries(ctx, syslogng_options, NULL);
 
199
  main_loop_add_options(ctx);
389
200
  if (!g_option_context_parse(ctx, &argc, &argv, &error))
390
201
    {
391
 
      fprintf(stderr, "Error parsing command line arguments: %s", error ? error->message : "Invalid arguments");
 
202
      fprintf(stderr, "Error parsing command line arguments: %s\n", error ? error->message : "Invalid arguments");
392
203
      g_option_context_free(ctx);
393
204
      return 1;
394
205
    }
404
215
      version();
405
216
      return 0;
406
217
    }
407
 
  if (preprocess_into)
408
 
    syntax_only = TRUE;
 
218
  if (display_module_registry)
 
219
    {
 
220
      plugin_list_modules(stdout, TRUE);
 
221
      return 0;
 
222
    }
409
223
 
410
224
  if (debug_flag)
411
225
    {
416
230
    {
417
231
      g_process_set_mode(G_PM_FOREGROUND);
418
232
    }
419
 
 
420
233
  g_process_set_name("syslog-ng");
421
234
  
422
235
  /* in this case we switch users early while retaining a limited set of
423
236
   * credentials in order to initialize/reinitialize the configuration.
424
237
   */
425
238
  g_process_start();
426
 
  rc = initial_init(&cfg);
 
239
  rc = main_loop_init();
427
240
  
428
241
  if (rc)
429
242
    {
443
256
  app_post_daemonized();
444
257
  app_post_config_loaded();
445
258
  /* from now on internal messages are written to the system log as well */
446
 
  msg_syslog_started();
447
259
  
448
 
  rc = main_loop_run(&cfg);
 
260
  rc = main_loop_run();
449
261
 
450
 
  cfg_deinit(cfg);
451
 
  cfg_free(cfg);
452
 
  
453
262
  app_shutdown();
454
263
  z_mem_trace_dump();
455
264
  g_process_finish();