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

  1. /*
  2. * gcc -Wall -O2 xctrld.c -o /sbin/xctrld
  3. *
  4. * --- T2-COPYRIGHT-NOTE-BEGIN ---
  5. * This copyright note is auto-generated by ./scripts/Create-CopyPatch.
  6. *
  7. * T2 SDE: misc/archive/xctrld.c
  8. * Copyright (C) 2004 - 2006 The T2 SDE Project
  9. * Copyright (C) 1998 - 2003 Clifford Wolf
  10. *
  11. * More information can be found in the files COPYING and README.
  12. *
  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 ---
  18. */
  19. #include <fcntl.h>
  20. #include <netinet/in.h>
  21. #include <signal.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <sys/socket.h>
  26. #include <sys/stat.h>
  27. #include <sys/time.h>
  28. #include <sys/types.h>
  29. #include <sys/wait.h>
  30. #include <unistd.h>
  31. #include <errno.h>
  32. #define PORT 2225
  33. #define BUFSIZE 1024
  34. FILE * out = NULL;
  35. #define xprf(format, args... ) fprintf(out,"Cliffords Control-Daemon: " format "\r", ## args)
  36. /* This function is very dirty - but it seams to to the only way that
  37. * works without using pty devices. making the netfd directly the stdin
  38. * stdout and stderr channels of /bin/sh caused a lot of problems ...
  39. */
  40. void do_session(int netfd) {
  41. int p_in[2],p_out[2];
  42. int rc,maxfd,pid,c;
  43. struct timeval tv;
  44. char buf[BUFSIZE];
  45. fd_set rfds;
  46. snprintf(buf,BUFSIZE,"\n"
  47. "Hello! This is a mini telnet daemon which is not using a pty device.\n"
  48. "So you wont have job control or other things where ptys are needed.\n"
  49. "\nThis session has the PID %d. Have fun.\n\n",(int)getpid());
  50. write(netfd,buf,strlen(buf));
  51. pipe(p_in); pipe(p_out);
  52. if (signal(SIGCHLD,SIG_DFL) == SIG_ERR) xprf("signal: %s",strerror(errno));
  53. if ( (pid=fork()) == 0 ) {
  54. close(0); dup2(p_in[0],0);
  55. close(1); dup2(p_out[1],1);
  56. close(2); dup2(p_out[1],2);
  57. close(p_in[0]); close(p_in[1]);
  58. close(p_out[0]); close(p_out[1]); close(netfd);
  59. setenv("USER","root",1); setenv("HOME","/root",1);
  60. setenv("LOGNAME","root",1); setenv("TERM","linux",1);
  61. execl("/bin/sh","/bin/sh","--login","-i",NULL);
  62. xprf("execl: %s",strerror(errno)); exit(1);
  63. }
  64. close(p_in[0]); close(p_out[1]);
  65. while (waitpid(pid,NULL,WNOHANG) != pid) {
  66. FD_ZERO(&rfds); FD_SET(netfd,&rfds); FD_SET(p_out[0],&rfds);
  67. maxfd = netfd>p_out[0] ? netfd : p_out[0];
  68. tv.tv_sec=1; tv.tv_usec=0;
  69. rc=select(maxfd+1, &rfds, NULL, NULL, NULL);
  70. if (rc == -1) { xprf("select: %s",strerror(errno)); return; }
  71. if (FD_ISSET(netfd, &rfds)) {
  72. rc=read(netfd,buf,BUFSIZE);
  73. for (c=0; c<rc; c++)
  74. if (buf[c]!='\r') write(p_in[1],buf+c,1);
  75. }
  76. if (FD_ISSET(p_out[0], &rfds)) {
  77. rc=read(p_out[0],buf,BUFSIZE);
  78. for (c=0; c<rc; c+=write(netfd,buf,rc)) ;
  79. }
  80. }
  81. }
  82. int main(int argc, char ** argv) {
  83. struct sockaddr_in addr;
  84. int listenfd,fd;
  85. if (argc != 2 || argv[1][0] == '-') {
  86. fprintf(stderr,"Usage: %s < log-file | tty-device >\n",argv[0]);
  87. return 1;
  88. }
  89. if ( (out=fopen(argv[1],"a+")) == NULL ) {
  90. fprintf(stderr,"Can't open log file '%s': %s",argv[1],strerror(errno));
  91. return 1;
  92. }
  93. setvbuf(out,NULL,_IONBF,0);
  94. chdir("/");
  95. printf("Cliffords Remote Control Daemon starting in 3 seconds ...\n");
  96. if (fork()) return 0;
  97. sleep(3);
  98. fprintf(out,"\n\n\r");
  99. xprf("Binding port %d and waiting for connections ...\n",PORT);
  100. if (signal(SIGCHLD,SIG_IGN) == SIG_ERR) xprf("signal: %s",strerror(errno));
  101. if ((listenfd=socket(AF_INET,SOCK_STREAM,0)) == -1) xprf("socket: %s",strerror(errno));
  102. bzero(&addr,sizeof(addr));
  103. addr.sin_family=AF_INET;
  104. addr.sin_addr.s_addr = htonl(INADDR_ANY);
  105. addr.sin_port = htons(PORT);
  106. if (bind(listenfd,&addr,sizeof(addr)) == -1) xprf("bind: %s",strerror(errno));
  107. if (listen(listenfd,5)==-1) xprf("listen: %s",strerror(errno));
  108. while (1) {
  109. if ((fd=accept(listenfd,NULL,NULL)) == -1) xprf("accept: %s",strerror(errno));
  110. if (!fork()) {
  111. xprf("connection %d opened.\n",(int)getpid());
  112. do_session(fd);
  113. xprf("connection %d closed.\n",(int)getpid());
  114. return 0;
  115. } else close(fd);
  116. }
  117. return 0;
  118. }