]> git.ipfire.org Git - pakfire.git/commitdiff
libpakfire: Refactor files
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 24 Jan 2021 16:34:30 +0000 (16:34 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 24 Jan 2021 16:34:30 +0000 (16:34 +0000)
This used to be used to implement lists which was a right mess.

Lists are now filelists and files are now files only.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/package.c
src/libpakfire/archive.c
src/libpakfire/db.c
src/libpakfire/file.c
src/libpakfire/filelist.c
src/libpakfire/include/pakfire/archive.h
src/libpakfire/include/pakfire/file.h
src/libpakfire/include/pakfire/filelist.h
src/libpakfire/include/pakfire/package.h
src/libpakfire/libpakfire.sym
src/libpakfire/package.c

index 3ecd1e5238ebc84efca187746af3314b5623311a..df1ff161d328514fe7a82c2bb22f9e16db771942 100644 (file)
@@ -21,6 +21,7 @@
 #include <Python.h>
 
 #include <pakfire/file.h>
+#include <pakfire/filelist.h>
 #include <pakfire/package.h>
 #include <pakfire/relationlist.h>
 #include <pakfire/repo.h>
@@ -722,26 +723,28 @@ static PyObject* Package_get_filelist(PackageObject* self, PyObject* args) {
        if (list == NULL)
                return NULL;
 
-       PakfireFile file = pakfire_package_get_filelist(self->package);
-       while (file) {
+       PakfireFilelist filelist = pakfire_package_get_filelist(self->package);
+       for (unsigned int i = 0; i < pakfire_filelist_size(filelist); i++) {
+               PakfireFile file = pakfire_filelist_get(filelist, i);
                const char* name = pakfire_file_get_name(file);
+               pakfire_file_unref(file);
 
                PyObject* obj = PyUnicode_FromString(name);
 
                int ret = PyList_Append(list, obj);
                Py_DECREF(obj);
 
-               if (ret == -1)
-                       goto fail;
+               if (ret) {
+                       pakfire_filelist_unref(filelist);
+                       Py_DECREF(list);
 
-               file = pakfire_file_get_next(file);
+                       return NULL;
+               }
        }
 
-       return list;
+       pakfire_filelist_unref(filelist);
 
-fail:
-       Py_DECREF(list);
-       return NULL;
+       return list;
 }
 
 static int Package_set_filelist(PackageObject* self, PyObject* value) {
@@ -750,8 +753,16 @@ static int Package_set_filelist(PackageObject* self, PyObject* value) {
                return -1;
        }
 
-       PakfirePackage pkg = self->package;
-       pakfire_package_filelist_remove(pkg);
+       // Create a new filelist
+       PakfireFilelist filelist;
+
+       int r = pakfire_filelist_create(&filelist);
+       if (r) {
+               errno = -r;
+               PyErr_SetFromErrno(PyExc_OSError);
+
+               return -1;
+       }
 
        const int length = PySequence_Length(value);
        for (int i = 0; i < length; i++) {
@@ -759,21 +770,43 @@ static int Package_set_filelist(PackageObject* self, PyObject* value) {
 
                if (!PyUnicode_Check(item)) {
                        Py_DECREF(item);
+                       pakfire_filelist_unref(filelist);
 
                        PyErr_SetString(PyExc_AttributeError, "Expected a string");
                        return -1;
                }
 
                const char* name = PyUnicode_AsUTF8(item);
+               Py_DECREF(item);
+
+               // Create a new file
+               PakfireFile file;
 
-               PakfireFile file = pakfire_package_filelist_append(pkg, name);
+               r = pakfire_file_create(&file);
+               if (r) {
+                       errno = -r;
+                       PyErr_SetFromErrno(PyExc_OSError);
+                       pakfire_filelist_unref(filelist);
+                       return -1;
+               }
 
-# if 0
-               PakfireFile file = pakfire_package_filelist_append(pkg);
+               // Set the name
                pakfire_file_set_name(file, name);
-#endif
 
-               Py_DECREF(item);
+               // Append the file to the filelist
+               pakfire_filelist_append(filelist, file);
+               pakfire_file_unref(file);
+       }
+
+       // Set filelist
+       r = pakfire_package_set_filelist(self->package, filelist);
+       pakfire_filelist_unref(filelist);
+
+       if (r) {
+               errno = -r;
+               PyErr_SetFromErrno(PyExc_OSError);
+
+               return -1;
        }
 
        return 0;
index 154d488ff13b4cc18e609108e435a2ab04a1789a..0e7f29c9d1da7e1c3f9582ececeb53f5d87aadc9 100644 (file)
@@ -38,6 +38,7 @@
 #include <pakfire/archive.h>
 #include <pakfire/errno.h>
 #include <pakfire/file.h>
+#include <pakfire/filelist.h>
 #include <pakfire/i18n.h>
 #include <pakfire/key.h>
 #include <pakfire/logging.h>
@@ -66,7 +67,7 @@ struct _PakfireArchive {
        int format;
        PakfireParser parser;
 
-       PakfireFile filelist;
+       PakfireFilelist filelist;
        archive_checksum_t** checksums;
 
        // Signatures
@@ -397,12 +398,12 @@ static int pakfire_archive_parse_entry_filelist(PakfireArchive archive,
        data[data_size] = '\0';
 
        if (data_size > 0) {
-               archive->filelist = pakfire_file_parse_from_file(data, archive->format);
+               r = pakfire_filelist_create_from_file(&archive->filelist, data, archive->format);
        }
 
        pakfire_free(data);
 
-       return 0;
+       return r;
 }
 
 static int pakfire_archive_parse_entry_checksums(PakfireArchive archive,
@@ -849,7 +850,7 @@ PAKFIRE_EXPORT unsigned int pakfire_archive_get_format(PakfireArchive archive) {
        return archive->format;
 }
 
-PAKFIRE_EXPORT PakfireFile pakfire_archive_get_filelist(PakfireArchive archive) {
+PAKFIRE_EXPORT PakfireFilelist pakfire_archive_get_filelist(PakfireArchive archive) {
        return archive->filelist;
 }
 
@@ -1361,11 +1362,7 @@ PAKFIRE_EXPORT PakfirePackage pakfire_archive_make_package(PakfireArchive archiv
        }
 
        // Import filelist
-       PakfireFile file = pakfire_archive_get_filelist(archive);
-       while (file) {
-               pakfire_package_filelist_append(pkg, pakfire_file_get_name(file));
-               file = pakfire_file_get_next(file);
-       }
+       pakfire_package_set_filelist(pkg, archive->filelist);
 
        return pkg;
 }
index 6a7492256566238ca19d7f2bcf9033609ffdb742..e0b4ef3c1d24959e06f263bb213b2d6dbbc4c8c6 100644 (file)
@@ -631,12 +631,16 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, Pakfire
        int r;
 
        // Get the filelist from the archive
-       PakfireFile file = pakfire_archive_get_filelist(archive);
-       if (!file) {
+       PakfireFilelist filelist = pakfire_archive_get_filelist(archive);
+       if (!filelist) {
                ERROR(db->pakfire, "Could not fetch filelist from archive\n");
                return 1;
        }
 
+       // Nothing to do if the list is empty
+       if (pakfire_filelist_is_empty(filelist))
+               goto END;
+
        const char* sql = "INSERT INTO files(pkg, name, size, type, config, datafile, mode, "
                "user, 'group', hash1, mtime, capabilities) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
 
@@ -648,11 +652,14 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, Pakfire
                goto END;
        }
 
-       while (file) {
+       for (unsigned int i = 0; i < pakfire_filelist_size(filelist); i++) {
+               PakfireFile file = pakfire_filelist_get(filelist, i);
+
                // Bind package ID
                r = sqlite3_bind_int64(stmt, 1, id);
                if (r) {
                        ERROR(db->pakfire, "Could not bind id: %s\n", sqlite3_errmsg(db->handle));
+                       pakfire_file_unref(file);
                        goto END;
                }
 
@@ -662,6 +669,7 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, Pakfire
                r = sqlite3_bind_text(stmt, 2, name, -1, NULL);
                if (r) {
                        ERROR(db->pakfire, "Could not bind name: %s\n", sqlite3_errmsg(db->handle));
+                       pakfire_file_unref(file);
                        goto END;
                }
 
@@ -671,6 +679,7 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, Pakfire
                r = sqlite3_bind_int64(stmt, 3, size);
                if (r) {
                        ERROR(db->pakfire, "Could not bind size: %s\n", sqlite3_errmsg(db->handle));
+                       pakfire_file_unref(file);
                        goto END;
                }
 
@@ -680,6 +689,7 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, Pakfire
                r = sqlite3_bind_null(stmt, 4);
                if (r) {
                        ERROR(db->pakfire, "Could not bind type: %s\n", sqlite3_errmsg(db->handle));
+                       pakfire_file_unref(file);
                        goto END;
                }
 
@@ -687,6 +697,7 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, Pakfire
                r = sqlite3_bind_null(stmt, 5);
                if (r) {
                        ERROR(db->pakfire, "Could not bind config: %s\n", sqlite3_errmsg(db->handle));
+                       pakfire_file_unref(file);
                        goto END;
                }
 
@@ -694,6 +705,7 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, Pakfire
                r = sqlite3_bind_null(stmt, 6);
                if (r) {
                        ERROR(db->pakfire, "Could not bind datafile: %s\n", sqlite3_errmsg(db->handle));
+                       pakfire_file_unref(file);
                        goto END;
                }
 
@@ -703,6 +715,7 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, Pakfire
                r = sqlite3_bind_int64(stmt, 7, mode);
                if (r) {
                        ERROR(db->pakfire, "Could not bind mode: %s\n", sqlite3_errmsg(db->handle));
+                       pakfire_file_unref(file);
                        goto END;
                }
 
@@ -712,6 +725,7 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, Pakfire
                r = sqlite3_bind_text(stmt, 8, user, -1, NULL);
                if (r) {
                        ERROR(db->pakfire, "Could not bind user: %s\n", sqlite3_errmsg(db->handle));
+                       pakfire_file_unref(file);
                        goto END;
                }
 
@@ -721,6 +735,7 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, Pakfire
                r = sqlite3_bind_text(stmt, 9, group, -1, NULL);
                if (r) {
                        ERROR(db->pakfire, "Could not bind group: %s\n", sqlite3_errmsg(db->handle));
+                       pakfire_file_unref(file);
                        goto END;
                }
 
@@ -730,6 +745,7 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, Pakfire
                r = sqlite3_bind_text(stmt, 10, chksum, -1, NULL);
                if (r) {
                        ERROR(db->pakfire, "Could not bind hash1: %s\n", sqlite3_errmsg(db->handle));
+                       pakfire_file_unref(file);
                        goto END;
                }
 
@@ -739,6 +755,7 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, Pakfire
                r = sqlite3_bind_int64(stmt, 11, mtime);
                if (r) {
                        ERROR(db->pakfire, "Could not bind mtime: %s\n", sqlite3_errmsg(db->handle));
+                       pakfire_file_unref(file);
                        goto END;
                }
 
@@ -746,6 +763,7 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, Pakfire
                r = sqlite3_bind_null(stmt, 12);
                if (r) {
                        ERROR(db->pakfire, "Could not bind capabilities: %s\n", sqlite3_errmsg(db->handle));
+                       pakfire_file_unref(file);
                        goto END;
                }
 
@@ -755,7 +773,7 @@ static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, Pakfire
                } while (r == SQLITE_BUSY);
 
                // Move on to next file
-               file = pakfire_file_get_next(file);
+               pakfire_file_unref(file);
 
                // Reset bound values
                sqlite3_reset(stmt);
@@ -768,6 +786,8 @@ END:
        if (stmt)
                sqlite3_finalize(stmt);
 
+       pakfire_filelist_unref(filelist);
+
        return r;
 }
 
index 42119a0c1e7d961c53dd601f2f1bbcba0785327d..f15bdac6f75c7a481794043adcd9b6f027738ec9 100644 (file)
@@ -19,6 +19,7 @@
 #############################################################################*/
 
 #include <assert.h>
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <pakfire/private.h>
 #include <pakfire/util.h>
 
-PAKFIRE_EXPORT PakfireFile pakfire_file_create() {
-       PakfireFile file = pakfire_calloc(1, sizeof(*file));
-       if (file) {
-               file->name = NULL;
+struct _PakfireFile {
+       int nrefs;
 
-               file->prev = NULL;
-               file->next = NULL;
-       }
+       char* name;
+       char type;
+       ssize_t size;
 
-       return file;
-}
+       char* user;
+       char* group;
 
-PAKFIRE_EXPORT PakfireFile pakfire_file_ref(PakfireFile file) {
-       return file;    
-}
+       mode_t mode;
+       time_t time;
 
-PAKFIRE_EXPORT PakfireFile pakfire_file_unref(PakfireFile file) {
-       return file;
+       char* chksum;
+
+       #warning TODO capabilities, config, data
+       // capabilities
+       //int is_configfile;
+       //int is_datafile;
+};
+
+PAKFIRE_EXPORT int pakfire_file_create(PakfireFile* file) {
+       PakfireFile f = pakfire_calloc(1, sizeof(*f));
+       if (!f)
+               return -ENOMEM;
+
+       f->nrefs = 1;
+
+       *file = f;
+       return 0;
 }
 
-PAKFIRE_EXPORT void pakfire_file_free(PakfireFile file) {
+static void pakfire_file_free(PakfireFile file) {
        if (file->name)
                pakfire_free(file->name);
-
        if (file->user)
                pakfire_free(file->user);
        if (file->group)
                pakfire_free(file->group);
-
-       // Update pointers in the previous and next element in the list.
-       if (file->next)
-               file->next->prev = NULL;
-       if (file->prev)
-               file->prev->next = NULL;
+       if (file->chksum)
+               pakfire_free(file->chksum);
 
        pakfire_free(file);
 }
 
-PAKFIRE_EXPORT void pakfire_file_free_all(PakfireFile file) {
-       file = pakfire_file_get_first(file);
+PAKFIRE_EXPORT PakfireFile pakfire_file_ref(PakfireFile file) {
+       file->nrefs++;
 
-       while (file) {
-               PakfireFile next = file->next;
-               pakfire_file_free(file);
+       return file;
+}
 
-               file = next;
-       }
+PAKFIRE_EXPORT PakfireFile pakfire_file_unref(PakfireFile file) {
+       if (--file->nrefs > 0)
+               return file;
+
+       pakfire_file_free(file);
+       return NULL;
 }
 
 PAKFIRE_EXPORT int pakfire_file_cmp(PakfireFile file1, PakfireFile file2) {
@@ -88,96 +99,6 @@ PAKFIRE_EXPORT int pakfire_file_cmp(PakfireFile file1, PakfireFile file2) {
        return strcmp(name1, name2);
 }
 
-PAKFIRE_EXPORT void pakfire_file_swap(PakfireFile file1, PakfireFile file2) {
-       PakfireFile file_prev = file1->prev;
-       PakfireFile file_next = file2->next;
-
-       if (file_prev)
-               file_prev->next = file2;
-       file2->prev = file_prev;
-
-       if (file_next)
-               file_next->prev = file1;
-       file1->next = file_next;
-
-       file2->next = file1;
-       file1->prev = file2;
-}
-
-PAKFIRE_EXPORT PakfireFile pakfire_file_sort(PakfireFile head) {
-       unsigned int count = pakfire_file_count(head);
-
-       for (unsigned int i = 0; i < count; i++) {
-               PakfireFile file = head;
-               PakfireFile next = pakfire_file_get_next(file);
-
-               while (next) {
-                       if (pakfire_file_cmp(file, next) > 0) {
-                               if (head == file)
-                                       head = next;
-
-                               pakfire_file_swap(file, next);
-                       }
-
-                       file = next;
-                       next = pakfire_file_get_next(file);
-               }
-       }
-
-       return head;
-}
-
-PAKFIRE_EXPORT PakfireFile pakfire_file_get_prev(PakfireFile file) {
-       return file->prev;
-}
-
-PAKFIRE_EXPORT PakfireFile pakfire_file_get_next(PakfireFile file) {
-       return file->next;
-}
-
-PAKFIRE_EXPORT PakfireFile pakfire_file_get_first(PakfireFile file) {
-       if (file->prev)
-               return pakfire_file_get_first(file->prev);
-
-       return file;
-}
-
-PAKFIRE_EXPORT PakfireFile pakfire_file_get_last(PakfireFile file) {
-       if (file->next)
-               return pakfire_file_get_last(file->next);
-
-       return file;
-}
-
-static PakfireFile __pakfire_file_append(PakfireFile file, PakfireFile appended_file) {
-       // Get the last file in the queue.
-       file = pakfire_file_get_last(file);
-
-       // Set the links.
-       file->next = appended_file;
-       appended_file->prev = file;
-
-       return appended_file;
-}
-
-PAKFIRE_EXPORT PakfireFile pakfire_file_append(PakfireFile file) {
-       // Create a new file object.
-       PakfireFile appended_file = pakfire_file_create();
-
-       return __pakfire_file_append(file, appended_file);
-}
-
-PAKFIRE_EXPORT unsigned int pakfire_file_count(PakfireFile file) {
-       unsigned int counter = 0;
-
-       while (file) {
-               file = pakfire_file_get_next(file);
-               ++counter;
-       }
-
-       return counter;
-}
-
 static char pakfire_file_sprintf_type(PakfireFile file) {
        if (pakfire_file_is_dir(file))
                return 'd';
@@ -254,6 +175,14 @@ PAKFIRE_EXPORT void pakfire_file_set_name(PakfireFile file, const char* name) {
        }
 }
 
+PAKFIRE_EXPORT char* pakfire_file_get_dirname(PakfireFile file) {
+       return pakfire_dirname(file->name);
+}
+
+PAKFIRE_EXPORT char* pakfire_file_get_basename(PakfireFile file) {
+       return pakfire_basename(file->name);
+}
+
 PAKFIRE_EXPORT char pakfire_file_get_type(PakfireFile file) {
        return file->type;
 }
@@ -333,151 +262,3 @@ PAKFIRE_EXPORT const char* pakfire_file_get_chksum(PakfireFile file) {
 PAKFIRE_EXPORT void pakfire_file_set_chksum(PakfireFile file, const char* chksum) {
        file->chksum = pakfire_strdup(chksum);
 }
-
-static PakfireFile pakfire_file_parse_line(char* line, unsigned int format) {
-       unsigned int i = 0;
-
-       PakfireFile file = pakfire_file_create();
-       ssize_t size;
-       mode_t mode;
-       time_t time;
-
-       unsigned int bytes_read = 0;
-
-       char* word = strtok(line, " ");
-       while (word) {
-               if (format >= 4) {
-                       switch (i) {
-                               // type
-                               case 0:
-                                       pakfire_file_set_type(file, *word);
-                                       break;
-
-                               // size
-                               case 1:
-                                       size = atoi(word);
-                                       pakfire_file_set_size(file, size);
-                                       break;
-
-                               // user
-                               case 2:
-                                       pakfire_file_set_user(file, word);
-                                       break;
-
-                               // group
-                               case 3:
-                                       pakfire_file_set_group(file, word);
-                                       break;
-
-                               // mode
-                               case 4:
-                                       mode = atoi(word);
-                                       pakfire_file_set_mode(file, mode);
-                                       break;
-
-                               // time
-                               case 5:
-                                       time = atoi(word);
-                                       pakfire_file_set_time(file, time);
-                                       break;
-
-                               // checksum
-                               case 6:
-                                       pakfire_file_set_chksum(file, word);
-                                       break;
-
-                               // name
-                               #warning handle filenames with spaces
-                               case 8:
-                                       pakfire_file_set_name(file, line + bytes_read);
-                                       break;
-                       }
-
-               } else if (format >= 3) {
-                       switch (i) {
-                               // name
-                               case 0:
-                                       pakfire_file_set_name(file, word);
-                                       break;
-
-                               // type
-                               case 1:
-                                       pakfire_file_set_type(file, *word);
-                                       break;
-
-                               // size
-                               case 2:
-                                       size = atoi(word);
-                                       pakfire_file_set_size(file, size);
-                                       break;
-
-                               // user
-                               case 3:
-                                       pakfire_file_set_user(file, word);
-                                       break;
-
-                               // group
-                               case 4:
-                                       pakfire_file_set_group(file, word);
-                                       break;
-
-                               // mode
-                               case 5:
-                                       mode = atoi(word);
-                                       pakfire_file_set_mode(file, mode);
-                                       break;
-
-                               // time
-                               case 6:
-                                       time = atoi(word);
-                                       pakfire_file_set_time(file, time);
-                                       break;
-
-                               // checksum
-                               case 7:
-                                       pakfire_file_set_chksum(file, word);
-                                       break;
-                       }
-               }
-
-               // Count the bytes of the line that have been processed so far
-               // (Skip all padding spaces)
-               bytes_read += strlen(word) + 1;
-               while (*(line + bytes_read) == ' ')
-                       bytes_read += 1;
-
-               word = strtok(NULL, " ");
-               ++i;
-       }
-
-       return file;
-}
-
-PAKFIRE_EXPORT PakfireFile pakfire_file_parse_from_file(const char* list, unsigned int format) {
-       PakfireFile head = NULL;
-
-       char* plist = (char *)list;
-       char line[32 * 1024];
-
-       for (;;) {
-               line[0] = '\0';
-
-               pakfire_sgets(line, sizeof(line), &plist);
-               pakfire_remove_trailing_newline(line);
-
-               if (*line == '\0')
-                       break;
-
-               PakfireFile file = pakfire_file_parse_line(line, format);
-
-               if (!file)
-                       continue;
-
-               if (head)
-                       file = __pakfire_file_append(head, file);
-               else
-                       head = file;
-       }
-
-       return head;
-}
index 3afd1c4f04b7d508ac0cd8ca0d30d86134949493..35720800a41efa111ce35b609a2802e8633b417d 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <errno.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include <pakfire/file.h>
 #include <pakfire/filelist.h>
@@ -81,6 +82,10 @@ PAKFIRE_EXPORT size_t pakfire_filelist_size(PakfireFilelist list) {
        return list->size;
 }
 
+PAKFIRE_EXPORT int pakfire_filelist_is_empty(PakfireFilelist list) {
+       return list->size == 0;
+}
+
 PAKFIRE_EXPORT void pakfire_filelist_clear(PakfireFilelist list) {
        if (!list->elements)
                return;
@@ -99,7 +104,7 @@ PAKFIRE_EXPORT PakfireFile pakfire_filelist_get(PakfireFilelist list, size_t ind
        if (index >= list->size)
                return NULL;
 
-       return list->elements[index];
+       return pakfire_file_ref(list->elements[index]);
 }
 
 PAKFIRE_EXPORT int pakfire_filelist_append(PakfireFilelist list, PakfireFile file) {
@@ -114,3 +119,169 @@ PAKFIRE_EXPORT int pakfire_filelist_append(PakfireFilelist list, PakfireFile fil
 
        return 0;
 }
+
+PAKFIRE_EXPORT void pakfire_filelist_sort(PakfireFilelist list) {
+       // XXX TODO
+}
+
+static int pakfire_filelist_parse_line(PakfireFile* file, char* line, unsigned int format) {
+       unsigned int i = 0;
+
+       // Allocate file
+       int r = pakfire_file_create(file);
+       if (r)
+               return r;
+
+       ssize_t size;
+       mode_t mode;
+       time_t time;
+
+       unsigned int bytes_read = 0;
+
+       char* word = strtok(line, " ");
+       while (word) {
+               if (format >= 4) {
+                       switch (i) {
+                               // type
+                               case 0:
+                                       pakfire_file_set_type(*file, *word);
+                                       break;
+
+                               // size
+                               case 1:
+                                       size = atoi(word);
+                                       pakfire_file_set_size(*file, size);
+                                       break;
+
+                               // user
+                               case 2:
+                                       pakfire_file_set_user(*file, word);
+                                       break;
+
+                               // group
+                               case 3:
+                                       pakfire_file_set_group(*file, word);
+                                       break;
+
+                               // mode
+                               case 4:
+                                       mode = atoi(word);
+                                       pakfire_file_set_mode(*file, mode);
+                                       break;
+
+                               // time
+                               case 5:
+                                       time = atoi(word);
+                                       pakfire_file_set_time(*file, time);
+                                       break;
+
+                               // checksum
+                               case 6:
+                                       pakfire_file_set_chksum(*file, word);
+                                       break;
+
+                               // name
+                               #warning handle filenames with spaces
+                               case 8:
+                                       pakfire_file_set_name(*file, line + bytes_read);
+                                       break;
+                       }
+
+               } else if (format >= 3) {
+                       switch (i) {
+                               // name
+                               case 0:
+                                       pakfire_file_set_name(*file, word);
+                                       break;
+
+                               // type
+                               case 1:
+                                       pakfire_file_set_type(*file, *word);
+                                       break;
+
+                               // size
+                               case 2:
+                                       size = atoi(word);
+                                       pakfire_file_set_size(*file, size);
+                                       break;
+
+                               // user
+                               case 3:
+                                       pakfire_file_set_user(*file, word);
+                                       break;
+
+                               // group
+                               case 4:
+                                       pakfire_file_set_group(*file, word);
+                                       break;
+
+                               // mode
+                               case 5:
+                                       mode = atoi(word);
+                                       pakfire_file_set_mode(*file, mode);
+                                       break;
+
+                               // time
+                               case 6:
+                                       time = atoi(word);
+                                       pakfire_file_set_time(*file, time);
+                                       break;
+
+                               // checksum
+                               case 7:
+                                       pakfire_file_set_chksum(*file, word);
+                                       break;
+                       }
+               }
+
+               // Count the bytes of the line that have been processed so far
+               // (Skip all padding spaces)
+               bytes_read += strlen(word) + 1;
+               while (*(line + bytes_read) == ' ')
+                       bytes_read += 1;
+
+               word = strtok(NULL, " ");
+               ++i;
+       }
+
+       return 0;
+}
+
+int pakfire_filelist_create_from_file(PakfireFilelist* list, const char* data, unsigned int format) {
+       int r = pakfire_filelist_create(list);
+       if (r)
+               return r;
+
+       PakfireFile file = NULL;
+
+       char* p = (char *)data;
+       char line[32 * 1024];
+
+       for (;;) {
+               line[0] = '\0';
+
+               pakfire_sgets(line, sizeof(line), &p);
+               pakfire_remove_trailing_newline(line);
+
+               if (*line == '\0')
+                       break;
+
+               int r = pakfire_filelist_parse_line(&file, line, format);
+               if (r)
+                       goto ERROR;
+
+               // Append file
+               r = pakfire_filelist_append(*list, file);
+               if (r)
+                       goto ERROR;
+
+               pakfire_file_unref(file);
+       }
+
+       return 0;
+
+ERROR:
+       pakfire_filelist_unref(*list);
+
+       return 1;
+}
index 4270732f6af17d3d59f66d0ddabed930556f8922..a2283b8e02b13fadaea521121e77965324435a43 100644 (file)
@@ -58,7 +58,7 @@ const char* pakfire_archive_get_path(PakfireArchive archive);
 
 unsigned int pakfire_archive_get_format(PakfireArchive archive);
 
-PakfireFile pakfire_archive_get_filelist(PakfireArchive archive);
+PakfireFilelist pakfire_archive_get_filelist(PakfireArchive archive);
 
 pakfire_archive_verify_status_t pakfire_archive_verify(PakfireArchive archive);
 const char* pakfire_archive_verify_strerror(pakfire_archive_verify_status_t status);
index ac813245c80a737f672facf2760cc2803cd617a8..956d377d9492392010a083df0de2a7c5aca8dea6 100644 (file)
 
 #include <pakfire/types.h>
 
-PakfireFile pakfire_file_create();
+int pakfire_file_create(PakfireFile* file);
 
 PakfireFile pakfire_file_ref(PakfireFile file);
 PakfireFile pakfire_file_unref(PakfireFile file);
 
-void pakfire_file_free(PakfireFile file);
-void pakfire_file_free_all(PakfireFile file);
-
 int pakfire_file_cmp(PakfireFile file1, PakfireFile file2);
-void pakfire_file_swap(PakfireFile file1, PakfireFile file2);
-PakfireFile pakfire_file_sort(PakfireFile head);
-
-PakfireFile pakfire_file_get_prev(PakfireFile file);
-PakfireFile pakfire_file_get_next(PakfireFile file);
-PakfireFile pakfire_file_get_first(PakfireFile file);
-PakfireFile pakfire_file_get_last(PakfireFile file);
-
-PakfireFile pakfire_file_append(PakfireFile file);
-
-unsigned int pakfire_file_count(PakfireFile file);
-
 void pakfire_file_sprintf(PakfireFile file, char* str, size_t len);
 
 const char* pakfire_file_get_name(PakfireFile file);
 void pakfire_file_set_name(PakfireFile file, const char* name);
+char* pakfire_file_get_dirname(PakfireFile file);
+char* pakfire_file_get_basename(PakfireFile file);
 
 char pakfire_file_get_type(PakfireFile file);
 void pakfire_file_set_type(PakfireFile file, char type);
@@ -83,30 +70,4 @@ void pakfire_file_set_chksum(PakfireFile file, const char* chksum);
 
 PakfireFile pakfire_file_parse_from_file(const char* list, unsigned int format);
 
-#ifdef PAKFIRE_PRIVATE
-
-struct _PakfireFile {
-       char* name;
-       char type;
-       ssize_t size;
-
-       char* user;
-       char* group;
-
-       mode_t mode;
-       time_t time;
-
-       char* chksum;
-
-       #warning TODO capabilities, config, data
-       // capabilities
-       //int is_configfile;
-       //int is_datafile;
-
-       PakfireFile prev;
-       PakfireFile next;
-};
-
-#endif
-
 #endif /* PAKFIRE_FILE_H */
index 20e176745ece4612351b12b8f215e89791b682a8..6d6bdc329032f890b792beb171142adf3cb9410a 100644 (file)
@@ -29,9 +29,18 @@ PakfireFilelist pakfire_filelist_ref(PakfireFilelist list);
 PakfireFilelist pakfire_filelist_unref(PakfireFilelist list);
 
 size_t pakfire_filelist_size(PakfireFilelist list);
+int pakfire_filelist_is_empty(PakfireFilelist list);
 void pakfire_filelist_clear(PakfireFilelist list);
 
 PakfireFile pakfire_filelist_get(PakfireFilelist list, size_t index);
 int pakfire_filelist_append(PakfireFilelist list, PakfireFile file);
 
+void pakfire_filelist_sort(PakfireFilelist list);
+
+#ifdef PAKFIRE_PRIVATE
+
+int pakfire_filelist_create_from_file(PakfireFilelist* list, const char* data, unsigned int format);
+
+#endif
+
 #endif /* PAKFIRE_FILELIST_H */
index 2f17aba4a953b1e676d3d141ff6762b5bd6b7bad..56f6c2d96370a1e671ffbd3d0cbe10e6e271775a 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <solv/pooltypes.h>
 
+#include <pakfire/filelist.h>
 #include <pakfire/relation.h>
 #include <pakfire/relationlist.h>
 #include <pakfire/types.h>
@@ -118,12 +119,8 @@ int pakfire_package_is_cached(PakfirePackage pkg);
 char* pakfire_package_get_cache_path(PakfirePackage pkg);
 char* pakfire_package_get_cache_full_path(PakfirePackage pkg);
 
-PakfireFile pakfire_package_get_filelist(PakfirePackage pkg);
-PakfireFile pakfire_package_filelist_append(PakfirePackage pkg, const char* filename);
-#if 0
-PakfireFile pakfire_package_filelist_append(PakfirePackage pkg);
-#endif
-void pakfire_package_filelist_remove(PakfirePackage pkg);
+PakfireFilelist pakfire_package_get_filelist(PakfirePackage pkg);
+int pakfire_package_set_filelist(PakfirePackage pkg, PakfireFilelist filelist);
 
 enum pakfire_package_keynames {
     PAKFIRE_PKG,
index 67c71f109b4c88d6146dcabb643bad0d08b8e118..ef5621c81b7f72b5289a80983f95a573f46155b4 100644 (file)
@@ -87,12 +87,8 @@ global:
        pakfire_db_unref;
 
        # file
-       pakfire_file_append;
        pakfire_file_cmp;
-       pakfire_file_count;
        pakfire_file_create;
-       pakfire_file_free;
-       pakfire_file_free_all;
        pakfire_file_get_first;
        pakfire_file_get_group;
        pakfire_file_get_last;
@@ -114,8 +110,19 @@ global:
        pakfire_file_set_time;
        pakfire_file_set_user;
        pakfire_file_sprintf;
-       pakfire_file_sort;
-       pakfire_file_swap;
+       pakfire_file_ref;
+       pakfire_file_unref;
+
+       # filelist
+       pakfire_filelist_append;
+       pakfire_filelist_clear;
+       pakfire_filelist_create;
+       pakfire_filelist_get;
+       pakfire_filelist_is_empty;
+       pakfire_filelist_ref;
+       pakfire_filelist_size;
+       pakfire_filelist_sort;
+       pakfire_filelist_unref;
 
        # key
        pakfire_key_create;
@@ -156,8 +163,6 @@ global:
        pakfire_package_create;
        pakfire_package_create2;
        pakfire_package_dump;
-       pakfire_package_filelist_append;
-       pakfire_package_filelist_remove;
        pakfire_package_get_arch;
        pakfire_package_get_buildhost;
        pakfire_package_get_buildtime;
@@ -205,6 +210,7 @@ global:
        pakfire_package_set_description;
        pakfire_package_set_downloadsize;
        pakfire_package_set_evr;
+       pakfire_package_set_filelist;
        pakfire_package_set_filename;
        pakfire_package_set_groups;
        pakfire_package_set_installsize;
index c8242d9e38840be55052dedd5637c9693fc60298..b8c47cded9ba1261b6dff31fdaf60277e2dce2a9 100644 (file)
@@ -32,6 +32,7 @@
 #include <pakfire/archive.h>
 #include <pakfire/constants.h>
 #include <pakfire/file.h>
+#include <pakfire/filelist.h>
 #include <pakfire/i18n.h>
 #include <pakfire/logging.h>
 #include <pakfire/package.h>
@@ -45,7 +46,7 @@
 struct _PakfirePackage {
        Pakfire pakfire;
        Id id;
-       PakfireFile filelist;
+       PakfireFilelist filelist;
        int nrefs;
 };
 
@@ -69,6 +70,12 @@ PAKFIRE_EXPORT PakfirePackage pakfire_package_create(Pakfire pakfire, Id id) {
 
                // Initialize reference counter
                pkg->nrefs = 1;
+
+               // Initialize filelist
+               int r = pakfire_filelist_create(&pkg->filelist);
+               if (r) {
+                       // XXX what do we do here?
+               }
        }
 
        return pkg;
@@ -88,9 +95,9 @@ PAKFIRE_EXPORT PakfirePackage pakfire_package_create2(Pakfire pakfire, PakfireRe
 
 static void pakfire_package_free(PakfirePackage pkg) {
        DEBUG(pkg->pakfire, "Releasing Package at %p\n", pkg);
-       pakfire_unref(pkg->pakfire);
 
-       pakfire_package_filelist_remove(pkg);
+       pakfire_filelist_unref(pkg->filelist);
+       pakfire_unref(pkg->pakfire);
        pakfire_free(pkg);
 }
 
@@ -847,18 +854,23 @@ PAKFIRE_EXPORT char* pakfire_package_dump(PakfirePackage pkg, int flags) {
        }
 
        if (flags & PAKFIRE_PKG_DUMP_FILELIST) {
-               PakfireFile file = pakfire_package_get_filelist(pkg);
+               PakfireFilelist filelist = pakfire_package_get_filelist(pkg);
+
+               const char* prefix = _("Filelist");
+
+               for (unsigned int i = 0; i < pakfire_filelist_size(filelist); i++) {
+                       PakfireFile file = pakfire_filelist_get(filelist, i);
 
-               char* prefix = _("Filelist");
-               while (file) {
                        const char* name = pakfire_file_get_name(file);
                        pakfire_package_dump_add_line(&string, prefix, name);
 
-                       file = pakfire_file_get_next(file);
+                       pakfire_file_unref(file);
 
-                       // Only prefix the first line.
+                       // Only prefix the first line
                        prefix = NULL;
                }
+
+               pakfire_filelist_unref(filelist);
        }
 
        return string;
@@ -902,14 +914,14 @@ PAKFIRE_EXPORT PakfireArchive pakfire_package_get_archive(PakfirePackage pkg) {
        return archive;
 }
 
-static PakfireFile pakfire_package_fetch_legacy_filelist(PakfirePackage pkg) {
+static int pakfire_package_fetch_legacy_filelist(PakfirePackage pkg) {
        pakfire_package_internalize_repo(pkg);
 
-       PakfireFile file = NULL;
        PakfireRepo repo = pakfire_package_get_repo(pkg);
        Solvable* s = get_solvable(pkg);
        Pool* p = pakfire_package_get_solv_pool(pkg);
        Repo* r = pakfire_repo_get_repo(repo);
+       pakfire_repo_unref(repo);
 
        int found_marker = 0;
 
@@ -919,13 +931,20 @@ static PakfireFile pakfire_package_fetch_legacy_filelist(PakfirePackage pkg) {
                const char* filename = pool_dep2str(p, id);
 
                if (found_marker) {
-                       if (file) {
-                               file = pakfire_file_append(file);
-                       } else {
-                               file = pakfire_file_create();
-                       }
+                       PakfireFile file;
 
+                       int r = pakfire_file_create(&file);
+                       if (r)
+                               return r;
+
+                       // Set name
                        pakfire_file_set_name(file, filename);
+
+                       r = pakfire_filelist_append(pkg->filelist, file);
+                       if (r)
+                               return r;
+
+                       pakfire_file_unref(file);
                        continue;
                }
 
@@ -933,22 +952,14 @@ static PakfireFile pakfire_package_fetch_legacy_filelist(PakfirePackage pkg) {
                        ++found_marker;
        }
 
-       if (file) {
-               file = pakfire_file_get_first(file);
-
-               // Sort the output
-               file = pakfire_file_sort(file);
-       }
-
-       pakfire_repo_unref(repo);
-
-       return file;
+       return 0;
 }
 
-static PakfireFile pakfire_package_fetch_filelist(PakfirePackage pkg) {
+static int pakfire_package_fetch_filelist(PakfirePackage pkg) {
+       int r;
+
        pakfire_package_internalize_repo(pkg);
 
-       PakfireFile file = NULL;
        Pool* pool = pakfire_package_get_solv_pool(pkg);
        Repo* repo = pakfire_package_solv_repo(pkg);
        Id handle = pakfire_package_get_handle(pkg);
@@ -956,64 +967,80 @@ static PakfireFile pakfire_package_fetch_filelist(PakfirePackage pkg) {
        Dataiterator di;
        dataiterator_init(&di, pool, repo, handle,
                SOLVABLE_FILELIST, NULL, SEARCH_FILES | SEARCH_COMPLETE_FILELIST);
+
        while (dataiterator_step(&di)) {
-               if (file) {
-                       file = pakfire_file_append(file);
-               } else {
-                       file = pakfire_file_create();
-               }
+               PakfireFile file;
 
-               pakfire_file_set_name(file, di.kv.str);
-       }
-       dataiterator_free(&di);
+               r = pakfire_file_create(&file);
+               if (r)
+                       return r;
 
-       if (file) {
-               file = pakfire_file_get_first(file);
+               pakfire_file_set_name(file, di.kv.str);
 
-               // Sort the result.
-               file = pakfire_file_sort(file);
+               // Append to filelist
+               pakfire_filelist_append(pkg->filelist, file);
+               pakfire_file_unref(file);
        }
+       dataiterator_free(&di);
 
        // If the file list is empty, we fall back to read files
        // in the older format.
-       if (!file)
-               file = pakfire_package_fetch_legacy_filelist(pkg);
+       if (pakfire_filelist_is_empty(pkg->filelist)) {
+               r = pakfire_package_fetch_legacy_filelist(pkg);
+               if (r)
+                       return r;
+       }
+
+       // Sort the list
+       pakfire_filelist_sort(pkg->filelist);
 
-       return file;
+       return 0;
 }
 
-PAKFIRE_EXPORT PakfireFile pakfire_package_get_filelist(PakfirePackage pkg) {
+PAKFIRE_EXPORT PakfireFilelist pakfire_package_get_filelist(PakfirePackage pkg) {
        if (!pkg->filelist) {
-               pkg->filelist = pakfire_package_fetch_filelist(pkg);
+               int r = pakfire_filelist_create(&pkg->filelist);
+               if (r)
+                       return NULL;
+
+               r = pakfire_package_fetch_filelist(pkg);
+               if (r) {
+                       pakfire_filelist_unref(pkg->filelist);
+
+                       return NULL;
+               }
        }
 
-       return pkg->filelist;
+       return pakfire_filelist_ref(pkg->filelist);
 }
 
-PAKFIRE_EXPORT PakfireFile pakfire_package_filelist_append(PakfirePackage pkg, const char* filename) {
+PAKFIRE_EXPORT int pakfire_package_set_filelist(PakfirePackage pkg, PakfireFilelist filelist) {
+       // Fetch repodata
        PakfireRepo repo = pakfire_package_get_repo(pkg);
        Repodata* repodata = pakfire_repo_get_repodata(repo);
+       pakfire_repo_unref(repo);
 
        Id handle = pakfire_package_get_handle(pkg);
 
-       char* dirname  = pakfire_dirname(filename);
-       char* basename = pakfire_basename(filename);
+       for (unsigned int i = 0; i < pakfire_filelist_size(filelist); i++) {
+               PakfireFile file = pakfire_filelist_get(filelist, i);
 
-       Id did = repodata_str2dir(repodata, dirname, 1);
-       if (!did)
-               did = repodata_str2dir(repodata, "/", 1);
+               char* basename = pakfire_file_get_basename(file);
+               char* dirname  = pakfire_file_get_dirname(file);
 
-       repodata_add_dirstr(repodata, handle,
-               SOLVABLE_FILELIST, did, basename);
+               // Convert directory into ID
+               Id did = repodata_str2dir(repodata, dirname, 1);
+               if (!did)
+                       did = repodata_str2dir(repodata, "/", 1);
 
-       pakfire_repo_unref(repo);
-       pakfire_free(dirname);
-       pakfire_free(basename);
+               // Add data to list
+               repodata_add_dirstr(repodata, handle,
+                       SOLVABLE_FILELIST, did, basename);
 
-       return NULL;
-}
+               pakfire_file_unref(file);
+               free(basename);
+               free(dirname);
+       }
 
-PAKFIRE_EXPORT void pakfire_package_filelist_remove(PakfirePackage pkg) {
-       if (pkg->filelist)
-               pakfire_file_free_all(pkg->filelist);
+       return 0;
 }