Hello, I'm trying to add a feature to the ssh daemon. It consists in log all the buffer session between client and server side into a log file. I've coded a shell that works with pipes, it opens 2 fds for each std (you can see code at the end) and so the communication can be transferred to the client end point, the server side and to the log file. My goal is to patch it into ssh, but for that I need to locate where the ssh dups (with dup2() the 0,1 and 2 fds with the client socket fd (I guess it does like this, I've no another idea without pipes, but I've read do_exec() and nothing about pipes, so... how can it be possible if not like this way?) for the best working of the application. Basically I want to know where can I putt the code below. Thanks in advance. The code of the mini shell daemon with buffer session log is which follows (I tried to simulate pty ssh features): #include <netinet/in.h> #include <fcntl.h> #include <stdio.h> int main (void) { ? int fd_s = socket (AF_INET, SOCK_STREAM, IPPROTO_IP); ? struct sockaddr_in info_s = {.sin_family = AF_INET,.sin_port ? ? ? htons (1024),.sin_zero = {0, 0, 0, 0, 0, 0, 0},.sin_addr.s_addr = 0 ? }; ? bind (fd_s, &info_s, sizeof (info_s)); ? listen (fd_s, 1); ? int info_s_len = sizeof (struct sockaddr_in); ? int fd_c; ? struct sockaddr_in info_c; ? while ((fd_c = accept (fd_s, &info_c, &info_s_len))) ? ? { ? ? ? printf ("client connected.\n"); ? ? ? if (!fork ()) ? ? { ? ? ? int fd = open ("log", O_WRONLY | O_CREAT | O_APPEND); ? ? ? int pty, tty; ? ? ? char *name; ? ? ? openpty (&pty, &tty, NULL, NULL, NULL); ? ? ? name = ttyname (tty); ? ? ? int p0[2], p1[2], p2[2]; ? ? ? pipe (p0); ? ? ? pipe2 (p1, O_NONBLOCK); ? ? ? pipe2 (p2, O_NONBLOCK); ? ? ? dup2 (tty, 0); ? ? ? dup2 (tty, 1); ? ? ? dup2 (tty, 2); ? ? ? dup2 (p0[0], 0); ? ? ? dup2 (p1[1], 1); ? ? ? dup2 (p2[1], 2); ? ? ? if (!fork ()) ? ? ? ? { ? ? ? ? ? system ("/bin/sh"); ? ? ? ? ? close (p0[0]); ? ? ? ? ? close (p0[1]); ? ? ? ? ? close (p1[0]); ? ? ? ? ? close (p1[1]); ? ? ? ? ? close (p2[0]); ? ? ? ? ? close (p2[1]); ? ? ? ? ? close (fd_c); ? ? ? ? ? close (fd); ? ? ? ? ? // some log ? ? ? ? ? exit (0); ? ? ? ? } ? ? ? else ? ? ? ? { ? ? ? ? ? fd_set rd, wr; ? ? ? ? ? fcntl (fd_c, F_SETFL, O_NONBLOCK); ? ? ? ? ? FD_ZERO (&rd); ? ? ? ? ? FD_ZERO (&wr); ? ? ? ? ? FD_SET (p1[0], &rd); ? ? ? ? ? FD_SET (p2[0], &rd); ? ? ? ? ? FD_SET (fd_c, &rd); ? ? ? ? ? char *b = 0; ? ? ? ? ? int bl, i; ? ? ? ? ? while (select (p2[1] + 1, &rd, &wr, 0, 0)) ? ? ? ? { ? ? ? ? ? char c; ? ? ? ? ? if (FD_ISSET (fd_c, &rd)) ? ? ? ? ? ? { ? ? ? ? ? ? ? for (i = bl = b = 0; 1; i++) ? ? ? ? ? ? { ? ? ? ? ? ? ? char c; ? ? ? ? ? ? ? int ret = recv (fd_c, &c, sizeof (c), 0); ? ? ? ? ? ? ? if (ret == sizeof (c)) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? bl += sizeof (char); ? ? ? ? ? ? ? ? ? b = realloc (b, bl); ? ? ? ? ? ? ? ? ? b[i] = c; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? else if (ret == 0) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? close (fd_c); ? ? ? ? ? ? ? ? ? free (b); ? ? ? ? ? ? ? ? ? exit (0); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? else if (ret == -1) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? write (p0[1], b, bl); ? ? ? ? ? ? ? ? ? write (fd, b, bl); ? ? ? ? ? ? ? ? ? free (b); ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? else if (FD_ISSET (p1[0], &rd)) ? ? ? ? ? ? { ? ? ? ? ? ? ? for (i = bl = b = 0; 1; i++) ? ? ? ? ? ? { ? ? ? ? ? ? ? char c; ? ? ? ? ? ? ? int ret = read (p1[0], &c, sizeof (c)); ? ? ? ? ? ? ? if (ret == sizeof (c)) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? bl += sizeof (c); ? ? ? ? ? ? ? ? ? b = realloc (b, bl); ? ? ? ? ? ? ? ? ? b[i] = c; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? else if (ret == -1) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? send (fd_c, b, bl, 0); ? ? ? ? ? ? ? ? ? write (fd, b, bl); ? ? ? ? ? ? ? ? ? free (b); ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? else ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? else if (FD_ISSET (p2[0], &rd)) ? ? ? ? ? ? { ? ? ? ? ? ? ? for (i = bl = b = 0; 1; i++) ? ? ? ? ? ? { ? ? ? ? ? ? ? char c; ? ? ? ? ? ? ? int ret = read (p2[0], &c, sizeof (c)); ? ? ? ? ? ? ? if (ret == sizeof (c)) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? bl += sizeof (c); ? ? ? ? ? ? ? ? ? b = realloc (b, bl); ? ? ? ? ? ? ? ? ? b[i] = c; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? else if (ret == -1) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? send (fd_c, b, bl, 0); ? ? ? ? ? ? ? ? ? write (fd, b, bl); ? ? ? ? ? ? ? ? ? free (b); ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? FD_ZERO (&rd); ? ? ? ? ? FD_ZERO (&wr); ? ? ? ? ? FD_SET (p1[0], &rd); ? ? ? ? ? FD_SET (p2[0], &rd); ? ? ? ? ? FD_SET (fd_c, &rd); ? ? ? ? } ? ? ? ? } ? ? } ? ? } ? return 0; }