|
@@ -0,0 +1,305 @@
|
|
|
+#define _POSIX_C_SOURCE 200809L
|
|
|
+
|
|
|
+#include <stdlib.h>
|
|
|
+#include <stdio.h>
|
|
|
+#include <dirent.h>
|
|
|
+#include <string.h>
|
|
|
+#include <sys/types.h>
|
|
|
+#include <sys/stat.h>
|
|
|
+#include <unistd.h>
|
|
|
+#include <fcntl.h>
|
|
|
+#include <pwd.h>
|
|
|
+#include "error.h"
|
|
|
+#include "color.h"
|
|
|
+#include "constante.h"
|
|
|
+
|
|
|
+typedef struct{
|
|
|
+ char* path;
|
|
|
+ int pid;
|
|
|
+ int uid;
|
|
|
+ char state;
|
|
|
+ char* cmd;
|
|
|
+}processus;
|
|
|
+
|
|
|
+boolean is_numeric(const char* str){
|
|
|
+ while(*str){
|
|
|
+ if(*str < '0' || *str > '9'){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ str++;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+processus** list_process(int* nb){
|
|
|
+ struct dirent** dir;
|
|
|
+ struct stat info;
|
|
|
+ int nbRes;
|
|
|
+ int length, compteur = 0;
|
|
|
+ char* path;
|
|
|
+ processus** result;
|
|
|
+ //Recup les dossiers
|
|
|
+ if((nbRes = scandir("/./proc/", &dir, 0, alphasort)) == ERR){
|
|
|
+ addperror("Impossible de scanner le dossier");
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ //Compte le nombre de resultat
|
|
|
+ for(int i = 0; i < nbRes; i++){
|
|
|
+ //Création chemin
|
|
|
+ length = strlen(dir[i]->d_name) + 10;
|
|
|
+ path = malloc(sizeof(char) * length);
|
|
|
+ memset(path, 0, length);
|
|
|
+ snprintf(path, length, "/./proc/%s/", dir[i]->d_name);
|
|
|
+ //Recup info
|
|
|
+ if(stat(path, &info) == ERR){
|
|
|
+ //Pas un dossier
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //Ne regarde que les dossiers dont le nom est un nombre
|
|
|
+ if(S_ISDIR(info.st_mode) && is_numeric(dir[i]->d_name)){
|
|
|
+ compteur++;
|
|
|
+ }
|
|
|
+ free(path);
|
|
|
+ }
|
|
|
+ //Allocation resultat
|
|
|
+ result = malloc(sizeof(processus*) * compteur);
|
|
|
+ //Ajout des resultats
|
|
|
+ compteur = 0;
|
|
|
+ for(int i = 0; i < nbRes; i++){
|
|
|
+ //Création chemin
|
|
|
+ length = strlen(dir[i]->d_name) + 10;
|
|
|
+ path = malloc(sizeof(char) * length);
|
|
|
+ memset(path, 0, length);
|
|
|
+ snprintf(path, length, "/./proc/%s/", dir[i]->d_name);
|
|
|
+ //Recup info
|
|
|
+ if(stat(path, &info) == ERR){
|
|
|
+ //Pas un dossier
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //Ne regarde que les dossiers dont le nom est un nombre
|
|
|
+ if(S_ISDIR(info.st_mode) && is_numeric(dir[i]->d_name)){
|
|
|
+ result[compteur] = malloc(sizeof(processus));
|
|
|
+ result[compteur]->path = path;
|
|
|
+ result[compteur]->pid = atoi(dir[i]->d_name);
|
|
|
+ result[compteur]->uid = info.st_uid;
|
|
|
+ compteur++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ free(path);
|
|
|
+ }
|
|
|
+ //Libere memoire
|
|
|
+ while(nbRes--){
|
|
|
+ free(dir[nbRes]);
|
|
|
+ }
|
|
|
+ free(dir);
|
|
|
+ //Retour
|
|
|
+ if(nb != NULL){
|
|
|
+ *nb = compteur;
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+boolean read_status(processus* proc){
|
|
|
+ char* file;
|
|
|
+ int length, fd;
|
|
|
+ char buffer;
|
|
|
+ //Recup nom du fichier
|
|
|
+ length = strlen(proc->path) + 7;
|
|
|
+ file = malloc(sizeof(char) * length);
|
|
|
+ memset(file, 0, length);
|
|
|
+ snprintf(file, length, "%sstatus", proc->path);
|
|
|
+ //Ouverture fichier
|
|
|
+ fd = open(file, O_RDONLY);
|
|
|
+ if(fd == ERR){
|
|
|
+ free(file);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ free(file);
|
|
|
+ //Lecture jusqu'a l'etat
|
|
|
+ int i = 0;
|
|
|
+ while(i < 2){
|
|
|
+ if(read(fd, &buffer, sizeof(char)) == ERR){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if(buffer == '\n'){
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ while(buffer != ' '){
|
|
|
+ if(read(fd, &buffer, sizeof(char)) == ERR){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ while(buffer == ' '){
|
|
|
+ if(read(fd, &buffer, sizeof(char)) == ERR){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(read(fd, &buffer, sizeof(char)) == ERR){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ proc->state = buffer;
|
|
|
+ //Fermeture
|
|
|
+ if(close(fd) == ERR){
|
|
|
+ //Rien de particulier
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+boolean read_comm(processus* proc){
|
|
|
+ char* file;
|
|
|
+ int length, fd;
|
|
|
+ int size = 0;
|
|
|
+ char buf = ' ';
|
|
|
+ char* buffer;
|
|
|
+ boolean first = true;
|
|
|
+ //Recup nom du fichier
|
|
|
+ length = strlen(proc->path) + 5;
|
|
|
+ file = malloc(sizeof(char) * length);
|
|
|
+ memset(file, 0, length);
|
|
|
+ snprintf(file, length, "%scomm", proc->path);
|
|
|
+ //Ouverture fichier
|
|
|
+ fd = open(file, O_RDONLY);
|
|
|
+ if(fd == ERR){
|
|
|
+ free(file);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ free(file);
|
|
|
+ //Compte la taille du mot
|
|
|
+ while(buf != '\n' && buf != '\0' && buf != EOF){
|
|
|
+ if(read(fd, &buf, sizeof(char)) == ERR){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //Au 1er tour
|
|
|
+ if(first){
|
|
|
+ //Si fichier vide
|
|
|
+ if(buf == ' '){
|
|
|
+ if(close(fd) == ERR){
|
|
|
+ //Rien de particulier
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ first = false;
|
|
|
+ }
|
|
|
+ size++;
|
|
|
+ }
|
|
|
+ size--;
|
|
|
+ //Revient au debut
|
|
|
+ if(lseek(fd, 0L, SEEK_SET) == ERR){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //Lecture commande
|
|
|
+ buffer = malloc(sizeof(char) * (size + 3));
|
|
|
+ memset(buffer, 0, size + 3);
|
|
|
+ buffer[0] = '[';
|
|
|
+ if(read(fd, buffer + 1, size) == ERR){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ buffer[strlen(buffer)] = ']';
|
|
|
+ proc->cmd = buffer;
|
|
|
+ //Fermeture
|
|
|
+ if(close(fd) == ERR){
|
|
|
+ //Rien de particulier
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+boolean read_cmd(processus* proc){
|
|
|
+ char* file;
|
|
|
+ int length, fd;
|
|
|
+ int size = 0;
|
|
|
+ char buf = ' ';
|
|
|
+ char* buffer;
|
|
|
+ boolean first = true;
|
|
|
+ //Recup nom du fichier
|
|
|
+ length = strlen(proc->path) + 8;
|
|
|
+ file = malloc(sizeof(char) * length);
|
|
|
+ memset(file, 0, length);
|
|
|
+ snprintf(file, length, "%scmdline", proc->path);
|
|
|
+ //Ouverture fichier
|
|
|
+ fd = open(file, O_RDONLY);
|
|
|
+ if(fd == ERR){
|
|
|
+ free(file);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ free(file);
|
|
|
+ //Compte la taille du mot
|
|
|
+ while(buf != '\n' && buf != '\0' && buf != EOF){
|
|
|
+ if(read(fd, &buf, sizeof(char)) == ERR){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //Au 1er tour
|
|
|
+ if(first){
|
|
|
+ //Si fichier vide
|
|
|
+ if(buf == ' '){
|
|
|
+ if(close(fd) == ERR){
|
|
|
+ //Rien de particulier
|
|
|
+ }
|
|
|
+ return read_comm(proc);
|
|
|
+ }
|
|
|
+ first = false;
|
|
|
+ }
|
|
|
+ size++;
|
|
|
+ //On evite les boucles infini
|
|
|
+ if(size > 50){
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ size--;
|
|
|
+ //Revient au debut
|
|
|
+ if(lseek(fd, 0L, SEEK_SET) == ERR){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //Lecture commande
|
|
|
+ buffer = malloc(sizeof(char) * (size + 1));
|
|
|
+ memset(buffer, 0, size + 1);
|
|
|
+ if(read(fd, buffer, size) == ERR){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ proc->cmd = buffer;
|
|
|
+ //Fermeture
|
|
|
+ if(close(fd) == ERR){
|
|
|
+ //Rien de particulier
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+void printps(processus* proc){
|
|
|
+ struct passwd* user;
|
|
|
+ //Recup le nom de l'utilisateur
|
|
|
+ user = getpwuid(proc->uid);
|
|
|
+ if(user == NULL){
|
|
|
+ addperror("Impossible de récupérer le nom de l'utilisateur");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //Affiche
|
|
|
+ if(proc->state == 's'){
|
|
|
+ printf(RED);
|
|
|
+ }
|
|
|
+ printf("%s %d %c %s\n", user->pw_name, proc->pid, proc->state, proc->cmd);
|
|
|
+ if(proc->state == 's'){
|
|
|
+ printf(RESET);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int main(){
|
|
|
+ int total;
|
|
|
+ processus** proc = list_process(&total);
|
|
|
+ for(int i = 0; i < total; i++){
|
|
|
+ //Recup info manquante
|
|
|
+ if(!read_status(proc[i])){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if(!read_cmd(proc[i])){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //Affiche
|
|
|
+ printps(proc[i]);
|
|
|
+ //Supprime
|
|
|
+ free(proc[i]->path);
|
|
|
+ free(proc[i]->cmd);
|
|
|
+ free(proc[i]);
|
|
|
+ }
|
|
|
+ free(proc);
|
|
|
+ return EXIT_SUCCESS;
|
|
|
+}
|