/* * Filesystem.download(path, offset, count) * */ static dbus_bool_t __ni_Testbus_Agent_Filesystem_download(ni_dbus_object_t *object, const ni_dbus_method_t *method, unsigned int argc, const ni_dbus_variant_t *argv, ni_dbus_message_t *reply, DBusError *error) { ni_dbus_variant_t res = NI_DBUS_VARIANT_INIT; const char *path; uint64_t offset; uint32_t count; dbus_bool_t rv; ni_buffer_t *bp = NULL; int fd = -1; if (argc != 3 || !ni_dbus_variant_get_string(&argv[0], &path) || path[0] != '/' || !ni_dbus_variant_get_uint64(&argv[1], &offset) || !ni_dbus_variant_get_uint32(&argv[2], &count) || count > 1024 * 1024 || offset + count < offset) return ni_dbus_error_invalid_args(error, object->path, method->name); if ((fd = open(path, O_RDONLY)) < 0) { ni_dbus_set_error_from_errno(error, errno, "unable to open file \"%s\"", path); return FALSE; } if (lseek(fd, offset, SEEK_SET) < 0) { ni_dbus_set_error_from_errno(error, errno, "seek faile"); goto out_fail; } bp = ni_buffer_new(count); while (count) { int n; n = read(fd, ni_buffer_tail(bp), ni_buffer_tailroom(bp)); if (n < 0) { ni_dbus_set_error_from_errno(error, errno, "read failed"); goto out_fail; } if (n == 0) break; ni_buffer_push_tail(bp, n); } ni_dbus_variant_init_dict(&res); ni_dbus_variant_set_byte_array(&res, ni_buffer_head(bp), ni_buffer_count(bp)); rv = ni_dbus_message_serialize_variants(reply, 1, &res, error); ni_dbus_variant_destroy(&res); ni_buffer_free(bp); close(fd); return rv; out_fail: if (fd >= 0) close(fd); return FALSE; }
/* * 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; }
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 the netif firmware discovery scripts and return their output * as an XML document. * The optional from parameter allow to specify the firmware extension * type (e.g. ibft) and a firmware type specific path (e.g. ethernet0), * passed as last argument to the discovery script. */ xml_document_t * ni_netconfig_firmware_discovery(const char *root, const char *from) { ni_buffer_t *buffer; xml_document_t *doc; char *path = NULL; char *type = NULL; /* sanity adjustments... */ if (ni_string_empty(root)) root = NULL; if (ni_string_empty(from)) from = NULL; else { ni_string_dup(&type, from); if ((path = strchr(type, ':'))) *path++ = '\0'; if (ni_string_empty(path)) path = NULL; } buffer = __ni_netconfig_firmware_discovery(root, type, path); if (buffer == NULL) { ni_string_free(&type); return NULL; } ni_debug_ifconfig("%s: %s%sbuffer has %u bytes", __func__, (from ? from : ""), (from ? " ": ""), ni_buffer_count(buffer)); doc = xml_document_from_buffer(buffer, from); ni_buffer_free(buffer); ni_string_free(&type); if (doc == NULL) ni_error("%s: error processing document", __func__); return doc; }