Nimbin2git.christianimmanuel.de / Linux & System / wifiConnect / main.c

wifiConnect files

last change 2026-09-04 (2 hours ago)

wget https://git.christianimmanuel.de/linux-system/wifiConnect/archive/wifiConnect.tar.gz
main.c 3.2 KB · 116 lines raw
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define DIR_CONFIG "/etc/sysconfig/wpa_supplicant"
#define CARD "wifi0"
#define INTERFACE "wlan0"

void displayhelp() {
    fprintf(stderr, "Usage: program down|home|studium\n");
    exit(1);
}

int extract_value(const char *filename, const char *key, char *out, size_t outsize) {
    FILE *f = fopen(filename, "r");
    if (!f) return 0;

    char line[256];
    size_t keylen = strlen(key);

    while (fgets(line, sizeof(line), f)) {
        if (strncmp(line, key, keylen) == 0) {
            char *start = strchr(line, '"');
            if (!start) continue;
            start++;
            char *end = strchr(start, '"');
            if (!end) continue;
            size_t len = end - start;
            if (len >= outsize) len = outsize - 1;
            strncpy(out, start, len);
            out[len] = '\0';
            fclose(f);
            return 1;
        }
    }
    fclose(f);
    return 0;
}

int main(int argc, char **argv) {
    if (argc != 2) displayhelp();

    // Set PATH explicitly so system() can find commands when run setuid
    setenv("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", 1);

    const char *passed = argv[1];
    char ssid[64];

    if (strcmp(passed, "down") == 0) {
        // Kill wpa_supplicant for wlan0 - no quotes in pkill pattern
        if (system("/usr/bin/pkill -f 'wpa_supplicant.*-i wlan0'") != 0) {
            fprintf(stderr, "Warning: could not kill wpa_supplicant\n");
        }

        // Bring interface down
        if (system("/usr/sbin/ifdown " CARD ) != 0) {
            fprintf(stderr, "Warning: could not bring down interface %s\n", CARD);
        }

        printf("Disconnected and interface down.\n");
        return 0;
    }

    if (strcmp(passed, "home") == 0) {
        strcpy(ssid, "nSchnellererKeks");
    } else if (strcmp(passed, "studium") == 0) {
        strcpy(ssid, "HN1X");
    } else {
        displayhelp();
    }

    char file_config[128];
    snprintf(file_config, sizeof(file_config), "%s/%s", DIR_CONFIG, ssid);

    // Bring interface up
    char cmd[256];
    snprintf(cmd, sizeof(cmd), "/usr/sbin/ifup %s", CARD);
    if (system(cmd) != 0) {
        fprintf(stderr, "Failed to bring up interface %s\n", CARD);
        return 1;
    }

    char config_ssid[64];
    char psk[64];

    if (!extract_value(file_config, "ssid=", config_ssid, sizeof(config_ssid))) {
        fprintf(stderr, "SSID not found in %s\n", file_config);
        return 1;
    }
    if (!extract_value(file_config, "psk=", psk, sizeof(psk))) {
        fprintf(stderr, "PSK not found in %s\n", file_config);
        return 1;
    }

    // Start wpa_supplicant
    snprintf(cmd, sizeof(cmd), "/usr/sbin/wpa_supplicant -B -i %s -c %s", INTERFACE, file_config);
    if (system(cmd) != 0) {
        fprintf(stderr, "Failed to start wpa_supplicant\n");
        return 1;
    }

    // Ping test 10 times max
    for (int i = 1; i <= 10; i++) {
        sleep(2);
        if (system("/bin/ping -c 3 archlinux.org") == 0) {
            printf("Successfully connected using %s\n", file_config);
            return 0;
        } else {
            fprintf(stderr, "Failed test %d of 10\n", i);
        }
    }

    fprintf(stderr, "Could not connect after 10 attempts\n");
    return 1;
}