void* keydb_tree(int fd, int64_t pos, struct keydb_column **list) { // Return a linked list of keys (stored as struct keydb_column) // found in the tree pointed at by pos. The caller must free the list. struct keydb_node* parent; struct keydb_node* buffer; struct keydb_column *mid = NULL; int64_t next_pos; int64_t n; buffer = key_buf_read(fd, pos); if (buffer == NULL) return NULL; if ((mid = malloc(sizeof(struct keydb_column))) == NULL) { perror(NULL); cleanup_and_exit; } mid->next = NULL; if (buffer->refcount <= 0) { //this record is tombstoned. mid->column[0] = '\0'; // Put a terminator at the start of the string. } else { memcpy(mid->column, buffer->column, KEY_LEN); // otherwise load it up. mid->refcount = buffer->refcount; } // Right if (buffer->right != 0) keydb_tree(fd, buffer->right, list); // Middle mid->next = *list; *list = mid; // Left if (buffer->left != 0) keydb_tree(fd, buffer->left, list); free(buffer); return NULL; }
struct response_struct keys_command(char* token_vector[], int token_count) { char* part = NULL; char key[KEY_LEN] = ""; int length = 0; int i = 0; int retval; int64_t pos = 0; struct keydb_node *node; struct keydb_column *list, *tmp, *cursor; bool some_content = false; // Does our key list have any keys in it? list = NULL; char* tmp_response; int response_free_bytes = MSG_SIZE; int responselen = 0; int column_size; struct response_struct response; response.status = 0; if ((response.msg = malloc(sizeof(char) * MSG_SIZE)) == NULL) { perror(NULL); cleanup_and_exit(); } bzero(response.msg, MSG_SIZE); for (i = 1; (part = token_vector[i]) && (i < MAX_ARGS); i++) { length += strlen(part); if (length > KEY_LEN - 1) { response.status = 1; sprintf(response.msg, "Key too large."); return response; } node = keydb_find(KEYDB_FD, part, pos); if (!(node = keydb_find(KEYDB_FD, part, pos))) { response.status = 1; sprintf(response.msg, "Not found."); return response; } if (node->refcount <= 0) { response.status = 1; sprintf(response.msg, "Not found."); return response; } pos = node->next; free(node); if (pos == 0) { // There is no next subtree. response.status = 1; sprintf(response.msg, "No subkeys."); return response; } } keydb_tree(KEYDB_FD, pos, &list); while (list) { if (list->column[0] != '\0') { column_size = strlen(list->column) + 2; response_free_bytes -= column_size; if (response_free_bytes < 1) { // need to expand response. responselen = strlen(response.msg); responselen += column_size; tmp_response = malloc(sizeof(char) * responselen); strcpy(tmp_response, response.msg); free(response.msg); response.msg = tmp_response; response_free_bytes = 0; } strcat(response.msg, list->column); strcat(response.msg, " "); some_content = true; } tmp = list->next; free(list); list = tmp; } if (!some_content) { sprintf(response.msg, "No subkeys."); response.status = 1; } response.msg[strlen(response.msg) - 1] = '\0'; // Knock out that last extra space. return response; }