将stdout重定向到客户端 - 来自服务器

时间:2015-12-04 04:42:58

标签: c server gdb client buffer

我有一个客户端和服务器程序,其中服务器是一个简单的shell。

客户端向服务器写入命令,服务器检查是否允许该命令,然后执行该命令

客户端代码就像......

  while(1){
      printf("rrsh> ");
      Fgets(buf, MAXLINE, stdin);
      if ((p3ret_val = p3parseline(buf, argv)) == 1)
        printf("You didn't enter anything\n");
      if (!strcmp(argv[0], "quit"))
        break;
      Rio_writen(clientfd, buf, strlen(buf));
      Rio_readlineb(&rio, buf, MAXLINE);
      if (!strcmp(buf, "Command not allowed\n")){
        strcpy(buf, "Cannot execute '");
        strcat(buf, argv[0]);
        strcat(buf, "' on this server\n");
        Fputs(buf, stdout);
      }
      memset(&buf[0], 0, sizeof(buf)); //flush the buffer
    }

服务器代码...

while((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0){ //loop until connection has been terminated
  if (n == 0)
    flag1 = 0; //the user will need to login again
  if (flag1 == 1){ //the user is loged in
    printf("server received %zu Byte(s)\n", n);
    bg = p3parseline(buf, argv);
    strcat(argv[0], "\n");

    //check if the command is allowed
    flag2 = 0; //set command allowed? flag back to false
    file = Fopen("rrshcommands.txt", "r");
    while (Fgets(command, MAXLINE, file) != NULL){
      if (!strcmp(argv[0], command)){
        flag2 = 1;
        strcpy(buf, "Command approved\n");
        // break;
      }
    }
    Fclose(file);

    strtok(argv[0], "\n");

    // Fputs(buf, stdout);

    if (flag2 == 0){ //case where the command is not allowed
      strcpy(buf, "Command not allowed\n");
      Rio_writen(connfd, buf, strlen(buf));
    }
    else{
      if ((pid = fork()) == 0) {   /* Child runs user job */
        Dup2(connfd, 1);
        // Close(connfd);
        if (execve(argv[0], argv, environ) < 0) {
          printf("%s: Command not found.", argv[0]);
          exit(0);
        }
      }
      /* Parent waits for foreground job to terminate */
      if (!bg) {
        int status;
        if (waitpid(pid, &status, 0) < 0)
          unix_error("waitfg: waitpid error");
      }
    }
    memset(&buf[0], 0, sizeof(buf)); //flush the buffer
  }
}

调试我发现客户端上的buf以某种方式填充了ls应该显示的第一个文件。

这是一系列奇怪的事件。我输入了有效的/ bin / ls命令,然后在执行该命令后,我输入另一个垃圾命令。第二次客户端从服务器读取后,它返回我刚才说的内容 - 应该显示/ bin / ls的第一个文件

这是来自客户端..

rrsh> /bin/ls

Breakpoint 1, main (argc=3, argv=0x7fffffffe5d8) at rrsh-client.c:42
42        Rio_writen(clientfd, buf, strlen(buf));
(gdb) continue
Continuing.
rrsh> wprg

Breakpoint 1, main (argc=3, argv=0x7fffffffe5d8) at rrsh-client.c:42
42        Rio_writen(clientfd, buf, strlen(buf));
(gdb) p buf
$2 = "wprg\n", '\000' <repeats 8186 times>
(gdb) n
43        Rio_readlineb(&rio, buf, MAXLINE);
(gdb) n
44        if (!strcmp(buf, "Command not allowed\n")){
(gdb) p buf
$3 = "csapp.h\n", '\000' <repeats 8183 times>

您会注意到我从不从服务器写入客户端,除非不允许该命令

为什么客户端在重定向stdout时从服务器读取第一个文件名 - 不写?

0 个答案:

没有答案