d0cc05979f70a1f034c1cbf51d8c5d73db58a8a9
[libsamsung-ipc.git] / samsung-ipc / utils.c
1 /*
2  * This file is part of libsamsung-ipc.
3  *
4  * Copyright (C) 2013-2014 Paul Kocialkowski <contact@paulk.fr>
5  *
6  * libsamsung-ipc is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * libsamsung-ipc is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with libsamsung-ipc.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <stdint.h>
23 #include <string.h>
24 #include <fcntl.h>
25 #include <ctype.h>
26 #include <sys/ioctl.h>
27 #include <sys/stat.h>
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <asm/types.h>
31 #include <linux/netlink.h>
32 #include <net/if.h>
33
34
35 void *file_data_read(const char *path, size_t size, size_t chunk_size,
36     size_t offset)
37 {
38     void *data = NULL;
39     int fd = -1;
40     size_t count;
41     off_t seek;
42     unsigned char *p;
43     int rc;
44
45     if (path == NULL || size == 0 || chunk_size == 0 || chunk_size > size)
46         return NULL;
47
48     fd = open(path, O_RDONLY);
49     if (fd < 0)
50         goto error;
51
52     seek = lseek(fd, (off_t) offset, SEEK_SET);
53     if (seek < (off_t) offset)
54         goto error;
55
56     data = calloc(1, size);
57
58     p = (unsigned char *) data;
59
60     count = 0;
61     while (count < size) {
62         rc = read(fd, p, size - count > chunk_size ? chunk_size : size - count);
63         if (rc <= 0)
64             goto error;
65
66         p += rc;
67         count += rc;
68     }
69
70     goto complete;
71
72 error:
73     if (data != NULL) {
74         free(data);
75         data = NULL;
76     }
77
78 complete:
79     if (fd >= 0)
80         close(fd);
81
82     return data;
83 }
84
85 int file_data_write(const char *path, const void *data, size_t size,
86     size_t chunk_size, size_t offset)
87 {
88     int fd = -1;
89     size_t count;
90     off_t seek;
91     unsigned char *p;
92     int rc;
93
94     if (path == NULL || data == NULL || size == 0 || chunk_size == 0 || chunk_size > size)
95         return -1;
96
97     fd = open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
98     if (fd < 0)
99         goto error;
100
101     seek = lseek(fd, (off_t) offset, SEEK_SET);
102     if (seek < (off_t) offset)
103         goto error;
104
105     p = (unsigned char *) data;
106
107     count = 0;
108     while (count < size) {
109         rc = write(fd, p, size - count > chunk_size ? chunk_size : size - count);
110         if (rc <= 0)
111             goto error;
112
113         p += rc;
114         count += rc;
115     }
116
117     rc = 0;
118     goto complete;
119
120 error:
121     rc = -1;
122
123 complete:
124     if (fd >= 0)
125         close(fd);
126
127     return rc;
128 }
129
130 int network_iface_up(const char *iface, int domain, int type)
131 {
132     struct ifreq ifr;
133     int fd = -1;
134     int rc;
135
136     if (iface == NULL)
137         return -1;
138
139     memset(&ifr, 0, sizeof(ifr));
140     strncpy(ifr.ifr_name, iface, IFNAMSIZ);
141
142     fd = socket(domain, type, 0);
143     if (fd < 0)
144         goto error;
145
146     rc = ioctl(fd, SIOCGIFFLAGS, &ifr);
147     if (rc < 0)
148         goto error;
149
150     ifr.ifr_flags |= IFF_UP;
151
152     rc = ioctl(fd, SIOCSIFFLAGS, &ifr);
153     if (rc < 0)
154         goto error;
155
156     rc = 0;
157     goto complete;
158
159 error:
160     rc = -1;
161
162 complete:
163     if (fd >= 0)
164         close(fd);
165
166     return rc;
167 }
168
169 int network_iface_down(const char *iface, int domain, int type)
170 {
171     struct ifreq ifr;
172     int fd = -1;
173     int rc;
174
175     if (iface == NULL)
176         return -1;
177
178     memset(&ifr, 0, sizeof(ifr));
179     strncpy(ifr.ifr_name, iface, IFNAMSIZ);
180
181     fd = socket(domain, type, 0);
182     if (fd < 0)
183         goto error;
184
185     rc = ioctl(fd, SIOCGIFFLAGS, &ifr);
186     if (rc < 0)
187         goto error;
188
189     ifr.ifr_flags = (ifr.ifr_flags & (~IFF_UP));
190
191     rc = ioctl(fd, SIOCSIFFLAGS, &ifr);
192     if (rc < 0)
193         goto error;
194
195     rc = 0;
196     goto complete;
197
198 error:
199     rc = -1;
200
201 complete:
202     if (fd >= 0)
203         close(fd);
204
205     return rc;
206 }
207
208 int sysfs_value_read(const char *path)
209 {
210     char buffer[100];
211     int value;
212     int fd = -1;
213     int rc;
214
215     if (path == NULL)
216         return -1;
217
218     fd = open(path, O_RDONLY);
219     if (fd < 0)
220         goto error;
221
222     rc = read(fd, &buffer, sizeof(buffer));
223     if (rc <= 0)
224         goto error;
225
226     value = atoi(buffer);
227     goto complete;
228
229 error:
230     value = -1;
231
232 complete:
233     if (fd >= 0)
234         close(fd);
235
236     return value;
237 }
238
239 int sysfs_value_write(const char *path, int value)
240 {
241     char buffer[100];
242     int fd = -1;
243     int rc;
244
245     if (path == NULL)
246         return -1;
247
248     fd = open(path, O_WRONLY);
249     if (fd < 0)
250         goto error;
251
252     snprintf((char *) &buffer, sizeof(buffer), "%d\n", value);
253
254     rc = write(fd, buffer, strlen(buffer));
255     if (rc < (int) strlen(buffer))
256         goto error;
257
258     rc = 0;
259     goto complete;
260
261 error:
262     rc = -1;
263
264 complete:
265     if (fd >= 0)
266         close(fd);
267
268     return rc;
269 }
270
271 char *sysfs_string_read(const char *path, size_t length)
272 {
273     char *string = NULL;
274     int fd = -1;
275     int rc;
276
277     if (path == NULL || length == 0)
278         return NULL;
279
280     fd = open(path, O_RDONLY);
281     if (fd < 0)
282         goto error;
283
284     string = (char *) calloc(1, length);
285
286     rc = read(fd, string, length);
287     if (rc <= 0)
288         goto error;
289
290     goto complete;
291
292 error:
293     if (string != NULL) {
294         free(string);
295         string = NULL;
296     }
297
298 complete:
299     if (fd >= 0)
300         close(fd);
301
302     return string;
303 }
304
305 int sysfs_string_write(const char *path, const char *buffer, size_t length)
306 {
307     int fd = -1;
308     int rc;
309
310     if (path == NULL || buffer == NULL || length == 0)
311         return -1;
312
313     fd = open(path, O_WRONLY);
314     if (fd < 0)
315         goto error;
316
317     rc = write(fd, buffer, length);
318     if (rc < (int) length)
319         goto error;
320
321     rc = 0;
322     goto complete;
323
324 error:
325     rc = -1;
326
327 complete:
328     if (fd >= 0)
329         close(fd);
330
331     return rc;
332 }
333
334 size_t data2string_length(const void *data, size_t size)
335 {
336     size_t length;
337
338     if (data == NULL || size == 0)
339         return 0;
340
341     length = size * 2 + 1;
342
343     return length;
344 }
345
346 char *data2string(const void *data, size_t size)
347 {
348     char *string;
349     size_t length;
350     char *p;
351     size_t i;
352
353     if (data == NULL || size == 0)
354         return NULL;
355
356     length = data2string_length(data, size);
357     if (length == 0)
358         return NULL;
359
360     string = (char *) calloc(1, length);
361
362     p = string;
363
364     for (i = 0; i < size; i++) {
365         sprintf(p, "%02x", *((unsigned char *) data + i));
366         p += 2 * sizeof(char);
367     }
368
369     return string;
370 }
371
372 size_t string2data_size(const char *string)
373 {
374     size_t length;
375     size_t size;
376
377     if (string == NULL)
378         return 0;
379
380     length = strlen(string);
381     if (length == 0)
382         return 0;
383
384     if (length % 2 == 0)
385         size = length / 2;
386     else
387         size = (length - (length % 2)) / 2 + 1;
388
389     return size;
390 }
391
392 void *string2data(const char *string)
393 {
394     void *data;
395     size_t size;
396     size_t length;
397     int shift;
398     unsigned char *p;
399     unsigned int b;
400     size_t i;
401     int rc;
402
403     if (string == NULL)
404         return NULL;
405
406     length = strlen(string);
407     if (length == 0)
408         return NULL;
409
410     if (length % 2 == 0)
411         shift = 0;
412     else
413         shift = 1;
414
415     size = string2data_size(string);
416     if (size == 0)
417         return NULL;
418
419     data = calloc(1, size);
420
421     p = (unsigned char *) data;
422
423     for (i = 0; i < length; i++) {
424         rc = sscanf(&string[i], "%01x", &b);
425         if (rc < 1)
426             b = 0;
427
428         if ((shift % 2) == 0)
429             *p |= ((b & 0x0f) << 4);
430         else
431             *p++ |= b & 0x0f;
432
433         shift++;
434     }
435
436     return data;
437 }
438
439 // vim:ts=4:sw=4:expandtab