int ni_file_write(FILE *fp, const ni_buffer_t *wbuf) { return __ni_file_write_partial(fp, ni_buffer_head(wbuf), ni_buffer_count(wbuf)); }
/* * 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; }
/* * Tmpfile.upload(path, offset, data) */ static dbus_bool_t __ni_Testbus_Agent_Filesystem_upload(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_buffer_t wbuf; const char *path; uint64_t offset; unsigned int written = 0; int fd; if (argc != 3 || !ni_dbus_variant_get_string(&argv[0], &path) || path[0] != '/' || !ni_dbus_variant_get_uint64(&argv[1], &offset) || !ni_dbus_variant_is_byte_array(&argv[2])) return ni_dbus_error_invalid_args(error, object->path, method->name); if (offset == 0) fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, 0644); else fd = open(path, O_WRONLY); if (fd < 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; } ni_buffer_init_reader(&wbuf, argv[2].byte_array_value, argv[2].array.len); while (ni_buffer_count(&wbuf)) { int n; n = write(fd, ni_buffer_head(&wbuf), ni_buffer_count(&wbuf)); if (n < 0) { ni_dbus_set_error_from_errno(error, errno, "error writing to \"%s\" at offset %Lu", path, (unsigned long long) offset + written); goto out_fail; } ni_buffer_pull_head(&wbuf, n); written += n; } close(fd); ni_debug_testbus("%s: wrote %u bytes at offset %Lu", path, written, (unsigned long long) offset); return TRUE; out_fail: if (fd >= 0) close(fd); return FALSE; }
int __ni_wireless_process_ie(ni_wireless_network_t *net, void *ptr, size_t len) { ni_buffer_t data; ni_buffer_init_reader(&data, ptr, len); while (ni_buffer_count(&data) >= 2) { unsigned char type, len; int rv = -1; if (ni_buffer_get(&data, &type, 1) < 0 || ni_buffer_get(&data, &len, 1) < 0) goto format_error; if (ni_buffer_count(&data) < len) goto format_error; ptr = ni_buffer_head(&data); data.head += len; switch (type) { case 0xdd: rv = __ni_wireless_process_wpa1(net, ptr, len); break; case 0x30: rv = __ni_wireless_process_wpa2(net, ptr, len); break; default: ni_debug_wireless("Skipping unsupported Informaton Element 0x%02x", type); continue; } if (rv < 0) return -1; } return 0; format_error: ni_error("error processing wireless Information Elements"); return -1; }
int ni_file_write_safe(FILE *fp, const ni_buffer_t *wbuf) { const unsigned char *string = ni_buffer_head(wbuf); unsigned int left = ni_buffer_count(wbuf); mbstate_t mbstate; size_t written = 0; ni_bool_t saw_newline = TRUE; if (left == 0) return 0; memset(&mbstate, 0, sizeof(mbstate)); while (left != 0) { unsigned int nbytes; wchar_t wc; /* Scan until we hit the first non-printable character. * Assume the test node uses the same locale as we do */ for (nbytes = 0; nbytes < left; ) { ssize_t n; saw_newline = FALSE; n = mbrtowc(&wc, (char *) string + nbytes, left - nbytes, &mbstate); if (n < 0) { /* We hit a bad path of string. * If this is preceded by one or more printable * chars, write those out first, then come back here. */ if (nbytes != 0) break; /* write one byte, and try to re-sync */ wc = ((unsigned char *) string)[nbytes++]; if (__ni_file_write_wchar_escaped(fp, wc) < 0) return -1; memset(&mbstate, 0, sizeof(mbstate)); goto consumed_some; } if (!iswprint(wc) && !iswspace(wc)) { /* If this is preceded by one or more printable * chars, write those out first */ if (nbytes != 0) break; if (__ni_file_write_wchar_escaped(fp, wc) < 0) return -1; nbytes += n; goto consumed_some; } if (wc == '\n') saw_newline = TRUE; nbytes += n; } ni_assert(nbytes); if (__ni_file_write_partial(fp, string, nbytes) < 0) return -1; consumed_some: string += nbytes; left -= nbytes; } /* Make sure we're writing a newline at the end of our output */ if (!saw_newline) fputc('\n', fp); fflush(fp); return written; }
/* * Decode an RFC3397 DNS search order option. */ static int ni_dhcp_decode_dnssearch(ni_buffer_t *optbuf, ni_string_array_t *list, const char *what) { ni_stringbuf_t namebuf = NI_STRINGBUF_INIT_DYNAMIC; unsigned char *base = ni_buffer_head(optbuf); unsigned int base_offset = optbuf->head; size_t len; ni_string_array_destroy(list); while (ni_buffer_count(optbuf) && !optbuf->underflow) { ni_buffer_t *bp = optbuf; ni_buffer_t jumpbuf; while (1) { unsigned int pos = bp->head - base_offset; unsigned int pointer; char label[64]; int length; if ((length = ni_buffer_getc(bp)) < 0) goto failure; /* unexpected EOF */ if (length == 0) break; /* end of this name */ switch (length & 0xC0) { case 0: /* Plain name component */ if (ni_buffer_get(bp, label, length) < 0) goto failure; label[length] = '\0'; if (!ni_stringbuf_empty(&namebuf)) ni_stringbuf_putc(&namebuf, '.'); ni_stringbuf_puts(&namebuf, label); break; case 0xC0: /* Pointer */ pointer = (length & 0x3F) << 8; if ((length = ni_buffer_getc(bp)) < 0) goto failure; pointer |= length; if (pointer >= pos) goto failure; ni_buffer_init_reader(&jumpbuf, base, pos); jumpbuf.head = pointer; bp = &jumpbuf; break; default: goto failure; } } if (!ni_stringbuf_empty(&namebuf)) { len = ni_string_len(namebuf.string); if (ni_check_domain_name(namebuf.string, len, 0)) { ni_string_array_append(list, namebuf.string); } else { ni_debug_dhcp("Discarded suspect %s: %s", what, ni_print_suspect(namebuf.string, len)); } } ni_stringbuf_destroy(&namebuf); } return 0; failure: ni_stringbuf_destroy(&namebuf); ni_string_array_destroy(list); return -1; }