static void update_bootloader(void) { int ret; log_basic("** Progress: Calling gummiboot_updaters\n"); ret = system("gummiboot_updaters.sh"); if (ret != 0) LOG_ERROR(NULL, "gummiboot_updaters failed", class_scripts, "%d", ret); }
static void update_kernel(void) { int ret; log_basic("** Progress: Calling kernel_update\n"); ret = system("kernel_updater.sh"); if (ret != 0) LOG_ERROR(NULL, "kernel_update failed", class_scripts, "%d", ret); }
/** * @brief Load the configuration file. * * This function will read the configuration JSON file and parse it into the * application wide @ref appconf structure. After this function is called the * configuration struct must be deleted with the @ref config_destroy function. * * The config file has the following structure: * @code * { * "daemonize" : true/false, * "ssh_poll_time" : 0-100, * "bluecherry_address" : "url.to.iot.server", * "ssh_path" : "/usr/bin/ssh", * "ssh_keygen_path" : "/usr/bin/ssh-keygen", * "loglevel" : "NONE/ERROR/WARNING/INFO/DEBUG", * "logfile" : "/tmp/path/to/logfile", * "pid_file" : "/path/to/pidfile.pid", * "identity_file" : "/path/to/id_rsa", * "ipc_path" : "/path/to/ipc_file" * } * @endcode * * @param path The path where to find the configuration JSON file. * * @return True if the configuration could be parsed successfully. */ bool config_load(const char *path) { appconf = (struct config*) malloc(sizeof(struct config)); if(appconf == NULL) { log_basic(stderr, LG_ERROR, "There was not enough memory to reserve the configuration memory\n"); return false; } return config_reload(path); }
/** * @brief Reload the application wide configuration structure. * * This function will read the configuration JSON file and parse it into the * already existing application wide @ref appconf structure. This function can * only be used if the @ref config_load function has been called earlier. * * @param path The path where to find the configuration JSON file. * * @return True if the configuration structure could be parsed successfully. */ bool config_reload(const char *path) { /* Check if the appconf structure has already been allocated */ if(appconf == NULL) { return false; } /* Try to open the configuration file */ FILE *fp = fopen(path, "r"); if(fp == NULL) { return false; } char buff[CONFIG_BUFF_SIZE]; size_t len = fread(buff, sizeof(char), CONFIG_BUFF_SIZE, fp); if(len == 0) { log_basic(stderr, LG_ERROR, "The configuration file '%s' was empty\n", path); fclose(fp); return false; } else if(len >= CONFIG_BUFF_SIZE) { log_basic(stderr, LG_ERROR, "The configuration file is to big for the config buffer (%dB)\n", CONFIG_BUFF_SIZE); fclose(fp); return false; } /* 0-terminate the buffer and close the config file */ buff[len] = '\0'; fclose(fp); /* Try to parse the configuration file */ json_object *j_config = json_tokener_parse(buff); if(json_object_is_type(j_config, json_type_null)) { log_basic(stderr, LG_ERROR, "The configuration file could not be parsed\n"); return false; } json_object *j_daemonize; json_object *j_ssh_poll_time; json_object *j_bluecherry_address; json_object *j_ssh_path; json_object *j_ssh_keygen_path; json_object *j_loglevel; json_object *j_logfile; json_object *j_pid_file; json_object *j_identity_file; json_object *j_ipc_file_path; if(!json_object_object_get_ex(j_config, "daemonize", &j_daemonize) || !json_object_object_get_ex(j_config, "ssh_poll_time", &j_ssh_poll_time) || !json_object_object_get_ex(j_config, "bluecherry_address", &j_bluecherry_address) || !json_object_object_get_ex(j_config, "ssh_path", &j_ssh_path) || !json_object_object_get_ex(j_config, "ssh_keygen_path", &j_ssh_keygen_path) || !json_object_object_get_ex(j_config, "loglevel", &j_loglevel) || !json_object_object_get_ex(j_config, "logfile", &j_logfile) || !json_object_object_get_ex(j_config, "pid_file", &j_pid_file) || !json_object_object_get_ex(j_config, "identity_file", &j_identity_file) || !json_object_object_get_ex(j_config, "ipc_path", &j_ipc_file_path)) { json_object_put(j_config); log_basic(stderr, LG_ERROR, "The configuration file syntax is malformed or incomplete\n"); return false; } /* Read out if this application should run as a daemon or not */ appconf->daemonize = json_object_get_boolean(j_daemonize); /* Read out SSH poll time */ appconf->ssh_poll_time = json_object_get_int(j_ssh_poll_time); /* Read out the BlueCherry server address */ const char* bluecherry_address = json_object_get_string(j_bluecherry_address); size_t bc_addr_len = strlen(bluecherry_address); if(bc_addr_len <= 0) { log_basic(stderr, LG_ERROR, "The BlueCherry server URL is empty and required\n"); json_object_put(j_config); return false; } appconf->bluecherry_address = (char*) realloc(appconf->bluecherry_address, (bc_addr_len + 1) * sizeof(char)); memcpy(appconf->bluecherry_address, bluecherry_address, bc_addr_len); appconf->bluecherry_address[bc_addr_len] = '\0'; /* Read out the SSH path */ const char* ssh_path = json_object_get_string(j_ssh_path); size_t ssh_path_len = strlen(ssh_path); if(ssh_path_len <= 0) { log_basic(stderr, LG_ERROR, "The OpenSSH path is empty and required\n"); json_object_put(j_config); return false; } appconf->ssh_path = (char*) realloc(appconf->ssh_path, (ssh_path_len + 1) * sizeof(char)); memcpy(appconf->ssh_path, ssh_path, ssh_path_len); appconf->ssh_path[ssh_path_len] = '\0'; /* Read out the SSH keygen path */ const char* ssh_keygen_path = json_object_get_string(j_ssh_keygen_path); size_t ssh_keygen_path_len = strlen(ssh_keygen_path); if(ssh_keygen_path_len <= 0) { log_basic(stderr, LG_ERROR, "The OpenSSH keygen path is empty and required\n"); json_object_put(j_config); return false; } appconf->ssh_keygen_path = (char*) realloc(appconf->ssh_keygen_path, (ssh_keygen_path_len + 1) * sizeof(char)); memcpy(appconf->ssh_keygen_path, ssh_keygen_path, ssh_keygen_path_len); appconf->ssh_keygen_path[ssh_keygen_path_len] = '\0'; /* Read out the application wide logging level */ const char* loglevel = json_object_get_string(j_loglevel); if(strlen(loglevel) <= 0) { log_basic(stderr, LG_ERROR, "The configuration file did not contain a valid logging level, falling back to LOG_ERROR\n"); appconf->loglevel = LG_ERROR; } switch(loglevel[0]) { case 'N': appconf->loglevel = LG_NONE; break; case 'E': appconf->loglevel = LG_ERROR; break; case 'W' : appconf->loglevel = LOG_WARNING; break; case 'I': appconf->loglevel = LOG_INFO; break; case 'D': appconf->loglevel = LOG_DEBUG; break; default: log_basic(stderr, LG_ERROR, "The configuration file did not contain a valid logging level, falling back to LOG_ERROR\n"); appconf->loglevel = LG_ERROR; break; } /* Read out the path of the logfile and open it if necessary */ const char* logfile = json_object_get_string(j_logfile); appconf->log_to_syslog = false; if(strlen(logfile) == 0) { /* Fall back to stdout if the path is empty */ appconf->logfile = stdout; } else { if(strcmp(logfile, "stdout") == 0) { appconf->logfile = stdout; } else if(strcmp(logfile, "stderr") == 0) { appconf->logfile = stderr; } else if(strcmp(logfile, "syslog") == 0) { appconf->logfile = NULL; appconf->log_to_syslog = true; /* Open the syslogger for this app */ openlog("DPT-connector", LOG_CONS | LOG_PID, LOG_DAEMON); } else { appconf->logfile = fopen(logfile, "a"); if(appconf->logfile == NULL) { /* When the logfile could not be opened and/or created, use stdout */ appconf->logfile = stdout; log_basic(stderr, LG_ERROR, "The logfile '%s' could not be opened\n", logfile); } } } /* Read out the PID file path */ const char* pid_filepath = json_object_get_string(j_pid_file); size_t pid_filepath_len = strlen(pid_filepath); if(pid_filepath_len <= 0) { log_basic(stderr, LG_ERROR, "The pid file path is required"); json_object_put(j_config); return false; } appconf->pidfile = (char*) realloc(appconf->pidfile, (pid_filepath_len + 1) * sizeof(char)); memcpy(appconf->pidfile, pid_filepath, pid_filepath_len); appconf->pidfile[pid_filepath_len] = '\0'; /* Read out the identity file path */ const char* identity_filepath = json_object_get_string(j_identity_file); size_t identity_filepath_len = strlen(identity_filepath); if(identity_filepath_len <= 0) { log_basic(stderr, LG_ERROR, "The identity file path is required"); json_object_put(j_config); return false; } appconf->identity_file = (char*) realloc(appconf->identity_file, (identity_filepath_len + 1) * sizeof(char)); memcpy(appconf->identity_file, identity_filepath, identity_filepath_len); appconf->identity_file[identity_filepath_len] = '\0'; /* Create the public filename */ size_t identity_file_pub_len = identity_filepath_len + strlen(".pub"); appconf->identity_file_pub = (char*) realloc(appconf->identity_file_pub, (identity_file_pub_len + 1) * sizeof(char)); snprintf(appconf->identity_file_pub, identity_file_pub_len + 1, "%s.pub", appconf->identity_file); /* Read out the IPC file path */ const char* ipc_file_path = json_object_get_string(j_ipc_file_path); size_t ipc_file_path_len = strlen(ipc_file_path); if(ipc_file_path_len <= 0) { log_basic(stderr, LG_ERROR, "The IPC file path is required"); json_object_put(j_config); return false; } appconf->ipc_file = (char*) realloc(appconf->ipc_file, (ipc_file_path_len + 1) * sizeof(char)); memcpy(appconf->ipc_file, ipc_file_path, ipc_file_path_len); appconf->ipc_file[ipc_file_path_len] = '\0'; /* Release parsed JSON and return */ json_object_put(j_config); return true; }