/** * @internal Common function used by turbulence server and logger * process to get configuration file location. */ char * main_common_get_config_location (TurbulenceCtx * ctx, VortexCtx * vortex_ctx) { char * config; /* init the vortex support module to allow finding the * configuration file */ vortex_support_init (vortex_ctx); /* configure lookup domain, and load configuration file */ vortex_support_add_domain_search_path_ref (vortex_ctx, axl_strdup ("turbulence-conf"), vortex_support_build_filename (SYSCONFDIR, "turbulence", NULL)); vortex_support_add_domain_search_path (vortex_ctx, "turbulence-conf", "."); /* find the configuration file */ if (exarg_is_defined ("config")) { /* get the configuration defined at the command line */ config = axl_strdup (exarg_get_string ("config")); } else { /* get the default configuration defined at * compilation time */ config = vortex_support_domain_find_data_file (vortex_ctx, "turbulence-conf", "turbulence.conf"); } /* end if */ /* load main turb */ if (config == NULL) { abort_error ("Unable to find turbulence.conf file at the default location: %s/turbulence/turbulence.conf", SYSCONFDIR); return NULL; } else msg ("using configuration file: %s", config); return config; }
/** * @brief Init the valvulad log module. */ void valvulad_log_init (ValvuladCtx * ctx) { /* get current valvulad configuration */ axlDoc * doc = ctx->config; axlNode * node; /* check log reporting */ node = axl_doc_get (doc, "/valvula/global-settings/log-reporting"); if (node == NULL) { abort_error ("Unable to find log configuration <valvula/global-settings/log-reporting>"); return; } /* end if */ /* check enabled attribute */ if (! HAS_ATTR (node, "enabled")) { abort_error ("Missing attribute 'enabled' located at <valvula/global-settings/log-reporting>. Unable to determine if log is enabled"); return; } /* check if log reporting is enabled or not */ if (! HAS_ATTR_VALUE (node, "enabled", "yes")) { msg ("log reporting to file disabled"); return; } /* check for syslog usage */ ctx->use_syslog = HAS_ATTR_VALUE (node, "use-syslog", "yes"); msg ("Checking for usage of syslog %d", ctx->use_syslog); if (ctx->use_syslog) { /* open syslog */ openlog ("valvulad", LOG_PID, LOG_MAIL); msg ("Using syslog facility for logging"); return; } /* end if */ return; }
/** * @internal Places current process identifier into the file provided * by the user. */ void valvulad_place_pidfile (ValvuladCtx * ctx) { FILE * pid_file = NULL; int pid = getpid (); char buffer[20]; int size; axlNode * node; int gid, uid; /* check if pid file exists */ if (! exarg_is_defined ("skip-pid-check")) { if (valvula_support_file_test (pid_file_path, FILE_EXISTS)) { abort_error ("Unable to start server, found pid file in place %s. There is a valvula server running. If not, remove file %s", pid_file_path, pid_file_path); exit (-1); return; } /* end if */ } else { wrn ("Skipping pid file checking.."); } /* end if */ /* open pid file or create it to place the pid file */ pid_file = fopen (pid_file_path, "w"); if (pid_file == NULL) { abort_error ("Unable to open pid file at: %s", pid_file_path); return; } /* end if */ /* stringfy pid */ size = axl_stream_printf_buffer (buffer, 20, NULL, "%d", pid); msg ("signaling PID %d at %s", pid, pid_file_path); if (fwrite (buffer, size, 1, pid_file) <= 0) { abort_error ("Unable to write pid file content at %s, error was: errno=%d : %s", pid_file, errno, strerror (errno)); return; } fclose (pid_file); pid_file = fopen (valvula_status, "w"); if (pid_file == NULL) { abort_error ("Unable to open valvula status file at: %s (errno=%d)", valvula_status, errno); return; } /* end if */ fprintf (pid_file, "<valvula-state>\n"); fprintf (pid_file, " <attr name='valvula pid' value='%d' />\n", getpid ()); fprintf (pid_file, "</valvula-state>\n"); fclose (pid_file); /* now change permissions (if required) */ node = axl_doc_get (ctx->config, "/valvula/global-settings/running"); if (node && ATTR_VALUE (node, "user") && ATTR_VALUE (node, "group") && HAS_ATTR_VALUE (node, "enabled", "yes")) { /* change group first */ gid = valvulad_get_system_id (ctx, ATTR_VALUE (node, "group"), axl_false); uid = valvulad_get_system_id (ctx, ATTR_VALUE (node, "user"), axl_true); msg ("Attempting to update pid ownership to %d:%d", uid, gid); if (gid > 0 && uid > 0) { if (chown (valvula_status, uid, gid) != 0) { error ("Unable to change permissions to file %s (%d:%d), error was errno=%d (%s)", valvula_status, uid, gid, errno, strerror (errno)); } /* end if */ /**** do no change pid file ownership is a security problem ****/ } /* end if */ } /* end if */ return; }
/* * This addline version assumes sorted input. This means that whenever * a split occurs all subtrees can be flushed. */ static void addline_trie (FILE *fp, int features, struct memnode **mpp, unsigned char *dat, int len) { /* Previous sib. Points to the last sib */ /* visited, or NULL is this is the first*/ /* sib in the node. */ struct memnode *prvsibp = NULL; while (len && dat[len-1] == '\n') len--; if (!len) return; for (;;) { int l1, l2, ct; unsigned char *d1, *d2; struct memnode *mp, *n1, *n2; mp = *mpp; /* In case of an empty trie: build one */ if (mp == NULL) { mp = newnode (dat, len); mp->end = 1; *mpp = mp; /* As the input is sorted, we won't*/ /* change the older sibs! So flush */ /* and forget prvsibp's subtrie */ if (prvsibp) { prvsibp->childpos = flush_node (fp, features, prvsibp->child, &(prvsibp->subcnt)); prvsibp->child = NULL; fflush (fp); } return; } /* Move to the next sib if appropriate */ if (len && dat[0] > mp->dat[0]) { prvsibp = mp; mpp = &(mp->sib); continue; } /* Introduce a new sib if appropriate */ if (len && dat[0] < mp->dat[0]) { abort_error (); } /* We found the right sib */ ct = 0; d1 = dat; l1 = len; d2 = mp->dat; l2 = mp->len; /* At what pos do the sib and the new */ /* value differ */ while (l1 && l2 && *d1 == *d2) { ct++; d1++; l1--; d2++; l2--; } if (!l2) { /* No sib string data left */ if (!l1) { /* No input string left as well*/ /* So we have a match! */ if (mp->child || mp->childpos) { abort_error (); } mp->end = 1; return; } /* Some input string data is left */ /* so the string is a child of sib */ /* Continue there */ mpp = &(mp->child); dat = d1; len = l1; prvsibp = NULL; continue; } /* There's unmatched sib string data */ /* left, so split the node */ if (!l1) { abort_error (); } /* New node n2 is the non matching tail*/ /* of mp */ n2 = newnode (d2, l2); n2->child = mp->child; n2->end = mp->end; /* New node n1 replaces mp, which has */ /* The prefix length ct of mp */ n1 = newnode (mp->dat, ct); n1->sib = mp->sib; n1->child = n2; *mpp = n1; /* mp is obsolete now */ delnode (mp); /* If there's no input string data left*/ /* Then the mp replacement n1 is an */ /* endpoint! */ if (!l1) { n1->end = 1; return; }; /* Now move on to the child, where the */ /* remainder of the input string will */ /* reside */ mpp = &(n1->child); dat = d1; len = l1; prvsibp = NULL; } }