1 /*#############################################################################
3 # Pakfire - The IPFire package management system #
4 # Copyright (C) 2014 Pakfire development team #
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. #
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. #
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/>. #
19 #############################################################################*/
23 #include <linux/limits.h>
28 #include <sys/types.h>
32 #include <archive_entry.h>
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>
56 #warning TODO capabilities, config, data
62 PAKFIRE_EXPORT
int pakfire_file_create(PakfireFile
* file
, Pakfire pakfire
) {
63 PakfireFile f
= calloc(1, sizeof(*f
));
67 f
->pakfire
= pakfire_ref(pakfire
);
74 PAKFIRE_EXPORT
int pakfire_file_copy_stat(PakfireFile file
, struct stat
* stat
) {
79 switch (stat
->st_mode
& S_IFMT
) {
81 pakfire_file_set_type(file
, REGTYPE
);
85 pakfire_file_set_type(file
, DIRTYPE
);
89 pakfire_file_set_type(file
, SYMTYPE
);
93 pakfire_file_set_type(file
, BLKTYPE
);
97 pakfire_file_set_type(file
, CHRTYPE
);
101 pakfire_file_set_type(file
, FIFOTYPE
);
106 pakfire_file_set_mode(file
, stat
->st_mode
);
109 pakfire_file_set_size(file
, stat
->st_size
);
113 pakfire_file_set_user(file
, "root");
114 pakfire_file_set_group(file
, "root");
117 pakfire_file_set_time(file
, stat
->st_ctime
);
122 int pakfire_file_copy_archive_entry(PakfireFile file
, struct archive_entry
* entry
) {
124 pakfire_file_set_path(file
, archive_entry_pathname(entry
));
127 pakfire_file_set_size(file
, archive_entry_size(entry
));
130 pakfire_file_set_mode(file
, archive_entry_mode(entry
));
133 pakfire_file_set_user(file
, archive_entry_uname(entry
));
136 pakfire_file_set_group(file
, archive_entry_gname(entry
));
139 pakfire_file_set_time(file
, archive_entry_mtime(entry
));
144 static void pakfire_file_free(PakfireFile file
) {
145 pakfire_unref(file
->pakfire
);
153 PAKFIRE_EXPORT PakfireFile
pakfire_file_ref(PakfireFile file
) {
159 PAKFIRE_EXPORT PakfireFile
pakfire_file_unref(PakfireFile file
) {
160 if (--file
->nrefs
> 0)
163 pakfire_file_free(file
);
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
);
171 return strcmp(path1
, path2
);
174 static char pakfire_file_sprintf_type(PakfireFile file
) {
175 if (pakfire_file_is_dir(file
))
178 if (pakfire_file_is_symlink(file
))
181 if (pakfire_file_is_char(file
))
187 static char* pakfire_file_format_perms(PakfireFile file
) {
190 mode_t mode
= pakfire_file_get_mode(file
);
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' : '-';
204 #warning TODO SUID bits, etc...
206 return strdup(buffer
);
209 static char* pakfire_file_format_mtime(PakfireFile file
) {
210 struct tm
* timer
= gmtime((time_t *)&file
->time
);
212 char buffer
[STRING_SIZE
];
213 strftime(buffer
, sizeof(buffer
), "%d %b %Y %T", timer
);
215 return strdup(buffer
);
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
);
222 const char* user
= pakfire_file_get_user(file
);
223 const char* group
= pakfire_file_get_group(file
);
225 char* perms
= pakfire_file_format_perms(file
);
226 char* mtime
= pakfire_file_format_mtime(file
);
228 snprintf(str
, len
, "%s %-8s %-8s %8d %s %s", perms
, user
, group
,
229 (int)size
, mtime
, path
);
235 PAKFIRE_EXPORT
const char* pakfire_file_get_path(PakfireFile file
) {
239 PAKFIRE_EXPORT
void pakfire_file_set_path(PakfireFile file
, const char* path
) {
240 snprintf(file
->path
, sizeof(file
->path
) - 1, "%s", path
);
243 PAKFIRE_EXPORT
char* pakfire_file_get_dirname(PakfireFile file
) {
244 return pakfire_dirname(file
->path
);
247 PAKFIRE_EXPORT
char* pakfire_file_get_basename(PakfireFile file
) {
248 return pakfire_basename(file
->path
);
251 PAKFIRE_EXPORT
char pakfire_file_get_type(PakfireFile file
) {
255 PAKFIRE_EXPORT
void pakfire_file_set_type(PakfireFile file
, char type
) {
259 PAKFIRE_EXPORT
int pakfire_file_is_file(PakfireFile file
) {
260 return (file
->type
== REGTYPE
) || (file
->type
== AREGTYPE
);
263 PAKFIRE_EXPORT
int pakfire_file_is_link(PakfireFile file
) {
264 return (file
->type
== LNKTYPE
);
267 PAKFIRE_EXPORT
int pakfire_file_is_symlink(PakfireFile file
) {
268 return (file
->type
== SYMTYPE
);
271 PAKFIRE_EXPORT
int pakfire_file_is_char(PakfireFile file
) {
272 return (file
->type
== CHRTYPE
);
275 PAKFIRE_EXPORT
int pakfire_file_is_block(PakfireFile file
) {
276 return (file
->type
== BLKTYPE
);
279 PAKFIRE_EXPORT
int pakfire_file_is_dir(PakfireFile file
) {
280 return (file
->type
== DIRTYPE
);
283 PAKFIRE_EXPORT ssize_t
pakfire_file_get_size(PakfireFile file
) {
287 PAKFIRE_EXPORT
void pakfire_file_set_size(PakfireFile file
, ssize_t size
) {
291 PAKFIRE_EXPORT
const char* pakfire_file_get_user(PakfireFile file
) {
295 PAKFIRE_EXPORT
void pakfire_file_set_user(PakfireFile file
, const char* user
) {
296 snprintf(file
->user
, sizeof(file
->user
) - 1, "%s", user
);
299 PAKFIRE_EXPORT
const char* pakfire_file_get_group(PakfireFile file
) {
303 PAKFIRE_EXPORT
void pakfire_file_set_group(PakfireFile file
, const char* group
) {
304 snprintf(file
->group
, sizeof(file
->group
) - 1, "%s", group
);
307 PAKFIRE_EXPORT mode_t
pakfire_file_get_mode(PakfireFile file
) {
311 PAKFIRE_EXPORT
void pakfire_file_set_mode(PakfireFile file
, mode_t mode
) {
315 PAKFIRE_EXPORT
time_t pakfire_file_get_time(PakfireFile file
) {
319 PAKFIRE_EXPORT
void pakfire_file_set_time(PakfireFile file
, time_t time
) {
323 PAKFIRE_EXPORT
const char* pakfire_file_get_chksum(PakfireFile file
) {
327 PAKFIRE_EXPORT
void pakfire_file_set_chksum(PakfireFile file
, const char* chksum
) {
334 file
->chksum
= strdup(chksum
);