txtdb.c - rohrpost - A commandline mail client to change the world as we see it.
(HTM) git clone git://r-36.net/rohrpost
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
txtdb.c (2780B)
---
1 /*
2 * Copy me if you can.
3 * by 20h
4 */
5
6 #include <fcntl.h>
7 #include <unistd.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <stdarg.h>
11 #include <string.h>
12 #include <strings.h>
13 #include <errno.h>
14 #include <sys/file.h>
15
16 #include "ind.h"
17 #include "arg.h"
18 #include "llist.h"
19 #include "txtdb.h"
20
21 txtdb_t *
22 txtdb_new(void)
23 {
24 txtdb_t *txtdb;
25
26 txtdb = mallocz(sizeof(txtdb_t), 2);
27 txtdb->values = llist_new();
28
29 return txtdb;
30 }
31
32 void
33 txtdb_free(txtdb_t *txtdb)
34 {
35 llist_free(txtdb->values);
36 if (txtdb->path != NULL)
37 free(txtdb->path);
38 if (txtdb->name != NULL)
39 free(txtdb->name);
40 free(txtdb);
41 }
42
43 llistelem_t *
44 txtdb_add(txtdb_t *txtdb, char *key, char *value)
45 {
46 llistelem_t *elem;
47
48 elem = llist_add(txtdb->values, key, value, strlen(value)+1);
49 if (elem != NULL)
50 txtdb->changed = 1;
51 return elem;
52 }
53
54 llistelem_t *
55 txtdb_del(txtdb_t *txtdb, char *key)
56 {
57 llistelem_t *elem;
58
59 elem = llist_del(txtdb->values, key);
60 if (elem != NULL)
61 txtdb->changed = 1;
62 return elem;
63 }
64
65 llistelem_t *
66 txtdb_get(txtdb_t *txtdb, char *key)
67 {
68 return llist_get(txtdb->values, key);
69 }
70
71 llist_t *
72 txtdb_find(txtdb_t *txtdb, char *regex)
73 {
74 return llist_find(txtdb->values, regex);
75 }
76
77 llistelem_t *
78 txtdb_set(txtdb_t *txtdb, char *key, char *value)
79 {
80 llistelem_t *result;
81
82 result = llist_get(txtdb->values, key);
83 if (result != NULL) {
84 txtdb->changed = 1;
85 return llistelem_set(result, key, value, strlen(value)+1);
86 } else {
87 return txtdb_add(txtdb, key, value);
88 }
89 }
90
91 int
92 txtdb_len(txtdb_t *txtdb)
93 {
94 return txtdb->values->len;
95 }
96
97 txtdb_t *
98 txtdb_read(char *file)
99 {
100 txtdb_t *txtdb;
101 FILE *fp;
102 char line[MAXLINESIZE], *key, *value, *p;
103
104 memset(line, 0, sizeof(line));
105
106 fp = fopen(file, "r");
107 if (fp == NULL)
108 return NULL;
109
110 if (flock(fileno(fp), LOCK_SH) < 0)
111 return NULL;
112
113 txtdb = txtdb_new();
114 while(fgets(line, sizeof(line)-1, fp)) {
115 if (line[0] == '#')
116 continue;
117 line[strlen(line)-1] = '\0';
118
119 p = line + strspn(line, "\t\r\v\f ");
120 key = p;
121 p = p + strcspn(p, "\t\r\v\f =");
122 p[0] = '\0';
123
124 p = p + 1 + strspn(p+1, "\t\r\v\f ");
125 if (p[0] != '=')
126 continue;
127
128 p = p + 1 + strspn(p+1, "\t\r\v\f ");
129 value = p;
130
131 txtdb_add(txtdb, key, value);
132 }
133
134 flock(fileno(fp), LOCK_UN);
135 fclose(fp);
136
137 if (txtdb_len(txtdb) < 1) {
138 txtdb_free(txtdb);
139 return NULL;
140 }
141
142 return txtdb;
143 }
144
145 txtdb_t *
146 txtdb_write(txtdb_t *txtdb, char *file)
147 {
148 FILE *fp;
149 llistelem_t *elem;
150
151 if (file == NULL) {
152 if (txtdb->path != NULL) {
153 file = txtdb->path;
154 } else {
155 return NULL;
156 }
157 }
158
159 fp = fopen(file, "w+");
160 if (fp == NULL)
161 return NULL;
162
163 if (flock(fileno(fp), LOCK_EX) < 0)
164 return NULL;
165
166 forllist(txtdb->values, elem)
167 fprintf(fp, "%s = %s\n", (char *)elem->key, (char *)elem->data);
168
169 flock(fileno(fp), LOCK_UN);
170
171 fflush(fp);
172 fclose(fp);
173
174 return txtdb;
175 }
176