static void test_one(const struct test_vector *vec) { uint8_t md[SHA1_DIGEST_SIZE]; int i; /* All at once. */ sha1_bytes(vec->data, vec->size, md); assert(!memcmp(md, vec->output, SHA1_DIGEST_SIZE)); /* In two pieces. */ for (i = 0; i < 20; i++) { int n0 = vec->size ? random_range(vec->size) : 0; int n1 = vec->size - n0; struct sha1_ctx sha1; sha1_init(&sha1); sha1_update(&sha1, vec->data, n0); sha1_update(&sha1, vec->data + n0, n1); sha1_final(&sha1, md); assert(!memcmp(md, vec->output, SHA1_DIGEST_SIZE)); } putchar('.'); fflush(stdout); }
struct ovsdb_error * ovsdb_log_write(struct ovsdb_log *file, struct json *json) { uint8_t sha1[SHA1_DIGEST_SIZE]; struct ovsdb_error *error; char *json_string; char header[128]; size_t length; json_string = NULL; if (file->mode == OVSDB_LOG_READ || file->write_error) { file->mode = OVSDB_LOG_WRITE; file->write_error = false; if (fseeko(file->stream, file->offset, SEEK_SET)) { error = ovsdb_io_error(errno, "%s: cannot seek to offset %lld", file->name, (long long int) file->offset); goto error; } if (ftruncate(fileno(file->stream), file->offset)) { error = ovsdb_io_error(errno, "%s: cannot truncate to length %lld", file->name, (long long int) file->offset); goto error; } } if (json->type != JSON_OBJECT && json->type != JSON_ARRAY) { error = OVSDB_BUG("bad JSON type"); goto error; } /* Compose content. Add a new-line (replacing the null terminator) to make * the file easier to read, even though it has no semantic value. */ json_string = json_to_string(json, 0); length = strlen(json_string) + 1; json_string[length - 1] = '\n'; /* Compose header. */ sha1_bytes(json_string, length, sha1); snprintf(header, sizeof header, "%s%"PRIuSIZE" "SHA1_FMT"\n", magic, length, SHA1_ARGS(sha1)); /* Write. */ if (fwrite(header, strlen(header), 1, file->stream) != 1 || fwrite(json_string, length, 1, file->stream) != 1 || fflush(file->stream)) { error = ovsdb_io_error(errno, "%s: write failed", file->name); /* Remove any partially written data, ignoring errors since there is * nothing further we can do. */ ignore(ftruncate(fileno(file->stream), file->offset)); goto error; } file->offset += strlen(header) + length; free(json_string); return NULL; error: file->write_error = true; free(json_string); return error; }