#include #include #include #include #include #include #include #include #include "index.h" #include "macros.h" #include "misc.h" static int index_strlen(index_t *idx) { int len = 0; /* Get the length of the index. */ for (index_t *i = idx; i != NULL; i = i->next) { const int is_last = (i->next == NULL); if (i->type) { len += format_len("%"PRIu64, i->num) + !is_last; } else { len += format_len("%s", i->name) + !is_last; } } return len; } int is_valid_index(index_t *idx) { int did_alloc = 0; char *err_str = NULL; /* Is the index NULL? */ if (idx == NULL) { err_str = "Index is NULL."; /* Is the index type invalid? */ } else if (idx->type > 1) { did_alloc = 1; err_str = calloc(format_len("Invalid index type: %u.", idx->type)+1, sizeof(char)); sprintf(err_str, "Invalid index type: %u.", idx->type); /* Is this named index empty? */ } else if (idx->type == 0 && is_empty(idx->name)) { err_str = "Named index is empty."; } /* Did we get an error? */ if (err_str != NULL) { log_reason(LOG_ERR, "Invalid index.", err_str); if (did_alloc) { free(err_str); } /* Invalid index, return false. */ return 0; /* Is there another index after this one? */ } else if (idx->next != NULL) { /* Return the validity of the next index. */ return is_valid_index(idx->next); } /* Valid index, return true. */ return 1; } char *make_index_path(const char *root, index_t *idx, int path_type) { char *path; char *tmp; int path_len = strlen(root) + 1; /* Is the index invalid? */ if (!is_valid_index(idx)) { return NULL; } /* Get the length of the path. */ for (index_t *i = idx; i != NULL; i = i->next) { const int is_last = (i->next == NULL); if (i->type) { path_len += format_len("%"PRIu64, i->num) + !is_last; } else { path_len += format_len("%s", i->name) + !is_last; } } path = calloc(path_len+1, sizeof(char)); tmp = path; /* Create the path. */ tmp += sprintf(tmp, "%s/", root); for (index_t *i = idx; i != NULL; i = i->next) { const int is_last = (i->next == NULL); const char *delm = (path_type) ? "-" : "/"; if (i->type) { tmp += sprintf(tmp, "%"PRIu64"%s", i->num, (!is_last) ? delm : ""); } else { tmp += sprintf(tmp, "%s%s", i->name, (!is_last) ? delm : ""); } } return path; } char *index_to_str(index_t *idx) { if (is_valid_index(idx)) { char *idx_str = calloc(index_strlen(idx)+1, sizeof(char)); char *tmp = idx_str; /* Create the index. */ for (index_t *i = idx; i != NULL; i = i->next) { const int is_last = (i->next == NULL); if (i->type) { tmp += sprintf(tmp, "%"PRIu64"%s", i->num, (!is_last) ? "-" : ""); } else { tmp += sprintf(tmp, "%s%s", i->name, (!is_last) ? "-" : ""); } } return idx_str; } else { return NULL; } } int index_path_exists(index_t *idx, const char *root, char **path) { char *dummy; path = (path != NULL) ? path : &dummy; for (int i = 0; i < 2; ++i) { struct stat st; *path = make_index_path(root, idx, i); /* Does the index path exist? */ if (*path != NULL && stat(*path, &st) == 0) { if (path == &dummy) { free(*path); *path = NULL; } return 1; } else { free(*path); *path = NULL; } } return 0; }