]> git.ipfire.org Git - people/ms/pakfire.git/blob - src/libpakfire/file.c
file: Rename "name" to "path"
[people/ms/pakfire.git] / src / libpakfire / file.c
1 /*#############################################################################
2 # #
3 # Pakfire - The IPFire package management system #
4 # Copyright (C) 2014 Pakfire development team #
5 # #
6 # This program 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 3 of the License, or #
9 # (at your option) any later version. #
10 # #
11 # This program 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 this program. If not, see <http://www.gnu.org/licenses/>. #
18 # #
19 #############################################################################*/
20
21 #include <assert.h>
22 #include <errno.h>
23 #include <linux/limits.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/stat.h>
28 #include <sys/types.h>
29 #include <tar.h>
30 #include <time.h>
31
32 #include <archive_entry.h>
33
34 #include <pakfire/constants.h>
35 #include <pakfire/file.h>
36 #include <pakfire/pakfire.h>
37 #include <pakfire/private.h>
38 #include <pakfire/util.h>
39
40 struct _PakfireFile {
41 Pakfire pakfire;
42 int nrefs;
43
44 char path[PATH_MAX];
45 char type;
46 ssize_t size;
47
48 char user[256];
49 char group[256];
50
51 mode_t mode;
52 time_t time;
53
54 char* chksum;
55
56 #warning TODO capabilities, config, data
57 // capabilities
58 //int is_configfile;
59 //int is_datafile;
60 };
61
62 PAKFIRE_EXPORT int pakfire_file_create(PakfireFile* file, Pakfire pakfire) {
63 PakfireFile f = calloc(1, sizeof(*f));
64 if (!f)
65 return -ENOMEM;
66
67 f->pakfire = pakfire_ref(pakfire);
68 f->nrefs = 1;
69
70 *file = f;
71 return 0;
72 }
73
74 PAKFIRE_EXPORT int pakfire_file_copy_stat(PakfireFile file, struct stat* stat) {
75 if (!stat)
76 return EINVAL;
77
78 // Set type
79 switch (stat->st_mode & S_IFMT) {
80 case S_IFREG:
81 pakfire_file_set_type(file, REGTYPE);
82 break;
83
84 case S_IFDIR:
85 pakfire_file_set_type(file, DIRTYPE);
86 break;
87
88 case S_IFLNK:
89 pakfire_file_set_type(file, SYMTYPE);
90 break;
91
92 case S_IFBLK:
93 pakfire_file_set_type(file, BLKTYPE);
94 break;
95
96 case S_IFCHR:
97 pakfire_file_set_type(file, CHRTYPE);
98 break;
99
100 case S_IFIFO:
101 pakfire_file_set_type(file, FIFOTYPE);
102 break;
103 }
104
105 // Set mode
106 pakfire_file_set_mode(file, stat->st_mode);
107
108 // Set size
109 pakfire_file_set_size(file, stat->st_size);
110
111 // Set user
112 // XXX
113 pakfire_file_set_user(file, "root");
114 pakfire_file_set_group(file, "root");
115
116 // Set time
117 pakfire_file_set_time(file, stat->st_ctime);
118
119 return 0;
120 }
121
122 int pakfire_file_copy_archive_entry(PakfireFile file, struct archive_entry* entry) {
123 // Set path
124 pakfire_file_set_path(file, archive_entry_pathname(entry));
125
126 // Set size
127 pakfire_file_set_size(file, archive_entry_size(entry));
128
129 // Set mode
130 pakfire_file_set_mode(file, archive_entry_mode(entry));
131
132 // Set user
133 pakfire_file_set_user(file, archive_entry_uname(entry));
134
135 // Set group
136 pakfire_file_set_group(file, archive_entry_gname(entry));
137
138 // Set mtime
139 pakfire_file_set_time(file, archive_entry_mtime(entry));
140
141 return 0;
142 }
143
144 static void pakfire_file_free(PakfireFile file) {
145 pakfire_unref(file->pakfire);
146
147 if (file->chksum)
148 free(file->chksum);
149
150 free(file);
151 }
152
153 PAKFIRE_EXPORT PakfireFile pakfire_file_ref(PakfireFile file) {
154 file->nrefs++;
155
156 return file;
157 }
158
159 PAKFIRE_EXPORT PakfireFile pakfire_file_unref(PakfireFile file) {
160 if (--file->nrefs > 0)
161 return file;
162
163 pakfire_file_free(file);
164 return NULL;
165 }
166
167 PAKFIRE_EXPORT int pakfire_file_cmp(PakfireFile file1, PakfireFile file2) {
168 const char* path1 = pakfire_file_get_path(file1);
169 const char* path2 = pakfire_file_get_path(file2);
170
171 return strcmp(path1, path2);
172 }
173
174 static char pakfire_file_sprintf_type(PakfireFile file) {
175 if (pakfire_file_is_dir(file))
176 return 'd';
177
178 if (pakfire_file_is_symlink(file))
179 return 'l';
180
181 if (pakfire_file_is_char(file))
182 return 'c';
183
184 return '-';
185 }
186
187 static char* pakfire_file_format_perms(PakfireFile file) {
188 char buffer[11];
189
190 mode_t mode = pakfire_file_get_mode(file);
191
192 buffer[0] = pakfire_file_sprintf_type(file);
193 buffer[1] = (S_IRUSR & mode) ? 'r' : '-';
194 buffer[2] = (S_IWUSR & mode) ? 'w' : '-';
195 buffer[3] = (S_IXUSR & mode) ? 'x' : '-';
196 buffer[4] = (S_IRGRP & mode) ? 'r' : '-';
197 buffer[5] = (S_IWGRP & mode) ? 'w' : '-';
198 buffer[6] = (S_IXGRP & mode) ? 'x' : '-';
199 buffer[7] = (S_IROTH & mode) ? 'r' : '-';
200 buffer[8] = (S_IWOTH & mode) ? 'w' : '-';
201 buffer[9] = (S_IXOTH & mode) ? 'x' : '-';
202 buffer[10] = '\0';
203
204 #warning TODO SUID bits, etc...
205
206 return strdup(buffer);
207 }
208
209 static char* pakfire_file_format_mtime(PakfireFile file) {
210 struct tm* timer = gmtime((time_t *)&file->time);
211
212 char buffer[STRING_SIZE];
213 strftime(buffer, sizeof(buffer), "%d %b %Y %T", timer);
214
215 return strdup(buffer);
216 }
217
218 PAKFIRE_EXPORT void pakfire_file_sprintf(PakfireFile file, char* str, size_t len) {
219 const char* path = pakfire_file_get_path(file);
220 ssize_t size = pakfire_file_get_size(file);
221
222 const char* user = pakfire_file_get_user(file);
223 const char* group = pakfire_file_get_group(file);
224
225 char* perms = pakfire_file_format_perms(file);
226 char* mtime = pakfire_file_format_mtime(file);
227
228 snprintf(str, len, "%s %-8s %-8s %8d %s %s", perms, user, group,
229 (int)size, mtime, path);
230
231 free(perms);
232 free(mtime);
233 }
234
235 PAKFIRE_EXPORT const char* pakfire_file_get_path(PakfireFile file) {
236 return file->path;
237 }
238
239 PAKFIRE_EXPORT void pakfire_file_set_path(PakfireFile file, const char* path) {
240 snprintf(file->path, sizeof(file->path) - 1, "%s", path);
241 }
242
243 PAKFIRE_EXPORT char* pakfire_file_get_dirname(PakfireFile file) {
244 return pakfire_dirname(file->path);
245 }
246
247 PAKFIRE_EXPORT char* pakfire_file_get_basename(PakfireFile file) {
248 return pakfire_basename(file->path);
249 }
250
251 PAKFIRE_EXPORT char pakfire_file_get_type(PakfireFile file) {
252 return file->type;
253 }
254
255 PAKFIRE_EXPORT void pakfire_file_set_type(PakfireFile file, char type) {
256 file->type = type;
257 }
258
259 PAKFIRE_EXPORT int pakfire_file_is_file(PakfireFile file) {
260 return (file->type == REGTYPE) || (file->type == AREGTYPE);
261 }
262
263 PAKFIRE_EXPORT int pakfire_file_is_link(PakfireFile file) {
264 return (file->type == LNKTYPE);
265 }
266
267 PAKFIRE_EXPORT int pakfire_file_is_symlink(PakfireFile file) {
268 return (file->type == SYMTYPE);
269 }
270
271 PAKFIRE_EXPORT int pakfire_file_is_char(PakfireFile file) {
272 return (file->type == CHRTYPE);
273 }
274
275 PAKFIRE_EXPORT int pakfire_file_is_block(PakfireFile file) {
276 return (file->type == BLKTYPE);
277 }
278
279 PAKFIRE_EXPORT int pakfire_file_is_dir(PakfireFile file) {
280 return (file->type == DIRTYPE);
281 }
282
283 PAKFIRE_EXPORT ssize_t pakfire_file_get_size(PakfireFile file) {
284 return file->size;
285 }
286
287 PAKFIRE_EXPORT void pakfire_file_set_size(PakfireFile file, ssize_t size) {
288 file->size = size;
289 }
290
291 PAKFIRE_EXPORT const char* pakfire_file_get_user(PakfireFile file) {
292 return file->user;
293 }
294
295 PAKFIRE_EXPORT void pakfire_file_set_user(PakfireFile file, const char* user) {
296 snprintf(file->user, sizeof(file->user) - 1, "%s", user);
297 }
298
299 PAKFIRE_EXPORT const char* pakfire_file_get_group(PakfireFile file) {
300 return file->group;
301 }
302
303 PAKFIRE_EXPORT void pakfire_file_set_group(PakfireFile file, const char* group) {
304 snprintf(file->group, sizeof(file->group) - 1, "%s", group);
305 }
306
307 PAKFIRE_EXPORT mode_t pakfire_file_get_mode(PakfireFile file) {
308 return file->mode;
309 }
310
311 PAKFIRE_EXPORT void pakfire_file_set_mode(PakfireFile file, mode_t mode) {
312 file->mode = mode;
313 }
314
315 PAKFIRE_EXPORT time_t pakfire_file_get_time(PakfireFile file) {
316 return file->time;
317 }
318
319 PAKFIRE_EXPORT void pakfire_file_set_time(PakfireFile file, time_t time) {
320 file->time = time;
321 }
322
323 PAKFIRE_EXPORT const char* pakfire_file_get_chksum(PakfireFile file) {
324 return file->chksum;
325 }
326
327 PAKFIRE_EXPORT void pakfire_file_set_chksum(PakfireFile file, const char* chksum) {
328 if (file->chksum) {
329 free(file->chksum);
330 file->chksum = NULL;
331 }
332
333 if (chksum)
334 file->chksum = strdup(chksum);
335 }