#include "def" #define MAXHOSTNAME 100 #define MAXCLIENTS 100 char ThisHost[MAXHOSTNAME]; char sockHost[MAXHOSTNAME]; void reusePort(int sock); void SIGhandler(int); pid_t ProcPID; fd_set readset, allset; int client[MAXCLIENTS]; char buf[512]; int rc; int sockPort; int ClientIndex = 0; int ConnServIndex = 0; int AcceptClientIndex = 0; int i; int ListenSock, ConnectSock[MAXCLIENTS], AcceptSock[MAXCLIENTS]; struct sockaddr_in from[MAXCLIENTS]; struct sockaddr_in ThisServer, ConnServ[MAXCLIENTS]; struct sockaddr_in LocalConnServ[MAXCLIENTS]; struct hostent *LocalHP, *RemoteHP, *gethostbyname(); struct sockaddr_in fromi; int fromlen; int length; FILE *sockFile; FILE *PIDFile; char sockFileN[100]; char PIDFileN[100]; main(argc, argv) int argc; char *argv[]; { char *username = cuserid(NULL); char cmd[100]; sprintf(sockFileN, "/tmp/sockFile%s", username); sprintf(PIDFileN, "/tmp/PIDFile%s", username); sockFile = fopen(sockFileN, "a+"); PIDFile = fopen(PIDFileN, "a+"); if (signal(SIGINT, SIGhandler) == SIG_ERR) { fprintf(stderr, "cannot set handler for SIGINT\n"); exit(1); } gethostname(ThisHost, MAXHOSTNAME); printf("----scg running at host NAME: %s\n", ThisHost); if ((LocalHP = gethostbyname(ThisHost)) == NULL) { fprintf(stderr, "Can't find host %s\n", ThisHost); exit(-1); } bcopy(LocalHP->h_addr, &(ThisServer.sin_addr), LocalHP->h_length); printf(" (scg INET ADDRESS is: %s )\n", inet_ntoa(ThisServer.sin_addr)); printf(" PID is: %d \n", getpid()); ThisServer.sin_family = AF_INET; ThisServer.sin_addr.s_addr = htonl(INADDR_ANY); ThisServer.sin_port = htons(0); ListenSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ListenSock < 0) { perror("opening stream socket"); exit(-1); } reusePort(ListenSock); if (bind(ListenSock, (SA *) & ThisServer, sizeof(ThisServer)) < 0) { close(ListenSock); perror("binding name to stream socket"); exit(-1); } length = sizeof(ThisServer); if (getsockname(ListenSock, (SA *) & ThisServer, &length)) { perror("getting socket name"); exit(0); } printf(" Server Port is: %d\n", ntohs(ThisServer.sin_port)); FD_ZERO(&allset); while (fscanf(sockFile, "%s %d\n", sockHost, &sockPort) > 0) { /** Connect to other scg */ ConnectSock[ConnServIndex] = socket(AF_INET, SOCK_STREAM, 0); ConnServ[ConnServIndex].sin_family = AF_INET; if ((RemoteHP = gethostbyname(sockHost)) == NULL) { fprintf(stderr, "Can't find host %s\n", sockHost); exit(-1); } bcopy(RemoteHP->h_addr, &ConnServ[ConnServIndex].sin_addr, RemoteHP->h_length); ConnServ[ConnServIndex].sin_port = htons(sockPort); if (ConnectSock[ConnServIndex] < 0) { perror("opening stream socket"); exit(-1); } if (connect(ConnectSock[ConnServIndex], (SA *) & ConnServ[ConnServIndex], sizeof(ConnServ[ConnServIndex])) < 0) { close(ConnectSock[ConnServIndex]); perror("connecting stream socket"); } length = sizeof(LocalConnServ[ConnServIndex]); if (getsockname(ConnectSock[ConnServIndex], (SA *) & LocalConnServ[ConnServIndex], &length)) { perror("getting socket name"); exit(0); } printf("Connected to Port: %d - Connection Port is: %d\n", ntohs(ConnServ[ConnServIndex].sin_port), ntohs(LocalConnServ[ConnServIndex].sin_port)); client[ClientIndex++] = ConnectSock[ConnServIndex]; /* save descriptor */ FD_SET(ConnectSock[ConnServIndex], &allset); /* add descriptor to set */ ConnServIndex++; } fseek(sockFile, 0, SEEK_END); fprintf(sockFile, "%s %d\n", ThisHost, ntohs(ThisServer.sin_port)); fflush(sockFile); fseek(PIDFile, 0, SEEK_END); fprintf(PIDFile, "%d\n", getpid()); fflush(PIDFile); /** accept TCP connections from clients and use select to serve each */ listen(ListenSock, 4); fromlen = sizeof(fromi); FD_SET(ListenSock, &allset); FD_SET(0, &allset); for (;;) { readset = allset; select(MAXCLIENTS, &readset, NULL, NULL, NULL); if (FD_ISSET(ListenSock, &readset)) { AcceptSock[AcceptClientIndex] = accept(ListenSock, (SA *) & fromi, &fromlen); client[ClientIndex++] = AcceptSock[AcceptClientIndex]; FD_SET(AcceptSock[AcceptClientIndex], &allset); AcceptClientIndex++; } if (FD_ISSET(0, &readset)) { rc = read(0, buf, sizeof(buf)); if (rc == 0) { printf("DONE\n"); printf("KILLING SPREE\n"); fseek(PIDFile, 0, SEEK_SET); while (fscanf(PIDFile, "%d\n", &ProcPID) > 0) { printf("Killing %d\n", ProcPID); if (getpid() != ProcPID) kill(ProcPID, SIGINT); } kill(getpid(), SIGINT); } for (i = 0; i < ClientIndex; i++) { if (write(client[i], buf, rc) < 0) perror("sending stream message"); } } for (i = 0; i < ClientIndex; i++) { if (FD_ISSET(client[i], &readset)) { if ((rc = recv(client[i], buf, sizeof(buf), 0)) < 0) { perror("receiving stream message"); printf("DONE\n"); exit(0); } if (rc > 0) { buf[rc] = NULL; write(1, buf, rc); } } } } } void reusePort(int s) { int one = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)) == -1) { printf("error in setsockopt,SO_REUSEPORT \n"); exit(-1); } } void SIGhandler(int sig) { /* * Print out what we received. */ psignal(sig, "Received signal"); printf("Session Ending in 3 second...\n"); for (i = 1; i <= 3; i++) { printf("%d.", i); fflush(stdout); sleep(1); } exit(0); }