LIBCOUCHSTORE_API view_group_info_t *couchstore_read_view_group_info(FILE *in_stream, FILE *error_stream) { view_group_info_t *info; char buf[4096]; char *dup; int i, j; int reduce_len; info = (view_group_info_t *) calloc(1, sizeof(*info)); if (info == NULL) { fprintf(error_stream, "Memory allocation failure\n"); goto out_error; } if (couchstore_read_line(in_stream, buf, sizeof(buf)) != buf) { fprintf(stderr, "Error reading source index file path\n"); goto out_error; } dup = strdup(buf); if (dup == NULL) { fprintf(error_stream, "Memory allocation failure\n"); goto out_error; } info->filepath = (const char *) dup; if (fscanf(in_stream, "%" SCNu64 "\n", &info->header_pos) != 1) { fprintf(error_stream, "Error reading header position\n"); goto out_error; } if (fscanf(in_stream, "%d\n", &info->num_btrees) != 1) { fprintf(error_stream, "Error reading number of btrees\n"); goto out_error; } info->btree_infos = (view_btree_info_t *) calloc(info->num_btrees, sizeof(view_btree_info_t)); if (info->btree_infos == NULL) { fprintf(error_stream, "Memory allocation failure\n"); info->num_btrees = 0; goto out_error; } for (i = 0; i < info->num_btrees; ++i) { view_btree_info_t *bti = &info->btree_infos[i]; if (fscanf(in_stream, "%d\n", &bti->num_reducers) != 1) { fprintf(error_stream, "Error reading number of reducers for btree %d\n", i); goto out_error; } bti->names = (const char **) calloc(bti->num_reducers, sizeof(char *)); if (bti->names == NULL) { fprintf(error_stream, "Memory allocation failure\n"); bti->num_reducers = 0; goto out_error; } bti->reducers = (const char **) calloc(bti->num_reducers, sizeof(char *)); if (bti->reducers == NULL) { fprintf(error_stream, "Memory allocation failure\n"); bti->num_reducers = 0; free(bti->names); goto out_error; } for (j = 0; j < bti->num_reducers; ++j) { if (couchstore_read_line(in_stream, buf, sizeof(buf)) != buf) { fprintf(error_stream, "Error reading btree %d view %d name\n", i, j); goto out_error; } dup = strdup(buf); if (dup == NULL) { fprintf(error_stream, "Memory allocation failure\n"); goto out_error; } bti->names[j] = (const char *) dup; if (fscanf(in_stream, "%d\n", &reduce_len) != 1) { fprintf(error_stream, "Error reading btree %d view %d " "reduce function size\n", i, j); goto out_error; } dup = (char *) malloc(reduce_len + 1); if (dup == NULL) { fprintf(error_stream, "Memory allocation failure\n"); goto out_error; } if (fread(dup, reduce_len, 1, in_stream) != 1) { fprintf(error_stream, "Error reading btree %d view %d reducer\n", i, j); free(dup); goto out_error; } dup[reduce_len] = '\0'; bti->reducers[j] = (const char *) dup; } } return info; out_error: couchstore_free_view_group_info(info); return NULL; }
int main(int argc, char *argv[]) { view_group_info_t *group_info = NULL; char buf[BUF_SIZE]; char **source_files = NULL; char *dest_file = NULL; int i; size_t len; int ret = 2; uint64_t header_pos; view_error_t error_info; (void) argc; (void) argv; group_info = couchstore_read_view_group_info(stdin, stderr); if (group_info == NULL) { ret = COUCHSTORE_ERROR_ALLOC_FAIL; goto out; } source_files = (char **) calloc(group_info->num_btrees + 1, sizeof(char *)); if (source_files == NULL) { fprintf(stderr, "Memory allocation failure\n"); ret = COUCHSTORE_ERROR_ALLOC_FAIL; goto out; } if (couchstore_read_line(stdin, buf, BUF_SIZE) != buf) { fprintf(stderr, "Error reading destination file\n"); ret = COUCHSTORE_ERROR_INVALID_ARGUMENTS; goto out; } len = strlen(buf); dest_file = (char *) malloc(len + 1); if (dest_file == NULL) { fprintf(stderr, "Memory allocation failure\n"); ret = COUCHSTORE_ERROR_ALLOC_FAIL; goto out; } memcpy(dest_file, buf, len); dest_file[len] = '\0'; for (i = 0; i <= group_info->num_btrees; ++i) { if (couchstore_read_line(stdin, buf, BUF_SIZE) != buf) { if (i == 0) { fprintf(stderr, "Error reading source file for id btree\n"); } else { fprintf(stderr, "Error reading source file for btree %d\n", i - 1); } ret = COUCHSTORE_ERROR_INVALID_ARGUMENTS; goto out; } len = strlen(buf); source_files[i] = (char *) malloc(len + 1); if (source_files[i] == NULL) { fprintf(stderr, "Memory allocation failure\n"); ret = COUCHSTORE_ERROR_ALLOC_FAIL; goto out; } memcpy(source_files[i], buf, len); source_files[i][len] = '\0'; } ret = couchstore_build_view_group(group_info, source_files[0], (const char **) &source_files[1], dest_file, &header_pos, &error_info); if (ret != COUCHSTORE_SUCCESS) { if (error_info.error_msg != NULL && error_info.view_name != NULL) { fprintf(stderr, "Error building index for view `%s`, reason: %s\n", error_info.view_name, error_info.error_msg); } goto out; } out: if (source_files != NULL) { for (i = 0; i <= group_info->num_btrees; ++i) { free(source_files[i]); } free(source_files); } free(dest_file); couchstore_free_view_group_info(group_info); free((void *) error_info.error_msg); free((void *) error_info.view_name); return (ret < 0) ? (100 + ret) : ret; }