#include <stdio.h> #include <stdlib.h> main() { printf("Hello world !/n"); system("pause"); } /**************************************************************** function:daemonize description: detach the server process from the current context, creating a pristine, predictable environment in which it will execute. arguments: servfd file descriptor in use by server. return value: none. calls: none. globals: none. ****************************************************************/ void daemonize (servfd) int servfd; { int childpid, fd, fdtablesize; /* ignore terminal I/O, stop signals */ signal(SIGTTOU,SIG_IGN); signal(SIGTTIN,SIG_IGN); signal(SIGTSTP,SIG_IGN); /* fork to put us in the background (whether or not the user specified '&' on the command line */ if ((childpid = fork()) < 0) { fputs("failed to fork first child/r/n",stderr); exit(1); } else if (childpid > 0) exit(0); /* terminate parent, continue in child */ /* dissociate from process group */ if (setpgrp(0,getpid())<0) { fputs("failed to become process group leader/r/n",stderr); exit(1); } /* lose controlling terminal */ if ((fd = open("/dev/tty",O_RDWR)) >= 0) { ioctl(fd,TIOCNOTTY,NULL); close(fd); } /* close any open file descriptors */ for (fd = 0, fdtablesize = getdtablesize(); fd < fdtablesize; fd++) if (fd != servfd) close(fd); /* set working directory to allow filesystems to be unmounted */ chdir("/"); /* clear the inherited umask */ umask(0); /* setup zombie prevention */ signal(SIGCLD,(Sigfunc *)reap_status); } /**************************************************************** function: reap_status description: handle a SIGCLD signal by reaping the exit status of the perished child, and discarding it. arguments: none. return value: none. calls: none. globals: none. ****************************************************************/ void reap_status() { int pid; union wait status; while ((pid = wait3(&status,WNOHANG,NULL)) > 0) ; /* loop while there are more dead children */ } /**************************************************************** function:do_proxy description:does the actual work of virtually connecting a client to the telnet service on the isolated host. arguments:usersockfd socket to which the client is connected. return value: none. calls:none. globals: reads hostaddr. ****************************************************************/ void do_proxy (usersockfd) int usersockfd; { int isosockfd; fd_set rdfdset; int connstat; int iolen; char buf[2048]; /* open a socket to connect to the isolated host */ if ((isosockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) errorout("failed to create socket to host"); /* attempt a connection */ connstat = connect(isosockfd,(struct sockaddr *) &hostaddr, sizeof(hostaddr)); switch (connstat) { case 0: break; case ETIMEDOUT: case ECONNREFUSED: case ENETUNREACH: strcpy(buf,sys_myerrlist[errno]); strcat(buf,"/r/n"); write(usersockfd,buf,strlen(buf)); close(usersockfd); exit(1); /* die peacefully if we can't establish a connection */ break; default: errorout("failed to connect to host"); } /* now we're connected, serve fall into the data echo loop */ while (1) { /* Select for readability on either of our two sockets */ FD_ZERO(&rdfdset); FD_SET(usersockfd,&rdfdset); FD_SET(isosockfd,&rdfdset); if (select(FD_SETSIZE,&rdfdset,NULL,NULL,NULL) < 0) errorout("select failed"); /* is the client sending data? */ if (FD_ISSET(usersockfd,&rdfdset)) { if ((iolen = read(usersockfd,buf,sizeof(buf))) <= 0) break; /* zero length means the client disconnected */ rite(isosockfd,buf,iolen); /* copy to host -- blocking semantics */ } /* is the host sending data? */ if (FD_ISSET(isosockfd,&rdfdset)) { f ((iolen = read(isosockfd,buf,sizeof(buf))) <= 0) break; /* zero length means the host disconnected */ rite(usersockfd,buf,iolen); /* copy to client -- blocking semantics */ } } /* we're done with the sockets */ close(isosockfd); lose(usersockfd); } /**************************************************************** function: errorout description: displays an error message on the console and kills the current process. arguments: msg -- message to be displayed. return value: none -- does not return. calls: none. globals: none. ****************************************************************/ void errorout (msg) char *msg; { FILE *console; console = fopen("/dev/console","a"); fprintf(console,"proxyd: %s/r/n",msg); fclose(console); exit(1); }