Esempio n. 1
0
EXPORTED int gzuc_member_end(struct gzuncat *gz, off_t *offset)
{
    if (gz->next_offset >= 0) return -1;

    int r = 0;

    if (gz->file_eof) goto done;

    if (gz->current_offset >= 0) {
        char discard[16 * 1024];
        while ((r = gzuc_read(gz, discard, sizeof(discard))) > 0);

        /* don't set next_offset if we're at end of underlying file */
        if (gz->file_eof) goto done;
        /* nor if there was an error */
        if (r < 0) goto done;
    }

    /* we're now at the start of the next member */
    gz->next_offset = lseek(gz->fd, 0, SEEK_CUR);

done:
    inflateEnd(&gz->strm);
    gz->current_offset = -1;
    gz->member_eof = -1;
    gz->bytes_read = 0;
    if (!r && offset) *offset = gz->next_offset;
    return r;
}
Esempio n. 2
0
static ssize_t _prot_fill_cb(unsigned char *buf, size_t len, void *rock)
{
    struct gzuncat *gzuc = (struct gzuncat *) rock;
    int r = gzuc_read(gzuc, buf, len);

    if (r < 0)
        syslog(LOG_ERR, "IOERROR: gzuc_read returned %i", r);
    if (r < -1)
        errno = EIO;

    return r;
}
Esempio n. 3
0
EXPORTED int gzuc_skip(struct gzuncat *gz, size_t len)
{
    if (gzuc_member_eof(gz)) return -1;

    while (len) {
        unsigned char discard[16 * 1024];

        size_t want = len;
        if (want > sizeof(discard)) want = sizeof(discard);

        ssize_t got = gzuc_read(gz, discard, want);
        if (got == 0) return -1;
        if (got < 0) return got;

        len -= got;
    }

    return 0;
}
Esempio n. 4
0
static ssize_t _prot_fill_cb(unsigned char *buf, size_t len, void *rock)
{
    struct gzuncat *gzuc = (struct gzuncat *) rock;
    return gzuc_read(gzuc, buf, len);
}
Esempio n. 5
0
static int verify_chunk_checksums(struct backup *backup, struct backup_chunk *chunk,
                                  struct gzuncat *gzuc, int verbose, FILE *out)
{
    int r;

    if (out && verbose)
        fprintf(out, "checking chunk %d checksums...\n", chunk->id);

    /* validate file-prior-to-this-chunk checksum */
    if (out && verbose > 1)
        fprintf(out, "  checking file checksum...\n");
    char file_sha1[2 * SHA1_DIGEST_LENGTH + 1];
    sha1_file(backup->fd, backup->data_fname, chunk->offset, file_sha1);
    r = strncmp(chunk->file_sha1, file_sha1, sizeof(file_sha1));
    if (r) {
        syslog(LOG_DEBUG, "%s: %s (chunk %d) file checksum mismatch: %s on disk, %s in index\n",
                __func__, backup->data_fname, chunk->id, file_sha1, chunk->file_sha1);
        if (out)
            fprintf(out, "file checksum mismatch for chunk %d: %s on disk, %s in index\n",
                    chunk->id, file_sha1, chunk->file_sha1);
        goto done;
    }

    /* validate data-within-this-chunk checksum */
    // FIXME length and data_sha1 are set at backup_append_end.
    //       detect and correctly report case where this hasn't occurred.
    if (out && verbose > 1)
        fprintf(out, "  checking data length\n");
    char buf[8192]; /* FIXME whatever */
    size_t len = 0;
    SHA_CTX sha_ctx;
    SHA1_Init(&sha_ctx);
    gzuc_member_start_from(gzuc, chunk->offset);
    while (!gzuc_member_eof(gzuc)) {
        ssize_t n = gzuc_read(gzuc, buf, sizeof(buf));
        if (n >= 0) {
            SHA1_Update(&sha_ctx, buf, n);
            len += n;
        }
    }
    gzuc_member_end(gzuc, NULL);
    if (len != chunk->length) {
        syslog(LOG_DEBUG, "%s: %s (chunk %d) data length mismatch: "
                        SIZE_T_FMT " on disk,"
                        SIZE_T_FMT " in index\n",
                __func__, backup->data_fname, chunk->id, len, chunk->length);
        if (out)
            fprintf(out, "data length mismatch for chunk %d: "
                         SIZE_T_FMT " on disk,"
                         SIZE_T_FMT " in index\n",
                    chunk->id, len, chunk->length);
        r = -1;
        goto done;
    }

    if (out && verbose > 1)
        fprintf(out, "  checking data checksum...\n");
    unsigned char sha1_raw[SHA1_DIGEST_LENGTH];
    char data_sha1[2 * SHA1_DIGEST_LENGTH + 1];
    SHA1_Final(sha1_raw, &sha_ctx);
    r = bin_to_hex(sha1_raw, SHA1_DIGEST_LENGTH, data_sha1, BH_LOWER);
    assert(r == 2 * SHA1_DIGEST_LENGTH);
    r = strncmp(chunk->data_sha1, data_sha1, sizeof(data_sha1));
    if (r) {
        syslog(LOG_DEBUG, "%s: %s (chunk %d) data checksum mismatch: %s on disk, %s in index\n",
                __func__, backup->data_fname, chunk->id, data_sha1, chunk->data_sha1);
        if (out)
            fprintf(out, "data checksum mismatch for chunk %d: %s on disk, %s in index\n",
                    chunk->id, data_sha1, chunk->data_sha1);
        goto done;
    }

done:
    syslog(LOG_DEBUG, "%s: checksum %s!\n", __func__, r ? "failed" : "passed");
    if (out && verbose)
        fprintf(out, "%s\n", r ? "error" : "ok");
    return r;
}