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