initial version
[vlendec/samba-autobuild/.git] / ctdb / 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 /**
41   return a timeval struct with the given elements
42 */
43 struct timeval timeval_set(uint32_t secs, uint32_t usecs)
44 {
45         struct timeval tv;
46         tv.tv_sec = secs;
47         tv.tv_usec = usecs;
48         return tv;
49 }
50
51 int timeval_compare(const struct timeval *tv1, const struct timeval *tv2)
52 {
53         if (tv1->tv_sec  > tv2->tv_sec)  return 1;
54         if (tv1->tv_sec  < tv2->tv_sec)  return -1;
55         if (tv1->tv_usec > tv2->tv_usec) return 1;
56         if (tv1->tv_usec < tv2->tv_usec) return -1;
57         return 0;
58 }
59
60 struct timeval timeval_until(const struct timeval *tv1,
61                              const struct timeval *tv2)
62 {
63         struct timeval t;
64         if (timeval_compare(tv1, tv2) >= 0) {
65                 return timeval_zero();
66         }
67         t.tv_sec = tv2->tv_sec - tv1->tv_sec;
68         if (tv1->tv_usec > tv2->tv_usec) {
69                 t.tv_sec--;
70                 t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec);
71         } else {
72                 t.tv_usec = tv2->tv_usec - tv1->tv_usec;
73         }
74         return t;
75 }
76
77 _PUBLIC_ struct timeval timeval_add(const struct timeval *tv,
78                            uint32_t secs, uint32_t usecs)
79 {
80         struct timeval tv2 = *tv;
81         const unsigned int million = 1000000;
82         tv2.tv_sec += secs;
83         tv2.tv_usec += usecs;
84         tv2.tv_sec += tv2.tv_usec / million;
85         tv2.tv_usec = tv2.tv_usec % million;
86         return tv2;
87 }
88
89
90 _PUBLIC_ struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs)
91 {
92         struct timeval tv = timeval_current();
93         return timeval_add(&tv, secs, usecs);
94 }
95
96 _PUBLIC_ char *fd_load(int fd, size_t *size, TALLOC_CTX *mem_ctx)
97 {
98         struct stat sbuf;
99         char *p;
100
101         if (fstat(fd, &sbuf) != 0) return NULL;
102
103         p = (char *)talloc_size(mem_ctx, sbuf.st_size+1);
104         if (!p) return NULL;
105
106         if (read(fd, p, sbuf.st_size) != sbuf.st_size) {
107                 talloc_free(p);
108                 return NULL;
109         }
110         p[sbuf.st_size] = 0;
111
112         if (size) *size = sbuf.st_size;
113
114         return p;
115 }
116
117
118 _PUBLIC_ char *file_load(const char *fname, size_t *size, TALLOC_CTX *mem_ctx)
119 {
120         int fd;
121         char *p;
122
123         if (!fname || !*fname) return NULL;
124         
125         fd = open(fname,O_RDONLY);
126         if (fd == -1) return NULL;
127
128         p = fd_load(fd, size, mem_ctx);
129
130         close(fd);
131
132         return p;
133 }
134
135
136 /**
137 parse a buffer into lines
138 'p' will be freed on error, and otherwise will be made a child of the returned array
139 **/
140 static char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *mem_ctx)
141 {
142         int i;
143         char *s, **ret;
144
145         if (!p) return NULL;
146
147         for (s = p, i=0; s < p+size; s++) {
148                 if (s[0] == '\n') i++;
149         }
150
151         ret = talloc_array(mem_ctx, char *, i+2);
152         if (!ret) {
153                 talloc_free(p);
154                 return NULL;
155         }       
156         
157         talloc_steal(ret, p);
158         
159         memset(ret, 0, sizeof(ret[0])*(i+2));
160         if (numlines) *numlines = i;
161
162         ret[0] = p;
163         for (s = p, i=0; s < p+size; s++) {
164                 if (s[0] == '\n') {
165                         s[0] = 0;
166                         i++;
167                         ret[i] = s+1;
168                 }
169                 if (s[0] == '\r') s[0] = 0;
170         }
171
172         return ret;
173 }
174
175
176 /**
177 load a file into memory and return an array of pointers to lines in the file
178 must be freed with talloc_free(). 
179 **/
180 _PUBLIC_ char **file_lines_load(const char *fname, int *numlines, TALLOC_CTX *mem_ctx)
181 {
182         char *p;
183         size_t size;
184
185         p = file_load(fname, &size, mem_ctx);
186         if (!p) return NULL;
187
188         return file_lines_parse(p, size, numlines, mem_ctx);
189 }