libqaeda

Unnamed repository; edit this file 'description' to name the repository.
Info | Log | Files | Refs | README | LICENSE

file.c (3291B)


      1 #include <stddef.h>
      2 #include <string.h>
      3 #include <stdio.h>
      4 #include <unistd.h>
      5 #include <fcntl.h>
      6 
      7 #include <llog.h>
      8 #include <hex.h>
      9 
     10 #include "lq/crypto.h"
     11 #include "lq/io.h"
     12 #include "lq/store.h"
     13 #include "lq/err.h"
     14 #include "lq/mem.h"
     15 #include "debug.h"
     16 
     17 static const int store_typ_file = 3;
     18 
     19 /// \todo key and val limits proper
     20 int lq_file_content_count(enum payload_e typ, LQStore *store, const char *key, size_t key_len) {
     21 	int r;
     22 	char **out;
     23 	char buf[LQ_DIGEST_LEN * 2 + 1];
     24 	char pfx[1024];
     25 
     26 	out = lq_alloc(sizeof(char**) * LQ_DIRS_MAX);
     27 	pfx[0] = (char)typ + 0x30;
     28 	b2h((const unsigned char*)key, (int)key_len, (unsigned char*)buf);
     29 	lq_cpy(pfx+1, buf, strlen(buf));
     30 
     31 	r = lq_files_pfx(store->userdata, out, LQ_DIRS_MAX, pfx, key_len + 1);
     32 
     33 	lq_free(out);
     34 
     35 	return r;
     36 }
     37 
     38 int lq_file_content_get(enum payload_e typ, LQStore *store, const char *key, size_t key_len, char *value, size_t *value_len) {
     39 	int f;
     40 	size_t l;
     41 	size_t c;
     42 	char buf[LQ_DIGEST_LEN * 2 + 1];
     43 	char path[1024];
     44 	char *p;
     45 
     46 	if (store->store_typ != store_typ_file) {
     47 		return ERR_COMPAT;
     48 	}
     49 
     50 	// \todo dry
     51 	p = (char*)store->userdata;
     52 	lq_cpy(path, p, strlen(p) + 1);
     53 	p = path + strlen(path);
     54 	b2h((const unsigned char*)key, (int)key_len, (unsigned char*)buf);
     55 	sprintf(p, "%d%s", (char)typ, buf);
     56 	f = lq_open(path, O_RDONLY, S_IRUSR);
     57 	if (f < 0) {
     58 		return ERR_NOENT;
     59 	}
     60 
     61 	p = value;
     62 	l = 0;
     63 	while (1) {
     64 		c = lq_read(f, p, *value_len - l);
     65 		if (c == 0) {
     66 			break;
     67 		}
     68 		l += c;
     69 		if (l > *value_len) {
     70 			lq_close(f);
     71 			return ERR_OVERFLOW;
     72 		}
     73 		p += c;	
     74 	}
     75 	lq_close(f);
     76 
     77 	*value_len = l;
     78 
     79 	debug_x(LLOG_DEBUG, "store.file", "get file", 2, MORGEL_TYP_STR, 0, "path", path, MORGEL_TYP_NUM, 0, "bytes", *value_len);
     80 
     81 	return ERR_OK;
     82 
     83 }
     84 
     85 int lq_file_content_put(enum payload_e typ, LQStore *store, const char *key, size_t *key_len, char *value, size_t value_len) {
     86 	size_t c;
     87 	size_t l;
     88 	char buf[LQ_STORE_KEY_MAX - 1];
     89 	char path[1024];
     90 	char *p;
     91 	int f;
     92 
     93 	if (*key_len > (LQ_STORE_KEY_MAX / 2) - 1) {
     94 		return ERR_OVERFLOW;
     95 	}
     96 	if (store->store_typ != store_typ_file) {
     97 		return ERR_COMPAT;
     98 	}
     99 	p = (char*)store->userdata;
    100 	lq_cpy(path, p, strlen(p) + 1);
    101 	p = path + strlen(path);
    102 	b2h((const unsigned char*)key, (int)*key_len, (unsigned char*)buf);
    103 	sprintf(p, "%d%s", (char)typ, (unsigned char*)buf);
    104 	f = lq_open(path, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR);
    105 	if (f < 0) {
    106 		return ERR_NOENT;
    107 	}
    108 	l = value_len;
    109 	p = value;
    110 	while (l > 0) {
    111 		c = write(f, p, l);
    112 		if (c < 0) {
    113 			lq_close(f);
    114 			return ERR_WRITE;
    115 		}
    116 		if (c == 0) {
    117 			break;
    118 		}
    119 		l -= c;
    120 		p += c;
    121 	}
    122 	debug_x(LLOG_DEBUG, "store.file", "put file", 2, MORGEL_TYP_STR, 0, "path", path, MORGEL_TYP_NUM, 0, "bytes", c);
    123 	lq_close(f);
    124 	return ERR_OK;
    125 }
    126 
    127 void lq_file_content_free(LQStore *store) {
    128 	lq_free(store->userdata);
    129 	lq_free(store);
    130 }
    131 
    132 struct lq_store_t LQFileContent = {
    133 	.store_typ = store_typ_file,
    134 	.userdata = "",
    135 	.get = lq_file_content_get,	
    136 	.put = lq_file_content_put,
    137 	.count = lq_file_content_count,
    138 	.free = lq_file_content_free,
    139 };
    140 
    141 LQStore* lq_store_new(const char *spec) {
    142 	int l;
    143 	LQStore *store;
    144 
    145 	l = strlen(spec) + 1;
    146 	store = lq_alloc(sizeof(LQStore));
    147 	lq_cpy(store, &LQFileContent, sizeof(LQFileContent));
    148 	store->userdata = lq_alloc(l);
    149 	lq_cpy(store->userdata, spec, l);
    150 	return store;
    151 }