Cluster events using AHAFS sample code

The sample program code, test_prog, is executed by using the following arguments:
./test_prog /aha/cluster/nodeState.monFactory/nodeStateEvent.mon "CHANGED=YES;CLUSTER=YES" 10 /tmp/nodestateevent
The following is the code for test_prog:
#include <stdio.h>
#include <string.h> /* for strcmp() */
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <libgen.h>
#include <usersec.h>

#define MAX_WRITE_STR_LEN    255

void       syntax(char *prog);
int        ahaMonFile(char *str);
static int mk_parent_dirs (char *path);
void       read_data (int fd,int outfd);

char       *monFile;

test_prog :: main

int main (int argc, char *argv[])
{
    int    fd,outfd, rc,i=0,cnt=0;
    fd_set readfds;
    char *outputFile;
    char   wrStr[MAX_WRITE_STR_LEN+1];
    char   waitInRead[] = "WAIT_TYPE=WAIT_IN_READ";
    if (argc < 5)
       syntax( argv[0]);
    monFile = argv[1];
    if ( ! ahaMonFile(monFile) )  /* Not a .mon file under /aha */
       syntax( argv[0]);
    /* Create intermediate directories of the .mon file */
    rc = mk_parent_dirs(monFile);
    if (rc)
    {
        fprintf (stderr,
        "Could not create intermediate directories of the file %s !\n", monFile);
        return(-1);
    }
    printf("Monitor file name: %s\n", monFile);
    sprintf (wrStr, "%s", argv[2]);
    cnt = atoi(argv[3]);
    printf("Write String  : %s\n", wrStr);
    outputFile = argv[4];
    fd = open (monFile, O_CREAT|O_RDWR);
    if (fd < 0)
    {
       fprintf (stderr,"Could not open the file %s; errno = %d\n", monFile,errno);
        exit (1);
    }
    outfd = open (outputFile, O_CREAT|O_RDWR);
    if (outfd < 0)
    {
        fprintf (stderr, "Could not open the file %s; errno = %d !\n", monFile, errno);
        return(-1);
    }
    write(fd, wrStr, strlen(wrStr));
 

    for(i = 0; i < cnt; i++)
    {
    if (strstr(wrStr, waitInRead) == NULL)
    {
        FD_ZERO(&readfds);
        FD_SET(fd, &readfds);
        printf(
         "Entering select() to wait till the event corresponding to the AHA node %s occurs.\n",
          monFile);
        printf("Please issue a command from another window to trigger this event.\n");
        rc = select (fd+1, &readfds, NULL, NULL, NULL);
        printf("\nThe select() completed. \n");
        if (rc <= 0) /* No event occurred or an error was found. */
        {
            fprintf (stderr, "The select() returned %d.\n", rc);
            perror ("select: ");
            return (-1);
        }
        if(! FD_ISSET(fd, &readfds))
                goto end;
        printf("The event corresponding to the AHA node %s has occurred.\n", monFile);
    }
    else
    {
      printf(
       "Entering read() to wait till the event corresponding to the AHA node %s occurs.\n",
        monFile);
      printf("Please issue a command from another window to trigger this event.\n");
    }
    read_data(fd,outfd);
}
 end:
    close(fd);
    close(outfd);
}

test_prog :: syntax

/* -------------------------------------------------------------------------- */
void syntax(char *prog)
{
  printf("\nSYNTAX: %s <aha-monitor-file> [<key1>=<value1>[;<key2>=<value2>;...]] <count> <outfile> \n",prog);
  exit (1);
}

test_prog :: ahaMonFile

/* --------------------------------------------------------------------------
 * PURPOSE: To check whether the file provided is an AHA monitor file.
 */
int ahaMonFile(char *str)
{
    char cwd[PATH_MAX];
    int len1=strlen(str), len2=strlen(".mon");
    int rc = 0;
    struct stat     sbuf;

    /* Make sure /aha is mounted. */
    if ((stat("/aha", &sbuf) < 0) ||
        (sbuf.st_flag != FS_MOUNT))
    {
        printf("ERROR: The filesystem /aha is not mounted!\n");
        return (rc);
    }

    /* Make sure the path has .mon as a suffix. */
    if ((len1 <= len2) ||
        (strcmp ( (str + len1 - len2), ".mon"))
        )
       goto end;

    if (! strncmp (str, "/aha",4))  /* The given path starts with /aha */
       rc = 1;
    else    /* It could be a relative path */
    {
        getcwd (cwd, PATH_MAX);
        if ((str[0] != '/' )  &&          /* Relative path and */
            (! strncmp (cwd, "/aha",4))  /* cwd starts with /aha . */
            )
           rc = 1;
    }
 end:
    if (!rc)
       printf("ERROR:  %s is not an AHA monitor file !\n", str);
    return (rc);
}

test_prog :: mk_parent_dirs

/*-----------------------------------------------------------------
 * NAME:  mk_parent_dirs()
 * PURPOSE: To create intermediate directories of a .mon file if
 *          they are not created.
 */
static int
mk_parent_dirs (char *path)
{
    char   s[PATH_MAX];
    char   *dirp;
    struct stat buf;
    int    rc=0;

    dirp = dirname(path);
    if (stat(dirp, &buf) != 0)
    {
        sprintf(s, "/usr/bin/mkdir -p %s", dirp);
        rc = system(s);
    }
    return (rc);
}

test_prog :: read_data

/*-----------------------------------------------------------------
 * PURPOSE: To parse and print the data received at the occurrence
 *      of the event.
 */
void
read_data (int fd,int outfd)
{
#define READ_BUF_SIZE  3072
    char   data[READ_BUF_SIZE];
    char   *p, *line;
    char   cmd[64];
    time_t sec, nsec;
    pid_t  pid;
    uid_t  uid, luid;
    gid_t  gid;
    char   curTm[64];
    int    n;
    int    stackInfo = 0;
    char   uname[64], lname[64], gname[64];

    bzero((char *)data, READ_BUF_SIZE);
/* Read the info from the beginning of the file. */
    n=pread(fd, data,READ_BUF_SIZE, 0);
    p = data;
    printf("%s\n",p);
    write(outfd, data, n);
}