Advertisement
Guest User

Untitled

a guest
Nov 23rd, 2017
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.50 KB | None | 0 0
  1. /*  COMPILADOR: GCC 3.3.4-11 SO: LINUX SUSE 9.2
  2.     Fecha: octubre 2006 */
  3. #include <stdio.h>
  4. #include <stdio_ext.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. #include <dirent.h>
  9. #define max_args 13  /*Numero maximo de argumentos (-1) cuando se trate de un comando externo*/
  10. #define maxln_Com_Amb 105 /*Numero de caracteres maximo para comando las variables de ambiente*/
  11.  
  12. /*Declarando variables*/
  13. char comando[maxln_Com_Amb]; /*Esta var lee el comando que ingrese el usuario*/
  14. char *args[max_args]; /*en este arreglo se almacenan los argumentos del comando ingresado*/
  15. /*Declarando variables de ambiente*/
  16. char SHELL[maxln_Com_Amb];
  17. char PATH[maxln_Com_Amb];
  18. char HOME[maxln_Com_Amb];
  19. char PWD[maxln_Com_Amb];
  20. /*Declarando cabeceras de funciones*/
  21. void separaArgs(void); /*Esta funcion separa la cadena ingresada por el usuario en
  22.   palabras individuales, la 1ra palabra sera considerada comando y el resto sus argumentos*/
  23. void listaDir(void); /*Esta func ejecuta el comando dir*/
  24. void eco(void); /*Esta func ejecuta el comando echo*/
  25. void comExterno(void); /*Esta func ejecuta lo que se considere comandos externos*/
  26.  
  27. main(void){
  28.   int continuar=1;
  29.   /*Inicializando variables de ambiente*/
  30.   getcwd(PWD,maxln_Com_Amb); /*Obteniendo la ruta actual y cargando en PWD*/
  31.   strcpy(PATH,getenv("PATH")); /*Obteniendo el directorio del path y cargando en PATH*/
  32.   /*strcpy(HOME,getenv("HOME")); Obteniendo el directorio home y cargando en HOME
  33.   strcpy(SHELL,getenv("SHELL")); Obteniendo el directorio de shell y cargando en SHELL
  34. NOTA: en el documento con las especificaciones del programa se pide que el valor
  35. de SHELL y de HOME sea la ruta absoluta desde donde se esta ejecutando el shell por
  36. ello no he dejado los valores que se obtienen desde el sistema, en su lugar ambas
  37. valdran El primer valor de PWD*/
  38.    strcpy(HOME,PWD);
  39.    strcpy(SHELL,PWD);
  40.   do{ /*Ciclo principal*/
  41.     printf(" %s>",PWD); /*Imprimiendo el indicador del shell (directorio actual)*/
  42.     __fpurge(stdin); /*Limpiando el buffer de entrada de teclado*/
  43.     memset(comando,'\0',maxln_Com_Amb); /*Borrando cualquier contenido previo de comando*/
  44.     scanf("%[^\n]s",comando); /*Esperar hasta que el usuario ingrese algun comando*/
  45.     if(strlen(comando)>0){ /*Actuar solo si comando contiene algo y solo un enter*/
  46.       separaArgs(); /*Separar comando de sus argumentos*/
  47.       if(strcmp(comando,"cd")==0){ /*Si el comando es cd*/
  48.         if(args[1]) /*Verificar que cuente con el argumento necesario*/
  49.     if(chdir(args[1])!=0) /*La func chdir hace el cambio de directorio si regresa un valor
  50.             diferente de cero la operacion no se pudo ejecutar con exito*/
  51.      printf("Error! %s no existe o no se puede cambiar a este directorio\n",args[1]);
  52.    else getcwd(PWD,maxln_Com_Amb);/*En caso de cambio exitoso actualizar PWD*/
  53.       }
  54.       else if(strcmp(comando,"dir")==0)
  55.         listaDir(); /*Si el comando es el dir llamar a la func correspondiente*/
  56.       else if(strcmp(comando,"clr")==0)
  57.         strcpy(comando,"clear"), comExterno(); /*Para limpiar la pantalla aprovecho la
  58.          funcion de comando externo y le paso como comando clear. Otra seria
  59.          implementar la func clear de la libreria ncurses.h pero tendria que
  60.          modificar bastantes cosas*/
  61.       else if(strcmp(comando,"environ")==0){
  62.         printf(" Variables de ambiente:\n");/*Mostrar los valores de las var de ambiente*/
  63.         printf("  HOME=%s\n  PWD=%s\n",HOME,PWD);
  64.         printf("  SHELL=%s\n  PATH=%s\n",SHELL,PATH);
  65.       }
  66.       else if(strcmp(comando,"echo")==0){
  67.         if(args[1]) eco(); /*Si hay al menos 1 argumento llamar la func que ejecuta echo*/
  68.       }
  69.       else if(strcmp(comando,"pwd")==0)
  70.         printf("%s\n",PWD); /*Mostrar el contenido de PWD (Directorio actual)*/
  71.       else if(strcmp(comando,"quit")==0)
  72.         continuar=0; /*Cambiar el valor de continuar para que termine*/
  73.       else comExterno(); /*Cualquier otra entrada llamar a comExterno*/
  74.     }
  75.   }while(continuar); /*Volver a ejecutar mientras no ingresen quit*/
  76.   return 0;
  77. }
  78.  
  79. void separaArgs(void){
  80.   int i;
  81.   for(i=0;i<(max_args-1);i++) args[i]=NULL; /*Borrar argumento previo que pudiera existir*/
  82.   strtok(comando," "), i=0; /*separar palabras individuales usando tokens (espacio vacio)*/
  83.   args[i]=comando; /*El 1er argumento sera comando por un requerimiento de execvp*/
  84.   while((args[++i]=strtok(NULL," "))!=NULL && i<(max_args-2));
  85. }
  86.  
  87. void listaDir(void){
  88.   char ruta[maxln_Com_Amb]; /*Var auxiliar para formar la ruta solicitada por el usuario*/
  89.   int archs; /*Numero de archivos encontrados en el dir indicado*/
  90.   int cnt=-1;
  91.   struct dirent **lista; /*var que guarda la lista de archivos/dirs encontrados*/
  92.   strcpy(ruta,PWD); /*Suponemos que el dir solicitado es de la ruta actual*/
  93.   if(args[1]) strcat(ruta,"/"), strcat(ruta,args[1]);
  94.     /*pero si se trata de una(s) subcarpeta(s) las concatenamos*/
  95.   archs=scandir(ruta,&lista,0,alphasort); /*Mandamos revisar el dir solicitado*/
  96.   if(archs<0) /*En caso de falla enviar mensaje*/
  97.     printf("Error no existe o no se pudo leer [%s]\n",ruta);
  98.   else if(archs==2){ /*Si solo encontro los directorios . (actual) y .. (padre)
  99.     consideraremos que el dir esta vacio a efectos practicos*/
  100.     printf(" El directorio [%s] esta vacio",ruta);
  101.   }
  102.   else{ /*Si se encontra al menos un archivo/directorio mostrarlo*/
  103.     printf(" Archivos y carpetas encontrados en: [%s]\n",ruta);
  104.     while(++cnt<archs)
  105.       if(strcmp(lista[cnt]->d_name,".")!=0 && strcmp(lista[cnt]->d_name,"..")!=0)
  106.         printf(" %s\n",lista[cnt]->d_name);
  107.   }
  108. }
  109.  
  110. void eco(void){
  111.   int i;
  112.   int j;
  113.   int k=0;
  114.   char aux[6];
  115.   while(args[++k]){ /*Aqui hay que recorrer argumento por  argumentos mientra este tenga valor*/
  116.     for(i=0;i<strlen(args[k]);i++){ /*Para imprimir lo hare de caracter en caracter para
  117.       interceptar el $ en caso de que este presente en cuanquier posicion*/
  118.       if(args[k][i]!='$') printf("%c",args[k][i]);
  119.       else{ /*Si se encuentra el $ ver si le sigue el nombre de alguna variable de ambiente
  120.         en caso afirmativo imprimir el valor correspondiente, sino imprimir el simbolo*/
  121.         j=-1;
  122.         while(++j<5 && (i+j+1)<strlen(args[k]) && args[k][i+j+1]!='\0')
  123.           aux[j]=args[k][i+j+1]; /*En aux copiar la sub cadena que sigue al simbolo $*/
  124.         aux[j]='\0';
  125.         if(strcmp(aux,"SHELL")==0) /*Ver si hay que imprimir el valor de SHELL*/
  126.           printf("%s",SHELL), i+=5;
  127.         else if(strncmp(aux,"PATH",4)==0) /*Idem PATH*/
  128.           printf("%s",PATH), i+=4;
  129.         else if(strncmp(aux,"PWD",3)==0) /*Idem PWD*/
  130.           printf("%s",PWD), i+=3;
  131.         else if(strncmp(aux,"HOME",4)==0) /*Idem HOME*/
  132.           printf("%s",HOME), i+=4;
  133.         else printf("$"); /*Ninguno de los anteriores el $ es solo un caracter mas*/
  134.       }
  135.     }
  136.     printf(" "); /*Imprimir el espacio entre los distintos argumentos*/
  137.   }
  138.   printf("\n"); /*Imprimir un salto de linea al final del ultimo argumento*/
  139. }
  140.  
  141. void comExterno(){ /*Ejecutar entradas consideradas comando externos*/
  142.   int pid=0;
  143.   int status;
  144.   pid=fork(); /*Crear un proceso hijo*/
  145.   if(pid<0) printf("Error! no se pudo crear un proceso hijo");
  146.   if (pid==0){
  147.     status=execvp(comando,args); /*Trata de ejecutar el comando y los argumentos que tenga*/
  148.     if(status){
  149.       printf("Error! %s no se reconoce o no se pudo ejecutar\n",comando);
  150.       exit(1); /*Como no se pudo ejecutar el comando cerramos el proceso hijo*/
  151.     }
  152.   }
  153.   else
  154.     wait(NULL); /*esperar a que termine el proceso hijo*/
  155. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement