2 * gcc -Wall -O2 xctrld.c -o /sbin/xctrld
4 * --- T2-COPYRIGHT-NOTE-BEGIN ---
5 * This copyright note is auto-generated by ./scripts/Create-CopyPatch.
7 * T2 SDE: misc/archive/xctrld.c
8 * Copyright (C) 2004 - 2005 The T2 SDE Project
9 * Copyright (C) 1998 - 2003 ROCK Linux Project
11 * More information can be found in the files COPYING and README.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; version 2 of the License. A copy of the
16 * GNU General Public License can be found in the file COPYING.
17 * --- T2-COPYRIGHT-NOTE-END ---
21 #include <netinet/in.h>
26 #include <sys/socket.h>
29 #include <sys/types.h>
40 #define xprf(format, args... ) fprintf(out,"Cliffords Control-Daemon: " format "\r", ## args)
42 /* This function is very dirty - but it seams to to the only way that
43 * works without using pty devices. making the netfd directly the stdin
44 * stdout and stderr channels of /bin/sh caused a lot of problems ...
46 void do_session(int netfd
) {
53 snprintf(buf
,BUFSIZE
,"\n"
54 "Hello! This is a mini telnet daemon which is not using a pty device.\n"
55 "So you wont have job control or other things where ptys are needed.\n"
56 "\nThis session has the PID %d. Have fun.\n\n",(int)getpid());
57 write(netfd
,buf
,strlen(buf
));
59 pipe(p_in
); pipe(p_out
);
60 if (signal(SIGCHLD
,SIG_DFL
) == SIG_ERR
) xprf("signal: %s",strerror(errno
));
62 if ( (pid
=fork()) == 0 ) {
63 close(0); dup2(p_in
[0],0);
64 close(1); dup2(p_out
[1],1);
65 close(2); dup2(p_out
[1],2);
66 close(p_in
[0]); close(p_in
[1]);
67 close(p_out
[0]); close(p_out
[1]); close(netfd
);
68 setenv("USER","root",1); setenv("HOME","/root",1);
69 setenv("LOGNAME","root",1); setenv("TERM","linux",1);
70 execl("/bin/sh","/bin/sh","--login","-i",NULL
);
71 xprf("execl: %s",strerror(errno
)); exit(1);
74 close(p_in
[0]); close(p_out
[1]);
76 while (waitpid(pid
,NULL
,WNOHANG
) != pid
) {
77 FD_ZERO(&rfds
); FD_SET(netfd
,&rfds
); FD_SET(p_out
[0],&rfds
);
78 maxfd
= netfd
>p_out
[0] ? netfd
: p_out
[0];
79 tv
.tv_sec
=1; tv
.tv_usec
=0;
80 rc
=select(maxfd
+1, &rfds
, NULL
, NULL
, NULL
);
81 if (rc
== -1) { xprf("select: %s",strerror(errno
)); return; }
82 if (FD_ISSET(netfd
, &rfds
)) {
83 rc
=read(netfd
,buf
,BUFSIZE
);
85 if (buf
[c
]!='\r') write(p_in
[1],buf
+c
,1);
87 if (FD_ISSET(p_out
[0], &rfds
)) {
88 rc
=read(p_out
[0],buf
,BUFSIZE
);
89 for (c
=0; c
<rc
; c
+=write(netfd
,buf
,rc
)) ;
94 int main(int argc
, char ** argv
) {
95 struct sockaddr_in addr
;
98 if (argc
!= 2 || argv
[1][0] == '-') {
99 fprintf(stderr
,"Usage: %s < log-file | tty-device >\n",argv
[0]);
103 if ( (out
=fopen(argv
[1],"a+")) == NULL
) {
104 fprintf(stderr
,"Can't open log file '%s': %s",argv
[1],strerror(errno
));
107 setvbuf(out
,NULL
,_IONBF
,0);
110 printf("Cliffords Remote Control Daemon starting in 3 seconds ...\n");
111 if (fork()) return 0;
114 fprintf(out
,"\n\n\r");
115 xprf("Binding port %d and waiting for connections ...\n",PORT
);
116 if (signal(SIGCHLD
,SIG_IGN
) == SIG_ERR
) xprf("signal: %s",strerror(errno
));
118 if ((listenfd
=socket(AF_INET
,SOCK_STREAM
,0)) == -1) xprf("socket: %s",strerror(errno
));
120 bzero(&addr
,sizeof(addr
));
121 addr
.sin_family
=AF_INET
;
122 addr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
123 addr
.sin_port
= htons(PORT
);
125 if (bind(listenfd
,&addr
,sizeof(addr
)) == -1) xprf("bind: %s",strerror(errno
));
127 if (listen(listenfd
,5)==-1) xprf("listen: %s",strerror(errno
));
130 if ((fd
=accept(listenfd
,NULL
,NULL
)) == -1) xprf("accept: %s",strerror(errno
));
132 xprf("connection %d opened.\n",(int)getpid());
134 xprf("connection %d closed.\n",(int)getpid());