/*
 * uniquecheck.c - Implementation of libuniquecheck (system-wide)
 * Copyright (C) 1995-2026  Artyomov Alexander
 * http://self-made-free.ru/
 * aralni@mail.ru
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <ctype.h>
#include "uniquecheck.h"

/* Global variables - not static, accessible from other files */
char *program_name = NULL;
int initialized = 0;

void uniquecheck_init(int argc, char *argv[]) {
    if (initialized) {
        return;
    }
    
    if (argc > 0 && argv[0]) {
        program_name = strrchr(argv[0], '/');
        if (program_name) {
            program_name++;
        } else {
            program_name = argv[0];
        }
        program_name = strdup(program_name);
    }
    
    initialized = 1;
}

const char* uniquecheck_get_program_name(void) {
    return program_name ? program_name : "unknown";
}

int uniquecheck_get_pid(void) {
    return getpid();
}

int uniquecheck_is_running_system(void) {
    DIR *proc_dir;
    struct dirent *entry;
    char path[512];
    char comm[256];
    FILE *fp;
    pid_t current_pid;
    int found = 0;
    
    if (!initialized || !program_name) {
        return 0;
    }
    
    current_pid = getpid();
    
    proc_dir = opendir("/proc");
    if (proc_dir == NULL) {
        return 0;
    }
    
    while ((entry = readdir(proc_dir)) != NULL) {
        if (!isdigit(entry->d_name[0])) {
            continue;
        }
        
        if (atoi(entry->d_name) == current_pid) {
            continue;
        }
        
        snprintf(path, sizeof(path), "/proc/%s/comm", entry->d_name);
        fp = fopen(path, "r");
        if (fp == NULL) {
            continue;
        }
        
        if (fgets(comm, sizeof(comm), fp) == NULL) {
            fclose(fp);
            continue;
        }
        fclose(fp);
        
        size_t len = strlen(comm);
        if (len > 0 && comm[len-1] == '\n') {
            comm[len-1] = '\0';
        }
        
        if (strcmp(comm, program_name) == 0) {
            found = 1;
            break;
        }
    }
    
    closedir(proc_dir);
    return found;
}