rohrpost

A commandline mail client to change the world as we see it.
git clone git://r-36.net/rohrpost
Log | Files | Refs | LICENSE

txtdb.c (2757B)


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