From: Michael Tremer Date: Tue, 31 Oct 2023 11:05:11 +0000 (+0000) Subject: os: Move code to read /etc/os-release here X-Git-Tag: 0.9.30~1374 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9e5b19ac8d5f1e29bb1c5bd4c9ac51e99619a95f;p=pakfire.git os: Move code to read /etc/os-release here Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/include/pakfire/os.h b/src/libpakfire/include/pakfire/os.h index 31e846bd3..469b3f129 100644 --- a/src/libpakfire/include/pakfire/os.h +++ b/src/libpakfire/include/pakfire/os.h @@ -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 */ diff --git a/src/libpakfire/include/pakfire/string.h b/src/libpakfire/include/pakfire/string.h index bca0ff23e..b1aa2ae25 100644 --- a/src/libpakfire/include/pakfire/string.h +++ b/src/libpakfire/include/pakfire/string.h @@ -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); diff --git a/src/libpakfire/include/pakfire/util.h b/src/libpakfire/include/pakfire/util.h index 20673c1d0..2fea79211 100644 --- a/src/libpakfire/include/pakfire/util.h +++ b/src/libpakfire/include/pakfire/util.h @@ -33,8 +33,6 @@ #include #include -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); diff --git a/src/libpakfire/os.c b/src/libpakfire/os.c index 32872a58e..c1b8807bc 100644 --- a/src/libpakfire/os.c +++ b/src/libpakfire/os.c @@ -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); +} diff --git a/src/libpakfire/pakfire.c b/src/libpakfire/pakfire.c index cc3d3b422..247e1beac 100644 --- a/src/libpakfire/pakfire.c +++ b/src/libpakfire/pakfire.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -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) { diff --git a/src/libpakfire/string.c b/src/libpakfire/string.c index 1a26ae566..bf64d2980 100644 --- a/src/libpakfire/string.c +++ b/src/libpakfire/string.c @@ -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) diff --git a/src/libpakfire/util.c b/src/libpakfire/util.c index c2bcfdc8b..2f0c8ef88 100644 --- a/src/libpakfire/util.c +++ b/src/libpakfire/util.c @@ -55,30 +55,6 @@ #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; diff --git a/tests/libpakfire/os.c b/tests/libpakfire/os.c index 2c1d90a60..3d1aa15ec 100644 --- a/tests/libpakfire/os.c +++ b/tests/libpakfire/os.c @@ -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); }