static gboolean handle_create (LoomSettings *object, GDBusMethodInvocation *invocation, GVariant *arg_configuration) { Settings *settings = SETTINGS (object); Setting *setting; gs_free gchar **object_paths = NULL; GError *error = NULL; if (!validate_configuration (arg_configuration, &error)) { g_dbus_method_invocation_take_error (invocation, error); return TRUE; } setting = SETTING (setting_new (settings->daemon, arg_configuration)); setting_export (setting); g_hash_table_insert (settings->settings, (gchar *)setting_get_object_path (setting), setting); object_paths = (gchar **)g_hash_table_get_keys_as_array (settings->settings, NULL); loom_settings_set_settings (object, (const gchar* const*)object_paths); loom_settings_complete_create (object, invocation, setting_get_object_path (setting)); return TRUE; }
/* Set up all details: - ip server name - dns server name - username, passwd - ... Implementation: - load defaults - parse cmd line - assign settings that may change due to cmd line options - check data Note: - if no argument is specified tries to call the cmd line parser with the default cfg file path. */ int get_config_data(ddns_t *ctx, int argc, char **argv) { int i; int rc = 0; int cache_file_len; cmd_desc_t *it; do { rc = ddns_default_config_data(ctx); if (rc != 0) break; it = cmd_options_table; while (it->option != NULL) { it->handler.context = ctx; ++it; } /* in case of no options, assume the default cfg file may be present */ if (argc == 1) { char *custom_argv[] = { "", DYNDNS_INPUT_FILE_OPT_STRING, DYNDNS_DEFAULT_CONFIG_FILE }; int custom_argc = sizeof(custom_argv) / sizeof(char *); if (ctx->dbg.level) logit(LOG_NOTICE, "Using default config file %s", DYNDNS_DEFAULT_CONFIG_FILE); if (ctx->cfgfile) free(ctx->cfgfile); ctx->cfgfile = strdup(DYNDNS_DEFAULT_CONFIG_FILE); rc = get_cmd_parse_data(custom_argv, custom_argc, cmd_options_table); } else { rc = get_cmd_parse_data(argv, argc, cmd_options_table); } if (rc != 0 || ctx->abort) break; /* settings that may change due to cmd line options */ i = 0; do { /*ip server */ if (strlen(ctx->info[i].ip_server_name.name) == 0) { if (sizeof(ctx->info[i].ip_server_name.name) < strlen(ctx->info[i].system->ip_server_name)) { rc = RC_DYNDNS_BUFFER_TOO_SMALL; break; } strcpy(ctx->info[i].ip_server_name.name, ctx->info[i].system->ip_server_name); if (sizeof(ctx->info[i].ip_server_url) < strlen(ctx->info[i].system->ip_server_url)) { rc = RC_DYNDNS_BUFFER_TOO_SMALL; break; } strcpy(ctx->info[i].ip_server_url, ctx->info[i].system->ip_server_url); } /*dyndns server */ if (strlen(ctx->info[i].dyndns_server_name.name) == 0) { if (sizeof(ctx->info[i].dyndns_server_name.name) < strlen(ctx->info[i].system->ddns_server_name)) { rc = RC_DYNDNS_BUFFER_TOO_SMALL; break; } strcpy(ctx->info[i].dyndns_server_name.name, ctx->info[i].system->ddns_server_name); if (sizeof(ctx->info[i].dyndns_server_url) < strlen(ctx->info[i].system->ddns_server_url)) { rc = RC_DYNDNS_BUFFER_TOO_SMALL; break; } strcpy(ctx->info[i].dyndns_server_url, ctx->info[i].system->ddns_server_url); } } while (++i < ctx->info_count); /* Check if the neccessary params have been provided */ if (validate_configuration(ctx)) { rc = RC_DYNDNS_INVALID_OR_MISSING_PARAMETERS; break; } /* Setup a default cache file, unless the user provided one for us. */ if (ctx->bind_interface && !ctx->cache_file) { cache_file_len = (strlen(DYNDNS_CACHE_FILE) - 2) + strlen(ctx->bind_interface); if ((ctx->cache_file = malloc(cache_file_len + 1)) == NULL) { rc = RC_OUT_OF_MEMORY; break; } if (snprintf (ctx->cache_file, cache_file_len + 1, DYNDNS_CACHE_FILE, ctx->bind_interface) != cache_file_len) { rc = RC_ERROR; break; } } else { ctx->cache_file = strdup(DYNDNS_DEFAULT_CACHE_FILE); } } while (0); return rc; }
/* Set up all details: - ip server name - dns server name - username, passwd - ... Implementation: - load defaults - parse cmd line - assign settings that may change due to cmd line options - check data Note: - if no argument is specified tries to call the cmd line parser with the default cfg file path. */ int get_config_data(ddns_t *ctx, int argc, char *argv[]) { int i; int rc = 0; cmd_desc_t *it; do { TRY(default_config(ctx)); it = cmd_options_table; while (it->option != NULL) { it->handler.context = ctx; ++it; } /* in case of no options, assume the default cfg file may be present */ if (argc == 1) { char *custom_argv[] = { "", DYNDNS_INPUT_FILE_OPT_STRING, DEFAULT_CONFIG_FILE }; int custom_argc = sizeof(custom_argv) / sizeof(char *); if (ctx->dbg.level > 1) logit(LOG_NOTICE, "Using default config file %s", DEFAULT_CONFIG_FILE); if (ctx->cfgfile) free(ctx->cfgfile); ctx->cfgfile = strdup(DEFAULT_CONFIG_FILE); rc = get_cmd_parse_data(custom_argv, custom_argc, cmd_options_table); } else { rc = get_cmd_parse_data(argv, argc, cmd_options_table); } if (rc || ctx->abort) break; /* settings that may change due to cmd line options */ i = 0; do { int port; size_t src_len; ddns_info_t *info = &ctx->info[i]; if (strlen(info->checkip_name.name) == 0) { if (strlen(info->system->checkip_name) > 0) { port = -1; info->checkip_name.port = HTTP_DEFAULT_PORT; if (get_name_and_port(info->system->checkip_name, info->checkip_name.name, sizeof(info->checkip_name.name), &port) == 0) { if (port > 0 && port < 65535) info->checkip_name.port = port; } } src_len = strlen(info->system->checkip_url); if (src_len > 0 && src_len < sizeof(info->checkip_url)) strcpy(info->checkip_url, info->system->checkip_url); } if (strlen(info->server_name.name) == 0) { if (strlen(info->system->server_name) > 0) { port = -1; info->server_name.port = HTTP_DEFAULT_PORT; if (get_name_and_port(info->system->server_name, info->server_name.name, sizeof(info->server_name.name), &port) == 0) { if (port > 0 && port < 65535) info->server_name.port = port; } } src_len = strlen(info->system->server_url); if (src_len > 0 && src_len < sizeof(info->server_url)) strcpy(info->server_url, info->system->server_url); } } while (++i < ctx->info_count); /* Check if the neccessary params have been provided */ TRY(validate_configuration(ctx)); } while (0); return rc; }
int main(int argc, char **argv){ int status = 0; init_globals(); atexit(cleanup); /* * PROBLEM * We used to call init_signals() only after init_daemon(). But in * that case, when started with -F or -D -D, the signals are * not caught in Linunx and OSX (they are caught in FreeBSD). nbspd and * npemwind die, but leave the pid file and the web server. * [It seems that the signals are not blocked in the main thread as * the code in signal.c should ensure.] * Adding this call here * * status = init_signals(); * * makes OSX and Linux respond well when the daemon is run in the foreground. * If the call is made after the tcl configure(), the problem repeats; * it has to be before the configure() function. * * The problem is that in FreeBSD-7.1, when init_signals() is called here, * then no threads are spawned afterwards. * * The solution was to split init_signals() in two parts, one that * block the signals and the other spawns the thread. I don't fully * understand what in tcl is causing this (Fri Mar 13 11:43:09 AST 2009). */ status = init_signals_block(); if(status == 0){ /* * This will configure it with the default configuration * file, if it exists. * * This note and Tcl... code line is taken from the nbsp source code. * [First initialize the tcl library once and for all. It was not * necessary to call this in unix, but cygwin needs it or EvalFile * seg faults.] */ Tcl_FindExecutable(argv[0]); status = configure(); } if(status == 0) status = parse_args(argc, argv); if(status == 0){ if(g.configfile != NULL){ /* * This will reconfigure it with the user-supplied config file */ status = configure(); } } /* * if [-C] was given, print the configuration and exit. */ if(status == 0){ if(g.option_C == 1){ print_confoptions(); return(0); } } if(status == 0) status = validate_configuration(); /* * user and group are configurable so this must be done after reading * configuration options. */ if(status == 0) status = drop_privs(); if(status == 0) status = init_server_list(); if(status == 0) status = init_directories(); /* * The last configuration step, just before becoming a daemon. */ if(status == 0) status = exec_startscript(); if((status == 0) && (g.f_ndaemon == 0)) status = init_daemon(); set_log_debug(g.f_debug); set_log_verbose(g.f_verbose); if(status == 0) status = init_signals_thread(); /* * This has to be done after daemon() so that the lock file contains the * daemon's pid, not the starting program's. */ if(status == 0) status = init_lock(); /* * There are no shared queues in npemwin, otherwise the initialization * would go here. * * if(status == 0) * status = init_queues(); */ if(status == 0){ if(g.serverprotocol != PROTOCOL_NONE) { g.f_server_enabled = 1; status = init_server(); } } if(status == 0){ if(g.httpd_enable > 0){ status = spawn_httpd_server(); } } if(status == 0){ if(g.bbserver_enable > 0){ status = spawn_bbregistrar(); } } if(status == 0) status = init_emwin_qfiles(); if(status == 0) init_periodic(); /* * If there are initialization errors, ask all threads to quit. */ if(status != 0) set_quit_flag(); while(get_quit_flag() == 0){ status = loop(); } if(status != 0) status = EXIT_FAILURE; return(status); }
int main(int argc, char** argv) { int ch; boolean priority_mode = TRUE; boolean test_mode = FALSE; boolean disable_partial_commit = FALSE; boolean full_commit_check = FALSE; boolean break_priority = FALSE; int break_priority_node = -1; boolean disable_hook = FALSE; char *commit_comment = NULL; /* this is needed before calling certain glib functions */ g_type_init(); //grab inputs while ((ch = getopt(argc, argv, "xdpthsecoafb:rlC:")) != -1) { switch (ch) { case 'x': g_old_print_output = TRUE; break; case 'd': g_debug = TRUE; break; case 'h': usage(); exit(0); break; case 'p': priority_mode = FALSE; break; case 't': test_mode = TRUE; break; case 's': g_dump_trans = TRUE; break; case 'e': g_display_error_node = TRUE; break; case 'c': g_coverage = TRUE; break; case 'o': disable_partial_commit = TRUE; break; case 'a': g_dump_actions = TRUE; break; case 'f': full_commit_check = TRUE; break; case 'b': break_priority_node = strtoul(optarg,NULL,10); break_priority = TRUE; break; case 'r': disable_hook = TRUE; break; case 'C': commit_comment = strdup(optarg); break; case 'l': release_config_lock(); break; default: usage(); exit(0); } } //can also be set via environment variable if (getenv("VYATTA_OUTPUT_ERROR_LOCATION") != NULL) { g_print_error_location_all = TRUE; } if (disable_hook == FALSE) { execute_hook(PRE_COMMIT_HOOK_DIR,commit_comment); } initialize_output("Commit"); init_paths(TRUE); d_dplog("commit2: starting up"); if (get_config_lock() != 0) { fprintf(out_stream, "Configuration system temporarily locked " "due to another commit in progress\n"); exit(1); } //get local session data plus configuration data GNode *config_data = common_get_local_session_data(); if (g_node_n_children(config_data) == 0) { common_commit_clean_temp_config(NULL, test_mode); fprintf(out_stream, "No configuration changes to commit\n"); return 0; } GNode *orig_node_tree = g_node_copy(config_data); // Get collection of transactions, i.e. trans nodes that have been activated. GNode *trans_coll = get_transactions(config_data, priority_mode); if (trans_coll == NULL) { printf("commit2: transactions collection is empty, exiting\n"); exit(0); } if (g_debug == TRUE || g_dump_trans == TRUE) { if (g_dump_trans == TRUE) { fprintf(out_stream,"Dumping transactions\n"); syslog(LOG_DEBUG,"Dumping transactions"); } //iterate over config_data and dump... g_node_traverse(trans_coll, G_PRE_ORDER, G_TRAVERSE_ALL, -1, (GNodeTraverseFunc)dump_func, (gpointer)NULL); if (g_dump_trans == TRUE) { exit(0); } } set_in_commit(TRUE); GNode *trans_child_node = (GNode*)g_node_first_child(trans_coll); if (trans_child_node == NULL) { printf("commit2: No child nodes to process, exiting\n"); exit(0); } //open the changes file and clear FILE *fp_changes = fopen(COMMIT_CHANGES_FILE,"w"); if (fp_changes == NULL) { cond_plog(true, LOG_ERR, "commit2: Cannot access changes file, exiting"); exit(0); } GSList *completed_root_node_coll = NULL; GSList *nodes_visited_coll = NULL; int errors = 0; int i = 0; do { boolean success = FALSE; d_dplog("commit2: Starting new transaction processing pass on root: [%s]", ((trans_child_node && trans_child_node->data && ((struct VyattaNode*)(trans_child_node->data))->_data._name) ? ((struct VyattaNode*)(trans_child_node->data))->_data._name : "")); if (break_priority) { gpointer gp = ((GNode*)trans_child_node)->data; long p = (long) ((struct VyattaNode*)gp)->_config._priority; if (p >= break_priority_node) { g_dump_trans = TRUE; g_node_traverse(trans_child_node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, (GNodeTraverseFunc)dump_func, (gpointer)NULL); g_dump_trans = FALSE; fprintf(out_stream,"Press any key to commit...\n"); // Wait for single character char input = getchar(); input = input; //to fix stupid compilier warning } } //complete() now requires a undisturbed copy of the trans_child_node tree GNode *comp_cp_node = g_node_copy(trans_child_node); if (g_dump_actions == TRUE) { fprintf(out_stream,"\n"); //add an extra line here } //on each priority node now execute actions nodes_visited_coll = NULL; if (validate_configuration(trans_child_node, full_commit_check, &nodes_visited_coll) == TRUE && (success = process_priority_node(trans_child_node)) == TRUE) { //this below copies the node directory from the local to active location //if this is true root skip if (trans_child_node != NULL && trans_child_node->data != NULL && strcmp(((struct VyattaNode*)(trans_child_node->data)) ->_data._path, "/") == 0) { //no op, need better way to define true root } else { if (disable_partial_commit == FALSE && g_dump_actions == FALSE) { completed_root_node_coll = g_slist_append(completed_root_node_coll, comp_cp_node); } } } if (g_dump_actions == TRUE) { success = TRUE; //FORCE SUCCESS ON DISPLAY MODE OF ACTIONS } if (success == FALSE) { errors |= 1; d_dplog("commit2: Failed in processing node"); } else { errors |= 2; } //now update the changes file update_change_file(fp_changes,nodes_visited_coll); fflush(fp_changes); ++i; } while ((trans_child_node = (GNode*) g_node_nth_child((GNode*) trans_coll, (guint) i)) != NULL); if (errors == 2) { /* * Need to add to the following func below to clean up dangling .wh. files */ if (g_dump_actions == FALSE) { common_commit_copy_to_live_config(orig_node_tree, TRUE, test_mode); common_commit_clean_temp_config(orig_node_tree, test_mode); } d_dplog("commit2: successful commit, now cleaning up temp directories"); } else { fprintf(out_stream,"Commit failed\n"); complete(completed_root_node_coll, test_mode); } set_in_commit(FALSE); d_dplog("DONE"); if (fp_changes != NULL) { fclose(fp_changes); } restore_output(); if (disable_hook == FALSE) { if (errors == 2) { setenv(ENV_COMMIT_STATUS,"SUCCESS",1); } else if (errors == 3) { setenv(ENV_COMMIT_STATUS,"PARTIAL",1); } else { setenv(ENV_COMMIT_STATUS,"FAILURE",1); } execute_hook(POST_COMMIT_HOOK_DIR,commit_comment); unsetenv(ENV_COMMIT_STATUS); } //remove tmp changes file as all the work is now done unlink(COMMIT_CHANGES_FILE); exit (errors == 2 ? 0 : 1); }