added missing autotools-dev dep
[prss.git] / src / io.c
1 /*
2  * Copyright (C) 2011-2012 jeanfi@gmail.com
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301 USA
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <sys/stat.h>
24
25 #include "io.h"
26
27 /* Directory separator is \ when cross-compiling for MS Windows
28    systems */
29 #if defined(__MINGW32__)
30 #define DIRSEP ('\\')
31 #else
32 #define DIRSEP '/'
33 #endif
34
35 #define FCOPY_BUF_SZ 4096
36
37 static int file_copy(FILE *src, FILE *dst)
38 {
39         int ret = 0;
40         char *buf = malloc(FCOPY_BUF_SZ);
41         int n;
42
43         if (!buf)
44                 return FILE_COPY_ERROR_ALLOC_BUFFER;
45
46         while (!ret) {
47                 n = fread(buf, 1, FCOPY_BUF_SZ, src);
48                 if (n) {
49                         if (fwrite(buf, 1, n, dst) != n)
50                                 ret = FILE_COPY_ERROR_WRITE;
51                 } else {
52                         if (!feof(src))
53                                 ret = FILE_COPY_ERROR_READ;
54                         else
55                                 break;
56                 }
57         }
58
59         free(buf);
60
61         return ret;
62 }
63
64 int fcopy(const char *src, const char *dst)
65 {
66         FILE *fsrc, *fdst;
67         int ret = 0;
68
69         fsrc = fopen(src, "r");
70
71         if (fsrc) {
72                 fdst = fopen(dst, "w+");
73
74                 if (fdst) {
75                         ret = file_copy(fsrc, fdst);
76                         fclose(fdst);
77                 } else {
78                         ret = FILE_COPY_ERROR_OPEN_DST;
79                 }
80
81                 fclose(fsrc);
82         } else {
83                 ret = FILE_COPY_ERROR_OPEN_SRC;
84         }
85
86         return ret;
87 }
88
89 char *path_append(const char *odir, const char *name)
90 {
91         char *dir;
92
93         dir = malloc(strlen(odir)+1+strlen(name)+1);
94
95         strcpy(dir, odir);
96         if (odir[strlen(odir) - 1] != '/' && name[0] != '/')
97                 strcat(dir, "/");
98         strcat(dir, name);
99
100         return dir;
101 }
102
103 void mkdirs(const char *dirs, mode_t mode)
104 {
105         char *c = (char *)dirs;
106         char *dir = malloc(strlen(dirs) + 1);
107
108         int i = 0;
109         while (*c) {
110                 if ((*c == DIRSEP || *c == '\0') && c != dirs) {
111                         strncpy(dir, dirs, i);
112                         dir[i] = '\0';
113                         mkdir(dir, mode);
114                 }
115
116                 c++;
117                 i++;
118         }
119
120         mkdir(dirs, mode);
121
122         free(dir);
123 }
124
125 static int is_file(const char *path)
126 {
127         struct stat st;
128
129         int ret = lstat(path, &st);
130
131         if (ret == 0 && S_ISREG(st.st_mode))
132                 return 1;
133
134         return 0;
135 }
136
137 static long file_get_size(const char *path)
138 {
139         FILE *fp;
140
141         if (!is_file(path))
142                 return -1;
143
144         fp = fopen(path, "rb");
145         if (fp) {
146                 long size;
147
148                 if (fseek(fp, 0, SEEK_END) == -1)
149                         return -1;
150
151                 size = ftell(fp);
152
153                 fclose(fp);
154
155                 return size;
156         }
157
158         return -1;
159 }
160
161 char *file_get_content(const char *fpath)
162 {
163         long size;
164
165         char *page;
166
167         size = file_get_size(fpath);
168         if (size == -1) {
169                 page = NULL;
170
171         } else if (size == 0) {
172                 page = malloc(1);
173                 *page = '\0';
174
175         } else {
176                 FILE *fp = fopen(fpath, "rb");
177                 if (fp) {
178                         page = malloc(size + 1);
179                         if (!page || size != fread(page, 1, size, fp)) {
180                                 free(page);
181                                 return NULL;
182                         }
183
184                         *(page + size) = '\0';
185
186                         fclose(fp);
187                 } else {
188                         page = NULL;
189                 }
190         }
191
192         return page;
193 }
194