summaryrefslogtreecommitdiff
path: root/backend/slackpkg.cc
diff options
context:
space:
mode:
Diffstat (limited to 'backend/slackpkg.cc')
-rw-r--r--backend/slackpkg.cc512
1 files changed, 0 insertions, 512 deletions
diff --git a/backend/slackpkg.cc b/backend/slackpkg.cc
deleted file mode 100644
index a750f2e..0000000
--- a/backend/slackpkg.cc
+++ /dev/null
@@ -1,512 +0,0 @@
-#include <bzlib.h>
-#include <sqlite3.h>
-#include <stdlib.h>
-#include <string.h>
-#include <gio/gio.h>
-#include "slackpkg.h"
-#include "utils.h"
-
-namespace katja
-{
-GHashTable *Slackpkg::cat_map = nullptr;
-
-/*
- * katja::Slackpkg::manifest:
- * @job: a #JobData.
- * @tmpl: temporary directory.
- * @filename: manifest filename
- *
- * Parse the manifest file and save the file list in the database.
- */
-void
-Slackpkg::manifest(JobData *job_data, const char *tmpl, char *filename) noexcept
-{
- FILE *manifest;
- int err, read_len;
- unsigned pos;
- char buf[max_buf_size], *path, *pkg_filename, *rest = nullptr, *start;
- char *full_name = nullptr;
- char **line, **lines;
- BZFILE *manifest_bz2;
- GRegex *pkg_expr = nullptr, *file_expr = nullptr;
- GMatchInfo *match_info;
- sqlite3_stmt *statement = nullptr;
-
- path = g_build_filename(tmpl,
- this->get_name(),
- filename,
- nullptr);
- manifest = fopen(path, "rb");
- g_free(path);
-
- if (!manifest)
- {
- return;
- }
- if (!(manifest_bz2 = BZ2_bzReadOpen(&err, manifest, 0, 0, nullptr, 0)))
- {
- goto out;
- }
-
- /* Prepare regular expressions */
- pkg_expr = g_regex_new("^\\|\\|[[:blank:]]+Package:[[:blank:]]+.+\\/(.+)\\.(t[blxg]z$)?",
- static_cast<GRegexCompileFlags> (G_REGEX_OPTIMIZE | G_REGEX_DUPNAMES),
- static_cast<GRegexMatchFlags> (0),
- nullptr);
- file_expr = g_regex_new("^[-bcdlps][-r][-w][-xsS][-r][-w][-xsS][-r][-w]"
- "[-xtT][[:space:]][^[:space:]]+[[:space:]]+"
- "[[:digit:]]+[[:space:]][[:digit:]-]+[[:space:]]"
- "[[:digit:]:]+[[:space:]](?!install\\/|\\.)(.*)",
- static_cast<GRegexCompileFlags> (G_REGEX_OPTIMIZE | G_REGEX_DUPNAMES),
- static_cast<GRegexMatchFlags> (0),
- nullptr);
- if (!(file_expr) || !(pkg_expr))
- {
- goto out;
- }
-
- /* Prepare SQL statements */
- if (sqlite3_prepare_v2(job_data->db,
- "INSERT INTO filelist (full_name, filename) VALUES (@full_name, @filename)",
- -1,
- &statement,
- nullptr) != SQLITE_OK)
- {
- goto out;
- }
-
- sqlite3_exec(job_data->db, "BEGIN TRANSACTION", nullptr, nullptr, nullptr);
- while ((read_len = BZ2_bzRead(&err, manifest_bz2, buf, max_buf_size - 1)))
- {
- if ((err != BZ_OK) && (err != BZ_STREAM_END))
- {
- break;
- }
- buf[read_len] = '\0';
-
- /* Split the read text into lines */
- lines = g_strsplit(buf, "\n", 0);
- if (rest)
- { /* Add to the first line rest characters from the previous read operation */
- start = lines[0];
- lines[0] = g_strconcat(rest, lines[0], nullptr);
- g_free(start);
- g_free(rest);
- }
- if (err != BZ_STREAM_END) /* The last line can be incomplete */
- {
- pos = g_strv_length(lines) - 1;
- rest = lines[pos];
- lines[pos] = nullptr;
- }
- for (line = lines; *line; line++)
- {
- if (g_regex_match(pkg_expr, *line, static_cast<GRegexMatchFlags> (0), &match_info))
- {
- if (g_match_info_get_match_count(match_info) > 2)
- { /* If the extension matches */
- g_free(full_name);
- full_name = g_match_info_fetch(match_info, 1);
- }
- else
- {
- full_name = nullptr;
- }
- }
- g_match_info_free(match_info);
-
- match_info = nullptr;
- if (full_name && g_regex_match(file_expr, *line, static_cast<GRegexMatchFlags> (0), &match_info))
- {
- pkg_filename = g_match_info_fetch(match_info, 1);
- sqlite3_bind_text(statement, 1, full_name, -1, SQLITE_TRANSIENT);
- sqlite3_bind_text(statement, 2, pkg_filename, -1, SQLITE_TRANSIENT);
- sqlite3_step(statement);
- sqlite3_clear_bindings(statement);
- sqlite3_reset(statement);
- g_free(pkg_filename);
- }
- g_match_info_free(match_info);
- }
- g_strfreev(lines);
- }
-
- sqlite3_exec(job_data->db, "END TRANSACTION", nullptr, nullptr, nullptr);
- g_free(full_name);
- BZ2_bzReadClose(&err, manifest_bz2);
-
-out:
- sqlite3_finalize(statement);
- if (file_expr)
- {
- g_regex_unref(file_expr);
- }
- if (pkg_expr)
- {
- g_regex_unref(pkg_expr);
- }
- fclose(manifest);
-}
-
-/**
- * katja::Slackpkg::collect_cache_info:
- * @tmpl: temporary directory for downloading the files.
- *
- * Download files needed to get the information like the list of packages
- * in available repositories, updates, package descriptions and so on.
- *
- * Returns: List of files needed for building the cache.
- **/
-GSList *
-Slackpkg::collect_cache_info (const char *tmpl) noexcept
-{
- CURL *curl = nullptr;
- char **source_dest;
- GSList *file_list = nullptr;
- GFile *tmp_dir, *repo_tmp_dir;
-
- /* Create the temporary directory for the repository */
- tmp_dir = g_file_new_for_path(tmpl);
- repo_tmp_dir = g_file_get_child(tmp_dir, this->get_name());
- g_file_make_directory(repo_tmp_dir, nullptr, nullptr);
-
- /* Download PACKAGES.TXT. These files are most important, break if some of them couldn't be found */
- for (char **cur_priority = this->priority; *cur_priority; cur_priority++)
- {
- source_dest = static_cast<char **> (g_malloc_n(3, sizeof(char *)));
- source_dest[0] = g_strconcat(this->get_mirror(),
- *cur_priority,
- "/PACKAGES.TXT",
- nullptr);
- source_dest[1] = g_build_filename(tmpl,
- this->get_name(),
- "PACKAGES.TXT",
- nullptr);
- source_dest[2] = nullptr;
-
- if (get_file(&curl, source_dest[0], nullptr) == CURLE_OK)
- {
- file_list = g_slist_prepend(file_list, source_dest);
- }
- else
- {
- g_strfreev(source_dest);
- g_slist_free_full(file_list, (GDestroyNotify)g_strfreev);
- goto out;
- }
-
- /* Download file lists if available */
- source_dest = static_cast<char **> (g_malloc_n(3, sizeof(char *)));
- source_dest[0] = g_strconcat(this->get_mirror(),
- *cur_priority,
- "/MANIFEST.bz2",
- nullptr);
- source_dest[1] = g_strconcat(tmpl,
- "/", this->get_name(),
- "/", *cur_priority, "-MANIFEST.bz2",
- nullptr);
- source_dest[2] = nullptr;
- if (get_file(&curl, source_dest[0], nullptr) == CURLE_OK)
- {
- file_list = g_slist_prepend(file_list, source_dest);
- }
- else
- {
- g_strfreev(source_dest);
- }
- }
-out:
- g_object_unref(repo_tmp_dir);
- g_object_unref(tmp_dir);
-
- if (curl)
- {
- curl_easy_cleanup(curl);
- }
- return file_list;
-}
-
-/**
- * katja::Slackpkg::generate_cache:
- * @job_data: A #JobData.
- * @tmpl: temporary directory for downloading the files.
- *
- * Download files needed to get the information like the list of packages
- * in available repositories, updates, package descriptions and so on.
- *
- * Returns: List of files needed for building the cache.
- **/
-void
-Slackpkg::generate_cache(JobData *job_data, const char *tmpl) noexcept
-{
- char **pkg_tokens = nullptr;
- char *query = nullptr, *filename = nullptr, *location = nullptr, *summary = nullptr, *line, *packages_txt;
- unsigned pkg_compressed = 0, pkg_uncompressed = 0;
- gushort pkg_name_len;
- GString *desc;
- GFile *list_file;
- GFileInputStream *fin = nullptr;
- GDataInputStream *data_in = nullptr;
- sqlite3_stmt *insert_statement = nullptr, *update_statement = nullptr, *insert_default_statement = nullptr, *statement;
-
- /* Check if the temporary directory for this repository exists, then the file metadata have to be generated */
- packages_txt = g_build_filename(tmpl, this->get_name(), "PACKAGES.TXT", nullptr);
- list_file = g_file_new_for_path(packages_txt);
- fin = g_file_read(list_file, nullptr, nullptr);
- g_object_unref(list_file);
- g_free(packages_txt);
- if (!fin)
- {
- goto out;
- }
- /* Remove the old entries from this repository */
- if (sqlite3_prepare_v2(job_data->db,
- "DELETE FROM repos WHERE repo LIKE @repo",
- -1,
- &statement,
- nullptr) == SQLITE_OK)
- {
- sqlite3_bind_text(statement, 1, this->get_name(), -1, SQLITE_TRANSIENT);
- sqlite3_step(statement);
- sqlite3_finalize(statement);
- }
- if (sqlite3_prepare_v2(job_data->db,
- "INSERT INTO repos (repo_order, repo) VALUES (@repo_order, @repo)",
- -1,
- &statement,
- nullptr) != SQLITE_OK)
- {
- goto out;
- }
- sqlite3_bind_int(statement, 1, this->get_order());
- sqlite3_bind_text(statement, 2, this->get_name(), -1, SQLITE_TRANSIENT);
- sqlite3_step(statement);
- sqlite3_finalize(statement);
-
- /* Insert new records */
- if ((sqlite3_prepare_v2(job_data->db,
- "INSERT OR REPLACE INTO pkglist (full_name, ver, arch, ext, location, "
- "summary, desc, compressed, uncompressed, name, repo_order, cat) "
- "VALUES (@full_name, @ver, @arch, @ext, @location, @summary, "
- "@desc, @compressed, @uncompressed, @name, @repo_order, @cat)",
- -1,
- &insert_statement,
- nullptr) != SQLITE_OK)
- || (sqlite3_prepare_v2(job_data->db,
- "INSERT OR REPLACE INTO pkglist (full_name, ver, arch, ext, location, "
- "summary, desc, compressed, uncompressed, name, repo_order) "
- "VALUES (@full_name, @ver, @arch, @ext, @location, @summary, "
- "@desc, @compressed, @uncompressed, @name, @repo_order)",
- -1,
- &insert_default_statement,
- nullptr) != SQLITE_OK))
- {
- goto out;
- }
- query = sqlite3_mprintf("UPDATE pkglist SET full_name = @full_name, ver = @ver, arch = @arch, "
- "ext = @ext, location = @location, summary = @summary, "
- "desc = @desc, compressed = @compressed, uncompressed = @uncompressed "
- "WHERE name LIKE @name AND repo_order = %u",
- this->get_order());
- if (sqlite3_prepare_v2(job_data->db, query, -1, &update_statement, nullptr) != SQLITE_OK)
- {
- goto out;
- }
-
- data_in = g_data_input_stream_new(G_INPUT_STREAM(fin));
- desc = g_string_new("");
-
- sqlite3_exec(job_data->db, "BEGIN TRANSACTION", nullptr, nullptr, nullptr);
-
- while ((line = g_data_input_stream_read_line(data_in, nullptr, nullptr, nullptr)))
- {
- if (!strncmp(line, "PACKAGE NAME: ", 15))
- {
- filename = g_strdup(line + 15);
- if (this->is_blacklisted (filename))
- {
- g_free(filename);
- filename = nullptr;
- }
- }
- else if (filename && !strncmp(line, "PACKAGE LOCATION: ", 19))
- {
- location = g_strdup(line + 21); /* Exclude ./ at the path beginning */
- }
- else if (filename && !strncmp(line, "PACKAGE SIZE (compressed): ", 28))
- {
- /* Remove the unit (kilobytes) */
- pkg_compressed = atoi(g_strndup(line + 28, strlen(line + 28) - 2)) * 1024;
- }
- else if (filename && !strncmp(line, "PACKAGE SIZE (uncompressed): ", 30))
- {
- /* Remove the unit (kilobytes) */
- pkg_uncompressed = atoi(g_strndup(line + 30, strlen(line + 30) - 2)) * 1024;
- }
- else if (filename && !g_strcmp0(line, "PACKAGE DESCRIPTION:"))
- {
- g_free(line);
- line = g_data_input_stream_read_line(data_in, nullptr, nullptr, nullptr); /* Short description */
-
- summary = g_strstr_len(line, -1, "(");
- if (summary) /* Else summary = nullptr */
- {
- summary = g_strndup(summary + 1, strlen(summary) - 2); /* Without ( ) */
- }
- pkg_tokens = split_package_name(filename);
- pkg_name_len = strlen(pkg_tokens[0]); /* Description begins with pkg_name: */
- }
- else if (filename && !strncmp(line, pkg_tokens[0], pkg_name_len))
- {
- g_string_append(desc, line + pkg_name_len + 1);
- }
- else if (filename && !g_strcmp0(line, ""))
- {
- if (g_strcmp0(location, "patches/packages")) /* Insert a new package */
- {
- /* Get the package group based on its location */
- const char *cat = g_strrstr(location, "/");
- if (cat) /* Else cat = nullptr */
- {
- cat = static_cast<const char *> (g_hash_table_lookup(cat_map, cat + 1));
- }
- if (cat)
- {
- statement = insert_statement;
- sqlite3_bind_text(insert_statement, 12, cat, -1, SQLITE_TRANSIENT);
- }
- else
- {
- statement = insert_default_statement;
- }
- sqlite3_bind_int(statement, 11, this->get_order());
- }
- else /* Update package information if it is a patch */
- {
- statement = update_statement;
- }
- sqlite3_bind_text(statement, 1, pkg_tokens[3], -1, SQLITE_TRANSIENT);
- sqlite3_bind_text(statement, 2, pkg_tokens[1], -1, SQLITE_TRANSIENT);
- sqlite3_bind_text(statement, 3, pkg_tokens[2], -1, SQLITE_TRANSIENT);
- sqlite3_bind_text(statement, 4, pkg_tokens[4], -1, SQLITE_TRANSIENT);
- sqlite3_bind_text(statement, 5, location, -1, SQLITE_TRANSIENT);
- sqlite3_bind_text(statement, 6, summary, -1, SQLITE_TRANSIENT);
- sqlite3_bind_text(statement, 7, desc->str, -1, SQLITE_TRANSIENT);
- sqlite3_bind_int(statement, 8, pkg_compressed);
- sqlite3_bind_int(statement, 9, pkg_uncompressed);
- sqlite3_bind_text(statement, 10, pkg_tokens[0], -1, SQLITE_TRANSIENT);
-
- sqlite3_step(statement);
- sqlite3_clear_bindings(statement);
- sqlite3_reset(statement);
-
- /* Reset for the next package */
- g_strfreev(pkg_tokens);
- g_free(filename);
- g_free(location);
- g_free(summary);
- filename = location = summary = nullptr;
- g_string_assign(desc, "");
- pkg_compressed = pkg_uncompressed = 0;
- }
- g_free(line);
- }
- sqlite3_exec(job_data->db, "END TRANSACTION", nullptr, nullptr, nullptr);
-
- g_string_free(desc, true);
- g_object_unref(data_in);
-
- /* Parse MANIFEST.bz2 */
- for (char **p = this->priority; *p; p++)
- {
- filename = g_strconcat(*p, "-MANIFEST.bz2", nullptr);
- manifest(job_data, tmpl, filename);
- g_free(filename);
- }
-out:
- sqlite3_finalize(update_statement);
- sqlite3_free(query);
- sqlite3_finalize(insert_default_statement);
- sqlite3_finalize(insert_statement);
-
- if (fin)
- {
- g_object_unref(fin);
- }
-}
-
-Slackpkg::~Slackpkg () noexcept
-{
- if (this->blacklist)
- {
- g_regex_unref (this->blacklist);
- }
-
- g_free (this->name);
- g_free (this->mirror);
- if (this->priority)
- {
- g_strfreev (this->priority);
- }
-}
-
-/**
- * katja::Slackpkg::Slackpkg:
- * @name: Repository name.
- * @mirror: Repository mirror.
- * @order: Repository order.
- * @blacklist: Blacklist.
- * @priority: Groups priority.
- *
- * Constructor.
- *
- * Returns: New #katja::Slackpkg.
- **/
-Slackpkg::Slackpkg (const char *name, const char *mirror,
- std::uint8_t order, const char *blacklist, char **priority) noexcept
-{
- GRegex *regex;
-
- if (blacklist)
- {
- regex = static_cast<GRegex *> (g_regex_new (blacklist,
- G_REGEX_OPTIMIZE, static_cast<GRegexMatchFlags> (0), nullptr));
- }
- else
- {
- regex = nullptr;
- }
-
- this->name = g_strdup (name);
- this->mirror = g_strdup (mirror);
-
- this->order = order;
-
- this->blacklist = regex;
-
- this->priority = priority;
-
- // Initialize category map
- if (cat_map == nullptr)
- {
- cat_map = g_hash_table_new(g_str_hash, g_str_equal);
- g_hash_table_insert (cat_map, (void *) "a", (void *) "system");
- g_hash_table_insert (cat_map, (void *) "ap", (void *) "admin-tools");
- g_hash_table_insert (cat_map, (void *) "d", (void *) "programming");
- g_hash_table_insert (cat_map, (void *) "e", (void *) "programming");
- g_hash_table_insert (cat_map, (void *) "f", (void *) "documentation");
- g_hash_table_insert (cat_map, (void *) "k", (void *) "system");
- g_hash_table_insert (cat_map, (void *) "kde", (void *) "desktop-kde");
- g_hash_table_insert (cat_map, (void *) "kdei", (void *) "localization");
- g_hash_table_insert (cat_map, (void *) "l", (void *) "system");
- g_hash_table_insert (cat_map, (void *) "n", (void *) "network");
- g_hash_table_insert (cat_map, (void *) "t", (void *) "publishing");
- g_hash_table_insert (cat_map, (void *) "tcl", (void *) "system");
- g_hash_table_insert (cat_map, (void *) "x", (void *) "desktop-other");
- g_hash_table_insert (cat_map, (void *) "xap", (void *) "accessories");
- g_hash_table_insert (cat_map, (void *) "xfce", (void *) "desktop-xfce");
- g_hash_table_insert (cat_map, (void *) "y", (void *) "games");
- }
-}
-
-}