ni_buffer_t * ni_file_read(FILE *fp) { struct stat stb; unsigned int count, done, size; ni_buffer_t *result; if (fstat(fileno(fp), &stb) < 0) return NULL; if (S_ISREG(stb.st_mode)) { size = stb.st_size; result = ni_buffer_new_dynamic(size); if (result == NULL) return NULL; for (done = 0; done < size; done += count) { void *buffer = ni_buffer_tail(result); count = fread(buffer, 1, size - done, fp); if (count == 0) break; ni_buffer_push_tail(result, count); } } else { /* Could be a pipe or tty or socket */ result = ni_buffer_new_dynamic(4096); if (result == NULL) return NULL; while (TRUE) { void *buffer; ni_buffer_ensure_tailroom(result, 4096); buffer = ni_buffer_tail(result); count = fread(buffer, 1, ni_buffer_tailroom(result), fp); if (count == 0) break; ni_buffer_push_tail(result, count); } } if (ferror(fp)) { ni_error("%s: read error on file", __func__); ni_buffer_free(result); return NULL; } return result; }
/* * Run all the netif firmware discovery scripts and return their output * as one large buffer. */ static ni_buffer_t * __ni_netconfig_firmware_discovery(const char *root, const char *type, const char *path) { ni_buffer_t *result; ni_config_t *config = ni_global.config; ni_extension_t *ex; ni_assert(config); result = ni_buffer_new_dynamic(1024); for (ex = config->fw_extensions; ex; ex = ex->next) { ni_script_action_t *script; if (ex->c_bindings) ni_warn("builtins specified in a netif-firmware-discovery element: not supported"); for (script = ex->actions; script; script = script->next) { ni_process_t *process; int rv; /* Check if requested to use specific type/name only (e.g. "ibft") */ if (type && !ni_string_eq_nocase(type, script->name)) continue; ni_debug_ifconfig("trying to discover netif config via firmware service \"%s\"", script->name); /* Create an instance of this command */ process = ni_process_new(script->process); /* Add root directory argument if given */ if (root) { ni_string_array_append(&process->argv, "-r"); ni_string_array_append(&process->argv, root); } /* Add firmware type specific path argument if given */ if (type && path) { ni_string_array_append(&process->argv, "-p"); ni_string_array_append(&process->argv, path); } rv = ni_process_run_and_capture_output(process, result); ni_process_free(process); if (rv) { ni_error("unable to discover firmware (script \"%s\")", script->name); ni_buffer_free(result); return NULL; } } } return result; }