1
0
mirror of https://github.com/lxsang/ant-http synced 2024-07-03 13:39:46 +02:00
ant-http/plugins/wterm/wterm.c

191 lines
4.2 KiB
C

#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <termios.h>
#include <sys/select.h>
#include <sys/ioctl.h>
#include <string.h>
#include "../plugin.h"
void pexit()
{
}
void handler(int cl, const char* m, const char* rqp, dictionary rq)
{
ws_msg_header_t* h = NULL;
if(ws_enable(rq))
{
int fdm, fds;
int rc;
char buff[1024];
// Check arguments
fdm = posix_openpt(O_RDWR);
if (fdm < 0)
{
LOG("Error %d on posix_openpt()\n", errno);
ws_close(cl, 1011);
return ;
}
rc = grantpt(fdm);
if (rc != 0)
{
LOG("Error %d on grantpt()\n", errno);
ws_close(cl, 1011);
return ;
}
rc = unlockpt(fdm);
if (rc != 0)
{
LOG( "Error %d on unlockpt()\n", errno);
ws_close(cl, 1011);
return ;
}
// Open the slave side ot the PTY
fds = open(ptsname(fdm), O_RDWR);
// Create the child process
if (fork())
{
fd_set fd_in;
// FATHER
// Close the slave side of the PTY
close(fds);
int max_fdm;
while (1)
{
FD_ZERO(&fd_in);
//FD_SET(0, &fd_in);
FD_SET(fdm, &fd_in);
FD_SET(cl,&fd_in);
max_fdm = fdm>cl?fdm:cl;
rc = select(max_fdm + 1, &fd_in, NULL, NULL, NULL);
switch(rc)
{
case -1 :
LOG("Error %d on select()\n", errno);
ws_close(cl, 1011);
return;
default :
{
// If data is on websocket side
if (FD_ISSET(cl, &fd_in))
{
h = ws_read_header(cl);
if(h)
{
if(h->opcode == WS_CLOSE)
{
LOG("%s\n","Websocket: connection closed");
write(fdm, "exit\n", 5);
return;
}
else if(h->opcode == WS_TEXT)
{
int l;
while((l = ws_read_data(cl,h,sizeof(buff),buff)) > 0)
{
//buff[l] = '\0';
write(fdm, buff, l);
//ws_t(cl,buff);
}
/*if(l == -1)
{
printf("EXIT FROM CLIENT \n");
write(fdm, "exit\n", 5);
return;
}*/
}
free(h);
}
else
{
write(fdm, "exit\n", 5);
ws_close(cl,1000);
}
}
// If data on master side of PTY
if (FD_ISSET(fdm, &fd_in))
{
//rc = read(fdm, buff, sizeof(buff));
if ( (rc = read(fdm, buff,sizeof(buff)-1)) > 0)
{
// Send data to websocket
buff[rc] = '\0';
ws_t(cl,buff);
} else
{
if (rc < 0)
{
LOG("Error %d on read standard input. Exit now\n", errno);
write(fdm, "exit\n", 5);
ws_close(cl,1011);
return;
}
}
}
//printf("DONE\n");
}
} // End switch
} // End while
}
else
{
struct termios slave_orig_term_settings; // Saved terminal settings
struct termios new_term_settings; // Current terminal settings
// CHILD
// Close the master side of the PTY
close(fdm);
// Save the defaults parameters of the slave side of the PTY
//rc = tcgetattr(fds, &slave_orig_term_settings);
// Set RAW mode on slave side of PTY
//new_term_settings = slave_orig_term_settings;
//cfmakeraw (&new_term_settings);
//tcsetattr (fds, TCSANOW, &new_term_settings);
// The slave side of the PTY becomes the standard input and outputs of the child process
// we use cook mode here
close(0); // Close standard input (current terminal)
close(1); // Close standard output (current terminal)
close(2); // Close standard error (current terminal)
dup(fds); // PTY becomes standard input (0)
dup(fds); // PTY becomes standard output (1)
dup(fds); // PTY becomes standard error (2)
// Now the original file descriptor is useless
close(fds);
// Make the current process a new session leader
setsid();
// As the child is a session leader, set the controlling terminal to be the slave side of the PTY
// (Mandatory for programs like the shell to make them manage correctly their outputs)
ioctl(0, TIOCSCTTY, 1);
//system("/bin/bash");
system("sudo login");
// if Error...
ws_close(cl,1000);
//LOG("%s\n","Terminal exit");
_exit(1);
}
}
LOG("%s\n","All processes exit");
}