aboutsummaryrefslogtreecommitdiff
path: root/linux.c
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2023-04-23 17:55:16 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2023-04-23 17:55:16 -0400
commit1f0c894080e0a3d62694a056456e378e36eb12a1 (patch)
tree7abd3928808aa9f03a4dd17dd3eb5ecde7607d18 /linux.c
parent0ec45301dc4d1a61cc1d9bd2906cd010c88f81c0 (diff)
downloadwhatami-1f0c894080e0a3d62694a056456e378e36eb12a1.tar.gz
Refactor
Split linux, darwin, and x86 into separate modules
Diffstat (limited to 'linux.c')
-rw-r--r--linux.c187
1 files changed, 187 insertions, 0 deletions
diff --git a/linux.c b/linux.c
new file mode 100644
index 0000000..4836955
--- /dev/null
+++ b/linux.c
@@ -0,0 +1,187 @@
+#if defined(__linux__)
+#include "common.h"
+
+int get_sys_os_dist(char **name, char **version) {
+ char buf[255] = {0};
+ const char *filename = "/etc/os-release";
+ FILE *fp;
+
+ fp = fopen(filename, "r");
+ if (!fp) {
+ *name = strdup("Unknown");
+ *version = strdup("Unknown");
+ return -1;
+ }
+
+ while (fgets(buf, sizeof(buf) - 1, fp) != NULL) {
+ rstrip(buf);
+ char *key, *value;
+ char *start;
+ start = buf;
+ key = strchr(buf, '=');
+ if (key) {
+ size_t diff = key - start;
+ *key = 0;
+ key = start;
+ value = key + diff + 1;
+ } else {
+ continue;
+ }
+ key = buf;
+
+ if (value[0] == '\"') {
+ memmove(value, &value[1], strlen(&value[1]));
+ if (strlen(value))
+ value[strlen(value) - 1] = '\0';
+ }
+ if (strlen(value) && value[strlen(value) - 1] == '\"') {
+ value[strlen(value) - 1] = '\0';
+ }
+ if (!strcmp(key, "NAME")) {
+ *name = strdup(value);
+ }
+ if (!strcmp(key, "VERSION") || !strcmp(key, "VERSION_ID") || !strcmp(key, "BUILD_ID")) {
+ *version = strdup(value);
+ }
+ }
+ fclose(fp);
+ return 0;
+}
+
+ssize_t get_sys_memory() {
+ char buf[255] = {0};
+ ssize_t result;
+ FILE *fp;
+
+ fp = fopen("/proc/meminfo", "r");
+ if (!fp) {
+ perror("Unable to open /proc/meminfo");
+ return -1;
+ }
+
+ result = 0;
+ while (fgets(buf, sizeof(buf) - 1, fp) != NULL) {
+ char *key = strstr(buf, "MemTotal:");
+ if (key) {
+ result = strtoll(key + strlen("MemTotal:"), NULL, 10);
+ break;
+ }
+ }
+
+ fclose(fp);
+ return result;
+}
+
+char *get_sys_dmi_product() {
+ FILE *fp;
+ char *buf;
+ const int buf_size = 255;
+
+ buf = calloc(buf_size, sizeof(*buf));
+ if (!buf) {
+ return NULL;
+ }
+
+ fp = fopen("/sys/class/dmi/id/product_name", "r");
+ if (!fp) {
+ free(buf);
+ return NULL;
+ }
+
+ if (!fgets(buf, buf_size, fp)) {
+ perror("Unable to read system vendor");
+ if (fp != NULL) {
+ free(buf);
+ fclose(fp);
+ }
+ return NULL;
+ }
+
+ fclose(fp);
+ return buf;
+}
+
+struct Block_Device **get_block_devices(size_t *total) {
+ struct Block_Device **result;
+ struct dirent *rec;
+ DIR *dp;
+ size_t i;
+ size_t devices_total;
+
+ dp = opendir("/sys/block");
+ if (!dp) {
+ perror("/sys/block");
+ return 0;
+ }
+
+ i = 0;
+ devices_total = 0;
+ *total = devices_total;
+ while ((rec = readdir(dp)) != NULL) {
+ if (!strcmp(rec->d_name, ".") || !strcmp(rec->d_name, "..")) {
+ continue;
+ }
+ devices_total++;
+ }
+ rewinddir(dp);
+
+ result = calloc(devices_total + 1, sizeof(result));
+ for (size_t d = 0; d < devices_total; d++) {
+ result[d] = calloc(1, sizeof(*result[0]));
+ }
+
+ while ((rec = readdir(dp)) != NULL) {
+ if (!strcmp(rec->d_name, ".") || !strcmp(rec->d_name, "..")) {
+ continue;
+ }
+
+ char device_path[PATH_MAX] = {0};
+ snprintf(device_path, sizeof(device_path) - 1, "/dev/%s", rec->d_name);
+
+ char device_size_file[PATH_MAX] = {0};
+ snprintf(device_size_file, sizeof(device_size_file) - 1, "/sys/block/%s/size", rec->d_name);
+
+ char device_model_file[PATH_MAX] = {0};
+ snprintf(device_model_file, sizeof(device_model_file) - 1, "/sys/block/%s/device/model", rec->d_name);
+
+ char line[255] = {0};
+ FILE *fp;
+
+ size_t device_size;
+ fp = fopen(device_size_file, "r");
+ if (!fp) {
+ device_size = 0;
+ } else {
+ if (!fgets(line, sizeof(line) - 1, fp)) {
+ perror("Unable to read from file");
+ continue;
+ }
+ device_size = strtoull(line, NULL, 10);
+ fclose(fp);
+ }
+
+ char device_model[255] = {0};
+ fp = fopen(device_model_file, "r");
+ if (!fp) {
+ // no model file
+ strcpy(device_model, "Unnamed");
+ } else {
+ if (!fgets(device_model, sizeof(line) - 1, fp)) {
+ perror("Unable to read device model");
+ continue;
+ }
+ fclose(fp);
+ }
+
+ rstrip(device_model);
+ strcpy(result[i]->model, device_model);
+ strncpy(result[i]->path, rec->d_name, sizeof(result[i]->path) - 1);
+ result[i]->size = device_size;
+ i++;
+ }
+
+ *total = devices_total;
+ closedir(dp);
+ return result;
+}
+#endif \ No newline at end of file