[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: 20000128: LDM Build using gcc on IRIX64-6.5



Paul Hamer wrote:

> Anne,
>
> I've just downloaded and unpacked  ldm-5.0.9.tar.Z and pqact.c is missing
> from the distribution.
>
> Thought you might like to know.
>
> Paul.
>

Yikes!  You're right.  I just discovered that as I was trying to install and 
build our own IRIX version.

Attached is pqact.c for you.  We'll fix the distribution.   Thanks!  And our 
apologies for the inconvenience.

Anne

--
***************************************************
Anne Wilson                     UCAR Unidata Program
address@hidden                  P.O. Box 3000
(303) 497-8677                    Boulder, CO  80307
----------------------------------------------------
Unidata WWW server       http://www.unidata.ucar.edu/
****************************************************


/*
 *   Copyright 1993, University Corporation for Atmospheric Research
 *   See ../COPYRIGHT file for copying and redistribution conditions.
 */
/* $Id: pqact.c,v 1.37 1999/04/02 23:16:19 davis Exp $ */

/* 
 * ldm server mainline program module
 */

#include <ldmconfig.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <rpc/rpc.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <regex.h>
#ifndef NO_WAITPID
#include <sys/wait.h>
#endif 
#include "paths.h" /* built by configure from paths.h.in */
#include "ldm.h"
#include "atofeedt.h"
#include "pq.h"
#include "palt.h"
#include "ldmprint.h"
#include "filel.h" /* pipe_timeo */
#include "ulog.h"

#ifdef NO_ATEXIT
#include "atexit.h"
#endif

static const char *pqfname = DEFAULT_QUEUE;

static pqueue *pq = NULL;

static volatile int done = 0;
static volatile int hupped = 0;
static char *conffilename = 0;

#ifndef DEFAULT_INTERVAL
#define DEFAULT_INTERVAL 15
#endif
#ifndef DEFAULT_FEEDTYPE
#define DEFAULT_FEEDTYPE ANY
#endif
#ifndef DEFAULT_PATTERN
#define DEFAULT_PATTERN ".*"
#endif

/*
 * Timeout used for PIPE actions,
 * referenced in filel.c
 */
#ifndef DEFAULT_PIPE_TIMEO
#define DEFAULT_PIPE_TIMEO 60
#endif /* !DEFAULT_PIPE_TIMEO */
int pipe_timeo = DEFAULT_PIPE_TIMEO;


/*
 * called at exit
 */
static void
cleanup(void)
{
        unotice("Exiting");

        if(done)
        {
                /*
                 * We are not in the interrupt context, so these can
                 * be performed safely.
                 */
                fl_close_all();
                if(pq)
                        (void) pq_close(pq);
                while ( reap(-1, WNOHANG) > 0 )
                        /* EMPTY */;
        }
        (void) closeulog();
}


/*
 * called upon receipt of signals
 */
static void
signal_handler(int sig)
{
#ifdef SVR3SIGNALS
        /* 
         * Some systems reset handler to SIG_DFL upon entry to handler.
         * In that case, we reregister our handler.
         */
        (void) signal(sig, signal_handler);
#endif
        switch(sig) {
        case SIGHUP :
                udebug("SIGHUP");
                hupped = !0;
                return;
        case SIGINT :
                unotice("Interrupt");
                exit(0);
        case SIGTERM :
                udebug("SIGTERM");
                done = !0;
                return;
        case SIGUSR1 :
                udebug("SIGUSR1");
                /* TODO? stats */
                return;
        case SIGUSR2 :
                udebug("SIGUSR2");
                rollulogpri();
                return;
        case SIGALRM :
                udebug("SIGALRM");
                return;
        case SIGCHLD :
                udebug("SIGCHLD");
                return;
        }
        udebug("signal_handler: unhandled signal: %d", sig);
}


/*
 * register the signal_handler
 */
static void
set_sigactions(void)
{
        struct sigaction sigact;

        sigemptyset(&sigact.sa_mask);
        sigact.sa_flags = 0;

        /* Ignore these */
        sigact.sa_handler = SIG_IGN;
        (void) sigaction(SIGPIPE, &sigact, NULL);

        /* Handle these */
#ifdef SA_RESTART       /* SVR4, 4.3+ BSD */
        /* usually, restart system calls */
        sigact.sa_flags |= SA_RESTART;
#endif
        sigact.sa_handler = signal_handler;
        (void) sigaction(SIGHUP, &sigact, NULL);
        (void) sigaction(SIGTERM, &sigact, NULL);
        (void) sigaction(SIGUSR1, &sigact, NULL);
        (void) sigaction(SIGUSR2, &sigact, NULL);
        (void) sigaction(SIGALRM, &sigact, NULL);
        (void) sigaction(SIGCHLD, &sigact, NULL);

        /* Don't restart after interrupt */
        sigact.sa_flags = 0;
#ifdef SA_INTERRUPT     /* SunOS 4.x */
        sigact.sa_flags |= SA_INTERRUPT;
#endif
        (void) sigaction(SIGINT, &sigact, NULL);
}


static void
usage(
        char *av0 /*  id string */
)
{
        (void)fprintf(stderr,
                "Usage: %s [options] [confilename]\t\nOptions:\n",
                av0);
        (void)fprintf(stderr,
                "\t-v           Verbose, log each match (SIGUSR2 cycles)\n");
        (void)fprintf(stderr,
                "\t-x           Debug mode (SIGUSR2 cycles)\n");
        (void)fprintf(stderr,
                "\t-l logfile   Send log info to file (default uses 
syslogd)\n");
        (void)fprintf(stderr,
                "\t-d datadir   cd to \"datadir\" before interpreting filenames 
in\n");
        (void)fprintf(stderr,
                "\t             conffile (default %s)\n",
                DEFAULT_DATADIR);
        (void)fprintf(stderr,
                "\t-q queue     default \"%s\"\n", DEFAULT_QUEUE);
        (void)fprintf(stderr,
                "\t-p pattern   Interested in products matching \"pattern\" 
(default \"%s\")\n", DEFAULT_PATTERN);
        (void)fprintf(stderr,
                "\t-f feedtype  Interested in products from feed \"feedtype\" 
(default %s)\n", s_feedtypet(DEFAULT_FEEDTYPE));
        (void)fprintf(stderr,
                "\t-i interval  loop, polling each \"interval\" seconds 
(default %d)\n", DEFAULT_INTERVAL);
        (void)fprintf(stderr,
                "\t-t timeo     set write timeo for PIPE subprocs to \"timeo\" 
secs (default %d)\n", DEFAULT_PIPE_TIMEO);
        (void)fprintf(stderr,
                "\t-o offset    the oldest product we will consider is 
\"offset\" secs before now (default: most recent in queue)\n");
        (void)fprintf(stderr,
                "\t(default conffilename is %s)\n",
                DEFAULT_CONFFILENAME);
        exit(1);
}


int
main(int ac, char *av[])
{
        int status = 0;
        char *logfname = 0;
        int logfd = -1;
        /* data directory, conffile paths may be relative */
        char *datadir = DEFAULT_DATADIR;
        int interval = DEFAULT_INTERVAL;
        prod_spec spec;
        prod_class clss;
        int toffset = TOFFSET_NONE;

        conffilename = DEFAULT_CONFFILENAME;

        spec.feedtype = DEFAULT_FEEDTYPE;
        spec.pattern = DEFAULT_PATTERN;

        if(set_timestamp(&clss.from) != ENOERR) /* corrected by toffset below */
        {
                int errnum = errno;
                fprintf(stderr, "Couldn't set timestamp: %s", 
                        strerror(errnum));
                exit(1);
        }
        clss.to = TS_ENDT;
        clss.psa.psa_len = 1;
        clss.psa.psa_val = &spec;

        /*
         * Check the environment for some options.
         * May be overridden by command line switches below.
         */
        {
                const char *ldmpqfname = getenv("LDMPQFNAME");
                if(ldmpqfname != NULL)
                        pqfname = ldmpqfname;
        }
        /*
         * deal with the command line, set options
         */
        {
        extern int optind;
        extern int opterr;
        extern char *optarg;
        int ch;
        int logmask = (LOG_MASK(LOG_ERR) | LOG_MASK(LOG_NOTICE));
        int fterr;

        opterr = 1;

        while ((ch = getopt(ac, av, "vxl:d:f:q:o:p:i:t:")) != EOF)
                switch (ch) {
                case 'v':
                        logmask |= LOG_MASK(LOG_INFO);
                        break;
                case 'x':
                        logmask |= LOG_MASK(LOG_DEBUG);
                        break;
                case 'l':
                        logfname = optarg;
                        break;
                case 'd':
                        datadir = optarg;
                        break;
                case 'f':
                        fterr = strfeedtypet(optarg, &spec.feedtype);
                        if(fterr != FEEDTYPE_OK)
                        {
                                fprintf(stderr, "Bad feedtype \"%s\", %s\n",
                                        optarg, strfeederr(fterr));
                                usage(av[0]);
                        }
                        break;
                case 'q':
                        pqfname = optarg;
                        break;
                case 'o':
                        toffset = atoi(optarg);
                        if(toffset == 0 && *optarg != '0')
                        {
                                fprintf(stderr, "%s: invalid offset %s\n",
                                         av[0], optarg);
                                usage(av[0]);   
                        }
                        break;
                case 'i':
                        interval = atoi(optarg);
                        if(interval == 0 && *optarg != '0')
                        {
                                fprintf(stderr, "%s: invalid interval %s\n", 
av[0], optarg);
                                usage(av[0]);   
                        }
                        break;
                case 't':
                        pipe_timeo = atoi(optarg);
                        if(pipe_timeo == 0 && *optarg != 0)
                        {
                                fprintf(stderr, "%s: invalid pipe_timeo %s", 
av[0], optarg);
                                usage(av[0]);   
                        }
                        break;
                case 'p':
                        spec.pattern = optarg;
                        break;
                case '?':
                        usage(av[0]);
                        break;
                }
        if(ac - optind == 1)
                conffilename = av[optind];
        (void) setulogmask(logmask);

        status = regcomp(&spec.rgx,
                spec.pattern,
                REG_EXTENDED|REG_NOSUB);
        if(status != 0)
        {
                fprintf(stderr, "Can't compile regular expression \"%s\"\n",
                        spec.pattern);
                usage(av[0]);
        }
        }

        /*
         * initialize logger
         * (Close fd 2 to remap stderr to the logfile, when
         * appropriate. I know, this is anal.)
         */
        if(logfname != NULL && !(logfname[0] == '-' && logfname[1] == 0))
                (void)close(2);
        logfd = openulog(ubasename(av[0]),
                (LOG_CONS|LOG_PID), LOG_LDM, logfname);
        unotice("Starting Up");

        /*
         * register exit handler
         */
        if(atexit(cleanup) != 0)
        {
                serror("atexit");
                unotice("Exiting");
                exit(1);
        }

        /*
         * set up signal handlers
         */
        set_sigactions();

        /*
         * Read in (compile) the configuration file.  We do this first so
         * its syntax may be checked without opening a product queue.
         */
        if(readPatFile(conffilename) < 0)
                exit(1);

        /*
         * Open the product queue
         */
        (void) fclose(stdin); /* more anality :-) */
        status = pq_open(pqfname, PQ_READONLY, &pq);
        if(status)
        {
                uerror("pq_open failed: %s: %s\n",
                        pqfname, strerror(status));
                exit(1);
        }

        (void) fclose(stdout); /* more anality :-), get one more descriptor */

        if(toffset == TOFFSET_NONE)
        {
                /*
                 * Be permissive with the time filter,
                 * jump now to the end of the queue.
                 */
                clss.from = TS_ZERO;
                (void) pq_last(pq, &clss, NULL);
        }
        else
        {
                /*
                 * Filter and queue position set by
                 * toffset.
                 */
                clss.from.tv_sec -= toffset;
                pq_cset(pq, &clss.from);
        }

        if(ulogIsVerbose())
        {
                char buf[1984];
                uinfo("%s",
                         s_prod_class(buf, sizeof(buf), &clss));
        }

        /*
         * Change directories if datadir was specified
         */
        if(datadir != NULL && *datadir != 0) 
        {
                /* change to data directory */
                if (chdir(datadir) == -1)
                {
                        serror("cannot chdir to %s", datadir);
                        exit(4);
            }
        }


        /*
         *  Do special pre main loop actions in pattern/action file
         *  N.B. Deprecate.
         */
        dummyprod("_BEGIN_");


        /*
         * Main loop
         */
        while(!done)
        {
                if(hupped)
                {
                        unotice("ReReading configuration file %s",
                                conffilename);
                        (void) readPatFile(conffilename);
                        hupped = 0;
                }

                status = pq_sequence(pq, TV_GT, &clss, processProduct, 0);

                switch(status) {
                case 0: /* no error */
                        break;
                case PQUEUE_END:
                        udebug("End of Queue");
                        if(interval == 0)
                        {
                                /* one trip */
                                done = !0;
                                continue;
                        }
                        break;
                case EAGAIN:
                case EACCES:
                        udebug("Hit a lock");
                        break;
#if defined(EDEADLOCK) && EDEADLOCK != EDEADLK
                case EDEADLOCK:
#endif
                case EDEADLK:
                        uerror("%s", strerror(status));
                        break;
                default:
                        uerror("pq_sequence failed: %s (errno = %d)",
                                strerror(status), status);
                        exit(1);
                        break;
                }

                                

                if(status)
                {
                        pq_suspend(interval);
                        /* close the least recently used idle descriptor */
                        close_lru(FL_NOTRANSIENT);
                }

                /* Attempt (non-blocking) to sync everyone */
                fl_sync(-1, FALSE);

                /*
                 * Wait on any children which may have died
                 */
                while ( reap(-1, WNOHANG) > 0 )
                        /* EMPTY */;

        }

        exit(0);
        /*NOTREACHED*/
}