util: Add hex_decode_talloc() to decode hex string into a binary blob
[ctdb.git] / lib / util / util_file.c
1 /*
2   functions taken from samba4 for quick prototyping of ctdb. These are
3   not intended to remain part of ctdb
4 */
5
6 #include "includes.h"
7 #include "system/filesys.h"
8
9
10 static char *fd_load(int fd, size_t *size, TALLOC_CTX *mem_ctx)
11 {
12         struct stat sbuf;
13         char *p;
14
15         if (fstat(fd, &sbuf) != 0) return NULL;
16
17         p = (char *)talloc_size(mem_ctx, sbuf.st_size+1);
18         if (!p) return NULL;
19
20         if (read(fd, p, sbuf.st_size) != sbuf.st_size) {
21                 talloc_free(p);
22                 return NULL;
23         }
24         p[sbuf.st_size] = 0;
25
26         if (size) *size = sbuf.st_size;
27
28         return p;
29 }
30
31
32 static char *file_load(const char *fname, size_t *size, TALLOC_CTX *mem_ctx)
33 {
34         int fd;
35         char *p;
36
37         if (!fname || !*fname) return NULL;
38         
39         fd = open(fname,O_RDONLY);
40         if (fd == -1) return NULL;
41
42         p = fd_load(fd, size, mem_ctx);
43
44         close(fd);
45
46         return p;
47 }
48
49
50 /**
51 parse a buffer into lines
52 'p' will be freed on error, and otherwise will be made a child of the returned array
53 **/
54 static char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *mem_ctx)
55 {
56         int i;
57         char *s, **ret;
58
59         if (!p) return NULL;
60
61         for (s = p, i=0; s < p+size; s++) {
62                 if (s[0] == '\n') i++;
63         }
64
65         ret = talloc_array(mem_ctx, char *, i+2);
66         if (!ret) {
67                 talloc_free(p);
68                 return NULL;
69         }       
70         
71         talloc_steal(ret, p);
72         
73         memset(ret, 0, sizeof(ret[0])*(i+2));
74         if (numlines) *numlines = i;
75
76         ret[0] = p;
77         for (s = p, i=0; s < p+size; s++) {
78                 if (s[0] == '\n') {
79                         s[0] = 0;
80                         i++;
81                         ret[i] = s+1;
82                 }
83                 if (s[0] == '\r') s[0] = 0;
84         }
85
86         return ret;
87 }
88
89
90 /**
91 load a file into memory and return an array of pointers to lines in the file
92 must be freed with talloc_free(). 
93 **/
94 _PUBLIC_ char **file_lines_load(const char *fname, int *numlines, TALLOC_CTX *mem_ctx)
95 {
96         char *p;
97         size_t size;
98
99         p = file_load(fname, &size, mem_ctx);
100         if (!p) return NULL;
101
102         return file_lines_parse(p, size, numlines, mem_ctx);
103 }
104
105 char *hex_encode_talloc(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
106 {
107         int i;
108         char *hex_buffer;
109
110         hex_buffer = talloc_array(mem_ctx, char, (len*2)+1);
111
112         for (i = 0; i < len; i++)
113                 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
114
115         return hex_buffer;
116 }
117
118 uint8_t *hex_decode_talloc(TALLOC_CTX *mem_ctx, const char *hex_in, size_t *len)
119 {
120         int i, num;
121         uint8_t *buffer;
122
123         *len = strlen(hex_in) / 2;
124         buffer = talloc_array(mem_ctx, unsigned char, *len);
125
126         for (i=0; i<*len; i++) {
127                 sscanf(&hex_in[i*2], "%02X", &num);
128                 buffer[i] = (uint8_t)num;
129         }
130
131         return buffer;
132 }