summaryrefslogtreecommitdiff
path: root/index.c
blob: 3505d731d87dafae8ae6c364ffbfd52f3e93003b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <sys/stat.h>
#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;
}