Autor: Sefer | Publicado: 2006-07-13T21:49:00-05:00

Bom, depois de mais algumas semanas sem postar heheheAcho que ninguém mais entra aqui, mas ta blz...Estou dando um curso para alguns alunos que dao aulas em faculdades, esta bem legal, fiz uma shell ridicula em C para eles verem como funciona um pouco da linguagem e verem tb que da pra fazer alguma coisa util com ela hehehe, se bem que esta shell está muito longe de ser util!!!!Não recomendo que executem esta shell a nao ser em carater de testes!De preferencia num ambiente chrooted(nao me responsabilizo pelo mal funcionamento da mesma), e jamais como root!Bom fora as vulnerabilidades(deve ter um monte ai), pelo menos o código vai servir de exemplo.Escrevi ele em mais ou menos 3 horas, entao nao esperem organizacao! /*Esta shell foi desenvolvida para o curso de Desenvolvimento em C para motivos meramenteeducativos, nao rola usar na vida real...Este codigo pode ser reproduzido completamente, ou em trechos por terceirossem a necessidade de contatar o desenvolvedor.Comandos builtin:cd pwd ls cp mvPara inserir mais comandos, eh soh adicionar uma nova entrada em resolv_cmd e em call_cmdAlex Nunesalex@thesource.com.br*/#include "sys/types.h"#include "sys/stat.h"#include "stdio.h"#include "stdlib.h"#include "string.h"#include "unistd.h"#include "errno.h"#include "dirent.h"#define    CMDSIZE    512// definicao dos comando builtin da shell#define CD    0#define PWD    1#define LS    2#define CP    3#define MV    4#define EXIT    5#define EXECUTE 6// Funcoes para tratamento de errosvoid die(char *msg);void warn(char *msg);// Vai para home do usuarioint get_home(char *username);// Abre um diretorio indicado por pathint cd(char *path);// Escreve o nome do diretorio atualint get_pwd();// Lista os arquivos do diretorio indicado por pathint ls(char *path);// Copia o arquivo indicado por src para destint cp(char *src, char *dest);// Renomeia um arquivo apontado por src para destint mv(char *src, char *dest);// Sai da shellvoid exit_shell();// executa o arquivo indicadoi por path, com os argumentos apontados por argvint execute(char **argv);void die(char *msg){perror(msg);exit(1);}void warn(char *msg){perror(msg);return;}int get_home(char *username){char home[255] = "/home/";int ret;strncat(home, username, 245);ret = chdir(home);/*Caso algum erro ocorra tentar fazer de /tmp a home o usuario, se ainda assim algum erro acontecerretornar 1 para a shell, caso contrario retornar 0*/if (ret)    {    warn("get_user_home:chdir");    ret = chdir("/tmp");    if (ret)        {        return 1;        }    return 0;    }return 0;}int cd(char *path){int res;res = chdir(path);if (res)    {    warn("cd::chdir");    return 1;    }return 0;}int get_pwd(){char pwd[512];getcwd(pwd, 510);printf("%s\n", pwd);return 0;}int ls(char *path){DIR *dir;struct dirent *data;/*Abrir o diretorio que estamos tentando listar e checar por algum tipo de erro*/dir = opendir(path);if (!dir)    {    warn("ls:opendir");    return 1;    }/*Ler a estrutura dirent de cada diretorio escrevendo o seu nome, ateh que readdir retorne NULL,depois fechar o diretorio e sair*/while( (data = readdir(dir)))    {/*se a primeira letra do diretorio for ., ele nao eh mostrado*/    if (data->d_name[0] == '.')        {        continue;        }    printf("%s\t", data->d_name);    }printf("\n");closedir(dir);return 0;}int cp(char *src, char *dest){FILE *fs, *fd;struct stat status;void *buff;int i = 0;/*Reservar um byte para buff*/buff = malloc(sizeof(char));/*Abrir arquivos de origem e destino*/fs = fopen(src, "r");fd = fopen(dest, "w");if (!fs || !fd)    {    warn("cp:fopen");    return 1;    }/*Descobrir quantos bytes tera que copiar atraves de status->st_size*/if (stat(src, &status))    {    warn("cp:stat");    return 1;    }while(i < res =" rename(src," cmd =" strtok(string,">argv[0] = cmd;/*argc eh incrementado pq arrays comecam em zero, isto que dizer argv[0] eh o primeiro item*/ args->argc=1;// quando nao ouver mais espacos na linha de comando strtok ira retornar NULLwhile((cmd = strtok(NULL, " \n")))    {    if (args->argc > 254)        {        break;        }      args->argv[args->argc] = cmd;    args->argc++;    }// o ultimo argv == NULLargs->argv[args->argc] = NULL;return 0;}int execute(char **argv){int res, i=0;char cmd[512];memset(cmd, '\0', 512);while(argv[i] != NULL)    {    strcat(cmd, argv[i]);    i++;    }res = system(cmd);if (res == -1)    {    perror("execute:execvp");    }return 0;}int resolv_cmd(struct args *args){char *cmds[] = {"cd", "pwd", "ls", "cp", "mv", "exit", "exec", NULL };if(!strcmp(args->argv[0], cmds[CD])) return CD;if(!strcmp(args->argv[0], cmds[PWD])) return PWD;if(!strcmp(args->argv[0], cmds[LS])) return LS;if(!strcmp(args->argv[0], cmds[MV])) return MV;if(!strcmp(args->argv[0], cmds[EXIT])) return EXIT;if(!strcmp(args->argv[0], cmds[EXECUTE])) return EXECUTE;return -1;}int call_cmd(struct args *args){int ret;ret = resolv_cmd(args);switch(ret)    {    case CD:        if(args->argc != 2)            {            printf("cd \n");            return 1;            }        ret = cd(args->argv[1]);        return ret;    break;    case PWD:        if (args->argc != 1)            {            printf("pwd has no args");            return 1;            }           ret = get_pwd();        return ret;    break;    case LS:        if (args->argc == 1)            {            ret = ls(".");            return ret;            }        ret = ls(args->argv[1]);        return ret;    break;    case CP:        if (args->argc != 3)            {            printf("cp  \n");            return 1;            }        ret = cp(args->argv[1], args->argv[2]);        return ret;    break;    case MV:        if(args->argc != 3)            {            printf("mv  \n");            return 1;            }               ret = mv(args->argv[1], args->argv[2]);        return ret;    break;    case EXIT:        exit_shell();        return 0;    break;    case EXECUTE:        ret = execute(args->argv);        return ret;    break;    default:        ret = execute(args->argv);        return ret;    }}int main(int argc, char *argv[]){char *cmd;struct args args;while(1)    {    printf("fsh> ");    if (!(cmd = get_cmd())) continue;    build_cmd(cmd, &args);    call_cmd(&args);    }return 0;}