From 9e02e75a9801ec8e09048622f33752415b900625 Mon Sep 17 00:00:00 2001 From: Puechberty Arthur Date: Fri, 26 Jun 2026 21:41:36 +0200 Subject: [PATCH] major update --- .gitignore | 20 +++++++++++++- Makefile | 25 +++++++++++++++++ README.md | 51 +++++++++++++++++++++++++++++++++++ build.sh | 12 +++++++++ config.c | 54 ++++++++++++++++++------------------- logos.c | 23 +++++++++++----- main.c | 59 +++++++++++++++++++++++++++++++++++------ optifetch.h | 3 ++- packages/PKGBUILD | 22 +++++++++++++++ packages/debian/control | 13 +++++++++ packages/optifetch.spec | 27 +++++++++++++++++++ renderer.c | 34 +++++++++++++++++++----- sysinfo.c | 1 + 13 files changed, 293 insertions(+), 51 deletions(-) create mode 100644 Makefile create mode 100644 README.md create mode 100755 build.sh create mode 100644 packages/PKGBUILD create mode 100644 packages/debian/control create mode 100644 packages/optifetch.spec diff --git a/.gitignore b/.gitignore index f416275..6d40ec9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,20 @@ +# Exécutables et fichiers compilés optifetch -optifetch.conf \ No newline at end of file +*.o +*.a +*.so +*.exe + +# Fichiers système +.DS_Store +Thumbs.db + +# Fichiers de configuration générés localement +optifetch.conf + +# IDEs +.vscode/ +.idea/ +*.swp +*.swo +*~ \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..01db85b --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +CC = gcc +CFLAGS = -Wall -Wextra -O3 -s +TARGET = optifetch +SRC = main.c sysinfo.c logos.c config.c renderer.c + +all: $(TARGET) + + $(TARGET): $(SRC) + $(CC) $(CFLAGS) -o $(TARGET) $(SRC) + +install: $(TARGET) + mkdir -p $(DESTDIR)/usr/bin + cp $(TARGET) $(DESTDIR)/usr/bin/ + mkdir -p $(DESTDIR)/usr/share/optifetch/logos + cp -r logos/*.txt $(DESTDIR)/usr/share/optifetch/logos/ 2>/dev/null || true + mkdir -p $(DESTDIR)/etc + cp optifetch.conf $(DESTDIR)/etc/optifetch.conf 2>/dev/null || touch $(DESTDIR)/etc/optifetch.conf + +uninstall: + rm -f $(DESTDIR)/usr/bin/$(TARGET) + rm -rf $(DESTDIR)/usr/share/optifetch + rm -f $(DESTDIR)/etc/optifetch.conf + +clean: + rm -f $(TARGET) \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..afc2034 --- /dev/null +++ b/README.md @@ -0,0 +1,51 @@ +# Optifetch + +Un outil d'information système rapide, léger, écrit en C et sans dépendances externes. Inspiré de Fastfetch, il se concentre sur la rapidité d'exécution et la personnalisation via un fichier de configuration simple. + +## Fonctionnalités + +- **Zéro dépendance** : Uniquement la bibliothèque C standard (glibc/musl). +- **Ultra-rapide** : Aucun appel système lourd, lecture directe de `/proc` et `/sys`. +- **Hautement personnalisable** : Fichier de configuration texte avec variables et balises. +- **Logos dynamiques** : Place tes logos ASCII dans `logos/nom_os.txt`. +- **Alignement automatique** : Système de balises `{align:id}` pour un rendu parfait. +- **Couleurs True Color (RGB)** : Support de `{fg:R,G,B}` et `{distro_color}`. + +## Compilation + +Assure-toi d'avoir `gcc` et `make` d'installés, puis exécute : + +```bash +chmod +x build.sh +./build.sh +``` +Ou manuellement : +```bash +make +``` + +## Installation système + +Pour installer optifetch et ses logos globalement : + +```bash +sudo make install +``` + +## Configuration + +Au premier lancement, un fichier de configuration est généré dans `~/.config/optifetch.conf`. +Tu peux l'éditer pour modifier l'affichage. + +Pour obtenir la liste de toutes les variables et balises disponibles : +```bash +optifetch help +``` + +## Logos + +Les logos sont stockés dans des fichiers `.txt` situés dans : +1. `./logos/` (dossier local) +2. `/usr/share/optifetch/logos/` (dossier système) + +Le nom du fichier doit correspondre à l'ID de l'OS (ex: `arch.txt`, `debian.txt`). diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..16fa002 --- /dev/null +++ b/build.sh @@ -0,0 +1,12 @@ +#!/bin/bash +echo "Compilation d'Optifetch..." + +# Compilation directe sans Makefile +gcc -Wall -Wextra -O3 -s -o optifetch main.c sysinfo.c logos.c config.c renderer.c + +if [ $? -eq 0 ]; then + echo "Build réussi ! Exécutable créé : ./optifetch" +else + echo "Erreur lors de la compilation." + exit 1 +fi \ No newline at end of file diff --git a/config.c b/config.c index 4d263d4..b7e5099 100644 --- a/config.c +++ b/config.c @@ -4,32 +4,32 @@ void generate_default_config(const char* path) { FILE *f = fopen(path, "w"); if (!f) return; - fprintf(f, "{reset}{align:L}{bold}{user}{reset}@{bold}{host}{reset}\n"); - fprintf(f, "{align:L}-----------------------------\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}OS{reset}: {align:V}{os}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}Host{reset}: {align:V}{host_model}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}Kernel{reset}: {align:V}{kernel} {arch}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}Uptime{reset}: {align:V}{uptime}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}Packages{reset}: {align:V}{packages}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}Shell{reset}: {align:V}{shell}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}DE/WM{reset}: {align:V}{de} ({wm})\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}Display{reset}: {align:V}{display_server}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}Terminal{reset}: {align:V}{term}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}CPU{reset}: {align:V}{cpu} ({cores}) @ {cpu_max_freq}MHz\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{if:gpu}{fg:255,255,0}GPU{reset}: {align:V}{gpu}{endif}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}Memory{reset}: {align:V}{ram:gb} ({ram:%%})\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{if:swap}{fg:255,255,0}Swap{reset}: {align:V}{swap:gb} ({swap:%%}){endif}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}Disk{reset}: {align:V}{disk:gb} ({disk:%%}) - {disk_fs}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}Theme{reset}: {align:V}{theme}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}Font{reset}: {align:V}{font}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}Locale{reset}: {align:V}{locale}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{if:laptop}{fg:255,255,0}Battery{reset}: {align:V}{battery} ({bat_status}){endif}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}Date{reset}: {align:V}{date} {time}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}Local IP{reset}: {align:V}{ip_local}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{if:wifi}{fg:255,255,0}Wifi{reset}: {align:V}{wifi}{endif}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}Public IP{reset}: {align:V}{ip_public}\n"); - fprintf(f, "{fg:0,255,255} {logo} {align:L}{fg:255,255,0}DNS{reset}: {align:V}{dns}\n"); - fprintf(f, "{fg:0,255,255} {logo}\n"); - fprintf(f, "{fg:0,255,255} {logo}{align:L}{fg:0,255,0}███{fg:255,255,0}███{fg:255,0,255}███{fg:0,255,255}███{reset}\n"); + fprintf(f, "{reset}{align:L}{distro_color}{bold}{user}{reset}@{distro_color}{bold}{host}{reset}\n"); + fprintf(f, "{align:L}─────────────────────────────\n"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}OS{reset}: {align:V}{os}\n"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}Host{reset}: {align:V}{host_model}\n"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}Kernel{reset}: {align:V}{kernel} {arch}\n"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}Uptime{reset}: {align:V}{uptime}\n"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}Packages{reset}: {align:V}{packages}\n"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}Shell{reset}: {align:V}{shell}\n"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}DE/WM{reset}: {align:V}{de} ({wm})\n"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}Display{reset}: {align:V}{display_server}\n"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}Terminal{reset}: {align:V}{term}\n"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}CPU{reset}: {align:V}{cpu} ({cores}) @ {cpu_max_freq}MHz\n"); + fprintf(f, "{if:gpu} {distro_color}{logo} {align:L}{fg:157,211,154}GPU{reset}: {align:V}{gpu}\n{endif}"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}Memory{reset}: {align:V}{ram:gb} ({ram:%%})\n"); + fprintf(f, "{if:swap} {distro_color}{logo} {align:L}{fg:157,211,154}Swap{reset}: {align:V}{swap:gb} ({swap:%%})\n{endif}"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}Disk{reset}: {align:V}{disk:gb} ({disk:%%}) - {disk_fs}\n"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}Theme{reset}: {align:V}{theme}\n"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}Font{reset}: {align:V}{font}\n"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}Locale{reset}: {align:V}{locale}\n"); + fprintf(f, "{if:laptop} {distro_color}{logo} {align:L}{fg:157,211,154}Battery{reset}: {align:V}{battery} ({bat_status})\n{endif}"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}Date{reset}: {align:V}{date} {time}\n"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}Local IP{reset}: {align:V}{ip_local}\n"); + fprintf(f, "{if:wifi} {distro_color}{logo} {align:L}{fg:157,211,154}Wifi{reset}: {align:V}{wifi}\n{endif}"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}Public IP{reset}: {align:V}{ip_public}\n"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}DNS{reset}: {align:V}{dns}\n"); + fprintf(f, " {distro_color}{logo}\n"); + fprintf(f, " {distro_color}{logo} {align:L}{fg:157,211,154}███{fg:23,147,209}███{fg:255,200,87}███{fg:255,90,120}███{fg:180,120,255}███{fg:80,220,180}███{fg:240,240,240}███{fg:120,120,120}███{reset}\n"); fclose(f); } \ No newline at end of file diff --git a/logos.c b/logos.c index f0f3f90..96549ea 100644 --- a/logos.c +++ b/logos.c @@ -30,10 +30,21 @@ static LogoCache* load_logo(const char* os_id, int small) { new_cache->count = 0; new_cache->width = 0; - char path[256]; - snprintf(path, sizeof(path), "logos/%s%s.txt", os_id, small ? "_small" : ""); + char path[512]; + const char* search_paths[] = { + "logos", + "/usr/share/optifetch/logos", + "/usr/local/share/optifetch/logos", + NULL + }; + + FILE *f = NULL; + for (int i = 0; search_paths[i] != NULL; i++) { + snprintf(path, sizeof(path), "%s/%s%s.txt", search_paths[i], os_id, small ? "_small" : ""); + f = fopen(path, "r"); + if (f) break; + } - FILE *f = fopen(path, "r"); if (!f) return new_cache; char line[MAX_LOGO_WIDTH]; @@ -42,7 +53,8 @@ static LogoCache* load_logo(const char* os_id, int small) { snprintf(new_cache->lines[new_cache->count], MAX_LOGO_WIDTH, "%s", line); int w = 0; - for(int j=0; j new_cache->width) new_cache->width = w; @@ -61,12 +73,9 @@ void get_logo_line(const char* os_id, int small, int idx, char* out, size_t size return; } - // CORRECTION : On affiche la ligne telle quelle, sans ajouter d'espaces à la fin. - // Le texte collera donc directement au logo et suivra sa pente. if(idx < c->count) { snprintf(out, size, "%s", c->lines[idx]); } else { - // Si on dépasse la hauteur du logo, on ne renvoie rien (vide) out[0] = '\0'; } } diff --git a/main.c b/main.c index 38c32ff..23e5e8d 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,5 @@ #include "optifetch.h" +#include // Nécessaire pour mkdir() void print_help() { printf("Optifetch - Lightweight system info tool\n\n"); @@ -7,10 +8,13 @@ void print_help() { printf(" help Show this help message\n"); printf(" (none) Run optifetch with default or custom config\n\n"); printf("Configuration:\n"); - printf(" A file named 'optifetch.conf' is generated on first run.\n"); - printf(" You can edit it to customize the output.\n\n"); + printf(" Config file is searched in:\n"); + printf(" 1. ./optifetch.conf\n"); + printf(" 2. ~/.config/optifetch.conf\n"); + printf(" 3. /etc/optifetch.conf\n"); + printf(" It is generated on first run if not found.\n\n"); printf("Available Variables:\n"); - printf(" {logo} {small_logo} {user} {host} {os} {kernel} {uptime} {arch}\n"); + printf(" {logo} {small_logo} {distro_color} {user} {host} {os} {kernel} {uptime} {arch}\n"); printf(" {shell} {cpu} {cores} {cpu_max_freq} {gpu} {de} {wm} {term}\n"); printf(" {packages} {battery} {bat_status} {date} {time}\n"); printf(" {ip_local} {ip_public} {dns} {wifi} {host_model}\n"); @@ -42,11 +46,50 @@ int main(int argc, char *argv[]) { SysInfo info; get_info(&info); - const char *config_path = "optifetch.conf"; - - if (access(config_path, F_OK) != 0) { - generate_default_config(config_path); - printf("Fichier de configuration '%s' créé. Modifiez-le pour personnaliser l'affichage.\n\n", config_path); + char config_path[512] = "optifetch.conf"; + int config_found = 0; + + // 1. Cherche dans le dossier local + if (access(config_path, F_OK) == 0) { + config_found = 1; + } + + // 2. Cherche dans ~/.config/optifetch.conf + if (!config_found) { + const char *home = getenv("HOME"); + if (home) { + snprintf(config_path, sizeof(config_path), "%s/.config/optifetch.conf", home); + if (access(config_path, F_OK) == 0) { + config_found = 1; + } + } + } + + // 3. Cherche dans /etc/optifetch.conf + if (!config_found) { + snprintf(config_path, sizeof(config_path), "/etc/optifetch.conf"); + if (access(config_path, F_OK) == 0) { + config_found = 1; + } + } + + // 4. Si toujours pas trouvé, on le génère + if (!config_found) { + const char *home = getenv("HOME"); + if (home) { + // S'assurer que le dossier ~/.config existe bien avant de créer le fichier + char config_dir[512]; + snprintf(config_dir, sizeof(config_dir), "%s/.config", home); + mkdir(config_dir, 0755); // Crée le dossier (s'il existe déjà, ne fait rien) + + snprintf(config_path, sizeof(config_path), "%s/.config/optifetch.conf", home); + generate_default_config(config_path); + } else { + // Si pas de HOME (ex: environnement très restreint), on crée dans le dossier courant + snprintf(config_path, sizeof(config_path), "optifetch.conf"); + generate_default_config(config_path); + } + printf("Fichier de configuration créé : %s\n\n", config_path); } render_config(config_path, &info); diff --git a/optifetch.h b/optifetch.h index dd18f70..5bab60a 100644 --- a/optifetch.h +++ b/optifetch.h @@ -22,6 +22,7 @@ typedef struct { char hostname[256]; char os[256]; char os_id[64]; + char distro_color[64]; // NOUVEAU char kernel[128]; char uptime[128]; char arch[128]; @@ -60,7 +61,7 @@ typedef struct { void get_info(SysInfo *info); void get_logo_line(const char* os_id, int small, int idx, char* out, size_t size); -int get_logo_height(const char* os_id, int small); // NOUVEAU +int get_logo_height(const char* os_id, int small); void generate_default_config(const char* path); void render_config(const char* path, SysInfo *info); void print_help(); diff --git a/packages/PKGBUILD b/packages/PKGBUILD new file mode 100644 index 0000000..dbc5ba6 --- /dev/null +++ b/packages/PKGBUILD @@ -0,0 +1,22 @@ +# Maintainer: Ton Nom +pkgname=optifetch +pkgver=1.0.0 +pkgrel=1 +pkgdesc="Lightweight system info tool written in C" +arch=('x86_64') +url="https://github.com/tonpseudo/optifetch" +license=('MIT') +depends=('glibc') +makedepends=('gcc' 'make') +source=("$pkgname-$pkgver.tar.gz::$url/archive/refs/tags/v$pkgver.tar.gz") +# md5sums=('SKIP') # À remplir si tu release une version fixe + +build() { + cd "$pkgname-$pkgver" + make +} + +package() { + cd "$pkgname-$pkgver" + make DESTDIR="$pkgdir/" install +} \ No newline at end of file diff --git a/packages/debian/control b/packages/debian/control new file mode 100644 index 0000000..847387c --- /dev/null +++ b/packages/debian/control @@ -0,0 +1,13 @@ +Source: optifetch +Section: utils +Priority: optional +Maintainer: Ton Nom +Build-Depends: gcc, make +Standards-Version: 4.5.0 + +Package: optifetch +Architecture: amd64 +Depends: ${shlibs:Depends} +Description: Lightweight system info tool + Optifetch is a fast, dependency-free system information tool + written in C, similar to Fastfetch and Neofetch. \ No newline at end of file diff --git a/packages/optifetch.spec b/packages/optifetch.spec new file mode 100644 index 0000000..2c6ff6b --- /dev/null +++ b/packages/optifetch.spec @@ -0,0 +1,27 @@ +Name: optifetch +Version: 1.0.0 +Release: 1%{?dist} +Summary: Lightweight system info tool written in C +License: MIT +URL: https://github.com/tonpseudo/optifetch +Source0: %{url}/archive/v%{version}/%{name}-%{version}.tar.gz + +BuildRequires: gcc +BuildRequires: make + +%description +Optifetch is a fast, dependency-free system information tool written in C. + +%prep +%setup -q + +%build +make %{?_smp_mflags} + +%install +make DESTDIR=%{buildroot} install + +%files +%{_bindir}/optifetch +%{_datadir}/optifetch/logos/ +%config(noreplace) /etc/optifetch.conf \ No newline at end of file diff --git a/renderer.c b/renderer.c index 9e44a2c..33eaf14 100644 --- a/renderer.c +++ b/renderer.c @@ -15,10 +15,12 @@ static int skip_output = 0; static int current_line_num = 0; static int current_pass = 1; -// NOUVEAU : Variables pour gérer l'index du logo indépendamment des lignes du fichier static int logo_line_idx = 0; static int prev_line_had_logo = 0; +// NOUVEAU : Variable pour ignorer les codes ANSI lors du calcul de la largeur +static int in_ansi_escape = 0; + static int get_align_width(const char* id) { for(int i=0; i= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { + in_ansi_escape = 0; + } + return; // On ne compte pas ces caractères dans current_col + } + + // Compte les caractères UTF-8 visuels if ((c & 0xC0) != 0x80) { current_col++; } @@ -80,9 +97,15 @@ static void print_variable(const char* name, SysInfo *info) { buf[0] = '\0'; if (strcmp(name, "logo") == 0 || strcmp(name, "small_logo") == 0) { - // NOUVEAU : On utilise logo_line_idx au lieu de current_line_num get_logo_line(info->os_id, name[0] == 's', logo_line_idx, buf, sizeof(buf)); } + else if (strcmp(name, "distro_color") == 0) { + if (strlen(info->distro_color) > 0) { + snprintf(buf, sizeof(buf), "\033[%sm", info->distro_color); + } else { + snprintf(buf, sizeof(buf), "\033[0m"); + } + } else if (strcmp(name, "user") == 0) snprintf(buf, sizeof(buf), "%s", info->user); else if (strcmp(name, "host") == 0) snprintf(buf, sizeof(buf), "%s", info->hostname); else if (strcmp(name, "os") == 0) snprintf(buf, sizeof(buf), "%s", info->os); @@ -144,11 +167,11 @@ static void process_line(const char* line, SysInfo *info) { int i = 0; current_col = 0; skip_output = 0; + in_ansi_escape = 0; // NOUVEAU : Réinitialiser l'état ANSI à chaque ligne - // NOUVEAU : Détection de la présence du logo sur la ligne courante int has_logo = (strstr(line, "{logo}") != NULL || strstr(line, "{small_logo}") != NULL); if (has_logo && !prev_line_had_logo) { - logo_line_idx = 0; // On réinitialise l'index du logo à 0 si c'est le début du logo + logo_line_idx = 0; } while (line[i] != '\0' && line[i] != '\n') { @@ -194,7 +217,6 @@ static void process_line(const char* line, SysInfo *info) { if (current_pass == 2 && !skip_output) putchar('\n'); current_line_num++; - // NOUVEAU : Mise à jour des variables pour la gestion du logo prev_line_had_logo = has_logo; if (has_logo) logo_line_idx++; } @@ -233,7 +255,6 @@ void render_config(const char* path, SysInfo *info) { align_count = 0; - // Pass 1 current_pass = 1; current_line_num = 0; logo_line_idx = 0; @@ -242,7 +263,6 @@ void render_config(const char* path, SysInfo *info) { process_line(lines[i], info); } - // Pass 2 current_pass = 2; current_line_num = 0; logo_line_idx = 0; diff --git a/sysinfo.c b/sysinfo.c index ced5107..d772e7b 100644 --- a/sysinfo.c +++ b/sysinfo.c @@ -37,6 +37,7 @@ void get_info(SysInfo *info) { read_file("/etc/os-release", buf, sizeof(buf)); extract_value(buf, "PRETTY_NAME", info->os, sizeof(info->os)); extract_value(buf, "ID", info->os_id, sizeof(info->os_id)); + extract_value(buf, "ANSI_COLOR", info->distro_color, sizeof(info->distro_color)); // NOUVEAU struct utsname uts; uname(&uts);