]> git.ipfire.org Git - people/stevee/pakfire.git/blame - src/libpakfire/file.c
packager: Import all file attributes from archive entry
[people/stevee/pakfire.git] / src / libpakfire / file.c
CommitLineData
221cc3ce
MT
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>
5e9463ec 22#include <errno.h>
c98132d1 23#include <linux/limits.h>
221cc3ce
MT
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
9a6e3e2d
MT
32#include <archive_entry.h>
33
221cc3ce
MT
34#include <pakfire/constants.h>
35#include <pakfire/file.h>
883b3be9 36#include <pakfire/pakfire.h>
9f953e68 37#include <pakfire/private.h>
221cc3ce
MT
38#include <pakfire/util.h>
39
5e9463ec 40struct _PakfireFile {
883b3be9 41 Pakfire pakfire;
5e9463ec 42 int nrefs;
221cc3ce 43
c98132d1 44 char name[PATH_MAX];
5e9463ec
MT
45 char type;
46 ssize_t size;
221cc3ce 47
c98132d1
MT
48 char user[256];
49 char group[256];
221cc3ce 50
5e9463ec
MT
51 mode_t mode;
52 time_t time;
d03fa9a3 53
5e9463ec
MT
54 char* chksum;
55
56 #warning TODO capabilities, config, data
57 // capabilities
58 //int is_configfile;
59 //int is_datafile;
60};
61
883b3be9 62PAKFIRE_EXPORT int pakfire_file_create(PakfireFile* file, Pakfire pakfire) {
90312f5c 63 PakfireFile f = calloc(1, sizeof(*f));
5e9463ec
MT
64 if (!f)
65 return -ENOMEM;
66
883b3be9 67 f->pakfire = pakfire_ref(pakfire);
5e9463ec
MT
68 f->nrefs = 1;
69
70 *file = f;
71 return 0;
d03fa9a3
MT
72}
73
548b6515
MT
74PAKFIRE_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
9a6e3e2d
MT
122int pakfire_file_copy_archive_entry(PakfireFile file, struct archive_entry* entry) {
123 // Set name
124 pakfire_file_set_name(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
5e9463ec 144static void pakfire_file_free(PakfireFile file) {
883b3be9
MT
145 pakfire_unref(file->pakfire);
146
5e9463ec 147 if (file->chksum)
f0d6233d 148 free(file->chksum);
221cc3ce 149
f0d6233d 150 free(file);
221cc3ce
MT
151}
152
5e9463ec
MT
153PAKFIRE_EXPORT PakfireFile pakfire_file_ref(PakfireFile file) {
154 file->nrefs++;
221cc3ce 155
5e9463ec
MT
156 return file;
157}
221cc3ce 158
5e9463ec
MT
159PAKFIRE_EXPORT PakfireFile pakfire_file_unref(PakfireFile file) {
160 if (--file->nrefs > 0)
161 return file;
162
163 pakfire_file_free(file);
164 return NULL;
221cc3ce
MT
165}
166
9f953e68 167PAKFIRE_EXPORT int pakfire_file_cmp(PakfireFile file1, PakfireFile file2) {
221cc3ce
MT
168 const char* name1 = pakfire_file_get_name(file1);
169 const char* name2 = pakfire_file_get_name(file2);
170
171 return strcmp(name1, name2);
172}
173
221cc3ce
MT
174static 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
187static 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
5d901566 206 return strdup(buffer);
221cc3ce
MT
207}
208
209static 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
5d901566 215 return strdup(buffer);
221cc3ce
MT
216}
217
9f953e68 218PAKFIRE_EXPORT void pakfire_file_sprintf(PakfireFile file, char* str, size_t len) {
221cc3ce
MT
219 const char* name = pakfire_file_get_name(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, name);
230
f0d6233d
MT
231 free(perms);
232 free(mtime);
221cc3ce
MT
233}
234
9f953e68 235PAKFIRE_EXPORT const char* pakfire_file_get_name(PakfireFile file) {
221cc3ce
MT
236 return file->name;
237}
238
9f953e68 239PAKFIRE_EXPORT void pakfire_file_set_name(PakfireFile file, const char* name) {
c98132d1 240 snprintf(file->name, sizeof(file->name) - 1, "%s", name);
221cc3ce
MT
241}
242
5e9463ec
MT
243PAKFIRE_EXPORT char* pakfire_file_get_dirname(PakfireFile file) {
244 return pakfire_dirname(file->name);
245}
246
247PAKFIRE_EXPORT char* pakfire_file_get_basename(PakfireFile file) {
248 return pakfire_basename(file->name);
249}
250
9f953e68 251PAKFIRE_EXPORT char pakfire_file_get_type(PakfireFile file) {
221cc3ce
MT
252 return file->type;
253}
254
9f953e68 255PAKFIRE_EXPORT void pakfire_file_set_type(PakfireFile file, char type) {
221cc3ce
MT
256 file->type = type;
257}
258
9f953e68 259PAKFIRE_EXPORT int pakfire_file_is_file(PakfireFile file) {
221cc3ce
MT
260 return (file->type == REGTYPE) || (file->type == AREGTYPE);
261}
262
9f953e68 263PAKFIRE_EXPORT int pakfire_file_is_link(PakfireFile file) {
221cc3ce
MT
264 return (file->type == LNKTYPE);
265}
266
9f953e68 267PAKFIRE_EXPORT int pakfire_file_is_symlink(PakfireFile file) {
221cc3ce
MT
268 return (file->type == SYMTYPE);
269}
270
9f953e68 271PAKFIRE_EXPORT int pakfire_file_is_char(PakfireFile file) {
221cc3ce
MT
272 return (file->type == CHRTYPE);
273}
274
9f953e68 275PAKFIRE_EXPORT int pakfire_file_is_block(PakfireFile file) {
221cc3ce
MT
276 return (file->type == BLKTYPE);
277}
278
9f953e68 279PAKFIRE_EXPORT int pakfire_file_is_dir(PakfireFile file) {
221cc3ce
MT
280 return (file->type == DIRTYPE);
281}
282
9f953e68 283PAKFIRE_EXPORT ssize_t pakfire_file_get_size(PakfireFile file) {
221cc3ce
MT
284 return file->size;
285}
286
9f953e68 287PAKFIRE_EXPORT void pakfire_file_set_size(PakfireFile file, ssize_t size) {
221cc3ce
MT
288 file->size = size;
289}
290
9f953e68 291PAKFIRE_EXPORT const char* pakfire_file_get_user(PakfireFile file) {
221cc3ce
MT
292 return file->user;
293}
294
9f953e68 295PAKFIRE_EXPORT void pakfire_file_set_user(PakfireFile file, const char* user) {
c98132d1 296 snprintf(file->user, sizeof(file->user) - 1, "%s", user);
221cc3ce
MT
297}
298
9f953e68 299PAKFIRE_EXPORT const char* pakfire_file_get_group(PakfireFile file) {
221cc3ce
MT
300 return file->group;
301}
302
9f953e68 303PAKFIRE_EXPORT void pakfire_file_set_group(PakfireFile file, const char* group) {
c98132d1 304 snprintf(file->group, sizeof(file->group) - 1, "%s", group);
221cc3ce
MT
305}
306
9f953e68 307PAKFIRE_EXPORT mode_t pakfire_file_get_mode(PakfireFile file) {
221cc3ce
MT
308 return file->mode;
309}
310
9f953e68 311PAKFIRE_EXPORT void pakfire_file_set_mode(PakfireFile file, mode_t mode) {
221cc3ce
MT
312 file->mode = mode;
313}
314
9f953e68 315PAKFIRE_EXPORT time_t pakfire_file_get_time(PakfireFile file) {
221cc3ce
MT
316 return file->time;
317}
318
9f953e68 319PAKFIRE_EXPORT void pakfire_file_set_time(PakfireFile file, time_t time) {
221cc3ce
MT
320 file->time = time;
321}
322
9f953e68 323PAKFIRE_EXPORT const char* pakfire_file_get_chksum(PakfireFile file) {
221cc3ce
MT
324 return file->chksum;
325}
326
9f953e68 327PAKFIRE_EXPORT void pakfire_file_set_chksum(PakfireFile file, const char* chksum) {
ffbef232
MT
328 if (file->chksum) {
329 free(file->chksum);
330 file->chksum = NULL;
331 }
332
333 if (chksum)
334 file->chksum = strdup(chksum);
221cc3ce 335}