/****************************************************************** * * * Nest version 2 - 3D Wasp Nest Simulator * * Copyright (C) 1997 Sylvain GUERIN * * LIASC, ENST Bretagne & Santa Fe Institute * * * ****************************************************************** E-mail: Sylvain.Guerin@enst-bretagne.fr or: Sylvain Guerin 13 rue des Monts Lorgeaux, 51460 L'EPINE, FRANCE ****************************************************************** This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ****************************************************************** Name : NetInt.c Component : evaluation interface Fonctionality : contains methods for objects refering to the net interface (including the Net object) ******************************************************************/ #include #include #include #include #include #include #include #include "config.h" #include "NetInt.h" extern char nest2ConfigFile[256]; Host::Host (char* aHostName) { hostName = strdup (aHostName); checkIfAlive (); } Host::~Host() { } void Host::checkIfAlive () { int s; struct sockaddr_in sin; struct hostent *hp; int status; switch (fork()) { case 0: hp = gethostbyname (hostName); if (hp == NULL) _exit(1); s = socket (AF_INET, SOCK_STREAM, 0); if (s < 0) _exit(1); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = 0; memset (sin.sin_zero, 0, 8); if (bind (s, (struct sockaddr *) &sin, sizeof (sin)) < 0) { close (s); _exit(1); } sin.sin_port = htons ((getservbyname ("shell", "tcp"))->s_port); memcpy (&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); alarm(TIMEOUT); signal(SIGALRM,exit); if (connect (s, (struct sockaddr *) &sin, sizeof (sin)) < 0) { close (s); _exit(2); } alarm(0); close (s); _exit(0); break; case -1: isEnable = BFalse; hostState = unknown; default: wait(&status); if (WIFEXITED(status) == 0) { isEnable = BFalse; hostState = unknown; return; } switch (WEXITSTATUS(status)) { case 1: isEnable = BFalse; hostState = unknown; break; case 2: isEnable = BFalse; hostState = unreachable; break; case SIGALRM: isEnable = BFalse; hostState = down; break; default: isEnable = BTrue; hostState = sleeping; } } } Net::Net (unsigned int aMaxHostsNumber) { maxHostsNumber = aMaxHostsNumber; numberOfHosts = 0; host = new Host*[maxHostsNumber]; netContent = new ArrayContent(5, maxHostsNumber); netContent->addColumn ("Nb", IntType, 3); netContent->addColumn ("HostName", CharType, 12); netContent->addColumn ("Enable", CharType, 7); netContent->addColumn ("State", CharType, 13); netContent->addColumn ("Began at", CharType, 11); } Net::~Net () { int i; for (i=0; i<(int)numberOfHosts; i++) { delete host[i]; } delete[] host; delete netContent; } void Net::testAll () { int i; for (i=0; i<(int)numberOfHosts; i++) { host[i]->checkIfAlive (); update (i); } } unsigned int Net::add (char* aHostName) { unsigned int line; host[numberOfHosts] = new Host (aHostName); numberOfHosts++; line = netContent->addLine (); update (line); return line; } void Net::remove (unsigned int index) { int i; delete host[index]; for (i=index; i<(int)numberOfHosts-1; i++) { host[i] = host[i+1]; } numberOfHosts--; netContent->removeLine (index); for (i=index; i<(int)numberOfHosts; i++) { netContent->addData (i, 0, (int)i); } } void Net::update (unsigned int index) { char aDate[40]; strcpy (aDate, host[index]->beginSimulationDate); netContent->addData (index, 0, (int)index); netContent->addData (index, 1, host[index]->hostName); if (host[index]->isEnable) { netContent->addData (index, 2, "yes"); } else { netContent->addData (index, 2, "no"); } if (host[index]->hostState == unreachable) { netContent->addData (index, 3, "unreachable"); } else if (host[index]->hostState == unknown) { netContent->addData (index, 3, "unknown"); } else if (host[index]->hostState == sleeping) { netContent->addData (index, 3, "sleeping"); } else if (host[index]->hostState == running) { netContent->addData (index, 3, "running"); } else if (host[index]->hostState == down) { netContent->addData (index, 3, "down"); } if (host[index]->hostState == running) { netContent->addData (index, 4, aDate); } else { netContent->addData (index, 4, "not running"); } } Host* Net::get (unsigned int index) { return host[index]; } unsigned int Net::getNumber () { return numberOfHosts; } ArrayContent* Net::getNetContent () { return netContent; } int Net::loadFromConfigFile (InfoBox* infoBox) { FILE* aFile; char currentHostName[256]; int i = 0; int nb = 0; if ((aFile = fopen (nest2ConfigFile, "r")) == NULL) { printf ("Error: unable to open %s\n", nest2ConfigFile); return -1; } else { while (fgets (currentHostName, 256, aFile) != NULL) { nb++; } fclose (aFile); aFile = fopen (nest2ConfigFile, "r"); while (fgets (currentHostName, 256, aFile) != NULL) { currentHostName[strlen (currentHostName)-1] = '\0'; add (currentHostName); i++; infoBox->setStatWindow ((double)(i+1)/(double)(nb)); infoBox->refreshStatWindow (); } fclose (aFile); return 0; } } int Net::saveInConfigFile () { FILE* aFile; /* USELESS char currentHostName[256]; */ int i = 0; if ((aFile = fopen (nest2ConfigFile, "w")) == NULL) { printf ("Error: unable to write %s\n", nest2ConfigFile); return -1; } else { for (i=0; i<(int)numberOfHosts; i++) { fprintf (aFile, "%s\n", (get (i))->hostName); } fclose (aFile); return 1; } } int Net::getFreeHost (char* returnedHost, int* returnedHostNb) { int i; int disabledHosts; disabledHosts = 0; for (i=0; i<(int)numberOfHosts; i++) { if (host[i]->hostState == sleeping) { strcpy (returnedHost, host[i]->hostName); *returnedHostNb = i; return 1; } else if ((host[i]->hostState == down) || (host[i]->hostState == unreachable)) { disabledHosts++; } } /* si toutes les machines sont nazes, alors on teste tout a nouveau */ if (disabledHosts == (int)numberOfHosts) { printf ("All remote hosts down... retesting....\n"); for (i=0; i<(int)numberOfHosts; i++) { host[i]->checkIfAlive (); update (i); } return 0; } else { return 0; } } /* ---------------------------------------------------------- */ NetInterface::NetInterface (Interface* theMainInterface, int x0, int y0, Display* aDisplay, Net* aNet) : Interface (x0, y0, 530, 500, 1, "Net configuration", "Net", aDisplay) { mainInterface = theMainInterface; net = aNet; exitButton = new Button (this, 20, 15, 100, 25, "Close", centerJustified, enabled); optionsButton = new Button (this, 130, 15, 100, 25, "Options", centerJustified, enabled); addButton = new Button (this, 20, 465, 90, 25, "Add", centerJustified, enabled); removeButton = new Button (this, 120, 465, 90, 25, "Remove", centerJustified, enabled); testButton = new Button (this, 220, 465, 90, 25, "Test", centerJustified, enabled); testAllButton = new Button (this, 320, 465, 90, 25, "Test all", centerJustified, enabled); saveButton = new Button (this, 420, 465, 90, 25, "Save", centerJustified, enabled); netArray = new ArrayWindow (this, 20, 50, 490, 400, enabled, Grey, net->getNetContent()); } NetInterface::~NetInterface () { delete exitButton; delete addButton; delete removeButton; delete saveButton; delete testButton; delete testAllButton; delete optionsButton; delete netArray; } actionType NetInterface::manageInterface (XEvent report) { if (exitButton->manageEvent (report) == buttonPressed) { return endInterface; } netArray->manageEvent (report); if (addButton->manageEvent (report) == buttonPressed) { char newHost[256]; strcpy (newHost, "host"); displayInputBox (mainInterface, "Add new host", "nest2", 1, 30); addCharInput ("Host ", 15, newHost); if (manageInputBox ()) { /* cancelled operation */ } else { net->add (newHost); netArray->refreshAll (); } } if (removeButton->manageEvent (report) == buttonPressed) { int line; line = netArray->getSelectedLine (); if (line > -1) { net->remove (line); netArray->setSelectedLine (); netArray->refreshAll (); } } if (saveButton->manageEvent (report) == buttonPressed) { if (net->saveInConfigFile () == -1) { displayDialogBox (mainInterface, "Error", "Nest2", "Unable to save net configuration file.", "Continue"); } else { displayDialogBox (mainInterface, "Save net configuration file", "Nest2", "Net configuration file has been saved.", "Continue"); } } if (testButton->manageEvent (report) == buttonPressed) { int line; line = netArray->getSelectedLine (); if (line > -1) { net->host[line]->checkIfAlive (); net->update (line); netArray->refreshAll (); } } if (testAllButton->manageEvent (report) == buttonPressed) { int i; displayInfoBox (mainInterface, "Net update", "Nest2", "Checking hosts, please wait..."); for (i=0; i< (int)net->getNumber (); i++) { net->host[i]->checkIfAlive (); net->update (i); netArray->refreshAll (); anInfoBox->setStatWindow ((double)(i+1)/(double)(net->getNumber ())); anInfoBox->refreshStatWindow (); } freeInfoBox (); } if (report.type == Expose) optionsButton->manageEvent (report); return noAction; } void NetInterface::refresh () { netArray->refresh (); exitButton->refresh (); addButton->refresh (); removeButton->refresh (); saveButton->refresh (); testButton->refresh (); testAllButton->refresh (); optionsButton->refresh (); }