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