AFS-Monitor

 view release on metacpan or  search on metacpan

src/Monitor.xs  view on Meta::CPAN

   "InitCallBackState",
   "Probe",
   "GetLock",
   "GetCE",
   "XStatsVersion",
   "GetXStats"
};


/*
 * from src/afsmonitor/afsmon-output.c
 *    ("$Header: /afs/slac/g/scs/slur/Repository/AFSDebug/Debug/src/Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $");
 */

static char *xferOpNames[] = {
   "FetchData",
   "StoreData"
};


/*
 * from src/afsmonitor/afsmonitor.h
 *
 */

/* structure of each threshold item */
struct Threshold {
   char itemName[THRESH_VAR_NAME_LEN];  /* field name */
   int index;                   /* positional index */
   char threshVal[THRESH_VAR_LEN];  /* user provided threshold value */
   char handler[256];           /* user provided ovf handler */
};


/*
 * from src/afsmonitor/afsmonitor.h
 *
 */

/* structures to store info of hosts to be monitored */
struct afsmon_hostEntry {
   char hostName[HOST_NAME_LEN];    /* fs or cm host name */
   int numThresh;               /* number of thresholds for this host */
   struct Threshold *thresh;    /* ptr to threshold entries */
   struct afsmon_hostEntry *next;
};


/*
 * from src/afsmonitor/afsmonitor.h
 *
 */

/* structures to store statistics in a format convenient to dump to the
screen */
/* for file servers */
struct fs_Display_Data {
   char hostName[HOST_NAME_LEN];
   int probeOK;                 /* 0 => probe failed */
   char data[NUM_FS_STAT_ENTRIES][FS_STAT_STRING_LEN];
   short threshOvf[NUM_FS_STAT_ENTRIES];    /* overflow flags */
   int ovfCount;                /* overflow count */
};
/* for cache managers */
struct cm_Display_Data {
   char hostName[HOST_NAME_LEN];
   int probeOK;                 /* 0 => probe failed */
   char data[NUM_CM_STAT_ENTRIES][CM_STAT_STRING_LEN];
   short threshOvf[NUM_CM_STAT_ENTRIES];    /* overflow flags */
   int ovfCount;                /* overflow count */
};



/*
 * from src/afsmonitor/afsmonitor.c
 *    ("$Header: /afs/slac/g/scs/slur/Repository/AFSDebug/Debug/src/Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $");
 */

/* wouldn't compile without this, but it wasn't in original afsmonitor.c */
#if !defined(__USE_GNU) && !defined(__APPLE_CC__)
char *
strcasestr(char *s1, char *s2)
{
   char *ptr;
   int len1, len2;

   len1 = strlen(s1);
   len2 = strlen(s2);

   if (len1 < len2)
      return ((char *)NULL);

   ptr = s1;

   while (len1 >= len2 && len1 > 0) {
      if ((strncasecmp(ptr, s2, len2)) == 0)
         return (ptr);
      ptr++;
      len1--;
   }
   return ((char *)NULL);
}
#endif           /* __USE_GNU */


/*
 * from src/afsmonitor/afsmonitor.c
 *    ("$Header: /afs/slac/g/scs/slur/Repository/AFSDebug/Debug/src/Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $");
 */

struct hostent *
GetHostByName(char *name)
{
   struct hostent *he;
#ifdef AFS_SUN5_ENV
   char ip_addr[32];
#endif

   he = gethostbyname(name);
#ifdef AFS_SUN5_ENV
   /* On solaris the above does not resolve hostnames to full names */
   if (he != NULL) {
      memcpy(ip_addr, he->h_addr, he->h_length);
      he = gethostbyaddr(ip_addr, he->h_length, he->h_addrtype);
   }
#endif
   return (he);
}


/*
 * from src/afsmonitor/afsmonitor.c
 *    ("$Header: /afs/slac/g/scs/slur/Repository/AFSDebug/Debug/src/Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $");
 */

/*
 * Constructs a string to pass back to Perl for easy execution of the threshold handler.
 * DOES NOT execute the threshold handler.
 *
 * from src/afsmonitor/afsmonitor.c
 *
 * int
 * execute_thresh_handler(a_handler, a_hostName, a_hostType,
 *                         a_threshName,a_threshValue, a_actValue)
 * char *a_handler;
 * char *a_hostName;
 * int a_hostType;
 * char *a_threshName;
 * char *a_threshValue;
 * char *a_actValue;
 */

int
my_execute_thresh_handler(a_handler, a_hostName, a_hostType, a_threshName,
                          a_threshValue, a_actValue,
                          ENTRY, buffer)
   char *a_handler;             /* ptr to handler function + args */
   char *a_hostName;            /* host name for which threshold crossed */
   int a_hostType;              /* fs or cm ? */
   char *a_threshName;          /* threshold variable name */
   char *a_threshValue;         /* threshold value */
   char *a_actValue;            /* actual value */
   HV *ENTRY;
   char *buffer;
{
   char fileName[256];          /* file name to execute */
   int i;
   char *ch;
   int argNum;
   int anotherArg;              /* boolean used to flag if another arg is available */
   char args[20 * 256] = "";
   char fsHandler_args[20][256];


   /* get the filename to execute - the first argument */
   sscanf(a_handler, "%s", fileName);

   /* construct the contents of *argv[] */

   strncpy(fsHandler_args[0], fileName, 256);
   strncpy(fsHandler_args[1], a_hostName, HOST_NAME_LEN);
   if (a_hostType == FS)
      strcpy(fsHandler_args[2], "fs");
   else
      strcpy(fsHandler_args[2], "cm");
   strncpy(fsHandler_args[3], a_threshName, THRESH_VAR_NAME_LEN);
   strncpy(fsHandler_args[4], a_threshValue, THRESH_VAR_LEN);
   strncpy(fsHandler_args[5], a_actValue, THRESH_VAR_LEN);


   argNum = 6;
   anotherArg = 1;
   ch = a_handler;

   /* we have already extracted the file name so skip to the 1st arg */
   while (isspace(*ch)) /* leading blanks */
      ch++;
   while (!isspace(*ch) && *ch != '\0') /* handler filename */
      ch++;

   while (*ch != '\0') {
      if (isspace(*ch)) {
         anotherArg = 1;
      }
      else if (anotherArg) {
         anotherArg = 0;
         sscanf(ch, "%s", fsHandler_args[argNum]);
         argNum++;
      }
      ch++;
      if (argNum >= 20) {
         sprintf(buffer,
                 "Threshold handlers cannot have more than 20 arguments (55)");
         return (55);
      }

   }

   strcpy(args, fsHandler_args[0]);

   for (i = 1; i < argNum; i++) {
      strcat(args, " ");
      strcat(args, fsHandler_args[i]);
   }

   hv_store(ENTRY, "overflow", 8, newSVpv(args, 0), 0);

   return (0);
}   /* my_execute_thresh_handler() */

src/Monitor.xs  view on Meta::CPAN

/*
 * from src/afsmonitor/afsmonitor.c
 *    ("$Header: /afs/slac/g/scs/slur/Repository/AFSDebug/Debug/src/Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $");
 */

int
my_process_config_file(a_config_filename, numFS, numCM, lastHostType,
                       last_hostEntry, fs_showDefault, cm_showDefault,
                       fs_showFlags, cm_showFlags, FSnameList, CMnameList)
   char *a_config_filename;
   int *numFS;
   int *numCM;
   int *lastHostType;
   struct afsmon_hostEntry **last_hostEntry;
   int *fs_showDefault;
   int *cm_showDefault;
   short *fs_showFlags;
   short *cm_showFlags;
   struct afsmon_hostEntry **FSnameList;
   struct afsmon_hostEntry **CMnameList;
{
   char buff1[256] = "";        /* for error messages */
   char buff2[256] = "";        /* for error messages returned from subroutines */
   FILE *configFD = 0;          /* config file descriptor */
   char line[4 * CFG_STR_LEN];  /* a line of config file */
   char opcode[CFG_STR_LEN];    /* specifies type of config entry */
   char arg1[CFG_STR_LEN];      /* hostname or qualifier (fs/cm?)  */
   char arg2[CFG_STR_LEN];      /* threshold variable */
   char arg3[CFG_STR_LEN];      /* threshold value */
   char arg4[CFG_STR_LEN];      /* user's handler  */
   struct afsmon_hostEntry *curr_host = 0;
   struct hostent *he = 0;      /* hostentry to resolve host name */
   char *handlerPtr = 0;        /* ptr to pass theresh handler string */
   int code = 0;                /* error code */
   int linenum = 0;             /* config file line number */
   int threshCount = 0;         /* count of thresholds for each server */
   int error_in_config = 0;     /* syntax errors in config file  ?? */
   int i = 0;
   int numBytes = 0;
   /* int global_ThreshFlag = 1; */
   int global_fsThreshCount = 0;
   int global_cmThreshCount = 0;
   static char last_fsHost[HOST_NAME_LEN];
   static char last_cmHost[HOST_NAME_LEN];

   /* open config file */
   configFD = fopen(a_config_filename, "r");
   if (configFD == (FILE *) NULL) {
      sprintf(buff1, "Failed to open config file %s", a_config_filename);
      BSETCODE(5, buff1);
      return (-1);
   }

   /* parse config file */

   /* First Pass - check syntax and count number of servers and thresholds to monitor */

   *numFS = 0;
   *numCM = 0;
   threshCount = 0;
   error_in_config = 0; /* flag to note if config file has syntax errors */

   while ((fgets(line, CFG_STR_LEN, configFD)) != NULL) {
      opcode[0] = 0;
      arg1[0] = 0;
      arg2[0] = 0;
      arg3[0] = 0;
      arg4[0] = 0;
      sscanf(line, "%s %s %s %s %s", opcode, arg1, arg2, arg3, arg4);
      linenum++;
      /* fprintf(STDERR, "Got line %d: \"%s %s %s %s %s\"\n",
       * linenum, opcode, arg1, arg2, arg3, arg4); */
      /* skip blank lines and comment lines */
      if ((strlen(opcode) == 0) || line[0] == '#') {
         /* fprintf(STDERR, " - skipping line %d\n", linenum); */
         continue;
      }
      if ((strcasecmp(opcode, "fs") == 0) || (strcasecmp(opcode, "cm")) == 0) {
         /* fprintf(STDERR, " - parsing host entry\n"); */
         code =
            my_parse_hostEntry(line, numFS, numCM, lastHostType,
                               last_hostEntry, FSnameList, CMnameList, buff2);
         /* thresholds are not global anymore */
         /* if (global_ThreshFlag) global_ThreshFlag = 0; */
      }
      else if ((strcasecmp(opcode, "thresh")) == 0) {
         /* fprintf(STDERR, " - parsing thresh entry\n"); */
         code =
            my_parse_threshEntry(line, &global_fsThreshCount,
                                 &global_cmThreshCount, *last_hostEntry,
                                 *lastHostType, buff2);
      }
      else if ((strcasecmp(opcode, "show")) == 0) {
         /* fprintf(STDERR, " - parsing show entry\n"); */
         code =
            my_parse_showEntry(line, fs_showDefault, cm_showDefault,
                               fs_showFlags, cm_showFlags, buff2);
      }
      else {
         /* fprintf(STDERR, " - unknown entry\n"); */
         sprintf(buff2, "Unknown opcode %s", opcode);
         code = 1;
      }

      if (code) {
         sprintf(buff1,
                 "Error processing config file line %d (\"%s %s %s %s %s\"). %s",
                 linenum, opcode, arg1, arg2, arg3, arg4, buff2);
         error_in_config = 1;
         BSETCODE(10, buff1);
         return (-1);
      }
   }
   /* fprintf(STDERR, "got to end of file.\n"); */

   if (error_in_config) {
      sprintf(buff1, "Error in config file. %s", buff2);
      BSETCODE(10, buff1);
      return (-1);
   }

src/Monitor.xs  view on Meta::CPAN

      }
      if (HvKEYS(SECTION))
         hv_store(HOSTINFO, section, strlen(section),
                  newRV_inc((SV *) SECTION), 0);
      secidx += numgrp + 1;
      grpidx = secidx + 1;
   }
}   /* fs_Results_to_Hash() */



/*
 * from src/afsmonitor/afsmonitor.c
 *    ("$Header: /afs/slac/g/scs/slur/Repository/AFSDebug/Debug/src/Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $");
 */

int
my_save_FS_data_forDisplay(a_fsResults, HOSTINFO, numFS, FSnameList,
                           fs_showFlags, fs_showDefault, buffer)
   struct xstat_fs_ProbeResults *a_fsResults;
   HV *HOSTINFO;
   int numFS;
   struct afsmon_hostEntry *FSnameList;
   short *fs_showFlags;
   int fs_showDefault;
   char *buffer;
{
   struct fs_Display_Data *curr_fsDataP;
   struct afsmon_hostEntry *curr_host = 0;
   int i = 0;
   int code = 0;
   int done = 0;
   char buff2[256] = "";

   curr_fsDataP =
      (struct fs_Display_Data *)malloc(sizeof(struct fs_Display_Data));
   if (curr_fsDataP == (struct fs_Display_Data *) NULL) {
      sprintf(buffer, "Memory allocation failure");
      return (-1);
   }
   memset(curr_fsDataP, 0, sizeof(struct fs_Display_Data));

   hv_store(HOSTINFO, "hostName", 8, newSVpv(a_fsResults->connP->hostName, 0),
            0);

   /*  Check the status of the probe. If it succeeded, we store its
    * results in the display data structure. If it failed we only mark
    * the failed status in the display data structure. */

   if (a_fsResults->probeOK) {  /* 1 => notOK the xstat results */
      hv_store(HOSTINFO, "probeOK", 7, newSViv(0), 0);
   }
   else {   /* probe succeeded, update display data structures */
      hv_store(HOSTINFO, "probeOK", 7, newSViv(1), 0);

      my_fs_Results_ltoa(curr_fsDataP, a_fsResults);

      fs_Results_to_Hash(curr_fsDataP, HOSTINFO, fs_showFlags,
                         fs_showDefault);

      /* compare with thresholds and set the overflow flags.
       * note that the threshold information is in the hostEntry structure and
       * each threshold item has a positional index associated with it */

      /* locate the hostEntry for this host */
      done = 0;
      curr_host = FSnameList;
      for (i = 0; i < numFS; i++) {
         if (strcasecmp(curr_host->hostName, a_fsResults->connP->hostName)
             == 0) {
            done = 1;
            break;
         }
         curr_host = curr_host->next;;
      }
      if (!done) {
         sprintf(buffer, "Error storing results for FS host %s (70)",
                 a_fsResults->connP->hostName);
         return (70);
      }

      code = my_check_thresholds(curr_host, HOSTINFO, FS, buff2);
      if (code) {
         sprintf(buffer, "Error in checking thresholds (75) %s", buff2);
         return (75);
      }

   }    /* the probe succeeded, so we store the data in the display structure */
   return (0);

}   /* my_save_FS_data_forDisplay() */



/*
 * from src/afsmonitor/afsmonitor.c
 *    ("$Header: /afs/slac/g/scs/slur/Repository/AFSDebug/Debug/src/Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $");
 */

int
my_afsmon_FS_Handler(xstat_fs_Results, numFS, conn_idx, buffer, argp)
   struct xstat_fs_ProbeResults xstat_fs_Results;
   int numFS;
   int conn_idx;
   char *buffer;
   va_list argp;
{
   char *outputfile = va_arg(argp, char *);
   int detailed = va_arg(argp, int);
   AV *FILESERV = va_arg(argp, AV *);
   struct afsmon_hostEntry *FSnameList =
      va_arg(argp, struct afsmon_hostEntry *);
   short *fs_showFlags = va_arg(argp, short *);
   int fs_showDefault = va_arg(argp, int);

   HV *HOSTINFO = newHV();

   int code = 0;

   if (outputfile)
      my_afsmon_fsOutput(outputfile, detailed, xstat_fs_Results);

src/Monitor.xs  view on Meta::CPAN




MODULE = AFS::Monitor    PACKAGE = AFS::Monitor    PREFIX = afs_
PROTOTYPES: ENABLE

BOOT:
    initialize_rxk_error_table();


void
afs_do_xstat_cm_test(args)
    HV* args = (HV*) SvRV($arg);
  PREINIT:
  PPCODE:
  {
    SV *value;
    I32 keylen = 0;
    char *key;
    int num_args = 0;
    char buffer[256] = "";
    AV *host_array=0;
    AV *coll_array=0;
    int code;                          /*Return code*/
    int numCMs=0;                      /*# Cache Managers to monitor*/
    int numCollIDs=0;                  /*# collections to fetch*/
    int currCM;                        /*Loop index*/
    int currCollIDIdx;                 /*Index of current collection ID*/
    afs_int32 *collIDP;                /*Ptr to array of collection IDs*/
    afs_int32 *currCollIDP;            /*Ptr to current collection ID*/
    struct sockaddr_in *CMSktArray;    /*Cache Manager socket array */
    struct hostent *he;                /*Host entry*/

    AV *RETVAL = newAV();

    /* parse arguments */
    num_args = hv_iterinit(args);
    while (num_args--) {

      value = hv_iternextsv(args, &key, &keylen);

      if(strncmp(key, "collID", keylen) == 0 && keylen <= 6) {
        if (SvROK(value))
          coll_array = (AV*) SvRV(value);
        else {
          coll_array = av_make(1, &value);
          sv_2mortal((SV *) coll_array);
        }
        numCollIDs = av_len(coll_array) + 1;
      }
      else if(strncmp(key, "cmname", keylen) == 0 && keylen <= 6) {
        if (SvROK(value))
          host_array = (AV*) SvRV(value);
        else {
          host_array = av_make(1, &value);
          sv_2mortal((SV *) host_array);
        }
        numCMs = av_len(host_array) + 1;
      }
      else {
        sprintf(buffer, "Unrecognized flag: %s", key);
        BSETCODE(-1, buffer);
        XSRETURN_UNDEF;
      } /* end ifs */

    } /* end while */
    /* done parsing arguments */

    if (host_array == 0) {
      sprintf(buffer, "Missing required parameter 'cmname'");
      BSETCODE(-1, buffer);
      XSRETURN_UNDEF;
    }
    else if (numCMs == 0) {
      sprintf(buffer, "The field 'cmname' isn't completed properly");
      BSETCODE(-1, buffer);
      XSRETURN_UNDEF;
    }
    else if (coll_array == 0) {
      sprintf(buffer, "Missing required parameter 'collID'");
      BSETCODE(-1, buffer);
      XSRETURN_UNDEF;
    }
    else if (numCollIDs == 0) {
      sprintf(buffer, "The field 'collID' isn't completed properly");
      BSETCODE(-1, buffer);
      XSRETURN_UNDEF;
    }

    CMSktArray = (struct sockaddr_in *)
        malloc(numCMs * sizeof(struct sockaddr_in));
    if (CMSktArray == (struct sockaddr_in *) NULL) {
        sprintf(buffer, "Can't allocate socket array for %d Cache Managers",
                numCMs);
        BSETCODE(-1, buffer);
        XSRETURN_UNDEF;
    }

    for (currCM = 0; currCM < numCMs; currCM++) {
#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
        CMSktArray[currCM].sin_family = AF_INET;        /*Internet family */
#else
        CMSktArray[currCM].sin_family = htons(AF_INET); /*Internet family */
#endif
        CMSktArray[currCM].sin_port = htons(7001);      /*Cache Manager port */
        he = hostutil_GetHostByName((char *) SvPV(*av_fetch(host_array, currCM, 0), PL_na));
        if (he == (struct hostent *) NULL) {
            sprintf(buffer,
                    "Can't get host info for '%s'\n",
                    (char *) SvPV(*av_fetch(host_array, currCM, 0), PL_na));
            BSETCODE(-1, buffer);
            XSRETURN_UNDEF;
        }
        memcpy(&(CMSktArray[currCM].sin_addr.s_addr), he->h_addr, 4);

    } /*Get socket info for each Cache Manager*/

    collIDP = (afs_int32 *) malloc(numCollIDs * sizeof(afs_int32));
    currCollIDP = collIDP;
    for (currCollIDIdx = 0; currCollIDIdx < numCollIDs; currCollIDIdx++) {
	*currCollIDP = (afs_int32) SvIV(*av_fetch(coll_array, currCollIDIdx, 0));

src/Monitor.xs  view on Meta::CPAN

afs_do_xstat_fs_test(args)
    HV* args = (HV*) SvRV($arg);
  PREINIT:
  PPCODE:
  {
    SV *value;
    I32 keylen = 0;
    char *key;
    int num_args = 0;
    char buffer[256] = "";
    AV *host_array=0;
    AV *coll_array=0;
    int code;                          /*Return code*/
    int numFSs=0;                      /*# File Servers to monitor*/
    int numCollIDs=0;                  /*# collections to fetch*/
    int currFS;                        /*Loop index*/
    int currCollIDIdx;                 /*Index of current collection ID*/
    afs_int32 *collIDP;                /*Ptr to array of collection IDs*/
    afs_int32 *currCollIDP;            /*Ptr to current collection ID*/
    struct sockaddr_in *FSSktArray;    /*File Server socket array */
    int sktbytes;
    struct hostent *he;                /*Host entry*/

    AV *RETVAL = newAV();


    /* parse arguments */
    num_args = hv_iterinit(args);
    while (num_args--) {

      value = hv_iternextsv(args, &key, &keylen);

      switch (*key) {

        case 'c':
          if(strncmp(key, "collID", keylen) == 0 && keylen <= 6) {
            if (SvROK(value))
              coll_array = (AV*) SvRV(value);
            else {
              coll_array = av_make(1, &value);
              sv_2mortal((SV *) coll_array);
            }
            numCollIDs = av_len(coll_array) + 1;
          } else goto unrecognized;
        break;

        case 'f':
          if(strncmp(key, "fsname", keylen) == 0 && keylen <= 6) {
            if (SvROK(value))
              host_array = (AV*) SvRV(value);
            else {
              host_array = av_make(1, &value);
              sv_2mortal((SV *) host_array);
            }
            numFSs = av_len(host_array) + 1;
          } else goto unrecognized;
        break;

        default:
          unrecognized:
          sprintf(buffer, "Unrecognized flag: %s", key);
          BSETCODE(-1, buffer);
          XSRETURN_UNDEF;
        break;
      } /* end switch */
    } /* end while */
    /* done parsing arguments */

    if (host_array == 0) {
      sprintf(buffer, "Missing required parameter 'fsname'");
      BSETCODE(-1, buffer);
      XSRETURN_UNDEF;
    }
    else if (numFSs == 0) {
      sprintf(buffer, "The field 'fsname' isn't completed properly");
      BSETCODE(-1, buffer);
      XSRETURN_UNDEF;
    }
    else if (coll_array == 0) {
      sprintf(buffer, "Missing required parameter 'collID'");
      BSETCODE(-1, buffer);
      XSRETURN_UNDEF;
    }
    else if (numCollIDs == 0) {
      sprintf(buffer, "The field 'collID' isn't completed properly");
      BSETCODE(-1, buffer);
      XSRETURN_UNDEF;
    }

    sktbytes = numFSs * sizeof(struct sockaddr_in);
    FSSktArray = (struct sockaddr_in *) malloc(sktbytes);
    if (FSSktArray == (struct sockaddr_in *) NULL) {
      sprintf(buffer,
              "Can't malloc() %d sockaddrs (%d bytes) for the given file servers",
              numFSs, sktbytes);
      BSETCODE(-1, buffer);
      XSRETURN_UNDEF;
    }
    memset(FSSktArray, 0, sktbytes);

     /*
     * Fill in the socket array for each of the File Servers listed.
     */
    for (currFS = 0; currFS < numFSs; currFS++) {
#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
        FSSktArray[currFS].sin_family = AF_INET;        /*Internet family */
#else
        FSSktArray[currFS].sin_family = htons(AF_INET); /*Internet family */
#endif
	FSSktArray[currFS].sin_port   = htons(7000);	/*FileServer port*/
	he = hostutil_GetHostByName((char *) SvPV(*av_fetch(host_array, currFS, 0), PL_na));
	if (he == (struct hostent *) NULL) {
	    sprintf(buffer,
		    "Can't get host info for '%s'",
		    (char *) SvPV(*av_fetch(host_array, currFS, 0), PL_na));
	    BSETCODE(-1, buffer);
            XSRETURN_UNDEF;
	}
	memcpy(&(FSSktArray[currFS].sin_addr.s_addr), he->h_addr, 4);

    } /*Get socket info for each File Server*/

src/Monitor.xs  view on Meta::CPAN

  {
    static char rn[] = "afs_do_scout";
    SV *value;
    I32 keylen = 0;
    char *key;
    int num_args = 0;
    char buffer[256] = "";
    struct fsprobe_ProbeResults fsprobe_Results;
    struct fsprobe_ConnectionInfo *fsprobe_ConnInfo; /*Ptr to connection array*/
    char buff2[256] = "";

    char basename[64] = "";
    int numservers = 0;
    char fullsrvname[128] = "";
    struct sockaddr_in *FSSktArray;
    struct sockaddr_in *curr_skt;
    struct hostent *he;
    int i, code;
    int sktbytes;
    FILE *scout_debugfd = (FILE *) NULL;
    char *debug_filename = (char *) NULL;

    AV *host_array = (AV *) NULL;

    AV *RETVAL = newAV();

    /* parse arguments */
    num_args = hv_iterinit(args);
    while (num_args--) {

      value = hv_iternextsv(args, &key, &keylen);

      switch (*key) {

        case 'b':
          if(strncmp(key, "basename", keylen) == 0 && keylen <= 8) {
            sprintf(basename, "%s", SvPV(value, PL_na));
          } else goto unrecognized;
        break;

        case 'd':
          if(strncmp(key, "debug", keylen) == 0 && keylen <= 5) {
            debug_filename = (char *) SvPV(value, PL_na);
          } else goto unrecognized;
        break;

        case 's':
          if(strncmp(key, "servers", keylen) == 0 && keylen <= 7) {
            if (SvROK(value))
              host_array = (AV*) SvRV(value);
            else {
              host_array = av_make(1, &value);
              sv_2mortal((SV *) host_array);
            }
            numservers = av_len(host_array) + 1;
          } else goto unrecognized;
        break;

        default:
          unrecognized:
          sprintf(buffer, "Unrecognized flag: %s", key);
          BSETCODE(-1, buffer);
          XSRETURN_UNDEF;
        break;
      } /* end switch */
    } /* end while */
    /* done parsing arguments */

    if(numservers == 0) {
      sprintf(buffer, "Missing required parameter 'server'");
      BSETCODE(-1, buffer);
      XSRETURN_UNDEF;
    }

    if(debug_filename) {
      scout_debugfd = fopen(debug_filename, "w");
      if(scout_debugfd == (FILE *) NULL) {
        sprintf(buffer, "Can't open debugging file '%s'!", debug_filename);
        BSETCODE(-1, buffer);
        XSRETURN_UNDEF;
      }
      fprintf(scout_debugfd, "[%s] Writing to Scout debugging file '%s'\n",
              rn, debug_filename);
      fflush(scout_debugfd);
    }

    /* execute_scout */

    sktbytes = numservers * sizeof(struct sockaddr_in);
    FSSktArray = (struct sockaddr_in *) malloc(sktbytes);
    if (FSSktArray == (struct sockaddr_in *) NULL) {
      sprintf(buffer,
              "Can't malloc() %d sockaddrs (%d bytes) for the given servers",
              numservers, sktbytes);
      BSETCODE(-1, buffer);
      if (scout_debugfd != (FILE *) NULL) {
        fprintf(scout_debugfd, "[%s] Closing debugging file\n", rn);
        fclose(scout_debugfd);
      }
      XSRETURN_UNDEF;
    }
    memset(FSSktArray, 0, sktbytes);

    curr_skt = FSSktArray;
    for(i=0; i<numservers; i++) {
       if(*basename == '\0')
         sprintf(fullsrvname, "%s", (char *) SvPV(*av_fetch(host_array, i, 0), PL_na));
       else
         sprintf(fullsrvname, "%s.%s", (char *) SvPV(*av_fetch(host_array, i, 0), PL_na), basename);
       he = hostutil_GetHostByName(fullsrvname);
       if(he == (struct hostent *) NULL) {
         sprintf(buffer, "Can't get host info for '%s'", fullsrvname);
         BSETCODE(-1, buffer);
         if (scout_debugfd != (FILE *) NULL) {
           fprintf(scout_debugfd, "[%s] Closing debugging file\n", rn);
           fclose(scout_debugfd);
         }
         XSRETURN_UNDEF;
       }
       memcpy(&(curr_skt->sin_addr.s_addr), he->h_addr, 4);
#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)

src/Monitor.xs  view on Meta::CPAN


    SV *value;
    I32 keylen = 0;
    char *key;
    int num_args = 0;
    char buffer[256] = "";

    char *hostName = (char *) NULL;
    char *portName = (char *) NULL;
    afs_int32 hostAddr;
    struct in_addr inhostAddr;
    register afs_int32 i, j, code;
    short port;
    int int32p = 0;
    struct hostent *th;
    struct rx_connection *tconn;
    struct rx_securityClass *sc;
    struct ubik_debug udebug;
    struct ubik_sdebug usdebug;
    int oldServer = 0;   /* are we talking to a pre 3.5 server? */
    afs_int32 isClone = 0;

    HV *RETVAL = newHV();
    AV *ADDRESSES;
    HV *LOCALVERSION;
    HV *SYNCVERSION;
    HV *SYNCTID;
    AV *SERVERS;
    HV *USDEBUG;
    AV *ALTADDR;
    HV *REMOTEVERSION;

    /* parse arguments */
    num_args = hv_iterinit(args);
    while (num_args--) {

      value = hv_iternextsv(args, &key, &keylen);

      switch (*key) {

        case 'l':
          if(strncmp(key, "long", keylen) == 0 && keylen <= 4) {
            int32p = (int) SvIV(value);
          } else goto unrecognized;
        break;

        case 'p':
          if(strncmp(key, "port", keylen) == 0 && keylen <= 4) {
            portName = (char *) SvPV(value, PL_na);
          } else goto unrecognized;
        break;

        case 's':
          if(strncmp(key, "server", keylen) == 0 && keylen <= 6) {
            hostName = (char *) SvPV(value, PL_na);
          } else goto unrecognized;
        break;

        default:
          unrecognized:
          sprintf(buffer, "Unrecognized flag: %s", key);
          BSETCODE(-1, buffer);
          XSRETURN_UNDEF;
        break;
      } /* end switch */
    } /* end while */
    /* done parsing arguments */


    /* lookup host */
    if (hostName) {
       th = hostutil_GetHostByName(hostName);
       if (!th) {
          sprintf(buffer, "udebug: host %s not found in host table", hostName);
          BSETCODE(1, buffer);
          XSRETURN_UNDEF;
       }
       memcpy(&hostAddr, th->h_addr, sizeof(afs_int32));
    }
    else hostAddr = htonl(0x7f000001);  /* IP localhost */


    if (!portName)
       port = htons(3000);             /* default */
    else {
       port = udebug_PortNumber(portName);
       if (port < 0)
          port = udebug_PortName(portName);
       if (port < 0) {
          sprintf(buffer, "udebug: can't resolve port name %s", portName);
          BSETCODE(1, buffer);
          XSRETURN_UNDEF;
       }
       port = htons(port);
    }

    rx_Init(0);
    sc = rxnull_NewClientSecurityObject();
    tconn = rx_NewConnection(hostAddr, port, VOTE_SERVICE_ID, sc, 0);

    /* now do the main call */
#ifdef USE_VOTEXDEBUG
    code = VOTE_XDebug(tconn, &udebug, &isClone);
    if (code) code = VOTE_Debug(tconn, &udebug);
#else
    code = VOTE_Debug(tconn, &udebug);
#endif
    if (code == RXGEN_OPCODE)
    {  ubik_debug * ptr = &udebug;
       oldServer = 1;             /* talking to a pre 3.5 server */
       memset(&udebug, 0, sizeof(udebug));
       code = VOTE_DebugOld(tconn, (struct ubik_debug_old *) ptr);
    }

    if (code) {
       sprintf(buffer, "return code %d from VOTE_Debug", code);
       BSETCODE(code, buffer);
       XSRETURN_UNDEF;
    }

    /* now print the main info */

src/Monitor.xs  view on Meta::CPAN

       hv_store(RETVAL, "servers", 7, newRV_inc((SV*)SERVERS), 0);
    }

    /* return RETVAL */
    ST(0) = sv_2mortal(newRV_inc((SV*)RETVAL));
    SETCODE(0);
    XSRETURN(1);

  }

void
afs_do_cmdebug(args)
    HV* args = (HV*) SvRV($arg);
  PREINIT:
  PPCODE:
  {
    SV *value;
    I32 keylen = 0;
    char *key;
    int num_args = 0;
    int code = 0;
    int aint32 = 0;
    struct rx_connection *conn;
    register char *hostName = "";
    register struct hostent *thp;
    struct rx_securityClass *secobj;
    afs_int32 addr = 0;
    afs_int32 port = 7001;
    char buffer[256] = "";

    AV *LOCKS = newAV();           /* return */
    AV *CACHE_ENTRIES = newAV();   /* values */

    /* parse arguments */
    num_args = hv_iterinit(args);
    while (num_args--) {
      value = hv_iternextsv(args, &key, &keylen);

      switch (*key) {

        case 'l':
          if(strncmp(key, "long", keylen) == 0 && keylen <= 4) {
            aint32 = (int) SvIV(value);
          } else goto unrecognized;
        break;

        case 'p':
          if(strncmp(key, "port", keylen) == 0 && keylen <= 4) {
            port = (int) SvIV(value);
          } else goto unrecognized;
        break;

        case 's':
          if(strncmp(key, "servers", keylen) == 0 && keylen <= 7) {
            hostName = (char *) SvPV(value, PL_na);
          } else goto unrecognized;
        break;

        default:
          unrecognized:
          sprintf(buffer, "Unrecognized flag: %s", key);
          BSETCODE(-1, buffer);
          XSRETURN_UNDEF;
        break;
      } /* end switch */
    } /* end while */
    /* done parsing arguments */

    rx_Init(0);

    thp = hostutil_GetHostByName(hostName);
    if (!thp) {
        sprintf(buffer, "can't resolve address for host %s", hostName);
        BSETCODE(1, buffer);
        XSRETURN_UNDEF;
    }
    memcpy(&addr, thp->h_addr, sizeof(afs_int32));
    secobj = rxnull_NewServerSecurityObject();
    conn = rx_NewConnection(addr, htons(port), 1, secobj, 0);
    if (!conn) {
        sprintf(buffer, "failed to create connection for host %s", hostName);
        BSETCODE(1, buffer);
        XSRETURN_UNDEF;
    }
    code = my_PrintLocks(conn, aint32, LOCKS, buffer);
    if(code) {
       BSETCODE(code, buffer);
       XSRETURN_UNDEF;
    }
    code = my_PrintCacheEntries(conn, aint32, CACHE_ENTRIES, buffer);
    if(code) {
       BSETCODE(code, buffer);
       XSRETURN_UNDEF;
    }

    SETCODE(0);
    EXTEND(SP, 2);
    PUSHs(sv_2mortal(newRV_inc((SV*)LOCKS)));
    PUSHs(sv_2mortal(newRV_inc((SV*)CACHE_ENTRIES)));

  }

void
afs_do_afsmonitor(args)
    HV* args = (HV*) SvRV($arg);
  PREINIT:
  PPCODE:
  {
    I32 keylen = 0;
    char* key = 0;
    SV* value = 0;
    char* host = 0;
    AV* host_array = 0;
    AV* show_array = 0;
    AV* fsthresh_array = 0;
    AV* cmthresh_array = 0;
    HV* thresh_entry = 0;
    int global_fsThreshCount = 0;
    int global_cmThreshCount = 0;
    int found = 0;
    int numBytes = 0;
    char* thresh_name = "";
    char* thresh_value = 0;
    char* thresh_host = "";
    char* thresh_handler = "";
    int num_args = 0;
    int detailed = 0;
    char* config_filename = 0;
    char* output_filename = 0;
    FILE *outputFD = 0;
    struct afsmon_hostEntry *temp_host = 0;
    int numFS = 0;
    int numCM = 0;
    struct afsmon_hostEntry *last_hostEntry = 0;
    int lastHostType = 0;
    short fs_showFlags[NUM_FS_STAT_ENTRIES];
    short cm_showFlags[NUM_CM_STAT_ENTRIES];
    int fs_showDefault = 1;
    int cm_showDefault = 1;

    int num = 0;
    int i = 0;
    int j = 0;
    int code = 0;
    char buffer[256] = "";
    char buff2[256] = "";

    /* from afsmon_execute() */
    static char fullhostname[128] = "";   /* full host name */
    struct sockaddr_in *FSSktArray = 0;   /* fs socket array */
    int FSsktbytes = 0;         /* num bytes in above */
    struct sockaddr_in *CMSktArray = 0;   /* cm socket array */
    int CMsktbytes = 0;         /* num bytes in above */
    struct sockaddr_in *curr_skt = 0;     /* ptr to current socket*/
    struct afsmon_hostEntry *curr_FS = 0; /* ptr to FS name list */
    struct afsmon_hostEntry *curr_CM = 0; /* ptr to CM name list */
    struct hostent *he = 0;     /* host entry */
    afs_int32 *collIDP = 0;     /* ptr to collection ID */
    int numCollIDs = 0;         /* number of collection IDs */
    /* end of from afsmon_execute() */

    AV* FILESERV = newAV(); /* File Servers */
    AV* CACHEMAN = newAV(); /* Cache Managers */

    struct afsmon_hostEntry *FSnameList=0;
    struct afsmon_hostEntry *CMnameList=0;

    /* initialize showFlags for processing "show" directives in config file */
    for(i=0; i<NUM_FS_STAT_ENTRIES; i++)
      fs_showFlags[i] = 0;
    for(i=0; i<NUM_CM_STAT_ENTRIES; i++)
      cm_showFlags[i] = 0;

    /* parse arguments */
    num_args = hv_iterinit(args);
    /* fprintf(STDERR, "[afsmonitor] Parsing args now: %d\n", num_args); */
    while (num_args--) {
      value = hv_iternextsv(args, &key, &keylen);

      /* fprintf(STDERR, "got flag %s, size %d. %d remaining.\n", key, keylen, num_args); */

      switch (*key) {
        case 'c':
          if(keylen < 2) goto unrecognized;
          switch(key[1]) {
            case 'o':
              if(strncmp(key, "config", keylen) == 0 && keylen <= 6) {
                /* fprintf(STDERR, "flag %s recognized as config; value is %s\n",
                   key, (char *) SvPV(value, PL_na)); */
                config_filename = (char *) SvPV(value, PL_na);
              } else goto unrecognized;
            break;

            case 'm':
              if(keylen < 3) goto unrecognized;
              switch(key[2]) {
                case 'h':
                 if(strncmp(key, "cmhosts", keylen) == 0 && keylen <= 7) {
                   /* fprintf(STDERR, "flag %s recognized as cmhosts\n", key); */
                  if (SvROK(value))
                    host_array = (AV*) SvRV(value);
                  else {
                    host_array = av_make(1, &value);
                    sv_2mortal((SV *) host_array);
                  }
                   num = av_len(host_array);
                   /* fprintf(STDERR, "it has %d elements.\n", num+1); */
                   for(i=0; i<=num; i++) {
                     host = (char *) SvPV(*av_fetch(host_array, i, 0), PL_na);
                     sprintf(buffer,"cm %s",host);
                     code = my_parse_hostEntry(buffer, &numFS, &numCM, &lastHostType,
                                            &last_hostEntry, &FSnameList, &CMnameList, buff2);
                     /* fprintf(STDERR, "got host: %s\n", host); */
                     if (code) {
                       sprintf(buffer, "Could not parse cache manager %s. %s", host, buff2);
                       BSETCODE(180, buffer);
                       /* 180 is the exit code for this error in the original afsmonitor.c */
                       XSRETURN_UNDEF;
                     }
                   }
                 } else goto unrecognized;
                 break;
                case 's':
                 if(strncmp(key, "cmshow", keylen) == 0 && keylen <= 6) {
                   /* fprintf(STDERR, "flag %s recognized as cmshow\n", key); */
                   show_array = (AV*) SvRV(value);
                   num = av_len(show_array);
                   for (i=0; i<=num; i++) {
                     sprintf(buffer, "show cm %s", SvPV(*av_fetch(show_array, i, 0), PL_na));
                     code = my_parse_showEntry(buffer, &fs_showDefault, &cm_showDefault,
                                               fs_showFlags, cm_showFlags, buff2);
                     if(code) {
                       sprintf(buffer, "Error parsing cmshow flag. %s", buff2);
                       BSETCODE(-1, buffer);
                       XSRETURN_UNDEF;
                     }
                   }
                 } else goto unrecognized;
                 break;
                case 't':
                 if(strncmp(key, "cmthresh", keylen) == 0 && keylen <= 8) {
                   /* fprintf(STDERR, "flag %s recognized as cmthresh\n", key); */
                   cmthresh_array = (AV*) SvRV(value);
                 } else goto unrecognized;
                 break;
                default:
                 goto unrecognized;
              }
            break;

            default:
              goto unrecognized;
          }
          break;

        case 'd':
          if(strncmp(key, "detailed", keylen) == 0 && keylen <= 8) {
            /* fprintf(STDERR, "flag %s recognized as detailed; value is %d\n",
                       key, (int) SvIV(value)); */
            detailed = (int) SvIV(value);
          } else goto unrecognized;
        break;

        case 'f':
          if(keylen < 3 || key[1] != 's') goto unrecognized;
          switch(key[2]) {
            case 'h':
              if(strncmp(key, "fshosts", keylen) == 0 && keylen <= 7) {
                /* fprintf(STDERR, "flag %s recognized as fshosts\n", key); */
                if (SvROK(value))
                  host_array = (AV*) SvRV(value);
                else {
                  host_array = av_make(1, &value);
                  sv_2mortal((SV *) host_array);
                }
                num = av_len(host_array);
                /* fprintf(STDERR, "it has %d elements.\n", num+1); */
                for(i=0; i<=num; i++) {
                  host = (char *) SvPV(*av_fetch(host_array, i, 0), PL_na);
                  sprintf(buffer,"fs %s",host);
                  code = my_parse_hostEntry(buffer, &numFS, &numCM, &lastHostType,
                                         &last_hostEntry, &FSnameList, &CMnameList, buff2);
                  /* fprintf(STDERR, "got host: %s\n", host); */
                  if (code) {
                    sprintf(buffer, "Could not parse file server %s. %s", host, buff2);
                    BSETCODE(180, buffer);
                    XSRETURN_UNDEF;
                  }
                }
              } else goto unrecognized;
              break;
            case 's':
              if(strncmp(key, "fsshow", keylen) == 0 && keylen <= 6) {
                /* fprintf(STDERR, "flag %s recognized as fsshow\n", key); */
                show_array = (AV*) SvRV(value);
                num = av_len(show_array);
                for (i=0; i<=num; i++) {
                  sprintf(buffer, "show fs %s", SvPV(*av_fetch(show_array, i, 0), PL_na));
                  code = my_parse_showEntry(buffer, &fs_showDefault, &cm_showDefault,
                                            fs_showFlags, cm_showFlags, buff2);
                  if(code) {
                    sprintf(buffer, "Error parsing fsshow flag. %s", buff2);
                    BSETCODE(-1, buffer);
                    XSRETURN_UNDEF;
                  }
                }
              } else goto unrecognized;
              break;
            case 't':
              if(strncmp(key, "fsthresh", keylen) == 0 && keylen <= 8) {
                /* fprintf(STDERR, "flag %s recognized as fsthresh\n", key); */
                fsthresh_array = (AV*) SvRV(value);
              } else goto unrecognized;
              break;
            default:
              goto unrecognized;
          }
        break;

        case 'o':
          if(strncmp(key, "output", keylen) == 0 && keylen <= 6) {
            /* fprintf(STDERR, "flag %s recognized as output; value is %s\n",
                       key, (char *) SvPV(value, PL_na)); */
            output_filename = (char *) SvPV(value, PL_na);
          } else goto unrecognized;
        break;

        default:
          unrecognized:
          /* fprintf(STDERR,
                     "flag not recognized. (key: %s) (value: %s)\n",
                     key, (char *) SvPV(value, PL_na)); */
          sprintf(buffer, "Unrecognized flag: %s", key);
          BSETCODE(-1, buffer);
          XSRETURN_UNDEF;
      } /* end switch */
    } /* end while */
    /* done parsing arguments */

    /* Open output file, if provided. */
    if (output_filename) {
      outputFD = fopen(output_filename,"a");
      if (outputFD == (FILE *) NULL) {
        sprintf(buffer, "Failed to open output file %s", output_filename);
        BSETCODE(160, buffer);
        XSRETURN_UNDEF;
      }
      fclose (outputFD);
    }

    /* cannot use 'detailed' without 'output' */
    if (detailed) {
      if (!output_filename) {
        sprintf(buffer, "detailed switch can be used only with output switch");
        BSETCODE(165, buffer);
        /* 165 is the exit code for this error in the original afsmonitor.c */
        XSRETURN_UNDEF;
      }
    }

    /* The config option is mutually exclusive with the fshosts,cmhosts options */
    if (config_filename) {
      if (numFS || numCM) {
        sprintf(buffer,"Cannot use config option with fshosts or cmhosts");
        BSETCODE(170, buffer);
        /* 170 is the exit code for this error in the original afsmonitor.c */
        XSRETURN_UNDEF;
      }
    }
    else {
      if (!numFS && !numCM) {
        sprintf(buffer,"Must specify either config or (fshosts and/or cmhosts) options");
        BSETCODE(175, buffer);
        /* 175 is the exit code for this error in the original afsmonitor.c */
        XSRETURN_UNDEF;
      }
    }

    if (fsthresh_array) {
      if(!numFS) {
        sprintf(buffer, "Cannot use fsthresh option without specifying fshosts");
        BSETCODE(-1, buffer);
        XSRETURN_UNDEF;
      }
      num = av_len(fsthresh_array);
      for (i=0; i<=num; i++) {
        thresh_host = 0;
        thresh_handler = "";
        thresh_entry = (HV*) SvRV(*av_fetch(fsthresh_array, i, 0));
        hv_iterinit(thresh_entry);
        while((value = hv_iternextsv(thresh_entry, &key, &keylen))) {
          if(strcmp(key, "host")==0) {
            thresh_host = (char *)SvPV(value, PL_na);
            he = GetHostByName(thresh_host);
            if(he == (struct hostent *) NULL) {
              sprintf(buffer,
                      "Couldn't parse fsthresh flag; unable to resolve hostname %s\n",
                      thresh_host);
              BSETCODE(-1, buffer);
              XSRETURN_UNDEF;
            }
            thresh_host = he->h_name;
          }
          else if(strcmp(key, "handler")==0) {
            thresh_handler = (char *) SvPV(value, PL_na);
          }
          else {
            thresh_name = key;
            thresh_value = (char *) SvPV(value, PL_na);
          }
        }
        sprintf(buffer, "thresh fs %s %s %s",
                thresh_name, thresh_value, thresh_handler);
        if(!thresh_host) {
          code = my_parse_threshEntry(buffer, &global_fsThreshCount,
                      &global_cmThreshCount, (struct afsmon_hostEntry *) NULL, 0, buff2);
          if (code) {
            sprintf(buffer, "Couldn't parse fsthresh entry. %s", buff2);
            BSETCODE(code, buffer);
            XSRETURN_UNDEF;
          }
        }
        else {
          temp_host = FSnameList;
          found = 0;
          for (j = 0; j < numFS; j++) {
            if(strcmp(thresh_host, temp_host->hostName) == 0) {
              found = 1;
              break;
            }
            temp_host = temp_host->next;
          }
          if(found) {
            code = my_parse_threshEntry(buffer, &global_fsThreshCount,
                                        &global_cmThreshCount, temp_host,
                                        1, buff2);
            if(code) {
              sprintf(buffer, "Couldn't parse fsthresh entry. %s", buff2);
              BSETCODE(code, buffer);
              XSRETURN_UNDEF;
            }
          }
          else {
            sprintf(buffer,
                    "Couldn't parse fsthresh entry for host %s; host not found",
                    thresh_host);
            BSETCODE(-1, buffer);
            XSRETURN_UNDEF;
          }
        }
      }
      if (global_fsThreshCount) {
        temp_host = FSnameList;
        for (i = 0; i < numFS; i++) {
          temp_host->numThresh += global_fsThreshCount;
          temp_host = temp_host->next;
        }
      }
      temp_host = FSnameList;
      for (i = 0; i < numFS; i++) {
        if (temp_host->numThresh) {
          numBytes = temp_host->numThresh * sizeof(struct Threshold);
          temp_host->thresh = (struct Threshold *)malloc(numBytes);
          if (temp_host->thresh == (struct Threshold *) NULL) {
            sprintf(buffer, "Memory Allocation error 1.5");
            BSETCODE(25, buffer);
            XSRETURN_UNDEF;
          }
          memset(temp_host->thresh, 0, numBytes);
        }
        temp_host = temp_host->next;
      }
      num = av_len(fsthresh_array);
      for (i=0; i<=num; i++) {
        thresh_host = 0;
        thresh_handler = "";
        thresh_entry = (HV*) SvRV(*av_fetch(fsthresh_array, i, 0));
        hv_iterinit(thresh_entry);
        while((value = hv_iternextsv(thresh_entry, &key, &keylen))) {
          if(strcmp(key, "host") == 0) {
            thresh_host = (char *)SvPV(value, PL_na);
            he = GetHostByName(thresh_host);
            if(he == (struct hostent *) NULL) {
              sprintf(buffer,
                      "Couldn't parse fsthresh flag; unable to resolve hostname %s\n",
                      thresh_host);
              BSETCODE(-1, buffer);
              XSRETURN_UNDEF;
            }
            thresh_host = he->h_name;
          }
          else if(strcmp(key, "handler")==0) {
            thresh_handler = (char *) SvPV(value, PL_na);
          }
          else {
            thresh_name = key;
            thresh_value = (char *) SvPV(value, PL_na);
          }
        }
        if(thresh_host) global_fsThreshCount = 0;
        else global_fsThreshCount = 1;
        code = my_store_threshold(1, thresh_name, thresh_value, thresh_handler,
                           &global_fsThreshCount, FSnameList, thresh_host,
                           numFS, buff2);
        if(code) {
          sprintf(buffer, "Unable to store threshold %s. %s", thresh_name, buff2);
          BSETCODE(code, buffer);
          XSRETURN_UNDEF;
        }
      }
    }

    if (cmthresh_array) {
      if(!numCM) {
        sprintf(buffer, "Cannot use cmthresh option without specifying cmhosts");
        BSETCODE(-1, buffer);
        XSRETURN_UNDEF;
      }
      num = av_len(cmthresh_array);
      for (i=0; i<=num; i++) {
        thresh_host = 0;
        thresh_handler = "";
        thresh_entry = (HV*) SvRV(*av_fetch(cmthresh_array, i, 0));
        hv_iterinit(thresh_entry);
        while((value = hv_iternextsv(thresh_entry, &key, &keylen))) {
          if(strcmp(key, "host")==0) {
            thresh_host = (char *)SvPV(value, PL_na);
            he = GetHostByName(thresh_host);
            if(he == (struct hostent *) NULL) {
              sprintf(buffer,
                      "Couldn't parse cmthresh flag; unable to resolve hostname %s\n",
                      thresh_host);
              BSETCODE(-1, buffer);
              XSRETURN_UNDEF;
            }
            thresh_host = he->h_name;
          }
          else if(strcmp(key, "handler")==0) {
            thresh_handler = (char *) SvPV(value, PL_na);
          }
          else {
            thresh_name = key;
            thresh_value = (char *) SvPV(value, PL_na);
          }
        }
        sprintf(buffer, "thresh cm %s %s %s", thresh_name, thresh_value, thresh_handler);
        if(!thresh_host) {
          code = my_parse_threshEntry(buffer, &global_fsThreshCount,
                      &global_cmThreshCount, (struct afsmon_hostEntry *) NULL, 0, buff2);
          if (code) {
            sprintf(buffer, "Couldn't parse cmthresh entry. %s", buff2);
            BSETCODE(code, buffer);
            XSRETURN_UNDEF;
          }
        }
        else {
          temp_host = CMnameList;
          found = 0;
          for (j = 0; j < numCM; j++) {
            if(strcmp(thresh_host, temp_host->hostName) == 0) {
              found = 1;
              break;
            }
            temp_host = temp_host->next;
          }
          if(found) {
            code = my_parse_threshEntry(buffer, &global_fsThreshCount,
                                        &global_cmThreshCount, temp_host,
                                        2, buff2);
            if(code) {
              sprintf(buffer, "Couldn't parse cmthresh entry. %s", buff2);
              BSETCODE(code, buffer);
              XSRETURN_UNDEF;
            }
          }
          else {
            sprintf(buffer,
                    "Couldn't parse cmthresh entry for host %s; host not found",
                    thresh_host);
            BSETCODE(-1, buffer);
            XSRETURN_UNDEF;
          }
        }
      }
      if (global_cmThreshCount) {
        temp_host = CMnameList;
        for (i = 0; i < numCM; i++) {
          temp_host->numThresh += global_cmThreshCount;
          temp_host = temp_host->next;
        }
      }
      temp_host = CMnameList;
      for (i = 0; i < numCM; i++) {
        if (temp_host->numThresh) {
          numBytes = temp_host->numThresh * sizeof(struct Threshold);
          temp_host->thresh = (struct Threshold *)malloc(numBytes);
          if (temp_host->thresh == (struct Threshold *) NULL) {
            sprintf(buffer, "Memory Allocation error 2.5");
            BSETCODE(25, buffer);
            XSRETURN_UNDEF;
          }
          memset(temp_host->thresh, 0, numBytes);
        }
        temp_host = temp_host->next;
      }
      num = av_len(cmthresh_array);
      for (i=0; i<=num; i++) {
        thresh_host = 0;
        thresh_handler = "";
        thresh_entry = (HV*) SvRV(*av_fetch(cmthresh_array, i, 0));
        hv_iterinit(thresh_entry);
        while((value = hv_iternextsv(thresh_entry, &key, &keylen))) {
          if(strcmp(key, "host") == 0) {
            thresh_host = (char *)SvPV(value, PL_na);
            he = GetHostByName(thresh_host);
            if(he == (struct hostent *) NULL) {
              sprintf(buffer,
                      "Couldn't parse cmthresh flag; unable to resolve hostname %s\n",
                      thresh_host);
              BSETCODE(-1, buffer);
              XSRETURN_UNDEF;
            }
            thresh_host = he->h_name;
          }
          else if(strcmp(key, "handler")==0) {
            thresh_handler = (char *) SvPV(value, PL_na);
          }
          else {
            thresh_name = key;
            thresh_value = (char *) SvPV(value, PL_na);
          }
        }
        if(thresh_host) global_cmThreshCount = 0;
        else global_cmThreshCount = 1;
        code = my_store_threshold(2, thresh_name, thresh_value, thresh_handler,
                           &global_cmThreshCount, CMnameList, thresh_host,
                           numCM, buff2);
        if(code) {
          sprintf(buffer, "Unable to store threshold %s. %s", thresh_name, buff2);
          BSETCODE(code, buffer);
          XSRETURN_UNDEF;
        }
      }
    }

    /* process configuration file */
    if(config_filename) {
      code = my_process_config_file(config_filename, &numFS, &numCM, &lastHostType,
                                 &last_hostEntry, &fs_showDefault, &cm_showDefault,
                                 fs_showFlags, cm_showFlags, &FSnameList, &CMnameList);
      if(code == -1)
        XSRETURN_UNDEF;
    }

  /* from afsmon_execute() */

    /* process file server entries */
    if (numFS) {
    /* Allocate an array of sockets for each fileserver we monitor */

      FSsktbytes = numFS * sizeof(struct sockaddr_in);
      FSSktArray = (struct sockaddr_in *) malloc(FSsktbytes);
      if (FSSktArray == (struct sockaddr_in *) NULL) {
        sprintf(buffer,"cannot malloc %d sockaddr_ins for fileservers", numFS);
        BSETCODE(-1, buffer);
        XSRETURN_UNDEF;
      }

      memset(FSSktArray, 0, FSsktbytes);

      /* Fill in the socket information for each fileserve  */

      curr_skt = FSSktArray;
      curr_FS = FSnameList;  /* FS name list header */
      while (curr_FS) {
        strncpy(fullhostname,curr_FS->hostName,sizeof(fullhostname));
        he = GetHostByName(fullhostname);
        if (he == (struct hostent *) NULL) {

src/Monitor.xs  view on Meta::CPAN

        XSRETURN_UNDEF;
      }

    }  /* end of process fileserver entries */

  /* end from afsmon_execute() */

    SETCODE(0);

    EXTEND(SP, 2);
    PUSHs(sv_2mortal(newRV_inc((SV*)FILESERV)));
    PUSHs(sv_2mortal(newRV_inc((SV*)CACHEMAN)));
  }


void
afs_do_rxdebug(args)
    HV* args = (HV*) SvRV($arg);
  PREINIT:
  PPCODE:
  {
    int size;
    I32 keylen;
    char *key;
    HE* entry;
    SV* value;
    HV* RETVAL = newHV(); /* return value */
    HV* TSTATS;
    HV* RXSTATS;
    AV* CONNECTIONS;
    HV* TCONN;
    AV* CALLSTATE;
    AV* CALLMODE;
    AV* CALLFLAGS;
    AV* CALLOTHER;
    AV* CALLNUMBER;
    AV* PEERS;
    HV* TPEER;
    HV* BYTESSENT;
    HV* BYTESRECEIVED;
    HV* TIMEOUT;
    int index;

    register int i;
    int s;
    int j;
    struct sockaddr_in taddr;
    afs_int32 host;
    struct in_addr hostAddr;
    short port;
    struct hostent *th;
    register afs_int32 code;
    int nodally=0;
    int allconns=0;
    int rxstats=0;
    int onlyClient=0;
    int onlyServer=0;
    afs_int32 onlyHost = -1;
    short onlyPort = -1;
    int onlyAuth = 999;
    int flag;
    int dallyCounter;
    int withSecStats;
    int withAllConn;
    int withRxStats;
    int withWaiters;
    int withIdleThreads;
    int withPeers;
    struct rx_debugStats tstats;
    char *portName = (char *) NULL;
    char *hostName = (char *) NULL;
    struct rx_debugConn tconn;
    short noConns=0;
    short showPeers=0;
    short showLong=0;
    int version_flag=0;
    afs_int32 length=64;
    char version[64];
    char buffer[240]; /* for error messages */

    afs_uint32 supportedDebugValues = 0;
    afs_uint32 supportedStatValues = 0;
    afs_uint32 supportedConnValues = 0;
    afs_uint32 supportedPeerValues = 0;
    afs_int32 nextconn = 0;
    afs_int32 nextpeer = 0;

  size = hv_iterinit(args);
  /* fprintf(STDERR, "Parsing args now: %d\n", size); */
  while (size--) {
    char *flag;
    entry = hv_iternext(args);
    key = hv_iterkey(entry, &keylen);
    value = hv_iterval(args, entry);
    flag = key;
    /* fprintf(STDERR, "size = %d, format: got flag %s\n", size, key); */

    switch (*flag) {
    case 'a':
        if (memcmp( flag, "allconnections", 14) == 0 ) {
            allconns = (int) SvIV(value);
        }
        break;

    case 'l':
        if (memcmp( flag, "long", 4) == 0 ) {
            showLong = (int) SvIV(value);
        }
        break;

    case 'n':
        if (memcmp( flag, "nodally", 7) == 0 ) {
            nodally = (int) SvIV(value);
        } else if (memcmp( flag, "noconns", 7) == 0 ) {
            noConns = (int) SvIV(value);
        }
        break;

    case 'o':
        if (memcmp( flag, "onlyserver", 10) == 0 ) {
            onlyServer = (int) SvIV(value);
        } else if (memcmp( flag, "onlyclient", 10) == 0 ) {
            onlyClient = (int) SvIV(value);
        } else if (memcmp( flag, "onlyhost", 8) == 0 ) {
            char *name = (char *) SvPV(value, PL_na);
        struct hostent *th;
        th = hostutil_GetHostByName(name);
        if (!th) {
            sprintf(buffer, "rxdebug: host %s not found in host table", name);
            BSETCODE(-1, buffer);
            XSRETURN_UNDEF;
        }
        memcpy(&onlyHost, th->h_addr, sizeof(afs_int32));

        } else if (memcmp( flag, "onlyauth", 8) == 0 ) {
            char *name = (char *) SvPV(value, PL_na);
            if (strcmp (name, "clear") == 0) onlyAuth = 0;
            else if (strcmp (name, "auth") == 0) onlyAuth = 1;
            else if (strcmp (name, "crypt") == 0) onlyAuth = 2;
            else if ((strcmp (name, "null") == 0) ||
                     (strcmp (name, "none") == 0) ||
                     (strncmp (name, "noauth", 6) == 0) ||
                     (strncmp (name, "unauth", 6) == 0)) onlyAuth = -1;
            else {
              sprintf (buffer, "Unknown authentication level: %s", name);
              BSETCODE(-1, buffer);
              XSRETURN_UNDEF;
            }

        } else if (memcmp( flag, "onlyport", 8) == 0 ) {
            char *name = (char *) SvPV(value, PL_na);
            if ((onlyPort = rxdebug_PortNumber(name)) == -1)
              onlyPort = rxdebug_PortName(name);
            if (onlyPort == -1) {
              sprintf(buffer, "rxdebug: can't resolve port name %s", name);
              VSETCODE(-1, buffer);
              XSRETURN_UNDEF;
            }
        }

        break;

    case 'p':
        if (memcmp( flag, "port", 4) == 0 ) {
            portName = (char *) SvPV(value, PL_na);
        } else if (memcmp( flag, "peers", 5) == 0 ) {
           showPeers  = (int) SvIV(value);
        }
        break;

    case 'r':
        if (memcmp( flag, "rxstats", 7) == 0 ) {
            rxstats = (int) SvIV(value);
        }
        break;

    case 's':
        if (memcmp( flag, "servers", 7) == 0 ) {
            hostName = (char *) SvPV(value, PL_na);
        }
        break;

    case 'v':
        if (memcmp( flag, "version", 7) == 0 ) {
            version_flag = (int) SvIV(value);
        }
        break;

    default:
        break;
    } /* switch */
  } /* while */
  /*  fprintf(STDERR, "Done parsing args\n\n"); */

    /* lookup host */
    if (hostName) {
      th = hostutil_GetHostByName(hostName);
      if (!th) {
        sprintf(buffer, "rxdebug: host %s not found in host table", hostName);
        VSETCODE(-1, buffer);
        XSRETURN_UNDEF;
      }
      memcpy(&host, th->h_addr, sizeof(afs_int32));
    }
    else host = htonl(0x7f000001);    /* IP localhost */

    if (!portName)
      port = htons(7000);        /* default is fileserver */
    else {
      if ((port = rxdebug_PortNumber(portName)) == -1)
        port = rxdebug_PortName(portName);
      if (port == -1) {
        sprintf(buffer, "rxdebug: can't resolve port name %s", portName);
        VSETCODE(-1, buffer);
        XSRETURN_UNDEF;
      }
    }

    dallyCounter = 0;
    hostAddr.s_addr = host;
    /* add address and port to RETVAL hash */
    hv_store(RETVAL, "address", 7, newSVpv(inet_ntoa(hostAddr), 0), 0);
    hv_store(RETVAL, "port", 4, newSViv(ntohs(port)), 0);
    s = socket(AF_INET, SOCK_DGRAM, 0);
    taddr.sin_family = AF_INET;
    taddr.sin_port = 0;
    taddr.sin_addr.s_addr = 0;
#ifdef STRUCT_SOCKADDR_HAS_SA_LEN
    taddr.sin_len = sizeof(struct sockaddr_in);
#endif
    code = bind(s, (struct sockaddr *) &taddr, sizeof(struct sockaddr_in));
    FSSETCODE(code);
    if (code) {
      perror("bind");
      XSRETURN_UNDEF;
    }

    if (version_flag) /* add version to RETVAL and finish */
    {
       code = rx_GetServerVersion(s, host, port, length, version);
       if (code < 0)
       {
          sprintf(buffer, "get version call failed with code %d, errno %d",code,errno);
          BSETCODE(code, buffer);
          XSRETURN_UNDEF;
       }
       hv_store(RETVAL, "version", 7, newSVpv(version, 0), 0);
       goto done;
    }

    code = rx_GetServerDebug(s, host, port, &tstats, &supportedDebugValues);

    if (code < 0) {
      sprintf(buffer, "getstats call failed with code %d", code);
      BSETCODE(code, buffer);
      XSRETURN_UNDEF;
    }

    withSecStats = (supportedDebugValues & RX_SERVER_DEBUG_SEC_STATS);
    withAllConn = (supportedDebugValues & RX_SERVER_DEBUG_ALL_CONN);
    withRxStats = (supportedDebugValues & RX_SERVER_DEBUG_RX_STATS);
    withWaiters = (supportedDebugValues & RX_SERVER_DEBUG_WAITER_CNT);
    withIdleThreads = (supportedDebugValues & RX_SERVER_DEBUG_IDLE_THREADS);
    withPeers = (supportedDebugValues & RX_SERVER_DEBUG_ALL_PEER);

    TSTATS = newHV();
    hv_store(TSTATS, "nFreePackets", 12, newSViv(tstats.nFreePackets), 0);
    hv_store(TSTATS, "packetReclaims", 14, newSViv(tstats.packetReclaims), 0);
    hv_store(TSTATS, "callsExecuted", 13, newSViv(tstats.callsExecuted), 0);
    hv_store(TSTATS, "usedFDs", 7, newSViv(tstats.usedFDs), 0);
    hv_store(TSTATS, "waitingForPackets", 17, newSViv(tstats.waitingForPackets), 0);
    hv_store(TSTATS, "version", 7, newSViv(tstats.version), 0);
    if (withWaiters)
       hv_store(TSTATS, "nWaiting", 8, newSViv(tstats.nWaiting), 0);
    if ( withIdleThreads )
       hv_store(TSTATS, "idleThreads", 11, newSViv(tstats.idleThreads), 0);
    hv_store(RETVAL, "tstats", 6, newRV_inc((SV*)(TSTATS)), 0);

    /* get rxstats if requested, and supported by the server */
    /* hash containing stats added at key 'rxstats' in RETVAL */
    if (rxstats)
    {
      if (!withRxStats)
      {
        noRxStats:
        withRxStats = 0;
        warn("WARNING: Server doesn't support retrieval of Rx statistics\n");
      }
      else {
        struct rx_statistics rxstats;

        /* should gracefully handle the case where rx_statistics grows */
        code = rx_GetServerStats(s, host, port, &rxstats, &supportedStatValues);
        if (code < 0) {
          sprintf(buffer, "rxstats call failed with code %d", code);
          VSETCODE(code, buffer);
          XSRETURN_UNDEF;
        }
        if (code != sizeof(rxstats)) {
          if ((((struct rx_debugIn *)(&rxstats))->type == RX_DEBUGI_BADTYPE))
            goto noRxStats;
          warn("WARNING: returned Rx statistics of unexpected size (got %d)\n", code);
          /* handle other versions?... */
        }

        RXSTATS = newHV();

        myPrintTheseStats(RXSTATS, &rxstats);

        hv_store(RETVAL, "rxstats", 7, newRV_inc((SV*)(RXSTATS)), 0);

      }
    }

    /* get connections unless -noconns flag was set */
    /* array of connections added at key 'connections' in RETVAL hash */
    if (!noConns) {
      if (allconns) {
        if (!withAllConn) {
          warn("WARNING: Server doesn't support retrieval of all connections,\n");
          warn("         getting only interesting instead.\n");
          }
      }

      CONNECTIONS = newAV();
      index = 0;
      for ( i = 0; ; i++) {
        code = rx_GetServerConnections(s, host, port, &nextconn, allconns,
                      supportedDebugValues, &tconn,
                      &supportedConnValues);
        if (code < 0) {
          warn("getconn call failed with code %d\n", code);
          break;
        }
        if (tconn.cid == 0xffffffff) {
          break;
        }

        /* see if we're in nodally mode and all calls are dallying */
        if (nodally) {
          flag = 0;
          for (j = 0; j < RX_MAXCALLS; j++) {
             if (tconn.callState[j] != RX_STATE_NOTINIT &&
                 tconn.callState[j] != RX_STATE_DALLY) {
               flag = 1;
               break;
             }
          }
          if (flag == 0) {
            /* this call looks too ordinary, bump skipped count and go
             * around again */
            dallyCounter++;
            continue;
          }
        }
        if ((onlyHost != -1) && (onlyHost != tconn.host)) continue;
        if ((onlyPort != -1) && (onlyPort != tconn.port)) continue;
        if (onlyServer && (tconn.type != RX_SERVER_CONNECTION)) continue;
        if (onlyClient && (tconn.type != RX_CLIENT_CONNECTION)) continue;
        if (onlyAuth != 999) {
          if (onlyAuth == -1) {
            if (tconn.securityIndex != 0) continue;
          }
          else {
            if (tconn.securityIndex != 2) continue;
            if (withSecStats && (tconn.secStats.type == 3) &&
             (tconn.secStats.level != onlyAuth)) continue;
          }
        }
        TCONN = newHV();
        hostAddr.s_addr = tconn.host;
        hv_store(TCONN, "host", 4, newSVpv(inet_ntoa(hostAddr), 0), 0);
        hv_store(TCONN, "port", 4, newSViv(ntohs(tconn.port)), 0);

        hv_store(TCONN, "cid", 3, newSViv(tconn.cid), 0);
        hv_store(TCONN, "epoch", 5, newSViv(tconn.epoch), 0);
        hv_store(TCONN, "error", 5, newSViv(tconn.error), 0);
        hv_store(TCONN, "serial", 6, newSViv(tconn.serial), 0);
        hv_store(TCONN, "natMTU", 6, newSViv(tconn.natMTU), 0);

        hv_store(TCONN, "flags", 5, newSViv(tconn.flags), 0);

        hv_store(TCONN, "securityIndex", 13, newSViv(tconn.securityIndex), 0);

        hv_store(TCONN, "type", 4, newSViv(tconn.type), 0);

        if (withSecStats) {
          HV* SECSTATS = newHV();
          hv_store(SECSTATS, "type", 4,
                   newSViv(tconn.secStats.type), 0);
          hv_store(SECSTATS, "level", 5,
                   newSViv(tconn.secStats.level), 0);
          hv_store(SECSTATS, "flags", 5,
                   newSViv(tconn.secStats.flags), 0);
          hv_store(SECSTATS, "expires", 7,
                   newSViv(tconn.secStats.expires), 0);
          hv_store(SECSTATS, "packetsReceived", 15,
                   newSViv(tconn.secStats.packetsReceived), 0);
          hv_store(SECSTATS, "packetsSent", 11,
                   newSViv(tconn.secStats.packetsSent), 0);
          hv_store(SECSTATS, "bytesReceived", 13,
                   newSViv(tconn.secStats.bytesReceived), 0);
          hv_store(SECSTATS, "bytesSent", 9,
                   newSViv(tconn.secStats.bytesSent), 0);
          hv_store(TCONN, "secStats", 8, newRV_inc((SV*)(SECSTATS)), 0);
        }

        CALLSTATE = newAV();
        av_fill(CALLSTATE, RX_MAXCALLS-1);
        CALLMODE = newAV();
        av_fill(CALLMODE, RX_MAXCALLS-1);
        CALLFLAGS = newAV();
        av_fill(CALLFLAGS, RX_MAXCALLS-1);
        CALLOTHER = newAV();
        av_fill(CALLOTHER, RX_MAXCALLS-1);
        CALLNUMBER = newAV();
        av_fill(CALLNUMBER, RX_MAXCALLS-1);

        for (j = 0; j < RX_MAXCALLS; j++) {
          av_store(CALLSTATE, j, newSViv(tconn.callState[j]));
          av_store(CALLMODE, j, newSViv(tconn.callMode[j]));
          av_store(CALLFLAGS, j, newSViv(tconn.callFlags[j]));
          av_store(CALLOTHER, j, newSViv(tconn.callOther[j]));
          av_store(CALLNUMBER, j, newSViv(tconn.callNumber[j]));
        }

        hv_store(TCONN, "callState", 9, newRV_inc((SV*)(CALLSTATE)), 0);
        hv_store(TCONN, "callMode", 8, newRV_inc((SV*)(CALLMODE)), 0);
        hv_store(TCONN, "callFlags", 9, newRV_inc((SV*)(CALLFLAGS)), 0);
        hv_store(TCONN, "callOther", 9, newRV_inc((SV*)(CALLOTHER)), 0);
        hv_store(TCONN, "callNumber", 10, newRV_inc((SV*)(CALLNUMBER)), 0);

        av_store(CONNECTIONS, index, newRV_inc((SV*)(TCONN)));
        index++;
      } /* end of for loop */
      if (nodally) hv_store(RETVAL, "dallyCounter", 12, newSViv(dallyCounter), 0);
      hv_store(RETVAL, "connections", 11, newRV_inc((SV*)(CONNECTIONS)), 0);
    } /* end of if (!noConns) */

    /* get peers if requested */
    /* array of peers added at key 'peers' in RETVAL hash */
    if (showPeers && withPeers) {
      PEERS = newAV();
      index = 0;
      for (i = 0; ; i++) {
        struct rx_debugPeer tpeer;
        code = rx_GetServerPeers(s, host, port, &nextpeer, allconns,
                                 &tpeer, &supportedPeerValues);
        if (code < 0) {
          warn("getpeer call failed with code %d\n", code);
          break;
        }
        if (tpeer.host == 0xffffffff) {
          break;



( run in 0.545 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )