/* * __wt_turtle_read -- * Read the turtle file. */ int __wt_turtle_read(WT_SESSION_IMPL *session, const char *key, char **valuep) { FILE *fp; WT_DECL_ITEM(buf); WT_DECL_RET; int match; char *path; *valuep = NULL; fp = NULL; path = NULL; /* * Open the turtle file; there's one case where we won't find the turtle * file, yet still succeed. We create the metadata file before creating * the turtle file, and that means returning the default configuration * string for the metadata file. */ WT_RET(__wt_filename(session, WT_METADATA_TURTLE, &path)); if ((fp = fopen(path, "r")) == NULL) ret = __wt_errno(); __wt_free(session, path); if (fp == NULL) return (strcmp(key, WT_METAFILE_URI) == 0 ? __metadata_config(session, valuep) : ret); /* Search for the key. */ WT_ERR(__wt_scr_alloc(session, 512, &buf)); for (match = 0;;) { WT_ERR(__wt_getline(session, buf, fp)); if (buf->size == 0) WT_ERR(WT_NOTFOUND); if (strcmp(key, buf->data) == 0) match = 1; /* Key matched: read the subsequent line for the value. */ WT_ERR(__wt_getline(session, buf, fp)); if (buf->size == 0) WT_ERR(__wt_illegal_value(session, WT_METADATA_TURTLE)); if (match) break; } /* Copy the value for the caller. */ WT_ERR(__wt_strdup(session, buf->data, valuep)); err: if (fp != NULL) WT_TRET(fclose(fp) == 0 ? 0 : __wt_errno()); __wt_scr_free(&buf); return (ret); }
/* * __wt_turtle_read -- * Read the turtle file. */ int __wt_turtle_read(WT_SESSION_IMPL *session, const char *key, char **valuep) { WT_DECL_ITEM(buf); WT_DECL_RET; WT_FSTREAM *fs; bool exist, match; *valuep = NULL; /* * Open the turtle file; there's one case where we won't find the turtle * file, yet still succeed. We create the metadata file before creating * the turtle file, and that means returning the default configuration * string for the metadata file. */ WT_RET(__wt_fs_exist(session, WT_METADATA_TURTLE, &exist)); if (!exist) return (strcmp(key, WT_METAFILE_URI) == 0 ? __metadata_config(session, valuep) : WT_NOTFOUND); WT_RET(__wt_fopen(session, WT_METADATA_TURTLE, 0, WT_STREAM_READ, &fs)); /* Search for the key. */ WT_ERR(__wt_scr_alloc(session, 512, &buf)); for (match = false;;) { WT_ERR(__wt_getline(session, fs, buf)); if (buf->size == 0) WT_ERR(WT_NOTFOUND); if (strcmp(key, buf->data) == 0) match = true; /* Key matched: read the subsequent line for the value. */ WT_ERR(__wt_getline(session, fs, buf)); if (buf->size == 0) WT_ERR(__wt_illegal_value(session, WT_METADATA_TURTLE)); if (match) break; } /* Copy the value for the caller. */ WT_ERR(__wt_strdup(session, buf->data, valuep)); err: WT_TRET(__wt_fclose(session, &fs)); __wt_scr_free(session, &buf); if (ret != 0) __wt_free(session, *valuep); return (ret); }
/* * __wt_metadata_load_backup -- * Load the contents of any hot backup file. */ int __wt_metadata_load_backup(WT_SESSION_IMPL *session) { FILE *fp; WT_DECL_ITEM(key); WT_DECL_ITEM(value); WT_DECL_RET; const char *path; fp = NULL; path = NULL; /* Look for a hot backup file: if we find it, load it. */ WT_RET(__wt_filename(session, WT_METADATA_BACKUP, &path)); if ((fp = fopen(path, "r")) == NULL) { __wt_free(session, path); return (0); } /* Read line pairs and load them into the metadata file. */ WT_ERR(__wt_scr_alloc(session, 512, &key)); WT_ERR(__wt_scr_alloc(session, 512, &value)); for (;;) { WT_ERR(__wt_getline(session, key, fp)); if (key->size == 0) break; WT_ERR(__wt_getline(session, value, fp)); if (value->size == 0) WT_ERR(__wt_illegal_value(session, WT_METADATA_BACKUP)); WT_ERR(__wt_metadata_update(session, key->data, value->data)); } /* Remove the hot backup file, it's only read (successfully) once. */ WT_ERR(__wt_remove(session, WT_METADATA_BACKUP)); err: if (fp != NULL) WT_TRET(fclose(fp) == 0 ? 0 : __wt_errno()); if (path != NULL) __wt_free(session, path); __wt_scr_free(&key); __wt_scr_free(&value); return (ret); }
/* * __metadata_load_hot_backup -- * Load the contents of any hot backup file. */ static int __metadata_load_hot_backup(WT_SESSION_IMPL *session) { FILE *fp; WT_DECL_ITEM(key); WT_DECL_ITEM(value); WT_DECL_RET; char *path; fp = NULL; path = NULL; /* Look for a hot backup file: if we find it, load it. */ WT_RET(__wt_filename(session, WT_METADATA_BACKUP, &path)); fp = fopen(path, "r"); __wt_free(session, path); if (fp == NULL) return (0); /* Read line pairs and load them into the metadata file. */ WT_ERR(__wt_scr_alloc(session, 512, &key)); WT_ERR(__wt_scr_alloc(session, 512, &value)); for (;;) { WT_ERR(__wt_getline(session, key, fp)); if (key->size == 0) break; WT_ERR(__wt_getline(session, value, fp)); if (value->size == 0) WT_ERR(__wt_illegal_value(session, WT_METADATA_BACKUP)); WT_ERR(__wt_metadata_update(session, key->data, value->data)); } F_SET(S2C(session), WT_CONN_WAS_BACKUP); err: if (fp != NULL) WT_TRET(fclose(fp) == 0 ? 0 : __wt_errno()); __wt_scr_free(&key); __wt_scr_free(&value); return (ret); }
/* * __metadata_load_hot_backup -- * Load the contents of any hot backup file. */ static int __metadata_load_hot_backup(WT_SESSION_IMPL *session) { WT_DECL_ITEM(key); WT_DECL_ITEM(value); WT_DECL_RET; WT_FSTREAM *fs; bool exist; /* Look for a hot backup file: if we find it, load it. */ WT_RET(__wt_fs_exist(session, WT_METADATA_BACKUP, &exist)); if (!exist) return (0); WT_RET(__wt_fopen(session, WT_METADATA_BACKUP, 0, WT_STREAM_READ, &fs)); /* Read line pairs and load them into the metadata file. */ WT_ERR(__wt_scr_alloc(session, 512, &key)); WT_ERR(__wt_scr_alloc(session, 512, &value)); for (;;) { WT_ERR(__wt_getline(session, fs, key)); if (key->size == 0) break; WT_ERR(__wt_getline(session, fs, value)); if (value->size == 0) WT_ERR(__wt_illegal_value(session, WT_METADATA_BACKUP)); WT_ERR(__wt_metadata_update(session, key->data, value->data)); } F_SET(S2C(session), WT_CONN_WAS_BACKUP); err: WT_TRET(__wt_fclose(session, &fs)); __wt_scr_free(session, &key); __wt_scr_free(session, &value); return (ret); }
/* * __wt_huffman_read -- * Read a Huffman table from a file. */ static int __wt_huffman_read(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *ip, struct __wt_huffman_table **tablep, u_int *entriesp, u_int *numbytesp) { struct __wt_huffman_table *table, *tp; WT_DECL_ITEM(tmp); WT_DECL_RET; WT_FSTREAM *fs; int64_t symbol, frequency; u_int entries, lineno; int n; bool is_utf8; *tablep = NULL; *entriesp = *numbytesp = 0; fs = NULL; table = NULL; /* * Try and open the backing file. */ WT_RET(__huffman_confchk_file(session, ip, &is_utf8, &fs)); /* * UTF-8 table is 256 bytes, with a range of 0-255. * UTF-16 is 128KB (2 * 65536) bytes, with a range of 0-65535. */ if (is_utf8) { entries = UINT8_MAX; *numbytesp = 1; WT_ERR(__wt_calloc_def(session, entries, &table)); } else { entries = UINT16_MAX; *numbytesp = 2; WT_ERR(__wt_calloc_def(session, entries, &table)); } WT_ERR(__wt_scr_alloc(session, 0, &tmp)); for (tp = table, lineno = 1;; ++tp, ++lineno) { WT_ERR(__wt_getline(session, fs, tmp)); if (tmp->size == 0) break; n = sscanf( tmp->data, "%" SCNi64 " %" SCNi64, &symbol, &frequency); /* * Entries is 0-based, that is, there are (entries +1) possible * values that can be configured. The line number is 1-based, so * adjust the test for too many entries, and report (entries +1) * in the error as the maximum possible number of entries. */ if (lineno > entries + 1) WT_ERR_MSG(session, EINVAL, "Huffman table file %.*s is corrupted, " "more than %" PRIu32 " entries", (int)ip->len, ip->str, entries + 1); if (n != 2) WT_ERR_MSG(session, EINVAL, "line %u of Huffman table file %.*s is corrupted: " "expected two unsigned integral values", lineno, (int)ip->len, ip->str); if (symbol < 0 || symbol > entries) WT_ERR_MSG(session, EINVAL, "line %u of Huffman file %.*s is corrupted; " "symbol %" PRId64 " not in range, maximum " "value is %u", lineno, (int)ip->len, ip->str, symbol, entries); if (frequency < 0 || frequency > UINT32_MAX) WT_ERR_MSG(session, EINVAL, "line %u of Huffman file %.*s is corrupted; " "frequency %" PRId64 " not in range, maximum " "value is %" PRIu32, lineno, (int)ip->len, ip->str, frequency, (uint32_t)UINT32_MAX); tp->symbol = (uint32_t)symbol; tp->frequency = (uint32_t)frequency; } *entriesp = lineno - 1; *tablep = table; if (0) { err: __wt_free(session, table); } (void)__wt_fclose(session, &fs); __wt_scr_free(session, &tmp); return (ret); }