discover: separate file-reading code into file.c
[petitboot] / discover / file.c
1 /*
2  *  Copyright (C) 2013 Jeremy Kerr <jk@ozlabs.org>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; version 2 of the License.
7  *
8  *  This program is distributed in the hope that it will be useful,
9  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  *  GNU General Public License for more details.
12  *
13  *  You should have received a copy of the GNU General Public License
14  *  along with this program; if not, write to the Free Software
15  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16  */
17
18 #include <fcntl.h>
19 #include <unistd.h>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22
23 #include <talloc/talloc.h>
24
25 #include "file.h"
26
27 static const int max_file_size = 1024 * 1024;
28
29 int read_file(void *ctx, const char *filename, char **bufp, int *lenp)
30 {
31         struct stat statbuf;
32         int rc, fd, i, len;
33         char *buf;
34
35         fd = open(filename, O_RDONLY);
36         if (fd < 0)
37                 return -1;
38
39         rc = fstat(fd, &statbuf);
40         if (rc < 0)
41                 goto err_close;
42
43         len = statbuf.st_size;
44         if (len > max_file_size)
45                 goto err_close;
46
47         buf = talloc_array(ctx, char, len + 1);
48         if (!buf)
49                 goto err_close;
50
51         for (i = 0; i < len; i += rc) {
52                 rc = read(fd, buf + i, len - i);
53
54                 /* unexpected EOF: trim and return */
55                 if (rc == 0) {
56                         len = i;
57                         break;
58                 }
59
60                 if (rc < 0)
61                         goto err_free;
62
63         }
64
65         buf[len] = '\0';
66
67         close(fd);
68         *bufp = buf;
69         *lenp = len;
70         return 0;
71
72 err_free:
73         talloc_free(buf);
74 err_close:
75         close(fd);
76         return -1;
77 }