#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include<getopt.h>
#include <time.h>
#include <dirent.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#define FINAL -1
#define NOFINAL 0
#define PATH_MAXIMO 2048
char TipoFichero (mode_t m){
switch (m&S_IFMT) { /*and bit a bit con los bits de formato,0170000 */
case S_IFSOCK: return 's'; /*socket */
case S_IFLNK:
return 'l';
/*symbolic link*/
case S_IFREG:
return '-';
/* fichero normal*/
case S_IFBLK:
return 'b';
/*block device*/
case S_IFDIR:
return 'd';
/*directorio */
case S_IFCHR:
return 'c';
/*char device*/
case S_IFIFO:
return 'p';
/*pipe*/
default: return '?';
/*desconocido, no deberia aparecer*/
}
}
void ConvierteModo (mode_t m, char *permisos){
strcpy (permisos,"---------- ");
permisos[0]=TipoFichero(m);
if (m&S_IRUSR) permisos[1]='r';
if (m&S_IWUSR) permisos[2]='w';
if (m&S_IXUSR) permisos[3]='x';
if (m&S_IRGRP) permisos[4]='r';
if (m&S_IWGRP) permisos[5]='w';
if (m&S_IXGRP) permisos[6]='x';
if (m&S_IROTH) permisos[7]='r';
if (m&S_IWOTH) permisos[8]='w';
if (m&S_IXOTH) permisos[9]='x';
if (m&S_ISUID) permisos[3]='s';
if (m&S_ISGID) permisos[6]='s';
if (m&S_ISVTX) permisos[9]='t';
}
char * ConvierteModo2 (mode_t m){
static char permisos[12];
strcpy (permisos,"---------- ");
/*propietario*/
/*grupo*/
/*resto*/
/*setuid, setgid y stickybit*/
permisos[0]=TipoFichero(m);
if (m&S_IRUSR) permisos[1]='r';
if (m&S_IWUSR) permisos[2]='w';
if (m&S_IXUSR) permisos[3]='x';
if (m&S_IRGRP) permisos[4]='r';
if (m&S_IWGRP) permisos[5]='w';
if (m&S_IXGRP) permisos[6]='x';
if (m&S_IROTH) permisos[7]='r';
if (m&S_IWOTH) permisos[8]='w';
if (m&S_IXOTH) permisos[9]='x';
if (m&S_ISUID) permisos[3]='s';
if (m&S_ISGID) permisos[6]='s';
if (m&S_ISVTX) permisos[9]='t';
/*propietario*/
/*grupo*/
/*resto*/
/*setuid, setgid y stickybit*/
return (permisos);
}
/*-------------------------------*/
int EliminarDirectorio( char *cadena) {
DIR *dir = opendir(cadena);
int longitud = strlen(cadena);//longitud de la cadena
int r = -1;
if (dir) {//que se pueda abrir el directorio
struct dirent *p;//de la libreria
r = 0;
while ((r==0) && (p=readdir(dir))) {//mientras se pueda leer lo que haya en el directorio...
int r2 = -1;
char *buf;
int len;
if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) {//para evitar entrar en los directorios padre y actual
continue;
}
len = longitud + strlen(p->d_name) + 2; //directorio+archivo+separador(2)
buf = malloc(len);
if (buf) {
struct stat statbuf;
snprintf(buf, len, "%s/%s", cadena, p->d_name);//para evitar desbordamiento del buf**
if (!stat(buf, &statbuf)) {
if (S_ISDIR(statbuf.st_mode)) {
r2 = EliminarDirectorio(buf);}//aqui esta la llamada recursiva
else {
r2 = unlink(buf);}//borrar un archivo especifico
}//if del stat
free(buf);
}//if del buf
r = r2;
}//while
closedir(dir);
}
if (!r) {
r = rmdir(cadena);}//cuando este vacia la carpeta,se borra[0 si ha tenido exito,-1 si ha fallado]
return r;
}
/*-------------------------------*/
int Dir(char **cadena,int num){
char ruta[PATH_MAXIMO];
if (cadena[1] == NULL){
if (NULL == getcwd(ruta,PATH_MAXIMO)) {
perror("ERROR.getcwd:\n");
}else
printf("El directorio actual es %s.\n",ruta);
}
else if (chdir(cadena[1]) == 0){
printf("cambiamos de directorio \n");
}
else {
perror("ERROR.CHDIR:\n");
}
return 0;
}
/*-------------------------------*/
int Eliminar(char **cadena){
if( remove( cadena[1] ) != 0 ){
perror("ERROR.remove:NO ENCONTRADO\n");
return -1;
}
else{
puts( "Archivo eliminado" );
return 0;}
}
/*-------------------------------*/
int Rdir(char **cadena,int num){
struct stat buf;
if (cadena[1]==NULL){ //cuando no se especifica la carpeta
perror("ERROR:DIRECTORIO NO ESPECIFICADO\n");
}else if (strcmp(cadena[1],"-f")==0) {
if (cadena[2]!=NULL){ //con la opcion -f
if (stat(cadena[2],&buf)==-1)
perror("ERROR.DIRECTORIO:NO ENCONTRADO\n");
else {
EliminarDirectorio(cadena[2]);
printf("Eliminado\n");}
}//if del directorio
}//else
else if (cadena[1]!=NULL){ //carpeta vacía
if (stat(cadena[1],&buf)==-1)
perror("ERROR.DIRECTORIO:NO ENCONTRADO\n");
else{
rmdir(cadena[1]);
printf("Eliminado\n");}
}
return 0;
}
/*-------------------------------*/
int esdir(char * path){
struct stat st_info;
if (stat(path, &st_info)<0){
return 0;
}else{
return S_ISDIR(st_info.st_mode);
}
}
/*-------------------------------*/
char * opcion(int *a, int *r, int *s, char **cadena){
char * path = "./";
int i;
*a = 0;
*r = 0;
*s = 0;
int contador;
for (i = 0; cadena[i]!=NULL;i++){
if (strcmp(cadena[i],"-a")==0){*a = 1; }
else if (strcmp(cadena[i],"-r")==0){ *r = 1; }
else if (strcmp(cadena[i],"-s")==0){ *s = 1; }
else { path = cadena[i];
}
contador=i;
}
if ((strcmp(cadena[contador],"-a")==0)||(strcmp(cadena[contador],"list")==0)||(strcmp(cadena[contador],"-r")==0)||(strcmp(cadena[contador],"-s")==0)){
if (!esdir(cadena[contador])){
printf("El directorio actual es: %s\n", cadena[contador]);
path=".";
}
}else {
path=cadena[contador];}
return path;
}
/*-------------------------------*/
void ListadoOculto(char*path,char*auxpath ){ //Para la opcion -a del list
DIR *dir;
struct dirent *diren;
dir = opendir(path);
diren=readdir(dir);
if ( diren->d_name[0] == '.'){
char *ptr;
ptr = realpath(path, auxpath);
printf("%2s\n", ptr);//no meter free
free(ptr); }
else if (realpath(path, auxpath) == 0)
perror("ERROR.realpath");
closedir(dir);
}
/*-------------------------------*/
void mInfo(char *path){ //para el listado asecas
struct stat estado;
struct passwd *pwd;
struct group *grp;
if (lstat(path,&estado)!=0){
printf("Error\t");
}else{ char *c;
printf(" %1lu " ,estado.st_ino);//numero inodo
printf(" %1s ",ConvierteModo2(estado.st_mode));//permisos
printf(" %1lld " , (unsigned long long)estado.st_nlink);
/* nombre y grupo de usuario*/
if ((pwd = getpwuid(estado.st_uid)) != NULL)//nombre usuario
printf(" %1s", pwd->pw_name);
else
printf(" %1d", estado.st_uid);
if ((grp = getgrgid(estado.st_gid)) != NULL)//nombre grupo
printf(" %1s", grp->gr_name);
else
printf(" %1d", estado.st_gid);
/* */
printf(" %1lld ", (unsigned long long)estado.st_size); //tamaño fichero
c = ctime(&estado.st_mtime);
c[strlen(c)-1]='\0';
printf("%1s",c);
}
}
/*-------------------------------*/
int Listar( int a,int s, char *path,int entra){
DIR *dir;
int contador=0;
char auxpath[PATH_MAXIMO];
struct stat tamans;
struct dirent *diren;
dir = opendir(path);
if (!esdir(path)){
perror("ERROR.opendir:fichero no encontrado");
}else{
while (diren = readdir(dir)){
if ((!a)&&(s)){ //list -s
contador++;
if ( diren->d_name[0] == '.')
continue;
sprintf(auxpath,"%s %s", path, diren->d_name);
if (lstat(path,&tamans)!=0)
printf("Error\t");
else
printf(" %2lld ", (unsigned long long)tamans.st_size/1024); //tamaño entre 1024
printf("%s",auxpath);//nombre fichero
printf("\t");
}
else if ((a)&&(!s)){ //list -a
contador++;
ListadoOculto(path,auxpath);
sprintf(auxpath,"%2s %2s", path, diren->d_name);
//mInfo(auxpath);
printf("%2s",auxpath);
}//fin del else de -a
else if (((entra==1) && s && a )|| (a && s && !entra)){
contador++;
if (a && s )//opcion -a -s
{
ListadoOculto(path,auxpath);//parte del -a
sprintf(auxpath,"%s/%s", path,diren->d_name);
if (lstat(path,&tamans)!=0)//parte del -s
printf("Error\t");
else
printf(" %2lld ", (unsigned long long)tamans.st_size/1024); //tamaño entre 1024
printf("%s",auxpath);//nombre fichero
printf("\t");}
}
else if ((entra==1)&&(s)){//list -r asecas en listado corto
if (diren->d_name[0] == '.')
continue;
sprintf(auxpath,"%s/%s", path, diren->d_name);
printf("%s\n",auxpath);
}
else if ((entra==1)&&(!s)){//list -r asecas en listado largo
if (diren->d_name[0] == '.')
continue;
sprintf(auxpath,"%s/%s", path, diren->d_name);
mInfo(auxpath);
printf("%s\n",auxpath);
}
else if(!a && !s && !entra){//list asecas
if (diren->d_name[0] == '.')
continue;
sprintf(auxpath,"%s/%s", path, diren->d_name);
mInfo(auxpath);
printf("%s\n",auxpath);}
if (contador==3){
printf("\n");
contador=0;
}
}//while
}
printf("\n");//no hacer free
closedir(dir);
return 0;
}
/*-------------------------------*/
void ListaRecursiva(int a, int s, char * path,int entra){
DIR *dir;
char auxpath[1024];
struct dirent *diren;
Listar(a,s,path,entra);
if ((dir=opendir(path))==NULL)
return;
while (diren = readdir(dir)){
if (!strcmp(diren->d_name,".") || !strcmp(diren->d_name,".."))
continue;
sprintf(auxpath,"%s/%s", path, diren->d_name);
if (esdir(auxpath)){
printf("%s\n",diren->d_name);
ListaRecursiva(a,s,auxpath,entra);
}
}
closedir(dir);
}
/*-------------------------------*/
void List(char **cadena,int num){
int a=0,r=0,s=0;
char *path;
int entra;
path = opcion(&a,&r,&s,cadena);
if (path!=NULL){
if (r){ // con opcion de listado recursivo -r
entra=1;
ListaRecursiva(a,s,path,entra);
}else{
entra=0;
Listar(a,s,path,entra);
}
}
else{
perror("ERROR.DIRECTORIO:fichero no encontrado");
}
}
/*-------------------------------*/
int Pid(char ** cadena,int num){
if (num==1){
printf("Mi proceso ID : %d\n", getpid());}
else if (strcmp(cadena[1],"-p")==0){
printf("Mi proceso Padre es ID : %d\n", getppid());
}
else
perror("ERROR:mala especificación\n");
return 0;
}
/*-------------------------------*/
int TrocearCadena(char * cadena, char * trozos[]){
int i=1;
if ((trozos[0]=strtok(cadena," \n\t"))==NULL)
return 0;
while ((trozos[i]=strtok(NULL," \n\t"))!=NULL)
i++;
return i;
}
/*-------------------------------*/
char* escanear(){
char * linea = (char *) malloc (1000);
linea = gets(linea);
return linea;
}
/*-------------------------------*/
void autores(){
printf("%15s","Autor: Andrés Cardoso -> nick:andres.cardoso \n ");
}
/*-------------------------------*/
int ejecutacomando(char **trozos,char * linea,int numeros) {
if ((strcmp(trozos[0],"fin")==0) ||
(strcmp(trozos[0],"quit")==0) ||
(strcmp(trozos[0],"exit")==0)) {
return FINAL;
} else if (strcmp(trozos[0],"getpid")==0) {
Pid(trozos, numeros);return NOFINAL;
} else if (strcmp(trozos[0],"list")==0) {
List(trozos, numeros);return NOFINAL;
} else if (strcmp(trozos[0],"delete")==0) {
Eliminar(trozos);return NOFINAL;
} else if (strcmp(trozos[0],"cdir")==0) {
Dir(trozos, numeros);return NOFINAL;
} else if (strcmp(trozos[0],"autores")==0) {
autores();return NOFINAL;
} else if (strcmp(trozos[0],"rdir")==0) {
Rdir(trozos,numeros);return NOFINAL;
}
else {
perror("ERROR.STRCMP:Caracter no admitido,vuelva a intentarlo\n");return NOFINAL;}
}
/*-------------------------------*/
/*-------------------------------*/
void main(){
char *trozos[1000];
int numero;
char * cadenita;
while (1){
printf("\n###");
cadenita=escanear();
numero=TrocearCadena(cadenita, trozos);
if (!numero) {free(cadenita);continue;}
int valor = ejecutacomando(trozos,cadenita,numero);
free(cadenita);
if (valor==FINAL)
break; //salida del shell
}//while
}//main
WAAAAAAAAAAAAAAA
ResponderEliminar