]> git.ipfire.org Git - pakfire.git/commitdiff
os: Move code to read /etc/os-release here
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 31 Oct 2023 11:05:11 +0000 (11:05 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 31 Oct 2023 11:25:57 +0000 (11:25 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/include/pakfire/os.h
src/libpakfire/include/pakfire/string.h
src/libpakfire/include/pakfire/util.h
src/libpakfire/os.c
src/libpakfire/pakfire.c
src/libpakfire/string.c
src/libpakfire/util.c
tests/libpakfire/os.c

index 31e846bd38c383063e8577a97d19ac22fcd558f2..469b3f1290181231d6e85dba065fbb34099ffc39 100644 (file)
@@ -86,6 +86,22 @@ struct pakfire_meminfo {
 
 int pakfire_meminfo(struct pakfire_meminfo* meminfo);
 
+// Distro
+
+struct pakfire_distro {
+       char pretty_name[256];
+       char name[64];
+       char id[32];
+       char slogan[256];
+       char vendor[64];
+       char version[64];
+       char version_codename[32];
+       char version_id[8];
+       char tag[40];
+};
+
+int pakfire_distro(struct pakfire_distro* distro, const char* path);
+
 #endif /* PAKFIRE_PRIVATE */
 
 #endif /* PAKFIRE_OS_H */
index bca0ff23e5e6b66cb32d4e0e2ff81e988a81915f..b1aa2ae25f5f4018d770447678b97e4dc3b9e474 100644 (file)
@@ -52,6 +52,7 @@ int pakfire_string_matches(const char* s, const char* pattern);
 void pakfire_string_lstrip(char* s);
 void pakfire_string_rstrip(char* s);
 void pakfire_string_strip(char* s);
+void pakfire_string_unquote(char* s);
 
 int pakfire_string_partition(const char* s, const char* delim, char** s1, char** s2);
 char* pakfire_string_replace(const char* s, const char* pattern, const char* repl);
index 20673c1d0d12fcc5222a7a469b213fa41cf27e37..2fea79211cc1a63f66fe7efd6ca3e98320dae2a2 100644 (file)
@@ -33,8 +33,6 @@
 #include <pakfire/digest.h>
 #include <pakfire/pakfire.h>
 
-char* pakfire_unquote_in_place(char* s);
-
 int pakfire_path_exists(const char* path);
 int pakfire_path_match(const char* p, const char* s);
 time_t pakfire_path_age(const char* path);
index 32872a58e8382bb305448e2a2cfd9f5a7d2dca94..c1b8807bc172e5f91d580d11cada87fb22009b77 100644 (file)
@@ -64,7 +64,7 @@ ERROR:
        return r;
 }
 
-static int pakfire_split_line(char* line, size_t length, const char** key, const char** value) {
+static int pakfire_split_line(char* line, size_t length, char** key, char** value, char delim) {
        char* k = line;
        char* v = NULL;
        char* p = NULL;
@@ -76,7 +76,7 @@ static int pakfire_split_line(char* line, size_t length, const char** key, const
                return 0;
 
        // Find the delimiter
-       p = strchr(line, ':');
+       p = strchr(line, delim);
        if (!p)
                return -EINVAL;
 
@@ -110,11 +110,11 @@ static int pakfire_parse_cpuinfo(char* line, size_t length, void* data) {
        int r;
 
        // Key & Value
-       const char* k = NULL;
-       const char* v = NULL;
+       char* k = NULL;
+       char* v = NULL;
 
        // Split the line
-       r = pakfire_split_line(line, length, &k, &v);
+       r = pakfire_split_line(line, length, &k, &v, ':');
        if (r)
                return r;
 
@@ -253,11 +253,11 @@ static int pakfire_parse_meminfo(char* line, size_t length, void* data) {
        int r;
 
        // Key & Value
-       const char* k = NULL;
-       const char* v = NULL;
+       char* k = NULL;
+       char* v = NULL;
 
        // Split the line
-       r = pakfire_split_line(line, length, &k, &v);
+       r = pakfire_split_line(line, length, &k, &v, ':');
        if (r)
                return r;
 
@@ -324,3 +324,59 @@ int pakfire_meminfo(struct pakfire_meminfo* meminfo) {
 
        return 0;
 }
+
+// Distro
+
+static int pakfire_parse_distro(char* line, size_t length, void* data) {
+       struct pakfire_distro* distro = data;
+       int r;
+
+       // Key & Value
+       char* k = NULL;
+       char* v = NULL;
+
+       // Split the line
+       r = pakfire_split_line(line, length, &k, &v, '=');
+       if (r)
+               return r;
+
+       // If we didn't get a result we skip this line
+       if (!k || !v)
+               return 0;
+
+       // Unquote the strings
+       pakfire_string_unquote(v);
+
+       // PRETTY_NAME
+       if (strcmp(k, "PRETTY_NAME") == 0)
+               return pakfire_string_set(distro->pretty_name, v);
+
+       // NAME
+       else if (strcmp(k, "NAME") == 0)
+               return pakfire_string_set(distro->name, v);
+
+       // ID
+       else if (strcmp(k, "ID") == 0)
+               return pakfire_string_set(distro->id, v);
+
+       // VERSION
+       else if (strcmp(k, "VERSION") == 0)
+               return pakfire_string_set(distro->version, v);
+
+       // VERSION_CODENAME
+       else if (strcmp(k, "VERSION_CODENAME") == 0)
+               return pakfire_string_set(distro->version_codename, v);
+
+       // VERSION_ID
+       else if (strcmp(k, "VERSION_ID") == 0)
+               return pakfire_string_set(distro->version_id, v);
+
+       return 0;
+}
+
+int pakfire_distro(struct pakfire_distro* distro, const char* path) {
+       if (!path)
+               path = "/etc/os-release";
+
+       return pakfire_parse_file(path, pakfire_parse_distro, distro);
+}
index cc3d3b422fded8343b86d34746dcc311f3039d7f..247e1beac5130d9260947fd066232e351ffab2d0 100644 (file)
@@ -52,6 +52,7 @@
 #include <pakfire/dist.h>
 #include <pakfire/logging.h>
 #include <pakfire/mount.h>
+#include <pakfire/os.h>
 #include <pakfire/package.h>
 #include <pakfire/packagelist.h>
 #include <pakfire/pakfire.h>
@@ -106,17 +107,8 @@ struct pakfire {
 
        struct pakfire_config* config;
 
-       struct pakfire_distro {
-               char pretty_name[256];
-               char name[64];
-               char id[32];
-               char slogan[256];
-               char vendor[64];
-               char version[64];
-               char version_codename[32];
-               char version_id[8];
-               char tag[40];
-       } distro;
+       // Distro
+       struct pakfire_distro distro;
 
        // Magic Context
        magic_t magic;
@@ -674,80 +666,14 @@ static int pakfire_read_config(struct pakfire* pakfire, FILE* f) {
 
 static int pakfire_read_os_release(struct pakfire* pakfire) {
        char path[PATH_MAX];
-       char* line = NULL;
-       size_t l = 0;
+       int r;
 
-       int r = pakfire_path(pakfire, path, "%s", "/etc/os-release");
+       // Compose path
+       r = pakfire_path(pakfire, path, "%s", "/etc/os-release");
        if (r)
                return r;
 
-       r = 1;
-
-       FILE* f = fopen(path, "r");
-       if (!f) {
-               // Ignore when the file does not exist
-               if (errno == ENOENT) {
-                       r = 0;
-                       goto ERROR;
-               }
-
-               ERROR(pakfire, "Could not open %s: %m\n", path);
-               goto ERROR;
-       }
-
-       while (1) {
-               ssize_t bytes_read = getline(&line, &l, f);
-               if (bytes_read < 0)
-                       break;
-
-               // Remove trailing newline
-               pakfire_remove_trailing_newline(line);
-
-               // Find =
-               char* delim = strchr(line, '=');
-               if (!delim)
-                       continue;
-
-               // Replace = by NULL
-               *delim = '\0';
-
-               // Set key and val to the start of the strings
-               char* key = line;
-               char* val = delim + 1;
-
-               // Unquote val
-               val = pakfire_unquote_in_place(val);
-
-               if (strcmp(key, "PRETTY_NAME") == 0)
-                       r = pakfire_string_set(pakfire->distro.pretty_name, val);
-               else if (strcmp(key, "NAME") == 0)
-                       r = pakfire_string_set(pakfire->distro.name, val);
-               else if (strcmp(key, "ID") == 0)
-                       r = pakfire_string_set(pakfire->distro.id, val);
-               else if (strcmp(key, "VERSION") == 0)
-                       r = pakfire_string_set(pakfire->distro.version, val);
-               else if (strcmp(key, "VERSION_CODENAME") == 0)
-                       r = pakfire_string_set(pakfire->distro.version_codename, val);
-               else if (strcmp(key, "VERSION_ID") == 0)
-                       r = pakfire_string_set(pakfire->distro.version_id, val);
-               else
-                       continue;
-
-               // Catch any errors
-               if (r)
-                       goto ERROR;
-       }
-
-       // Success
-       r = 0;
-
-ERROR:
-       if (f)
-               fclose(f);
-       if (line)
-               free(line);
-
-       return r;
+       return pakfire_distro(&pakfire->distro, path);
 }
 
 static int pakfire_set_cache_path(struct pakfire* pakfire) {
index 1a26ae566fec6a09134bd3353a656f79217814ef..bf64d2980d2cc8e6810399bd941d0dc91f104048 100644 (file)
@@ -118,6 +118,31 @@ void pakfire_string_strip(char* s) {
        pakfire_string_rstrip(s);
 }
 
+void pakfire_string_unquote(char* s) {
+       size_t length = 0;
+
+       // Nothing to do
+       if (!s || !*s)
+               return;
+
+       // Determine the length of the string
+       length = strlen(s);
+
+       // Check if the first character is "
+       if (s[0] != '"')
+               return;
+
+       // Check if the last characters is "
+       if (s[length - 1] != '"')
+               return;
+
+       // Remove the quotes
+       memmove(s, s + 1, length - 2);
+
+       // Terminate the string
+       s[length - 2] = '\0';
+}
+
 int pakfire_string_matches(const char* s, const char* pattern) {
        // Validate input
        if (!s || !pattern)
index c2bcfdc8bf8a494eebcca0a4c3f47be4962be38f..2f0c8ef881f4ace4e0b32df50b74f62c93680832 100644 (file)
 #define BUFFER_SIZE 64 * 1024
 #define NSEC_PER_SEC 1000000000
 
-char* pakfire_unquote_in_place(char* s) {
-       if (!s || !*s)
-               return s;
-
-       // Is the first character a quote?
-       if (*s != '"')
-               return s;
-
-       // Find the end of value
-       size_t l = strlen(s);
-       if (!l)
-               return s;
-
-       // Is the last character a quote?
-       if (s[l - 1] != '"')
-               return s;
-
-       // The string seems to be in quotes; remove them
-       s[l - 1] = '\0';
-       s++;
-
-       return s;
-}
-
 int pakfire_path_is_absolute(const char* path) {
        if (!path) {
                errno = EINVAL;
index 2c1d90a6013f0703fd95154e5a8db53685f50cb2..3d1aa15ec01391b163f1c2f3e425c3f1166c9f16 100644 (file)
@@ -102,11 +102,27 @@ FAIL:
        return EXIT_FAILURE;
 }
 
+// This test parses /etc/os-release
+static int test_distro(const struct test* t) {
+       struct pakfire_distro distro = {};
+
+       ASSERT_SUCCESS(pakfire_distro(&distro, NULL));
+
+       ASSERT(*distro.name);
+       ASSERT(*distro.version);
+
+       return EXIT_SUCCESS;
+
+FAIL:
+       return EXIT_FAILURE;
+}
+
 int main(int argc, const char* argv[]) {
        testsuite_add_test(test_cpuinfo);
        testsuite_add_test(test_cpustat);
        testsuite_add_test(test_loadavg);
        testsuite_add_test(test_meminfo);
+       testsuite_add_test(test_distro);
 
        return testsuite_run(argc, argv);
 }