]> git.ipfire.org Git - pakfire.git/commitdiff
file: Add function to dump the file
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 19 Sep 2022 19:14:37 +0000 (19:14 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 19 Sep 2022 19:14:37 +0000 (19:14 +0000)
This function returns a line which is similar to what "tar tvf"
produces.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/file.c
src/libpakfire/include/pakfire/file.h

index 15c8e276526534f6a11f0f14c870481f3eaf4f8d..c57ba6eb6eabbdb4164e04ed48a965c2e9f30f26 100644 (file)
@@ -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);
index 8ce073812aa6675ce582f419ab6469f411ea17a6..d626182ffbc6b72dd0be576e5d2b3a852584e08b 100644 (file)
@@ -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);