From: Michael Tremer Date: Sun, 24 Jan 2021 16:34:30 +0000 (+0000) Subject: libpakfire: Refactor files X-Git-Tag: 0.9.28~1285^2~809 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5e9463ec3cef2d18bdae2a1d5f70cc37a0cd0c4b;p=pakfire.git libpakfire: Refactor files 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 --- diff --git a/src/_pakfire/package.c b/src/_pakfire/package.c index 3ecd1e523..df1ff161d 100644 --- a/src/_pakfire/package.c +++ b/src/_pakfire/package.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -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; diff --git a/src/libpakfire/archive.c b/src/libpakfire/archive.c index 154d488ff..0e7f29c9d 100644 --- a/src/libpakfire/archive.c +++ b/src/libpakfire/archive.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -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; } diff --git a/src/libpakfire/db.c b/src/libpakfire/db.c index 6a7492256..e0b4ef3c1 100644 --- a/src/libpakfire/db.c +++ b/src/libpakfire/db.c @@ -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; } diff --git a/src/libpakfire/file.c b/src/libpakfire/file.c index 42119a0c1..f15bdac6f 100644 --- a/src/libpakfire/file.c +++ b/src/libpakfire/file.c @@ -19,6 +19,7 @@ #############################################################################*/ #include +#include #include #include #include @@ -32,53 +33,63 @@ #include #include -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; -} diff --git a/src/libpakfire/filelist.c b/src/libpakfire/filelist.c index 3afd1c4f0..35720800a 100644 --- a/src/libpakfire/filelist.c +++ b/src/libpakfire/filelist.c @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -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; +} diff --git a/src/libpakfire/include/pakfire/archive.h b/src/libpakfire/include/pakfire/archive.h index 4270732f6..a2283b8e0 100644 --- a/src/libpakfire/include/pakfire/archive.h +++ b/src/libpakfire/include/pakfire/archive.h @@ -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); diff --git a/src/libpakfire/include/pakfire/file.h b/src/libpakfire/include/pakfire/file.h index ac813245c..956d377d9 100644 --- a/src/libpakfire/include/pakfire/file.h +++ b/src/libpakfire/include/pakfire/file.h @@ -27,31 +27,18 @@ #include -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 */ diff --git a/src/libpakfire/include/pakfire/filelist.h b/src/libpakfire/include/pakfire/filelist.h index 20e176745..6d6bdc329 100644 --- a/src/libpakfire/include/pakfire/filelist.h +++ b/src/libpakfire/include/pakfire/filelist.h @@ -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 */ diff --git a/src/libpakfire/include/pakfire/package.h b/src/libpakfire/include/pakfire/package.h index 2f17aba4a..56f6c2d96 100644 --- a/src/libpakfire/include/pakfire/package.h +++ b/src/libpakfire/include/pakfire/package.h @@ -23,6 +23,7 @@ #include +#include #include #include #include @@ -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, diff --git a/src/libpakfire/libpakfire.sym b/src/libpakfire/libpakfire.sym index 67c71f109..ef5621c81 100644 --- a/src/libpakfire/libpakfire.sym +++ b/src/libpakfire/libpakfire.sym @@ -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; diff --git a/src/libpakfire/package.c b/src/libpakfire/package.c index c8242d9e3..b8c47cded 100644 --- a/src/libpakfire/package.c +++ b/src/libpakfire/package.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -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; }