c - 如何将 execlp 更改为 execv 并运行其他命令然后只是 'ls'

标签 c pipe output execv

目前我正在运行一个 HTML 网络服务器,它可以运行通过文本框和提交按钮给它的命令,但我需要将 execlp 转换为 execv 并且我不理解 execv 的数组部分。我试图将其设为 execv(command, command); ,但它给了我一个不兼容指针类型问题的传递参数。另外,由于某种原因,我的执行只会运行一个单词命令,例如 ls ,并且也不会接受任何标志,我不太确定这是为什么。下面的代码执行和解析部分,如果需要可以提供完整的代码。

Exection.c

char *parse(char *command){
    char * newCommand = (char *) malloc(sizeof(char)*50);
    int tgt = 0;
     newCommand = strstr(command, "/run?command=");
    newCommand = strtok(newCommand, " ");
    newCommand = newCommand + 13;
     for(int src = 0; src< strlen(newCommand); src++){
        if(newCommand[src] == '+')
        {
            newCommand[src] = ' ';
        }
        else if(newCommand[src] == '%')
        {
            newCommand[src] = ' ';
        }
        else if(newCommand[src] == '7')
        {
            newCommand[src] = ' ';
        }
        else if(newCommand[src] == 'C')
        {
            newCommand[src] = '|';
        }


    }

     return newCommand;
}

char * execution(char *command){

  int piper[2];
    size_t len = 0;
    pipe(piper);
  char* output =  malloc(1000 * sizeof(char));
    memset(output, '\0', 1000* sizeof(char));
    pid_t pid = fork();
    if(pid != 0)// parent
        {
            wait(NULL);
            close(piper[1]);
      int n = sizeof(output);

            struct pollfd * poll_fd = malloc(sizeof(struct pollfd));
             poll_fd->fd = piper[0];
             poll_fd->events = POLLIN;

            if(poll(poll_fd, 1, 0) == 1){ // pipe data check
            read(piper[0], output, 1000);
            }

        }
        else{

            close(1);
            dup(piper[1]);
            execlp(command, command, NULL);
        exit(1);
        }
                return output;
}

int main (void){
    int sockfd;
    int new_fd; 
    struct addrinfo hints;
    struct addrinfo *serverinfo; 
    struct addrinfo *p;
    struct sockaddr_storage client_addr;
    socklen_t addrsize;
    struct sigaction sa;
    int yes = 1;
    char s[INET6_ADDRSTRLEN];
    int status;

    memset(&hints, 0, sizeof hints); //makes struct empty 
    hints.ai_family = AF_UNSPEC; //IPv4 or v6 
    hints.ai_socktype = SOCK_STREAM; //TCP type need 
    hints.ai_flags = AI_PASSIVE; //Fill in IP for us 


    //if can't get address info print error 
    if((status = getaddrinfo(NULL, PORT, &hints, &serverinfo)) != 0){
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
        return 1;
    }


    for(p = serverinfo; p != NULL; p = p->ai_next){
        if((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){
            perror("server: socket");
            continue;
        }

        if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
            perror("setsockopt");
            exit(1);
        }

        if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1){
            close(sockfd);
            perror("server: bind");
            continue;
        }

        break;
    }

    freeaddrinfo(serverinfo);

    if(p == NULL){
        fprintf(stderr, "server: failed to bind\n");
        exit(1);
    }

    if(listen(sockfd, BACKLOG) == -1){
        perror("listen");
        exit(1);
    }

    sa.sa_handler = sigchld_handler; // reap all dead processes
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    if (sigaction(SIGCHLD, &sa, NULL) == -1) {
        perror("sigaction");
        exit(1);
    }

    printf("server: waiting for connections....\n");

    while(1){
        addrsize = sizeof client_addr;
        new_fd = accept(sockfd, (struct sockaddr *)&client_addr, &addrsize);
        if(new_fd == -1){
            perror("Did not accept");
            continue;
        }

        inet_ntop(client_addr.ss_family, get_in_addr((struct sockaddr *)&client_addr), s, sizeof s);
        printf("server: got connection from %s\n", s);

        if(!fork()){
            close(sockfd);
            int bufsize = 1024;

            char *buffer = malloc(bufsize);
            recv(new_fd, buffer, bufsize, 0);
            send(new_fd, header, bufsize, 0);

            if(send(new_fd, execution(parse(buffer)), 1000, 0) == -1)
                perror("send");
            close(new_fd);
            exit(0);
        }
        close(new_fd);
    }

    return 0;


}

最佳答案

如果你想要command要由 shell 解释,您需要将其作为参数传递,例如:

const char *args[] = {"/bin/sh", "-c", command};
execve("/bin/sh", args, NULL);

请注意,Web shell 在很大程度上被视为恶意软件或 future 的 CVE。

关于c - 如何将 execlp 更改为 execv 并运行其他命令然后只是 'ls',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56151716/

相关文章:

python - 有没有一种方法或函数可以从程序中隐藏selenium的输出?

c - 为什么这里没有将 signed char 升级为 unsigned int?

r - 在 R 中,为什么 example() 会产生非示例?

c++ - 如何将字符串的一部分识别为单词并将其保存以供以后在程序中使用?

c - 在 GDB 中打印多个变量?

linux - 如何通过ssh发送三个管道的数据?

iphone - 将 iOS 上的 printf 重定向到用户界面

c++ - 使用CMake获取包含库的包含路径列表

在 C 中使用 "if"语句的编译器错误

c++ - 是否可以使用 C++ 流类来缓冲从管道读取的数据?