Esempio n. 1
0
int main(int ac, char *av[])
{
        const char* pqfname = getQueuePath();
        const char *opqfname = getSurfQueuePath();
        const char *progname = ubasename(av[0]);
        char *logfname;
        prod_class_t clss;
        prod_spec spec;
        int status = 0;
        unsigned interval = DEFAULT_INTERVAL;
        int logoptions = (LOG_CONS|LOG_PID);
        double age = DEFAULT_AGE;
        /* these are containers for the pqact args */
        char *argv[16];
        int argc = 0;
        int toffset = TOFFSET_NONE;

        logfname = "";

        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;
        
        spec.feedtype = DEFAULT_FEEDTYPE;
        spec.pattern = DEFAULT_PATTERN;

        memset(argv, 0, sizeof(argv));
        argv[0] = "pqact";
        argc++;

        {
        extern int optind;
        extern int opterr;
        extern char *optarg;
        int ch;
        int logmask = (LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING) |
            LOG_MASK(LOG_NOTICE));
        int fterr;
        const char *conffilename = getPqsurfConfigPath();
        const char *datadir = getPqsurfDataDirPath();

        usePil = 1;
        opterr = 1;

        while ((ch = getopt(ac, av, "vxl:d:f:p:q:Q:o:i:a:t:")) != EOF)
                switch (ch) {
                case 'v':
                        argv[argc++] = "-v";
                        logmask |= LOG_MASK(LOG_INFO);
                        break;
                case 'x':
                        argv[argc++] = "-x";
                        logmask |= LOG_MASK(LOG_DEBUG);
                        break;
                case 'l':
                        argv[argc++] = "-l";
                        argv[argc++] = optarg;
                        logfname = optarg;
                        break;
                case 'd':
                        datadir = optarg;
                        break;
                case 'f':
                        fterr = strfeedtypet(optarg, &spec.feedtype);
                        if(fterr != FEEDTYPE_OK)
                        {
                                fprintf(stderr, "%s: %s: \"%s\"\n",
                                        av[0], strfeederr(fterr), optarg);
                                usage(progname);        
                        }
                        argv[argc++] = "-f";
                        argv[argc++] = optarg;
                        break;
                case 'p':
                        spec.pattern = optarg;
                        /* compiled below */
                        break;
                case 'q':
                        pqfname = optarg;
                        break;
                case 'Q':
                        opqfname = 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]);   
                        }
                        argv[argc++] = "-o";
                        argv[argc++] = optarg;
                        break;
                case 'i':
                        interval = atoi(optarg);
                        if(interval == 0 && *optarg != '0')
                        {
                                fprintf(stderr, "%s: invalid interval \"%s\"\n",
                                        av[0], optarg);
                                usage(av[0]);
                        }
                        /* N.B. -i just used for input queue. */
                        break;
                case 'a':
                        age = atof(optarg);
                        if(age < 0.)
                        {
                            (void) fprintf(stderr,
                                        "age (%s) must be non negative\n",
                                        optarg);
                                usage(av[0]);   
                        }
                        break;
                case 't':
                        /* pipe_timeo */
                        argv[argc++] = "-t";
                        argv[argc++] = optarg;
                        break;
                case '?':
                        usage(progname);
                        break;
                }

        (void) setulogmask(logmask);

        if (re_isPathological(spec.pattern))
        {
                fprintf(stderr, "Adjusting pathological regular-expression: "
                    "\"%s\"\n", spec.pattern);
                re_vetSpec(spec.pattern);
        }
        status = regcomp(&spec.rgx,
                spec.pattern,
                REG_EXTENDED|REG_NOSUB);
        if(status != 0)
        {
                fprintf(stderr, "Bad regular expression \"%s\"\n",
                        spec.pattern);
                usage(av[0]);
        }

        if(ac - optind == 1)
                conffilename = av[optind];

        argv[argc++] = "-d";
        argv[argc++] = (char*)datadir;
        argv[argc++] = "-q";
        argv[argc++] = (char*)opqfname;
        argv[argc++] = (char*)conffilename;

        age *= 3600.;

        }

        if(toffset != TOFFSET_NONE)
        {
                clss.from.tv_sec -= toffset;
        }
        else
        {
                clss.from.tv_sec -= (age - interval);
        }


        /*
         * Set up error logging.
         * N.B. log ident is the remote
         */
        (void) openulog(progname,
                logoptions, LOG_LDM, logfname);
        unotice("Starting Up (%d)", getpgrp());

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

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


        /*
         * Open the output product queue
         */
        status = pq_open(opqfname, PQ_DEFAULT, &opq);
        if(status)
        {
                if (PQ_CORRUPT == status) {
                    uerror("The output product-queue \"%s\" is inconsistent\n",
                            opqfname);
                }
                else {
                    uerror("pq_open failed: %s: %s\n",
                            opqfname, strerror(status));
                }
                exit(1);
        }


        act_pid = run_child(argc, argv);
        if(act_pid == (pid_t)-1)
                exit(1);

        /*
         * Open the input product queue
         */
        status = pq_open(pqfname, PQ_READONLY, &pq);
        if(status)
        {
                if (PQ_CORRUPT == status) {
                    uerror("The product-queue \"%s\" is inconsistent\n",
                            pqfname);
                }
                else {
                    uerror("pq_open failed: %s: %s\n",
                            pqfname, strerror(status));
                }
                exit(1);
        }
        if(toffset == TOFFSET_NONE)
        {
                /* Jump to the end of the queue */
                timestampt sav;
                sav = clss.from;
                clss.from = TS_ZERO;
                (void) pq_last(pq, &clss, NULL);
                clss.from = sav;
        }
        else
        {
                pq_cset(pq, &clss.from);
        }

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

        while(exitIfDone(0))
        {
                if(stats_req)
                {
                        dump_stats();
                        stats_req = 0;
                }

                status = pq_sequence(pq, TV_GT, &clss, split_prod, NULL);

                switch(status) {
                case 0: /* no error */
                        continue; /* N.B., other cases sleep */
                case PQUEUE_END:
                        udebug("surf: End of Queue");
                        break;
                case EAGAIN:
                case EACCES:
                        udebug("Hit a lock");
                        break;
                default:
                        uerror("pq_sequence failed: %s (errno = %d)",
                                strerror(status), status);
                        exit(1);
                        break;
                }

                if(interval == 0)
                {
                        break;
                }


                (void) expire(opq, interval, age);

                pq_suspend(interval);

                (void) reap_act(WNOHANG);
        }

        /*
         * TODO: how can we determine that pqact has finished
         *       the work in opq?
         */
        sleep(5);

        exit(0);
}
Esempio n. 2
0
int main(int ac, char *av[])
{
        const char* const       pqfname = getQueuePath();
        const char* const       progname = ubasename(av[0]);
        char *logfname = NULL; /* log to syslogd(8) */
        int logoptions = LOG_CONS | LOG_PID;
        int logmask = LOG_UPTO(LOG_NOTICE);
        prod_class_t clss;
        prod_spec spec;
        int status = 0;
        int interval = DEFAULT_INTERVAL;
        int toffset = TOFFSET_NONE;
        extern const char *remote;
        char* hostname = ghostname();

        /*
         * Setup default logging before anything else.
         */
        (void) openulog(progname, logoptions, LOG_LDM, logfname);
        (void) setulogmask(logmask);

        remote = "localhost";

        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;
        spec.feedtype = DEFAULT_FEEDTYPE;
        spec.pattern = ".*";
        
        /*
         * Sigh, in order to read back from existing stats files,
         * we call mktime(3). Since the stats are in UTC,
         * and mktime uses "local" time, the local time for
         * this program must be UTC.
         */
        if(setenv("TZ", "UTC0",1))
        {
                int errnum = errno;
                uerror("setenv: Couldn't set TZ: %s", strerror(errnum));
                exit(1);        
        }

        {
            int ch;

            opterr = 0; /* stops getopt() from printing to stderr */

            while ((ch = getopt(ac, av, ":vxl:p:f:q:o:i:H:h:P:")) != EOF) {
                switch (ch) {
                    case 'v':
                        logmask |= LOG_MASK(LOG_INFO);
                        (void) setulogmask(logmask);
                        break;
                    case 'x':
                        logmask |= LOG_MASK(LOG_DEBUG);
                        (void) setulogmask(logmask);
                        break;
                    case 'l':
                        logfname = optarg;
                        if (strcmp(logfname, "") == 0)
                            logfname = NULL;
                        logoptions = (logfname == NULL)
                                ? (LOG_CONS|LOG_PID)
                                : LOG_NOTIME;
                        openulog(progname, logoptions, LOG_LDM, logfname);
                        break;
                    case 'H':
                        hostname = optarg;
                        break;
                    case 'h':
                        remote = optarg;
                        break;
                    case 'p':
                        spec.pattern = optarg;
                        if (re_isPathological(spec.pattern)) {
                            unotice("Adjusting pathological regular-expression \"%s\"",
                                    spec.pattern);
                            re_vetSpec(spec.pattern);
                        }
                        break;
                    case 'f': {
                        int fterr = strfeedtypet(optarg, &spec.feedtype) ;
                        if (fterr != FEEDTYPE_OK) {
                            uerror("Bad feedtype \"%s\", %s", optarg,
                                    strfeederr(fterr)) ;
                            usage(progname);
                        }
                        break;
                    }
                    case 'q':
                        setQueuePath(optarg);
                        break;
                    case 'o':
                        toffset = atoi(optarg);
                        if(toffset == 0 && *optarg != '0') {
                            uerror("Invalid offset %s", optarg);
                            usage(progname);
                        }
                        break;
                    case 'P': {
                        char*       suffix = "";
                        long        port;

                        errno = 0;
                        port = strtol(optarg, &suffix, 0);

                        if (0 != errno || 0 != *suffix ||
                            0 >= port || 0xffff < port) {

                            uerror("Invalid port %s", optarg);
                            usage(progname);
                        }

                        remotePort = (unsigned)port;

                        break;
                    }
                    case 'i':
                        interval = atoi(optarg);
                        if (interval == 0 && *optarg != '0') {
                            uerror("Invalid interval %s", optarg);
                            usage(progname);
                        }
                        break;
                    case '?':
                        uerror("Invalid option \"%c\"", optopt);
                        usage(progname);
                        break;
                    case ':':
                        uerror("No argument for option \"%c\"", optopt);
                        usage(progname);
                        break;
                }
            } /* getopt() loop */

            if (optind != ac) {
                uerror("Invalid operand: \"%s\"", av[optind]);
                usage(progname);
            }
        } /* command-line decoding block */

        if (regcomp(&spec.rgx, spec.pattern, REG_EXTENDED|REG_NOSUB)) {
            uerror("Bad regular expression \"%s\"\n", spec.pattern);
            usage(progname);
        }

        unotice("Starting Up (%d)", getpgrp());

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

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


        /*
         * Open the product queue
         */
        status = pq_open(pqfname, PQ_READONLY, &pq);
        if(status)
        {
                if (PQ_CORRUPT == status) {
                    uerror("The product-queue \"%s\" is inconsistent\n",
                            pqfname);
                }
                else {
                    uerror("pq_open failed: %s: %s\n",
                            pqfname, strerror(status));
                }
                exit(1);
        }

        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);
        }

        while(exitIfDone(0))
        {
                if(stats_req)
                {
                        dump_statsbins();
                        stats_req = 0;
                }

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

                switch(status) {
                case 0: /* no error */
                        continue; /* N.B., other cases sleep */
                case PQUEUE_END:
                        udebug("End of Queue");
                        break;
                case EAGAIN:
                case EACCES:
                        udebug("Hit a lock");
                        break;
                default:
                        uerror("pq_sequence failed: %s (errno = %d)",
                                strerror(status), status);
                        exit(1);
                        break;
                }

                syncbinstats(hostname);

                if(interval == 0)
                {
                        done = 1;
                        break;
                }

                pq_suspend(interval);
        }

        return 0;
}