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 */
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);
#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);
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;
return 0;
// Find the delimiter
- p = strchr(line, ':');
+ p = strchr(line, delim);
if (!p)
return -EINVAL;
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;
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;
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);
+}
#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>
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;
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) {
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)
#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;
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);
}