rohrpost

A commandline mail client to change the world as we see it.
git clone git://r-36.net/rohrpost
Log | Files | Refs | README | 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