From: Michael Tremer Date: Mon, 19 Sep 2022 19:14:37 +0000 (+0000) Subject: file: Add function to dump the file X-Git-Tag: 0.9.28~299 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5852b822f17e429e78bde09e87d40a6a2abfd106;p=pakfire.git file: Add function to dump the file This function returns a line which is similar to what "tar tvf" produces. Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/file.c b/src/libpakfire/file.c index 15c8e2765..c57ba6eb6 100644 --- a/src/libpakfire/file.c +++ b/src/libpakfire/file.c @@ -382,6 +382,130 @@ PAKFIRE_EXPORT struct pakfire_file* pakfire_file_unref(struct pakfire_file* file return NULL; } +#define pakfire_file_strmode(file, buffer) \ + __pakfire_file_strmode(file, buffer, sizeof(buffer)) + +static int __pakfire_file_strmode(struct pakfire_file* file, char* s, const size_t length) { + int r; + + static const mode_t permbits[] = { + 0400, + 0200, + 0100, + 0040, + 0020, + 0010, + 0004, + 0002, + 0001 + }; + + const mode_t mode = pakfire_file_get_mode(file); + const mode_t type = pakfire_file_get_type(file); + + // Set some default string + r = __pakfire_string_set(s, length, "?rwxrwxrwx "); + if (r) + return r; + + switch (type) { + case S_IFREG: + s[0] = '-'; + break; + + case S_IFBLK: + s[0] = 'b'; + break; + + case S_IFCHR: + s[0] = 'c'; + break; + + case S_IFDIR: + s[0] = 'd'; + break; + + case S_IFLNK: + s[0] = 'l'; + break; + + case S_IFSOCK: + s[0] = 's'; + break; + + case S_IFIFO: + s[0] = 'p'; + break; + + default: + if (*file->hardlink) { + s[0] = 'h'; + break; + } + } + + for (unsigned int i = 0; i < 9; i++) { + if (mode & permbits[i]) + continue; + + s[i+1] = '-'; + } + + if (mode & S_ISUID) { + if (mode & 0100) + s[3] = 's'; + else + s[3] = 'S'; + } + + if (mode & S_ISGID) { + if (mode & 0010) + s[6] = 's'; + else + s[6] = 'S'; + } + + if (mode & S_ISVTX) { + if (mode & 0001) + s[9] = 't'; + else + s[9] = 'T'; + } + +#if 0 + if (file->caps) + s[10] = '+'; +#endif + + return 0; +} + +char* pakfire_file_dump(struct pakfire_file* file) { + char* buffer = NULL; + int r; + + char mode[12]; + char time[32]; + + // Format mode + r = pakfire_file_strmode(file, mode); + if (r) + return NULL; + + // Format time + r = pakfire_strftime(time, "%Y-%m-%d %H:%M", file->st.st_ctime); + if (r) + return NULL; + + // Put everything together + r = asprintf(&buffer, "%s %s/%s %8zu %s %s", + mode, file->user, file->group, file->st.st_size, time, file->path); + if (r < 0) + return NULL; + + return buffer; +} + PAKFIRE_EXPORT int pakfire_file_cmp(struct pakfire_file* file1, struct pakfire_file* file2) { const char* path1 = pakfire_file_get_path(file1); const char* path2 = pakfire_file_get_path(file2); diff --git a/src/libpakfire/include/pakfire/file.h b/src/libpakfire/include/pakfire/file.h index 8ce073812..d626182ff 100644 --- a/src/libpakfire/include/pakfire/file.h +++ b/src/libpakfire/include/pakfire/file.h @@ -35,6 +35,8 @@ int pakfire_file_create(struct pakfire_file** file, struct pakfire* pakfire); struct pakfire_file* pakfire_file_ref(struct pakfire_file* file); struct pakfire_file* pakfire_file_unref(struct pakfire_file* file); +char* pakfire_file_dump(struct pakfire_file* file); + int pakfire_file_cmp(struct pakfire_file* file1, struct pakfire_file* file2); const char* pakfire_file_get_path(struct pakfire_file* file);