OpenSDE Framework (without history before r20070)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

139 lines
4.0 KiB

/*
* gcc -Wall -O2 xctrld.c -o /sbin/xctrld
*
* --- T2-COPYRIGHT-NOTE-BEGIN ---
* This copyright note is auto-generated by ./scripts/Create-CopyPatch.
*
* T2 SDE: misc/archive/xctrld.c
* Copyright (C) 2004 - 2006 The T2 SDE Project
* Copyright (C) 1998 - 2003 Clifford Wolf
*
* More information can be found in the files COPYING and README.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License. A copy of the
* GNU General Public License can be found in the file COPYING.
* --- T2-COPYRIGHT-NOTE-END ---
*/
#include <fcntl.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#define PORT 2225
#define BUFSIZE 1024
FILE * out = NULL;
#define xprf(format, args... ) fprintf(out,"Cliffords Control-Daemon: " format "\r", ## args)
/* This function is very dirty - but it seams to to the only way that
* works without using pty devices. making the netfd directly the stdin
* stdout and stderr channels of /bin/sh caused a lot of problems ...
*/
void do_session(int netfd) {
int p_in[2],p_out[2];
int rc,maxfd,pid,c;
struct timeval tv;
char buf[BUFSIZE];
fd_set rfds;
snprintf(buf,BUFSIZE,"\n"
"Hello! This is a mini telnet daemon which is not using a pty device.\n"
"So you wont have job control or other things where ptys are needed.\n"
"\nThis session has the PID %d. Have fun.\n\n",(int)getpid());
write(netfd,buf,strlen(buf));
pipe(p_in); pipe(p_out);
if (signal(SIGCHLD,SIG_DFL) == SIG_ERR) xprf("signal: %s",strerror(errno));
if ( (pid=fork()) == 0 ) {
close(0); dup2(p_in[0],0);
close(1); dup2(p_out[1],1);
close(2); dup2(p_out[1],2);
close(p_in[0]); close(p_in[1]);
close(p_out[0]); close(p_out[1]); close(netfd);
setenv("USER","root",1); setenv("HOME","/root",1);
setenv("LOGNAME","root",1); setenv("TERM","linux",1);
execl("/bin/sh","/bin/sh","--login","-i",NULL);
xprf("execl: %s",strerror(errno)); exit(1);
}
close(p_in[0]); close(p_out[1]);
while (waitpid(pid,NULL,WNOHANG) != pid) {
FD_ZERO(&rfds); FD_SET(netfd,&rfds); FD_SET(p_out[0],&rfds);
maxfd = netfd>p_out[0] ? netfd : p_out[0];
tv.tv_sec=1; tv.tv_usec=0;
rc=select(maxfd+1, &rfds, NULL, NULL, NULL);
if (rc == -1) { xprf("select: %s",strerror(errno)); return; }
if (FD_ISSET(netfd, &rfds)) {
rc=read(netfd,buf,BUFSIZE);
for (c=0; c<rc; c++)
if (buf[c]!='\r') write(p_in[1],buf+c,1);
}
if (FD_ISSET(p_out[0], &rfds)) {
rc=read(p_out[0],buf,BUFSIZE);
for (c=0; c<rc; c+=write(netfd,buf,rc)) ;
}
}
}
int main(int argc, char ** argv) {
struct sockaddr_in addr;
int listenfd,fd;
if (argc != 2 || argv[1][0] == '-') {
fprintf(stderr,"Usage: %s < log-file | tty-device >\n",argv[0]);
return 1;
}
if ( (out=fopen(argv[1],"a+")) == NULL ) {
fprintf(stderr,"Can't open log file '%s': %s",argv[1],strerror(errno));
return 1;
}
setvbuf(out,NULL,_IONBF,0);
chdir("/");
printf("Cliffords Remote Control Daemon starting in 3 seconds ...\n");
if (fork()) return 0;
sleep(3);
fprintf(out,"\n\n\r");
xprf("Binding port %d and waiting for connections ...\n",PORT);
if (signal(SIGCHLD,SIG_IGN) == SIG_ERR) xprf("signal: %s",strerror(errno));
if ((listenfd=socket(AF_INET,SOCK_STREAM,0)) == -1) xprf("socket: %s",strerror(errno));
bzero(&addr,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(PORT);
if (bind(listenfd,&addr,sizeof(addr)) == -1) xprf("bind: %s",strerror(errno));
if (listen(listenfd,5)==-1) xprf("listen: %s",strerror(errno));
while (1) {
if ((fd=accept(listenfd,NULL,NULL)) == -1) xprf("accept: %s",strerror(errno));
if (!fork()) {
xprf("connection %d opened.\n",(int)getpid());
do_session(fd);
xprf("connection %d closed.\n",(int)getpid());
return 0;
} else close(fd);
}
return 0;
}