All pastes #464422 Raw Edit

Anonymous

public c v1 · immutable
#464422 ·published 2007-04-29 14:27 UTC
rendered paste body
#include <string.h>#include <stdio.h>#include <sys/types.h>#include <dirent.h>#include <sys/stat.h> #include <unistd.h>#include <stdlib.h>//Options#define OPT_ALL_FILES 			0x00000001 // -a, --all#define OPT_CTIME_SORT 			0x00000002 // -c, --time=ctime, --time=status#define OPT_ALL_FILES_NOSORT 	0x00000401 // -f#define OPT_INODE 				0x00000004 // -i, --inode#define OPT_LONG 				0x00000008 // -l, --format=long, --format=verbose#define OPT_NUMERIC_UIDGID 		0x0000000f // -n, --numeric-uid-gid#define OPT_TYPE_CHAR 			0x00000010 // -p#define OPT_REVERSE_SORT 		0x00000020 // -r, --reverse#define OPT_MTIME_SORT 			0x00000040 // -t, --sort=time#define OPT_ATIME_SORT 			0x00000080 // -u, --time=atime, --time=access, --time=use#define OPT_IGNORE_BACKUPS 		0x000000f0 // -B, --ignore-backups#define OPT_FULLTYPE_CHAR 		0x00000100 // -F, --classify#define OPT_RECURSIVE 			0x00000200 // -R, --recursive#define OPT_NOSORT 				0x00000400 // -U, --sort=none//Booléenstypedef enum {FALSE=0, TRUE} bool;//Filtres#define ISBACKUP(file) (file[strlen(file) - 1] == '~') ? TRUE : FALSE#define ISDOTDIR(file) (file[0] == '.') ? TRUE : FALSE//Le type d'une entréestruct ls_node{	struct dirent *entry;	struct stat ent_stat;	struct ls_node *next;};//Fonctions de comparaison pour le tri	/* Avec ctime */bool ctime_lt(struct ls_node *a, struct ls_node *b){	return a->ent_stat.st_ctime  <  b->ent_stat.st_ctime;}bool ctime_gt(struct ls_node *a, struct ls_node *b){	return a->ent_stat.st_ctime  >  b->ent_stat.st_ctime;}	/* Avec mtime */bool mtime_lt(struct ls_node *a, struct ls_node *b){	return a->ent_stat.st_ctime  <  b->ent_stat.st_ctime;}bool mtime_gt(struct ls_node *a, struct ls_node *b){	return a->ent_stat.st_ctime  >  b->ent_stat.st_ctime;}	/* Avec atime */bool atime_lt(struct ls_node *a, struct ls_node *b){	return a->ent_stat.st_ctime  <  b->ent_stat.st_ctime;}bool atime_gt(struct ls_node *a, struct ls_node *b){	return a->ent_stat.st_ctime  >  b->ent_stat.st_ctime;}	/* Alphabétique */bool alpha_gt(struct ls_node *a, struct ls_node *b){	return strcasecmp(a->entry->d_name, b->entry->d_name) > 0;}	bool alpha_lt(struct ls_node *a, struct ls_node *b){	return strcasecmp(a->entry->d_name, b->entry->d_name) < 0;}	/*Pas de comparaison */bool no_sort(struct ls_node *a, struct ls_node *b){	return FALSE;}//Type Pointeur vers le plus_petit choisitypedef bool (*cmp) (struct ls_node *, struct ls_node *);//Filtrage de certains fichiersbool filtered(int options, struct ls_node *node){	if( !(options & OPT_ALL_FILES) ){		if (ISDOTDIR(node->entry->d_name )){			return TRUE;		}	}	if(options & OPT_IGNORE_BACKUPS){		if (ISBACKUP(node->entry->d_name) ){			return TRUE;		}	}	return FALSE;}//Plus de mémoirevoid no_memory(){	puts ("Plus de mémoire");	exit(0);}//Insérer un noeud à un emplacement dicté par la fonction de tristruct ls_node * insert_node (struct ls_node *root, struct ls_node *current, cmp plus_petit){	struct ls_node *root_save = root;	if(root == NULL){		return current;	}	if(!plus_petit(current, root)){		while (root->next != NULL && !plus_petit(current, root->next))		{			root = root->next;		}		current->next = root->next;		root->next = current;		return root_save;	}	else{		current->next = root;		return current;	}	}//Effacer tous les noeudsvoid free_nodes(struct ls_node *root){	if (root == NULL){		return;	}	free_nodes(root->next);	free(root);}void display_node(struct ls_node *node){	printf("%s\n",node->entry->d_name);}/* Le traitement principal */void ls(int options, char *rep, cmp plus_petit){	DIR *d = opendir(rep);	//Entrée de repertoire courante	struct dirent *curdir;	if(d == NULL){		printf("ls: %s: Ne parvient pas à ouvrir le repertoire\n", rep);		return;	}	//La liste du contenu du repertoire	struct ls_node *root = NULL;	//Noeud courant	struct ls_node *current;	//Chemin d'un noeud	char * current_path;		//Plus commode si le repertoire se termine par un slash	if(rep[strlen(rep)-1] != '/'){		rep=realloc(rep, strlen(rep) + 2);		sprintf(rep, "%s/", rep);	}	while ( (curdir = readdir (d)) != NULL )	{		current = (struct ls_node *) calloc (1, sizeof(struct ls_node));		if (current == NULL){			no_memory();		}		current->entry = curdir;		current_path = (char *)calloc (1, strlen(rep) + strlen(curdir->d_name) + 1);		strcpy (current_path, rep);		strcat (current_path, curdir->d_name);		if(stat (current_path, &current->ent_stat) == -1){			printf("%s\n",current_path);		}		free(current_path);		if(!filtered(options, current) ){			root = insert_node (root, current, plus_petit);		}		else{			free(current);		}	}	current=root;	while(current!=NULL){		display_node(current);		if((options & OPT_RECURSIVE)  &&  (current->ent_stat.st_mode & S_IFDIR) ){			current_path = (char *)calloc (1, strlen(rep) + strlen(current->entry->d_name) + 1);			strcpy (current_path, rep);			strcat (current_path, current->entry->d_name);			printf("\n%s:\n", current_path);			ls(options, current_path, plus_petit);			free(current_path);		}		current=current->next;	}	closedir(d);	free_nodes(root);			}int main(int argc, char **argv){	int i;	//Pour les options	int options = 0;	int opt;	//Le repertoire à analyser	char *rep = (char *)malloc(2);	strcpy(rep, ".");	//Fonction de tri par défaut	cmp plus_petit = &alpha_lt;	while ( (opt = getopt(argc, argv, "acfilnprtuBRFU")) != -1 )	{		switch (opt)		{			case 'a':				options |= OPT_ALL_FILES;				break;			case 'c':				options |= OPT_CTIME_SORT;				if (options & OPT_ATIME_SORT){ 					options ^= OPT_ATIME_SORT;				}				if (options & OPT_MTIME_SORT){ 					options ^= OPT_MTIME_SORT;				}				if (options & OPT_CTIME_SORT){ 					options ^= OPT_CTIME_SORT;				}				break;			case 'f':				options |= OPT_ALL_FILES_NOSORT;				if (options & OPT_MTIME_SORT){ 					options ^= OPT_MTIME_SORT;				}				if (options & OPT_ATIME_SORT){ 					options ^= OPT_ATIME_SORT;				}				if (options & OPT_CTIME_SORT){ 					options ^= OPT_CTIME_SORT;				}				break;			case 'i':				options |= OPT_INODE;				break;			case 'l':				options |= OPT_LONG;				break;							case 'n':				options |= OPT_NUMERIC_UIDGID;				break;			case 'p':				options |= OPT_TYPE_CHAR;				break;			case 'r':				options |= OPT_REVERSE_SORT;				break;			case 't':				options |= OPT_MTIME_SORT;				if (options & OPT_ATIME_SORT){ 					options ^= OPT_ATIME_SORT;				}				if (options & OPT_NOSORT){ 					options ^= OPT_NOSORT;				}				if (options & OPT_CTIME_SORT){ 					options ^= OPT_CTIME_SORT;				}				break;			case 'u':				options |= OPT_ATIME_SORT;				if (options & OPT_MTIME_SORT){ 					options ^= OPT_MTIME_SORT;				}				if (options & OPT_NOSORT){ 					options ^= OPT_NOSORT;				}				if (options & OPT_CTIME_SORT){ 					options ^= OPT_CTIME_SORT;				}				break;					case 'B':				options |= OPT_IGNORE_BACKUPS;				break;				case 'F':				options |= OPT_FULLTYPE_CHAR;				break;			case 'R':				options |= OPT_RECURSIVE;				break;			case 'U':				options |= OPT_NOSORT;				if (options & OPT_MTIME_SORT){ 					options ^= OPT_MTIME_SORT;				}				if (options & OPT_ATIME_SORT){ 					options ^= OPT_ATIME_SORT;				}				if (options & OPT_CTIME_SORT){ 					options ^= OPT_CTIME_SORT;				}				break;		}	}	//On va chercher le repertoire	while (*(++argv)!=NULL)	{		if (argv[0][0] != '-'){			free(rep);			rep = (char *)malloc(strlen(*argv) +1);			strcpy(rep, *argv);		}	}	//Cherche le plus_petit	if (options & OPT_CTIME_SORT){		if(options & OPT_REVERSE_SORT){			plus_petit = &ctime_gt;		}		else{			plus_petit = &ctime_lt;		}	}	else if (options & OPT_MTIME_SORT){			if(options & OPT_REVERSE_SORT){				plus_petit = &mtime_gt;			}			else{				plus_petit = &mtime_lt;			}	}	else if (options & OPT_ATIME_SORT){			if(options & OPT_REVERSE_SORT){				plus_petit = &atime_gt;			}			else{				plus_petit = &atime_lt;			}	}	else if (options & OPT_ATIME_SORT){			if(options & OPT_REVERSE_SORT){				plus_petit = &atime_gt;			}			else{				plus_petit = &atime_lt;			}	}	else if (options & OPT_NOSORT){			plus_petit = &no_sort;	}	else if (options & OPT_REVERSE_SORT){			plus_petit = &alpha_gt;	}		//On lance tout	ls(options, rep, plus_petit);	free(rep);	return 0;}