6ccecc80c4e8ce7181396d7d1104b9de7f172884
[vlendec/samba-autobuild/.git] / ctdb / common / util.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/time.h"
8 #include "system/filesys.h"
9
10
11 /**
12   return a zero timeval
13 */
14 struct timeval timeval_zero(void)
15 {
16         struct timeval tv;
17         tv.tv_sec = 0;
18         tv.tv_usec = 0;
19         return tv;
20 }
21
22 /**
23   return True if a timeval is zero
24 */
25 bool timeval_is_zero(const struct timeval *tv)
26 {
27         return tv->tv_sec == 0 && tv->tv_usec == 0;
28 }
29
30 /**
31   return a timeval for the current time
32 */
33 struct timeval timeval_current(void)
34 {
35         struct timeval tv;
36         gettimeofday(&tv, NULL);
37         return tv;
38 }
39
40 double timeval_elapsed(struct timeval *tv)
41 {
42         struct timeval tv2 = timeval_current();
43         return (tv2.tv_sec - tv->tv_sec) + 
44                (tv2.tv_usec - tv->tv_usec)*1.0e-6;
45 }
46
47 /**
48   return a timeval struct with the given elements
49 */
50 struct timeval timeval_set(uint32_t secs, uint32_t usecs)
51 {
52         struct timeval tv;
53         tv.tv_sec = secs;
54         tv.tv_usec = usecs;
55         return tv;
56 }
57
58 int timeval_compare(const struct timeval *tv1, const struct timeval *tv2)
59 {
60         if (tv1->tv_sec  > tv2->tv_sec)  return 1;
61         if (tv1->tv_sec  < tv2->tv_sec)  return -1;
62         if (tv1->tv_usec > tv2->tv_usec) return 1;
63         if (tv1->tv_usec < tv2->tv_usec) return -1;
64         return 0;
65 }
66
67 struct timeval timeval_until(const struct timeval *tv1,
68                              const struct timeval *tv2)
69 {
70         struct timeval t;
71         if (timeval_compare(tv1, tv2) >= 0) {
72                 return timeval_zero();
73         }
74         t.tv_sec = tv2->tv_sec - tv1->tv_sec;
75         if (tv1->tv_usec > tv2->tv_usec) {
76                 t.tv_sec--;
77                 t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec);
78         } else {
79                 t.tv_usec = tv2->tv_usec - tv1->tv_usec;
80         }
81         return t;
82 }
83
84 _PUBLIC_ struct timeval timeval_add(const struct timeval *tv,
85                            uint32_t secs, uint32_t usecs)
86 {
87         struct timeval tv2 = *tv;
88         const unsigned int million = 1000000;
89         tv2.tv_sec += secs;
90         tv2.tv_usec += usecs;
91         tv2.tv_sec += tv2.tv_usec / million;
92         tv2.tv_usec = tv2.tv_usec % million;
93         return tv2;
94 }
95
96
97 _PUBLIC_ struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs)
98 {
99         struct timeval tv = timeval_current();
100         return timeval_add(&tv, secs, usecs);
101 }
102
103 _PUBLIC_ char *fd_load(int fd, size_t *size, TALLOC_CTX *mem_ctx)
104 {
105         struct stat sbuf;
106         char *p;
107
108         if (fstat(fd, &sbuf) != 0) return NULL;
109
110         p = (char *)talloc_size(mem_ctx, sbuf.st_size+1);
111         if (!p) return NULL;
112
113         if (read(fd, p, sbuf.st_size) != sbuf.st_size) {
114                 talloc_free(p);
115                 return NULL;
116         }
117         p[sbuf.st_size] = 0;
118
119         if (size) *size = sbuf.st_size;
120
121         return p;
122 }
123
124
125 _PUBLIC_ char *file_load(const char *fname, size_t *size, TALLOC_CTX *mem_ctx)
126 {
127         int fd;
128         char *p;
129
130         if (!fname || !*fname) return NULL;
131         
132         fd = open(fname,O_RDONLY);
133         if (fd == -1) return NULL;
134
135         p = fd_load(fd, size, mem_ctx);
136
137         close(fd);
138
139         return p;
140 }
141
142
143 /**
144 parse a buffer into lines
145 'p' will be freed on error, and otherwise will be made a child of the returned array
146 **/
147 static char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *mem_ctx)
148 {
149         int i;
150         char *s, **ret;
151
152         if (!p) return NULL;
153
154         for (s = p, i=0; s < p+size; s++) {
155                 if (s[0] == '\n') i++;
156         }
157
158         ret = talloc_array(mem_ctx, char *, i+2);
159         if (!ret) {
160                 talloc_free(p);
161                 return NULL;
162         }       
163         
164         talloc_steal(ret, p);
165         
166         memset(ret, 0, sizeof(ret[0])*(i+2));
167         if (numlines) *numlines = i;
168
169         ret[0] = p;
170         for (s = p, i=0; s < p+size; s++) {
171                 if (s[0] == '\n') {
172                         s[0] = 0;
173                         i++;
174                         ret[i] = s+1;
175                 }
176                 if (s[0] == '\r') s[0] = 0;
177         }
178
179         return ret;
180 }
181
182
183 /**
184 load a file into memory and return an array of pointers to lines in the file
185 must be freed with talloc_free(). 
186 **/
187 _PUBLIC_ char **file_lines_load(const char *fname, int *numlines, TALLOC_CTX *mem_ctx)
188 {
189         char *p;
190         size_t size;
191
192         p = file_load(fname, &size, mem_ctx);
193         if (!p) return NULL;
194
195         return file_lines_parse(p, size, numlines, mem_ctx);
196 }
197
198 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
199 {
200         int i;
201         char *hex_buffer;
202
203         hex_buffer = talloc_array(mem_ctx, char, (len*2)+1);
204
205         for (i = 0; i < len; i++)
206                 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
207
208         return hex_buffer;
209 }