Vous êtes sur la page 1sur 7

// cpi.

exe : C Package Installer


// Un petit gestionnaire de paquets pour le langage C
// Auteur : Bing
// Date : 28/08/2023

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>

// Le chemin vers le dossier de cpi


#define CPI_PATH "C:\\cpi\\"

// Le chemin vers le dossier des paquets de cpi


#define PACKAGES_PATH "C:\\cpi\\packages\\"

// Le nom du fichier pacman


#define PACMAN_FILE "pacman"

// La taille maximale d'un nom de paquet


#define MAX_NAME 50

// La taille maximale d'un chemin de fichier


#define MAX_PATH 256

// La structure d'un paquet


typedef struct {
char name[MAX_NAME]; // Le nom du paquet
char include[MAX_PATH]; // Le chemin vers le dossier include du paquet
char src[MAX_PATH]; // Le chemin vers le dossier src du paquet
} package;

// La structure d'une liste de paquets


typedef struct node {
package data; // Les données du paquet
struct node *next; // Le pointeur vers le prochain élément de la liste
} node;

// La fonction qui affiche l'aide du programme


void help() {
printf("cpi.exe : C Package Installer\n");
printf("Un petit gestionnaire de paquets pour le langage C\n");
printf("Usage : cpi.exe [command] [package_name]\n");
printf("Les commandes disponibles sont :\n");
printf(" install : installe le paquet du nom donné\n");
printf(" uninstall : désinstalle le paquet du nom donné\n");
printf(" list : affiche la liste des paquets installés dans le projet
courant\n");
printf(" list all : affiche la liste de tous les paquets disponibles dans le
dépôt\n");
}

// La fonction qui vérifie si un dossier existe


int dir_exists(char *path) {
struct stat st;
if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) {
return 1; // Le dossier existe
} else {
return 0; // Le dossier n'existe pas
}
}

// La fonction qui vérifie si un fichier existe


int file_exists(char *path) {
struct stat st;
if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
return 1; // Le fichier existe
} else {
return 0; // Le fichier n'existe pas
}
}

// La fonction qui crée un dossier s'il n'existe pas


void create_dir(char *path) {
if (!dir_exists(path)) {
mkdir(path); // Créer le dossier
}
}

// La fonction qui copie un fichier d'un chemin source vers un chemin destination
void copy_file(char *src, char *dest) {
FILE *fsrc, *fdest; // Les pointeurs vers les fichiers source et destination
int c; // Le caractère lu

fsrc = fopen(src, "r"); // Ouvrir le fichier source en lecture


if (fsrc == NULL) {
printf("Erreur : impossible d'ouvrir le fichier %s\n", src);
return;
}

fdest = fopen(dest, "w"); // Ouvrir le fichier destination en écriture


if (fdest == NULL) {
printf("Erreur : impossible d'ouvrir le fichier %s\n", dest);
fclose(fsrc); // Fermer le fichier source
return;
}

while ((c = fgetc(fsrc)) != EOF) { // Lire chaque caractère du fichier source


jusqu'à la fin du fichier
fputc(c, fdest); // Ecrire le caractère dans le fichier destination
}

fclose(fsrc); // Fermer le fichier source


fclose(fdest); // Fermer le fichier destination
}

// La fonction qui supprime un fichier


void delete_file(char *path) {
if (file_exists(path)) {
remove(path); // Supprimer le fichier
}
}

// La fonction qui crée un paquet à partir d'un nom


package create_package(char *name) {
package p; // Le paquet à créer
strcpy(p.name, name); // Copier le nom du paquet
sprintf(p.include, "%s%s\\include\\", PACKAGES_PATH, name); // Construire le
chemin vers le dossier include du paquet
sprintf(p.src, "%s%s\\src\\", PACKAGES_PATH, name); // Construire le chemin
vers le dossier src du paquet
return p; // Retourner le paquet créé
}

// La fonction qui vérifie si un paquet existe dans le dépôt de cpi


int package_exists(package p) {
if (dir_exists(p.include) && dir_exists(p.src)) {
return 1; // Le paquet existe
} else {
return 0; // Le paquet n'existe pas
}
}

// La fonction qui ajoute un paquet à la fin d'une liste de paquets


node *add_package(node *head, package p) {
node *new_node = (node *)malloc(sizeof(node)); // Allouer la mémoire pour le
nouveau noeud
new_node->data = p; // Copier les données du paquet dans le nouveau noeud
new_node->next = NULL; // Initialiser le pointeur vers le prochain élément à
NULL

if (head == NULL) { // Si la liste est vide


head = new_node; // Le nouveau noeud devient la tête de la liste
} else { // Sinon
node *current = head; // Créer un pointeur courant qui pointe vers la tête
de la liste
while (current->next != NULL) { // Parcourir la liste jusqu'au dernier
élément
current = current->next;
}
current->next = new_node; // Faire pointer le dernier élément vers le
nouveau noeud
}

return head; // Retourner la tête de la liste mise à jour


}

// La fonction qui supprime un paquet d'une liste de paquets


node *remove_package(node *head, package p) {
node *current = head; // Créer un pointeur courant qui pointe vers la tête de
la liste
node *previous = NULL; // Créer un pointeur précédent qui pointe vers NULL

while (current != NULL) { // Parcourir la liste jusqu'à la fin ou jusqu'à


trouver le paquet à supprimer
if (strcmp(current->data.name, p.name) == 0) { // Si le nom du paquet
courant correspond au nom du paquet à supprimer
break; // Sortir de la boucle
}
previous = current; // Mettre à jour le pointeur précédent avec le pointeur
courant
current = current->next; // Mettre à jour le pointeur courant avec le
pointeur suivant
}

if (current == NULL) { // Si le paquet n'a pas été trouvé dans la liste


printf("Erreur : le paquet %s n'est pas installé dans ce projet\n",
p.name);
return head; // Retourner la tête de la liste sans modification
}

if (previous == NULL) { // Si le paquet à supprimer est le premier élément de


la liste
head = current->next; // La tête de la liste devient le deuxième élément de
la liste
} else { // Sinon
previous->next = current->next; // Le pointeur précédent pointe vers
l'élément suivant le paquet à supprimer
}

free(current); // Libérer la mémoire du noeud contenant le paquet à supprimer

return head; // Retourner la tête de la liste mise à jour


}

// La fonction qui affiche un paquet sur la sortie standard


void print_package(package p) {
printf("%s\n", p.name); // Afficher le nom du paquet
}

// La fonction qui affiche une liste de paquets sur la sortie standard


void print_list(node *head) {
node *current = head; // Créer un pointeur courant qui pointe vers la tête de
la liste

while (current != NULL) { // Parcourir la liste jusqu'à la fin


print_package(current->data); // Afficher les données du paquet courant

// La fonction qui installe un paquet dans le projet courant


void install_package(package p) {
char include_path[MAX_PATH]; // Le chemin vers le dossier include du projet
courant
char src_path[MAX_PATH]; // Le chemin vers le dossier src du projet courant
char dest_path[MAX_PATH]; // Le chemin vers le fichier destination
DIR *dir; // Le pointeur vers le dossier
struct dirent *entry; // La structure qui contient les informations sur une
entrée du dossier

if (!package_exists(p)) { // Si le paquet n'existe pas dans le dépôt de cpi


printf("Erreur : le paquet %s n'existe pas dans le dépôt de cpi\n",
p.name);
return;
}

sprintf(include_path, "%s\\include\\", getcwd(NULL, 0)); // Construire le


chemin vers le dossier include du projet courant
sprintf(src_path, "%s\\", getcwd(NULL, 0)); // Construire le chemin vers le
dossier src du projet courant

if (!dir_exists(include_path)) { // Si le dossier include n'existe pas dans le


projet courant
printf("Attention : ce projet ne contient pas de dossier include\n");
printf("Voulez-vous créer un dossier include et installer le paquet %s ?
(O/N)\n", p.name);
char answer; // La réponse de l'utilisateur
scanf("%c", &answer); // Lire la réponse de l'utilisateur
if (answer == 'O' || answer == 'o') { // Si l'utilisateur accepte de créer
le dossier include
create_dir(include_path); // Créer le dossier include
} else { // Sinon
printf("Installation du paquet %s annulée\n", p.name);
return;
}
}

dir = opendir(p.include); // Ouvrir le dossier include du paquet


if (dir == NULL) {
printf("Erreur : impossible d'ouvrir le dossier %s\n", p.include);
return;
}

while ((entry = readdir(dir)) != NULL) { // Lire chaque entrée du dossier


include du paquet
if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0)
{ // Si l'entrée n'est pas . ou ..
sprintf(dest_path, "%s%s", include_path, entry->d_name); // Construire
le chemin vers le fichier destination dans le dossier include du projet courant
copy_file(entry->d_name, dest_path); // Copier le fichier source vers
le fichier destination
printf("Le fichier %s a été copié dans %s\n", entry->d_name,
dest_path);
}
}

closedir(dir); // Fermer le dossier include du paquet

dir = opendir(p.src); // Ouvrir le dossier src du paquet


if (dir == NULL) {
printf("Erreur : impossible d'ouvrir le dossier %s\n", p.src);
return;
}

while ((entry = readdir(dir)) != NULL) { // Lire chaque entrée du dossier src


du paquet
if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0)
{ // Si l'entrée n'est pas . ou ..
sprintf(dest_path, "%s%s", src_path, entry->d_name); // Construire le
chemin vers le fichier destination dans le dossier src du projet courant
copy_file(entry->d_name, dest_path); // Copier le fichier source vers
le fichier destination
printf("Le fichier %s a été copié dans %s\n", entry->d_name,
dest_path);
}
}

closedir(dir); // Fermer le dossier src du paquet

printf("Le paquet %s a été installé avec succès\n", p.name);


}
// La fonction qui désinstalle un paquet du projet courant
void uninstall_package(package p) {
char include_path[MAX_PATH]; // Le chemin vers le dossier include du projet
courant
char src_path[MAX_PATH]; // Le chemin vers le dossier src du projet courant
char file_path[MAX_PATH]; // Le chemin vers le fichier à supprimer
DIR *dir; // Le pointeur vers le dossier
struct dirent *entry; // La structure qui contient les informations sur une
entrée du dossier

sprintf(include_path, "%s\\include\\", getcwd(NULL, 0)); // Construire le


chemin vers le dossier include du projet courant
sprintf(src_path, "%s\\", getcwd(NULL, 0)); // Construire le chemin vers le
dossier src du projet courant

dir = opendir(p.include); // Ouvrir le dossier include du paquet


if (dir == NULL) {
printf("Erreur : impossible d'ouvrir le dossier %s\n", p.include);
return;
}

while ((entry = readdir(dir)) != NULL) { // Lire chaque entrée du dossier


include du paquet
if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0)
{ // Si l'entrée n'est pas . ou ..
sprintf(file_path, "%s%s", include_path, entry->d_name); // Construire
le chemin vers le fichier à supprimer dans le dossier include du projet courant
delete_file(file_path); // Supprimer le fichier
printf("Le fichier %s a été supprimé de %s\n", entry->d_name,
file_path);
}
}

closedir(dir); // Fermer le dossier include du paquet

dir = opendir(p.src); // Ouvrir le dossier src du paquet


if (dir == NULL) {
printf("Erreur : impossible d'ouvrir le dossier %s\n", p.src);
return;
}

while ((entry = readdir(dir)) != NULL) { // Lire chaque entrée du dossier src


du paquet
if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0)
{ // Si l'entrée n'est pas . ou ..
sprintf(file_path, "%s%s", src_path, entry->d_name); // Construire le
chemin vers le fichier à supprimer dans le dossier src du projet courant
delete_file(file_path); // Supprimer le fichier
printf("Le fichier %s a été supprimé de %s\n", entry->d_name,
file_path);
}
}

closedir(dir); // Fermer le dossier src du paquet

printf("Le paquet %s a été désinstallé avec succès\n", p.name);


}
// La fonction qui affiche la liste des paquets installés dans le projet courant
void list_packages() {
char pacman_path[MAX_PATH]; // Le chemin vers le fichier pacman
FILE *fp; // Le pointeur vers le fichier pacman
char line[MAX_NAME]; // La ligne lue dans le fichier pacman

sprintf(pacman_path, "%s\\%s", getcwd(NULL, 0), PACMAN_FILE); // Construire le


chemin vers le fichier pacman

if (!file_exists(pacman_path)) { // Si le fichier pacman n'existe pas dans le


projet courant
printf("Aucun paquet n'est installé dans ce projet\n");
return;
}

fp = fopen(pacman_path, "r"); // Ouvrir le fichier pacman en lecture


if (fp == NULL) {
printf("Erreur : impossible d'ouvrir le fichier %s\n", pacman_path);
return;
}

printf("Les paquets installés dans ce projet sont :\n");


while (fgets(line, MAX_NAME, fp) != NULL) { // Lire chaque ligne du fichier
pacman jusqu'à la fin du fichier
line[strcspn(line, "\n")] = '\0'; // Supprimer le caractère de fin de ligne
printf("%s\n", line); // Afficher le nom du paquet
}

fclose(fp); // Fermer le fichier pacman


}

// La fonction qui affiche la liste de tous les paquets disponibles dans le dépôt
de cpi
void list_all_packages() {
DIR *dir; // Le pointeur vers le dossier des paquets de cpi
struct dirent *entry; // La structure qui contient les informations sur une
entrée du dossier

dir = opendir(PACKAGES_PATH); // Ouvrir le dossier des paquets de cpi


if (dir == NULL) {
printf("Erreur : impossible d'ouvrir le dossier %s\n", PACKAGES_PATH);
return;
}

printf("Les paquets disponibles dans le dépôt de cpi sont :\n");


while ((entry = readdir(dir)) != NULL) { // Lire chaque entrée du dossier des
paquets de cpi
if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0)
{ // Si l'entrée n'est pas . ou ..
printf("%s\n", entry->d_name); // Afficher le nom

Vous aimerez peut-être aussi