mux/src/slave.cpp File Reference

#include "autoconf.h"
#include "config.h"
#include <netdb.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <signal.h>
#include "slave.h"
#include <arpa/inet.h>

Include dependency graph for slave.cpp:

Go to the source code of this file.

Defines

#define CAST_SIGNAL_FUNC
#define MAX_STRING   1000
#define INADDR_NONE   ((in_addr_t)-1)
#define MAX_CHILDREN   20

Functions

char * format_inet_addr (char *dest, long addr)
char * stpcpy (char *dest, const char *src)
RETSIGTYPE child_timeout_signal (int iSig)
int query (char *ip, char *orig_arg)
RETSIGTYPE alarm_signal (int iSig)
RETSIGTYPE child_signal (int iSig)
int main (int argc, char *argv[])

Variables

pid_t parent_pid
char * arg_for_errors
volatile int nChildrenStarted = 0
volatile int nChildrenEndedSIGCHLD = 0
volatile int nChildrenEndedMain = 0


Define Documentation

#define CAST_SIGNAL_FUNC

Definition at line 26 of file slave.cpp.

#define INADDR_NONE   ((in_addr_t)-1)

Definition at line 35 of file slave.cpp.

Referenced by query().

#define MAX_CHILDREN   20

Definition at line 223 of file slave.cpp.

Referenced by main().

#define MAX_STRING   1000

Definition at line 31 of file slave.cpp.

Referenced by main(), and query().


Function Documentation

RETSIGTYPE alarm_signal ( int  iSig  ) 

Definition at line 206 of file slave.cpp.

References CAST_SIGNAL_FUNC, and parent_pid.

Referenced by main().

00207 {
00208     struct itimerval itime;
00209     struct timeval interval;
00210 
00211     if (getppid() != parent_pid)
00212     {
00213         exit(1);
00214     }
00215     signal(SIGALRM, CAST_SIGNAL_FUNC alarm_signal);
00216     interval.tv_sec = 120;  // 2 minutes.
00217     interval.tv_usec = 0;
00218     itime.it_interval = interval;
00219     itime.it_value = interval;
00220     setitimer(ITIMER_REAL, &itime, 0);
00221 }

RETSIGTYPE child_signal ( int  iSig  ) 

Definition at line 228 of file slave.cpp.

References CAST_SIGNAL_FUNC, nChildrenEndedMain, nChildrenEndedSIGCHLD, and nChildrenStarted.

Referenced by main().

00229 {
00230     // Collect the children.
00231     //
00232     while (waitpid(0, NULL, WNOHANG) > 0)
00233     {
00234         int nChildren = nChildrenStarted - nChildrenEndedSIGCHLD
00235             - nChildrenEndedMain;
00236         if (0 < nChildren)
00237         {
00238             nChildrenEndedSIGCHLD++;
00239         }
00240     }
00241 
00242     signal(SIGCHLD, CAST_SIGNAL_FUNC child_signal);
00243 }

RETSIGTYPE child_timeout_signal ( int  iSig  ) 

Definition at line 61 of file slave.cpp.

Referenced by main().

00062 {
00063     exit(1);
00064 }

char* format_inet_addr ( char *  dest,
long  addr 
)

Definition at line 38 of file slave.cpp.

Referenced by query().

00039 {
00040     sprintf(dest, "%ld.%ld.%ld.%ld",
00041         (addr & 0xFF000000) >> 24,
00042         (addr & 0x00FF0000) >> 16,
00043         (addr & 0x0000FF00) >> 8,
00044         (addr & 0x000000FF));
00045     return (dest + strlen(dest));
00046 }

int main ( int  argc,
char *  argv[] 
)

Definition at line 245 of file slave.cpp.

References alarm_signal(), CAST_SIGNAL_FUNC, child_signal(), child_timeout_signal(), MAX_CHILDREN, MAX_STRING, nChildrenEndedMain, nChildrenEndedSIGCHLD, nChildrenStarted, parent_pid, and query().

00246 {
00247     char arg[MAX_STRING];
00248     char *p;
00249     int len;
00250     pid_t child;
00251 
00252     parent_pid = getppid();
00253     if (parent_pid == 1)
00254     {
00255         // Our real parent process is gone, and we have been inherited by the
00256         // init process.
00257         //
00258         exit(1);
00259     }
00260 
00261     alarm_signal(SIGALRM);
00262     signal(SIGCHLD, CAST_SIGNAL_FUNC child_signal);
00263     signal(SIGPIPE, SIG_DFL);
00264 
00265     for (;;)
00266     {
00267         len = read(0, arg, MAX_STRING - 1);
00268         if (len == 0)
00269         {
00270             break;
00271         }
00272         if (len < 0)
00273         {
00274             if (errno == EINTR)
00275             {
00276                 errno = 0;
00277                 continue;
00278             }
00279             break;
00280         }
00281         arg[len] = '\0';
00282         p = strchr(arg, '\n');
00283         if (p)
00284         {
00285             *p = '\0';
00286         }
00287         child = fork();
00288         switch (child)
00289         {
00290         case -1:
00291             exit(1);
00292             break;
00293 
00294         case 0: // child.
00295             {
00296                 // We don't want to try this for more than 5 minutes.
00297                 //
00298                 struct itimerval itime;
00299                 struct timeval interval;
00300 
00301                 interval.tv_sec = 300;  // 5 minutes.
00302                 interval.tv_usec = 0;
00303                 itime.it_interval = interval;
00304                 itime.it_value = interval;
00305                 signal(SIGALRM, CAST_SIGNAL_FUNC child_timeout_signal);
00306                 setitimer(ITIMER_REAL, &itime, 0);
00307             }
00308             exit(query(arg, p + 1) != 0);
00309             break;
00310         }
00311         if (child > 0)
00312         {
00313             nChildrenStarted++;
00314         }
00315 
00316         int nChildren = nChildrenStarted - nChildrenEndedSIGCHLD
00317             - nChildrenEndedMain;
00318 
00319         // Collect the children.
00320         //
00321         while (waitpid(0, NULL, (nChildren < MAX_CHILDREN) ? WNOHANG : 0) > 0)
00322         {
00323             if (0 < nChildren)
00324             {
00325                 nChildrenEndedMain++;
00326             }
00327         }
00328     }
00329     exit(0);
00330 }

int query ( char *  ip,
char *  orig_arg 
)

Definition at line 66 of file slave.cpp.

References arg_for_errors, format_inet_addr(), INADDR_NONE, MAX_STRING, and stpcpy().

Referenced by main().

00067 {
00068     char *comma;
00069     char *port_pair;
00070     struct hostent *hp;
00071     struct sockaddr_in sin;
00072     int s;
00073     FILE *f;
00074     char result[MAX_STRING];
00075     char buf[MAX_STRING * 2];
00076     char buf2[MAX_STRING * 2];
00077     char buf3[MAX_STRING * 4];
00078     char arg[MAX_STRING];
00079     size_t len;
00080     char *p;
00081     in_addr_t addr;
00082 
00083     addr = inet_addr(ip);
00084     if (addr == INADDR_NONE)
00085     {
00086         return -1;
00087     }
00088     const char *pHName = ip;
00089     hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
00090     if (  hp
00091        && strlen(hp->h_name) < MAX_STRING)
00092     {
00093         pHName = hp->h_name;
00094     }
00095     p = stpcpy(buf, ip);
00096     *p++ = ' ';
00097     p = stpcpy(p, pHName);
00098     *p++ = '\n';
00099     *p++ = '\0';
00100 
00101     arg_for_errors = orig_arg;
00102     strcpy(arg, orig_arg);
00103     comma = (char *)strrchr(arg, ',');
00104     if (comma == NULL)
00105     {
00106         return -1;
00107     }
00108     *comma = 0;
00109     port_pair = (char *)strrchr(arg, ',');
00110     if (port_pair == NULL)
00111     {
00112         return -1;
00113     }
00114     *port_pair++ = 0;
00115     *comma = ',';
00116 
00117     hp = gethostbyname(arg);
00118     if (hp == NULL)
00119     {
00120         static struct hostent def;
00121         static struct in_addr defaddr;
00122         static char *alist[1];
00123         static char namebuf[MAX_STRING];
00124 
00125         defaddr.s_addr = inet_addr(arg);
00126         if (defaddr.s_addr == INADDR_NONE)
00127         {
00128             return -1;
00129         }
00130         strcpy(namebuf, arg);
00131         def.h_name = namebuf;
00132         def.h_addr_list = alist;
00133         def.h_addr = (char *)&defaddr;
00134         def.h_length = sizeof(struct in_addr);
00135 
00136         def.h_addrtype = AF_INET;
00137         def.h_aliases = 0;
00138         hp = &def;
00139     }
00140     sin.sin_family = hp->h_addrtype;
00141     bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
00142     sin.sin_port = htons(113); // ident port
00143     s = socket(hp->h_addrtype, SOCK_STREAM, 0);
00144     if (s < 0)
00145     {
00146         return -1;
00147     }
00148     if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
00149         if (   errno != ECONNREFUSED
00150             && errno != ETIMEDOUT
00151             && errno != ENETUNREACH
00152             && errno != EHOSTUNREACH)
00153         {
00154             close(s);
00155             return -1;
00156         }
00157         buf2[0] = '\0';
00158     }
00159     else
00160     {
00161         len = strlen(port_pair);
00162         if ((size_t)write(s, port_pair, len) != len)
00163         {
00164             close(s);
00165             return (-1);
00166         }
00167         if (write(s, "\r\n", 2) != 2)
00168         {
00169             close(s);
00170             return (-1);
00171         }
00172         f = fdopen(s, "r");
00173         {
00174             int c;
00175 
00176             p = result;
00177             while ((c = fgetc(f)) != EOF)
00178             {
00179                 if (c == '\n')
00180                 {
00181                     break;
00182                 }
00183                 if (0x20 <= c && c <= 0x7E)
00184                 {
00185                     *p++ = c;
00186                     if (p - result == MAX_STRING - 1)
00187                     {
00188                         break;
00189                     }
00190                 }
00191             }
00192             *p = '\0';
00193         }
00194         fclose(f);
00195         p = (char *)format_inet_addr(buf2, ntohl(sin.sin_addr.s_addr));
00196         *p++ = ' ';
00197         p = stpcpy(p, result);
00198         *p++ = '\n';
00199         *p++ = '\0';
00200     }
00201     sprintf(buf3, "%s%s", buf, buf2);
00202     write(1, buf3, strlen(buf3));
00203     return 0;
00204 }

char* stpcpy ( char *  dest,
const char *  src 
)

Definition at line 51 of file slave.cpp.

Referenced by query().

00052 {
00053     while ((*dest = *src))
00054     {
00055         ++dest;
00056         ++src;
00057     }
00058     return (dest);
00059 }


Variable Documentation

char* arg_for_errors

Definition at line 32 of file slave.cpp.

Referenced by query().

volatile int nChildrenEndedMain = 0

Definition at line 226 of file slave.cpp.

Referenced by child_signal(), and main().

volatile int nChildrenEndedSIGCHLD = 0

Definition at line 225 of file slave.cpp.

Referenced by child_signal(), and main().

volatile int nChildrenStarted = 0

Definition at line 224 of file slave.cpp.

Referenced by child_signal(), and main().

pid_t parent_pid

Definition at line 29 of file slave.cpp.

Referenced by alarm_signal(), and main().


Generated on Mon May 28 04:40:22 2007 for MUX by  doxygen 1.4.7