mirror of the now-defunct rocklinux.org
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.

146 lines
4.4 KiB

  1. /*
  2. * gcc -Wall -O2 xctrld.c -o /sbin/xctrld
  3. *
  4. * --- ROCK-COPYRIGHT-NOTE-BEGIN ---
  5. *
  6. * This copyright note is auto-generated by ./scripts/Create-CopyPatch.
  7. * Please add additional copyright information _after_ the line containing
  8. * the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by
  9. * the ./scripts/Create-CopyPatch script. Do not edit this copyright text!
  10. *
  11. * ROCK Linux: rock-src/misc/archive/xctrld.c
  12. * ROCK Linux is Copyright (C) 1998 - 2005 Clifford Wolf
  13. *
  14. * This program is free software; you can redistribute it and/or modify
  15. * it under the terms of the GNU General Public License as published by
  16. * the Free Software Foundation; either version 2 of the License, or
  17. * (at your option) any later version. A copy of the GNU General Public
  18. * License can be found at Documentation/COPYING.
  19. *
  20. * Many people helped and are helping developing ROCK Linux. Please
  21. * have a look at http://www.rocklinux.org/ and the Documentation/TEAM
  22. * file for details.
  23. *
  24. * --- ROCK-COPYRIGHT-NOTE-END ---
  25. */
  26. #include <fcntl.h>
  27. #include <netinet/in.h>
  28. #include <signal.h>
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <sys/socket.h>
  33. #include <sys/stat.h>
  34. #include <sys/time.h>
  35. #include <sys/types.h>
  36. #include <sys/wait.h>
  37. #include <unistd.h>
  38. #include <errno.h>
  39. #define PORT 2225
  40. #define BUFSIZE 1024
  41. FILE * out = NULL;
  42. #define xprf(format, args... ) fprintf(out,"Cliffords Control-Daemon: " format "\r", ## args)
  43. /* This function is very dirty - but it seams to to the only way that
  44. * works without using pty devices. making the netfd directly the stdin
  45. * stdout and stderr channels of /bin/sh caused a lot of problems ...
  46. */
  47. void do_session(int netfd) {
  48. int p_in[2],p_out[2];
  49. int rc,maxfd,pid,c;
  50. struct timeval tv;
  51. char buf[BUFSIZE];
  52. fd_set rfds;
  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));
  58. pipe(p_in); pipe(p_out);
  59. if (signal(SIGCHLD,SIG_DFL) == SIG_ERR) xprf("signal: %s",strerror(errno));
  60. if ( (pid=fork()) == 0 ) {
  61. close(0); dup2(p_in[0],0);
  62. close(1); dup2(p_out[1],1);
  63. close(2); dup2(p_out[1],2);
  64. close(p_in[0]); close(p_in[1]);
  65. close(p_out[0]); close(p_out[1]); close(netfd);
  66. setenv("USER","root",1); setenv("HOME","/root",1);
  67. setenv("LOGNAME","root",1); setenv("TERM","linux",1);
  68. execl("/bin/sh","/bin/sh","--login","-i",NULL);
  69. xprf("execl: %s",strerror(errno)); exit(1);
  70. }
  71. close(p_in[0]); close(p_out[1]);
  72. while (waitpid(pid,NULL,WNOHANG) != pid) {
  73. FD_ZERO(&rfds); FD_SET(netfd,&rfds); FD_SET(p_out[0],&rfds);
  74. maxfd = netfd>p_out[0] ? netfd : p_out[0];
  75. tv.tv_sec=1; tv.tv_usec=0;
  76. rc=select(maxfd+1, &rfds, NULL, NULL, NULL);
  77. if (rc == -1) { xprf("select: %s",strerror(errno)); return; }
  78. if (FD_ISSET(netfd, &rfds)) {
  79. rc=read(netfd,buf,BUFSIZE);
  80. for (c=0; c<rc; c++)
  81. if (buf[c]!='\r') write(p_in[1],buf+c,1);
  82. }
  83. if (FD_ISSET(p_out[0], &rfds)) {
  84. rc=read(p_out[0],buf,BUFSIZE);
  85. for (c=0; c<rc; c+=write(netfd,buf,rc)) ;
  86. }
  87. }
  88. }
  89. int main(int argc, char ** argv) {
  90. struct sockaddr_in addr;
  91. int listenfd,fd;
  92. if (argc != 2 || argv[1][0] == '-') {
  93. fprintf(stderr,"Usage: %s < log-file | tty-device >\n",argv[0]);
  94. return 1;
  95. }
  96. if ( (out=fopen(argv[1],"a+")) == NULL ) {
  97. fprintf(stderr,"Can't open log file '%s': %s",argv[1],strerror(errno));
  98. return 1;
  99. }
  100. setvbuf(out,NULL,_IONBF,0);
  101. chdir("/");
  102. printf("Cliffords Remote Control Daemon starting in 3 seconds ...\n");
  103. if (fork()) return 0;
  104. sleep(3);
  105. fprintf(out,"\n\n\r");
  106. xprf("Binding port %d and waiting for connections ...\n",PORT);
  107. if (signal(SIGCHLD,SIG_IGN) == SIG_ERR) xprf("signal: %s",strerror(errno));
  108. if ((listenfd=socket(AF_INET,SOCK_STREAM,0)) == -1) xprf("socket: %s",strerror(errno));
  109. bzero(&addr,sizeof(addr));
  110. addr.sin_family=AF_INET;
  111. addr.sin_addr.s_addr = htonl(INADDR_ANY);
  112. addr.sin_port = htons(PORT);
  113. if (bind(listenfd,&addr,sizeof(addr)) == -1) xprf("bind: %s",strerror(errno));
  114. if (listen(listenfd,5)==-1) xprf("listen: %s",strerror(errno));
  115. while (1) {
  116. if ((fd=accept(listenfd,NULL,NULL)) == -1) xprf("accept: %s",strerror(errno));
  117. if (!fork()) {
  118. xprf("connection %d opened.\n",(int)getpid());
  119. do_session(fd);
  120. xprf("connection %d closed.\n",(int)getpid());
  121. return 0;
  122. } else close(fd);
  123. }
  124. return 0;
  125. }