Esempio n. 1
0
/**
 * @retval 0           Success.
 * @retval LDM7_INVAL  No multicast sender child process exists.
 */
static int
terminateMcastSender(void)
{
    int status;

    /*
     * Terminate the multicast sender process by sending a SIGTERM to the
     * process group.
     */
    {
        struct sigaction oldSigact;
        struct sigaction newSigact;
        status = sigemptyset(&newSigact.sa_mask);
        CU_ASSERT_EQUAL_FATAL(status, 0);

        udebug("Setting SIGTERM action to ignore");
        newSigact.sa_flags = 0;
        newSigact.sa_handler = SIG_IGN;
        status = sigaction(SIGTERM, &newSigact, &oldSigact);
        CU_ASSERT_EQUAL_FATAL(status, 0);

        udebug("Sending SIGTERM to process group");
        status = kill(0, SIGTERM);
        CU_ASSERT_EQUAL_FATAL(status, 0);

        udebug("Restoring SIGTERM action");
        status = sigaction(SIGTERM, &oldSigact, NULL);
        CU_ASSERT_EQUAL(status, 0);
    }

    /* Reap the terminated multicast sender. */
    {
        udebug("Reaping multicast sender child process");
        const pid_t wpid = wait(&status);
        if (wpid == (pid_t)-1) {
            CU_ASSERT_EQUAL(errno, ECHILD);
            status = LDM7_INVAL;
        }
        else {
            CU_ASSERT_TRUE_FATAL(wpid > 0);
            CU_ASSERT_TRUE(WIFEXITED(status));
            CU_ASSERT_EQUAL(WEXITSTATUS(status), 0);
            status = mlsm_terminated(wpid);
            CU_ASSERT_EQUAL(status, 0);
        }
    }

    return status;
}
Esempio n. 2
0
void *decode_suomi(char *infilnam, long miss, int *iret)
{
    int ier,cdfid;
    static int isinit=0;
    suomi_struct *head;

    if(isinit == 0)
    {
        isinit = -1;
        putenv("TZ=UTC0");
        tzset();
    }

    ier = nc_open(infilnam,0,&cdfid);
    if(ier != 0)
    {
        *iret = -1;
        uerror("Could not open %s\0",infilnam);
        return(NULL);
    }
    udebug("decode_suomi %s miss %ld ier %d cdfid %d\0",infilnam,miss,ier,cdfid);


    head = decode_ncsuomi(cdfid,miss,&ier);

    ier = nc_close(cdfid);

    *iret = 0;
    return(head);
}
Esempio n. 3
0
static int
servlet_run(
    const int  servSock)
{
    /* NULL-s => not interested in receiver's address */
    int sock = accept(servSock, NULL, NULL);
    int status;

    CU_ASSERT_NOT_EQUAL_FATAL(sock, -1);

    pthread_cleanup_push(closeSocket, &sock);

    Up7 up7;
    status = up7_init(&up7, sock);
    CU_ASSERT_EQUAL_FATAL(status, 0);

    pthread_cleanup_push(destroyUp7, &up7); // calls `up7_destroy()`

    status = up7_run(&up7); // might call `svc_destroy(up7->xprt)`
    CU_ASSERT_EQUAL(status, 0);

    pthread_cleanup_pop(1); // might call `svc_destroy(up7->xprt)`
    pthread_cleanup_pop(0); // `sock` already closed

    udebug("servlet_run(): Returning");
    return 0;
}
Esempio n. 4
0
static pid_t
run_child(int argc, char *argv[])
{
        pid_t pid;

        if(ulogIsDebug())
        {
                char command[1024];
                size_t left = sizeof(command) - 1;
                int ii;

                command[0] = 0;

                for (ii = 0; ii < argc; ++ii)
                {
                        size_t  nbytes;

                        if (ii > 0) {
                                (void)strncat(command, " ", left);
                                left -= (1 <= left) ? 1 : left;
                        }

                        (void)strncat(command, argv[ii], left);
                        nbytes = strlen(argv[ii]);
                        left -= (nbytes <= left) ? nbytes : left;
                }
                udebug("exec'ing: \"%s\"", command);
        }

        pid = ldmfork();
        if(pid == -1)
        {
                log_log(LOG_ERR);
                return pid;
        }

        if(pid == 0)
        {       /* child */
                const unsigned  ulogOptions = ulog_get_options();
                const char*     ulogIdent = getulogident();
                const unsigned  ulogFacility = getulogfacility();
                const char*     ulogPath = getulogpath();

                (void)signal(SIGCHLD, SIG_DFL);
                (void)signal(SIGTERM, SIG_DFL);

                /* keep same descriptors as parent */

                /* don't let child get real privilege */
                endpriv();

                (void) execvp(argv[0], &argv[0]);
                openulog(ulogIdent, ulogOptions, ulogFacility, ulogPath);
                serror("run_child: execvp: %s", argv[0]);
                _exit(127);
        }
        /* else, parent */

        return pid;
}
Esempio n. 5
0
static void hndlr_noop(int sig)
{
#ifndef NDEBUG
        switch(sig) {
        case SIGALRM :
                udebug("SIGALRM") ;
                return ;
        case SIGCONT :
                udebug("SIGCONT") ;
                return;
        }
        udebug("hndlr_noop: unhandled signal: %d", sig) ;
#endif
        /* nothing to do, just wake up */
        return;
}
Esempio n. 6
0
static void
funcCancelled(
    void* const arg)
{
    const char* funcName = (const char*)arg;
    udebug("funcCancelled(): %s() thread cancelled", funcName);
}
Esempio n. 7
0
static void
termSigHandler(
    const int sig)
{
    udebug("Caught signal %d", sig);
    setDoneCondition();
}
Esempio n. 8
0
int *is_alive_6_svc(
        unsigned *id,
        struct svc_req *rqstp)
{
    static int alive;
    SVCXPRT * const xprt = rqstp->rq_xprt;
    int error = 0;

    alive = cps_contains((pid_t) *id);

    if (ulogIsDebug()) {
        udebug("LDM %u is %s", *id, alive ? "alive" : "dead");
    }

    if (!svc_sendreply(xprt, (xdrproc_t) xdr_bool, (caddr_t) &alive)) {
        svcerr_systemerr(xprt);

        error = 1;
    }

    if (!svc_freeargs(xprt, xdr_u_int, (caddr_t)id)) {
        uerror("Couldn't free arguments");

        error = 1;
    }

    svc_destroy(xprt);
    exit(error);

    /*NOTREACHED*/

    return NULL ;
}
Esempio n. 9
0
static void signal_handler(
    int sig)
{
    switch (sig) {
    case SIGHUP:
        udebug("SIGHUP");
        return;
    case SIGINT:
        udebug("SIGINT");
        return;
    case SIGTERM:
        udebug("SIGTERM");
        return;
    default:
        udebug("Signal %d", sig);
        return;
    }
}
Esempio n. 10
0
static void
shmfifo_print (const struct shmhandle* const shm)
{
  struct shmprefix *p;

  uerror ("My Shared Memory information:\n");
  if (shm == NULL)
    {
      uerror ("Handle is NULL!\n");
      return;
    }

  if (shm->mem == NULL)
    {
      uerror ("isn't attached to shared mem\n");
      return;
    }
  p = (struct shmprefix *) shm->mem;


  uerror ("Segment id: %d\nMem: %p\nRead pos: %d\nWrite pos: %d\n",
	  shm->sid, shm->mem, p->read, p->write);

  if (p->read == p->write)
    uerror ("No blocks in shared memory\n");
  else
    {
      void *ptr = (char *) shm->mem + p->read;
      int count = 0;
      while (ptr != (char *) shm->mem + p->write)
	{
	  struct shmbh *h = (struct shmbh *) ptr;
	  count++;
	  udebug ("block: %d ", count);
	  udebug ("size: %d ", h->sz);
/*           printf("data: \"%s\" ",(char*)ptr + sizeof(struct shmbh)); */
/*           printf("\n"); */
	  /*(char*)ptr += h->sz + sizeof(struct shmbh); */
	  ptr = (char *) ptr + h->sz + sizeof (struct shmbh);
	}
/*      printf("---\n"); */

    }
}
Esempio n. 11
0
static void
unlockMutex(void)
{
    udebug("Unlocking mutex");
    int status = pthread_mutex_unlock(&mutex);
    if (status) {
        LOG_ERRNUM0(status, "Couldn't unlock mutex");
        abortProcess();
    }
}
Esempio n. 12
0
/**
 * Sets a data-structure so that it references the shared-memory FIFO
 * associated with a (partial) key.
 *
 * @retval  0   Success. The data-structure is initialized and references the
 *              shared-memory FIFO.
 * @retval -1   \e shm is \c NULL. An error message is logged.
 * @retval -2   \e nkey is \c -1.
 * @retval -3   The shared-memory FIFO doesn't exist.
 * @retval -4   The shared-memory FIFO couldn't be accessed. An error message
 *              is logged.
 */
int shmfifo_shm_from_key(
    struct shmhandle* const     shm,    /**< Pointer to the data-structure to
                                         * be set. */
    const int                   nkey)   /**< The (partial) key associated with
                                         * the shared-memory FIFO. */
{
    int   status;

    if (shm == NULL) {
        uerror ("shm_from_key(): shm is NULL");
        status = -1;
    }
    else if (-1 == nkey) {
        status = -2;
    }
    else {
        key_t     key = (key_t)(DVBS_ID + nkey);
        int       semid = semget(key, SI_SEM_COUNT, 0660);

        if (-1 == semid) {
            status = -3;
        }
        else {
            int   sid = shmget(key, 0, 0);

            if (-1 == sid) {
                status = -3;
            }
            else {
                shm->semid = semid;
                shm->sid = sid;

                if (shmfifo_attach(shm) == -1) {
                    status = -4;
                }
                else {
                    struct shmprefix*     p = (struct shmprefix*)(shm->mem);

                    shm->privsz = p->privsz;
                    shm->sz = p->sz;

                    udebug ("look sizes %d %d\n", shm->privsz, shm->sz);

                    status = 0;           /* success */
                }                         /* got shared-memory FIFO */
            }                             /* got shared-memory ID */
        }                                 /* got semaphore */
    }                                     /* valid "shm" and "nkey" */

    return status;
}
Esempio n. 13
0
/* get_cpio_addr -  Routine to get cpio address */
int get_cpio_addr(char *addr){
	int i_row;
	for(i_row=0; i_row < NUM_CPIO_ENTRIES ; i_row++){
		if(!strcmp(cpio_tbl[i_row].mcast_addr,addr)){
			break;
		}
	}	
	if(i_row >= NUM_CPIO_ENTRIES){
		i_row = -1;
		uerror("\n Fail to find match for cpio addr=%s\n",addr);
	}
        udebug("returning i_row = %d",i_row);
	return (i_row);
}
Esempio n. 14
0
static pid_t
run_child(int argc, char *argv[])
{
        pid_t pid;

        if(ulogIsDebug())
        {
                char command[1024];
                char *cp = command;
                int ii = 0;
                command[0] = 0;

                while (ii < argc)
                {
                        strcpy(cp, argv[ii]);   
                        cp += strlen(argv[ii]);
                        if(++ii == argc)
                                break;
                        *cp++ = ' ';
                        *cp = 0;
                }
                udebug("exec'ing: \"%s\"", command);
        }

        pid = ldmfork();
        if(pid == -1)
        {
                log_log(LOG_ERR);
                return pid;
        }

        if(pid == 0)
        {       /* child */
                (void)signal(SIGCHLD, SIG_DFL);
                (void)signal(SIGTERM, SIG_DFL);

                /* keep same descriptors as parent */

                /* don't let child get real privilege */
                endpriv();

                (void) execvp(argv[0], &argv[0]);
                serror("run_child: execvp: %s", argv[0]);
                _exit(127);
        }
        /* else, parent */

        return pid;
}
Esempio n. 15
0
/*
 * Logs shared-memory usage statistics at level DEBUG.
 *
 * Precondition:
 *      The FIFO is locked by this process. An error-message is logged if it
 *      isn't.
 * Arguments:
 *      shm             Pointer to the shared-memory FIFO data-structure.
 */
static void
shmfifo_printmemstatus(
    const struct shmhandle* const       shm)
{
    if (ulogIsDebug()) {
        struct shmprefix* p = (struct shmprefix*)shm->mem;

        (void)checkLocked(shm);
        udebug
          ("<%d> c: %d sz: %d, r: %d, w: %d, used: %d, free: %d, maxblock: %d",
           getpid (), p->counter, shm->sz, p->read, p->write,
           shmfifo_ll_memused (shm), shmfifo_ll_memfree (shm),
           shmfifo_ll_memfree (shm) - sizeof (struct shmbh));
    }
}
Esempio n. 16
0
/*
 * Send a data-product to an LDM using the LDM-6 HEREIS message.
 *
 * Arguments:
 *      proxy           Pointer to the LDM proxy data-structure.
 *      product         Pointer to the data-product to be sent.
 * Return:
 *      0               Success.
 *      LP_TIMEDOUT     RPC timeout. "log_start()" called.
 *      LP_RPC_ERROR    RPC error. "log_start()" called.
 *      LP_LDM_ERROR    LDM error. "log_start()" called.
 */
static LdmProxyStatus
my_hereis_6(
    LdmProxy* const     proxy,
    product* const      product)
{
    LdmProxyStatus      status = 0;     /* success */

    udebug("Sending file via HEREIS_6");

    if (NULL == hereis_6(product, proxy->clnt)) {
        status = getStatus(proxy, "HEREIS_6", &product->info);
    }

    return status;
}
Esempio n. 17
0
static void
setDoneCondition(void)
{
    lockMutex();

    done = 1;
    udebug("Signaling condition variable");
    int status = pthread_cond_broadcast(&cond);
    if (status) {
        LOG_ERRNUM0(status, "Couldn't signal condition variable");
        abortProcess();
    }

    unlockMutex();
}
Esempio n. 18
0
/**
 * Called by `pthread_create()`. The thread is cancelled by
 * `sender_terminate()`.
 *
 * @param[in] arg  Pointer to sender.
 * @retval    &0   Success. Input end of sender's termination pipe(2) is closed.
 */
static void*
sender_run(
    void* const arg)
{
    Sender* const sender = (Sender*)arg;
    static int    status;

    pthread_cleanup_push(freeLogging, NULL);

    const int     servSock = sender->sock;
    struct pollfd fds;
    fds.fd = servSock;
    fds.events = POLLIN;

    for (;;) {
        status = poll(&fds, 1, -1); // `-1` => indefinite timeout

        int cancelState;
        (void)pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelState);

        if (0 > status)
            break;
        if (fds.revents & POLLHUP) {
            status = 0;
            break;
        }
        if (fds.revents & POLLIN) {
            status = servlet_run(servSock);

            if (status) {
                LOG_ADD0("servlet_run() failure");
                break;
            }
        }

        (void)pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &cancelState);
    } // `poll()` loop

    /* Because the current thread is ending: */
    (status && !done)
    ? log_log(LOG_ERR)
    : log_clear(); // don't care about errors if termination requested

    pthread_cleanup_pop(1); // calls `log_free()`

    udebug("sender_run(): Returning &%d", status);
    return &status;
}
Esempio n. 19
0
static void
waitForDoneCondition(void)
{
    lockMutex();

    while (!done) {
        udebug("Waiting on condition variable");
        int status = pthread_cond_wait(&cond, &mutex);
        if (status) {
            LOG_ERRNUM0(status, "Couldn't wait on condition variable");
            abortProcess();
        }
    }

    unlockMutex();
}
Esempio n. 20
0
/*
 * Sends a data-product to an LDM using the LDM-6 COMINGSOON and BLOCKDATA
 * messages.
 *
 * Arguments:
 *      proxy           Pointer to the LDM proxy data-structure.
 *      product         Pointer to the data-product to be sent.
 * Return:
 *      0               Success.
 *      LP_UNWANTED     Data-product was unwanted.
 *      LP_TIMEDOUT     The RPC call timed-out. "log_start()" called.
 *      LP_RPC_ERROR    RPC error. "log_start()" called.
 *      LP_LDM_ERROR    LDM error. "log_start()" called.
 */
static LdmProxyStatus
my_csbd_6(
    LdmProxy* const     proxy,
    product* const      product)
{
    LdmProxyStatus      status = 0;     /* success */
    CLIENT* const       clnt = proxy->clnt;
    prod_info* const    info = &product->info;
    const unsigned      size = info->sz;
    comingsoon_reply_t* reply;
    comingsoon_args     soonArg;

    udebug("Sending file via COMINGSOON_6/BLKDATA_6");

    soonArg.infop = info;
    soonArg.pktsz = size;
    
    reply = comingsoon_6(&soonArg, clnt);

    if (NULL == reply) {
        status = getStatus(proxy, "COMINGSOON_6", &product->info);
    }
    else {
        if (DONT_SEND == *reply) {
            status = LP_UNWANTED;
        }
        else if (0 != *reply) {
            LOG_START1("Unexpected reply from LDM: %s", s_ldm_errt(*reply));
            status = LP_LDM_ERROR;
        }
        else {
            datapkt packet;

            packet.signaturep = (signaturet*)&info->signature;
            packet.pktnum = 0;
            packet.data.dbuf_len = size;
            packet.data.dbuf_val = product->data;

            if (NULL == blkdata_6(&packet, clnt))
                status = getStatus(proxy, "BLKDATA_6", &product->info);
        }
    }

    return status;
}
Esempio n. 21
0
int peek_ahead(xbuf *buf)
{
int i, j, k, ic[4], isstart=1;
static int IC[4]={SOH, CR, CR, NL};
static int TC[4]={CR, CR, NL, ETX};
static int UH[4]={NL, SOH, CR, CR};
/*
 * If there are at least 4 more characters in the buffer, and
 * they are not the start sequence for the next product, then
 * we may still be in the previous product. If there are fewer
 * than 4 characters in the buffer, assume we did find the end.
 */

for(i=0;i<4;i++)
   {
   ic[i] = nextc(buf); j = i;
   if(ic[i] == EOB) 
      {
      isstart = 1;
      break;
      }
   if((ic[i] != TC[i])&&(ic[i] != IC[i])&&(ic[i] != UH[i]))
      isstart = 0;
   }

for(i=j;i>=0;i--)
   {
   if(ic[i] != EOB)
      {
      k = unnextc(buf,ic[i]);
      if(k != ic[i])
         uerror("Error in peek_ahead unnext: %d %d\0",ic[i],k);
      }
   if(isstart == 0)
      udebug("Peek_ahead check %d %d\0",i,ic[i]);
   }

if(isstart)
   return(1);
else
   return(0);
}
Esempio n. 22
0
static int
doOne(const prod_info *infop, const void *datap)
{
        struct product prod;
        int status = ENOERR;

        if(ulogIsDebug())
                udebug("%s", s_prod_info(NULL, 0, infop, 1));
        
        prod.info = *infop;
        prod.data = (void *)datap; /* cast away const */

        nsplit++; /* ?? Do it here on only on success ?? */

        status = pq_insertNoSig(opq, &prod);
        if(status == ENOERR)
        {
                return status; /* Normal return */
        }

        /* else */
        if(status == PQUEUE_DUP)
        {
                ndups++;
                if(ulogIsVerbose())
                        uinfo("Product already in queue: %s",
                                s_prod_info(NULL, 0, &prod.info,
                                         ulogIsDebug()));
                return status;
        }

        /* else, error */
        uerror("pq_insert: %s\n", strerror(status));

        return status;
}
Esempio n. 23
0
File: ldmd.c Progetto: dgaer/LDM
int main(
        int ac,
        char* av[])
{
    const char* pqfname = getQueuePath();
    int status;
    int doSomething = 1;
    in_addr_t ldmIpAddr = (in_addr_t) htonl(INADDR_ANY );
    unsigned ldmPort = LDM_PORT;

    ensureDumpable();

    /*
     * 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_WARNING)
                | LOG_MASK(LOG_NOTICE);

        opterr = 1;

        while ((ch = getopt(ac, av, "I:vxl:nq:o:P:M:m:t:")) != EOF) {
            switch (ch) {
            case 'I': {
                in_addr_t ipAddr = inet_addr(optarg);

                if ((in_addr_t) -1 == ipAddr) {
                    (void) fprintf(stderr, "Interface specification \"%s\" "
                            "isn't an IP address\n", optarg);
                    exit(1);
                }

                ldmIpAddr = ipAddr;

                break;
            }
            case 'v':
                logmask |= LOG_MASK(LOG_INFO);
                break;
            case 'x':
                logmask |= LOG_MASK(LOG_DEBUG);
                break;
            case 'l':
                logfname = optarg;
                break;
            case 'q':
                pqfname = optarg;
                setQueuePath(optarg);
                break;
            case 'o':
                toffset = atoi(optarg);
                if (toffset == 0 && *optarg != '0') {
                    (void) fprintf(stderr, "%s: invalid offset %s\n", av[0],
                            optarg);
                    usage(av[0]);
                }
                break;
            case 'P': {
                unsigned port;
                int      nbytes;
                if (sscanf(optarg, "%5u %n", &port, &nbytes) != 1 ||
                        0 != optarg[nbytes] || port > 0xffff) {
                    (void)fprintf(stderr, "%s: invalid port number: %s\n",
                            av[0], optarg);
                    usage(av[0]);
                }
                ldmPort = port;
                break;
            }
            case 'M': {
                int max = atoi(optarg);
                if (max < 0) {
                    (void) fprintf(stderr,
                            "%s: invalid maximum number of clients %s\n", av[0],
                            optarg);
                    usage(av[0]);
                }
                maxClients = max;
                break;
            }
            case 'm':
                max_latency = atoi(optarg);
                if (max_latency <= 0) {
                    (void) fprintf(stderr, "%s: invalid max_latency %s\n",
                            av[0], optarg);
                    usage(av[0]);
                }
                break;
            case 'n':
                doSomething = 0;
                break;
            case 't':
                rpctimeo = (unsigned) atoi(optarg);
                if (rpctimeo == 0 || rpctimeo > 32767) {
                    (void) fprintf(stderr, "%s: invalid timeout %s", av[0],
                            optarg);
                    usage(av[0]);
                }
                break;
            case '?':
                usage(av[0]);
                break;
            } /* "switch" statement */
        } /* argument loop */

        if (ac - optind == 1)
            setLdmdConfigPath(av[optind]);
        (void) setulogmask(logmask);

        if (toffset != TOFFSET_NONE && toffset > max_latency) {
            (void) fprintf(stderr,
                    "%s: invalid toffset (%d) > max_latency (%d)\n", av[0],
                    toffset, max_latency);
            usage(av[0]);
        }
    } /* command-line argument decoding */

    if (logfname != NULL && *logfname == '-') {
        /*
         * Logging to standard error stream. Assume interactive.
         *
         * Make this process a process group leader so that all child processes
         * (e.g., upstream LDM, downstream LDM, pqact(1)s) will be signaled by
         * `cleanup()`.
         */
        (void)setpgid(0, 0); // can't fail
    }
#ifndef DONTFORK
    else {
        /*
         * Logging to system logging daemon or file. Make this process a daemon.
         */
        pid_t pid;
        pid = ldmfork();
        if (pid == -1) {
            log_add("Couldn't fork LDM daemon");
            log_log(LOG_ERR);
            exit(2);
        }

        if (pid > 0) {
            /* parent */
            (void) printf("%ld\n", (long) pid);
            exit(0);
        }

        /* detach the child from parents process group ?? */
        (void) setsid(); // also makes this process a process group leader
    }
#endif

    /*
     * Initialize logger.
     * (Close fd 2 to remap stderr to the logfile, when
     * appropriate. I know, this is anal.)
     */
    if (logfname == NULL )
        (void) fclose(stderr);
    else if (!(logfname[0] == '-' && logfname[1] == 0))
        (void) close(2);
    (void) openulog(ubasename(av[0]), (LOG_CONS | LOG_PID), LOG_LDM, logfname);
    unotice("Starting Up (version: %s; built: %s %s)", PACKAGE_VERSION,
            __DATE__, __TIME__);

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

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

    /*
     * Close the standard input and standard output streams because they won't
     * be used (more anality :-)
     */
    (void) fclose(stdout);
    (void) fclose(stdin);

    /*
     * Vet the configuration file.
     */
    udebug("main(): Vetting configuration-file");
    if (read_conf(getLdmdConfigPath(), 0, ldmIpAddr, ldmPort) != 0) {
        log_log(LOG_ERR);
        exit(1);
    }

    if (doSomething) {
        int sock = -1;

        if (lcf_isServerNeeded()) {
            /*
             * Create a service portal. This should be done before anything is
             * created because this is the function that relinquishes superuser
             * privileges.
             */
            udebug("main(): Creating service portal");
            if (create_ldm_tcp_svc(&sock, ldmIpAddr, ldmPort) != ENOERR) {
                /* error reports are emitted from create_ldm_tcp_svc() */
                exit(1);
            }
            udebug("tcp sock: %d", sock);
        }

        /*
         * Verify that the product-queue can be open for writing.
         */
        udebug("main(): Opening product-queue");
        if ((status = pq_open(pqfname, PQ_DEFAULT, &pq))) {
            if (PQ_CORRUPT == status) {
                uerror("The product-queue \"%s\" is inconsistent", pqfname);
            }
            else {
                uerror("pq_open failed: %s: %s", pqfname, strerror(status));
            }
            exit(1);
        }
        (void) pq_close(pq);
        pq = NULL;

        /*
         * Create the sharable database of upstream LDM metadata.
         */
        udebug("main(): Creating shared upstream LDM database");
        if ((status = uldb_delete(NULL))) {
            if (ULDB_EXIST == status) {
                log_clear();
            }
            else {
                LOG_ADD0(
                        "Couldn't delete existing shared upstream LDM database");
                log_log(LOG_ERR);
                exit(1);
            }
        }
        if (uldb_create(NULL, maxClients * 1024)) {
            LOG_ADD0("Couldn't create shared upstream LDM database");
            log_log(LOG_ERR);
            exit(1);
        }

        /*
         * Initialize the multicast sender map.
         */
#if WANT_MULTICAST
        if (msm_init()) {
            LOG_ADD0("Couldn't initialize multicast LDM sender map");
            log_log(LOG_ERR);
            exit(1);
        }
#endif

        /*
         * Re-read (and execute) the configuration file (downstream LDM-s are
         * started).
         */
        lcf_free(); // Start with a clean slate to prevent duplicates
        udebug("main(): Reading configuration-file");
        if (read_conf(getLdmdConfigPath(), 1, ldmIpAddr, ldmPort) != 0) {
            log_log(LOG_ERR);
            exit(1);
        }

        if (lcf_isServerNeeded()) {
            /*
             * Serve
             */
            udebug("main(): Serving socket");
            sock_svc(sock);
        }
        else {
            /*
             * Wait until all child processes have terminated.
             */
            while (reap(-1, 0) > 0)
                /* empty */;
        }
    }   // configuration-file will be executed

    return (0);
}
Esempio n. 24
0
File: ldmd.c Progetto: dgaer/LDM
/*
 * Create a TCP socket, bind it to a port, call 'listen' (we are a
 * server), and inform the portmap (rpcbind) service.  Does _not_ create
 * an RPC SVCXPRT or do the xprt_register() or svc_fds() stuff.
 *
 * Arguments:
 *      sockp           Pointer to socket (file) descriptor.  Set on and only on
 *                      success.
 *      localIpAddr     The IP address, in network byte order, of the 
 *                      local interface to use.  May be htonl(INADDR_ANY).
 *      localPort       The number of the local port on which the LDM server
 *                      should listen.
 * Returns:
 *      0               Success.
 *      EACCES          The process doesn't have appropriate privileges.
 *      EADDRINUSE      The local address is already in use.
 *      EADDRNOTAVAIL   The specified address is not available from the local
 *                      machine.
 *      EAFNOSUPPORT    The system doesn't support IP.
 *      EMFILE          No more file descriptors are available for this process.
 *      ENFILE          No more file descriptors are available for the system.
 *      ENOBUFS         Insufficient resources were available in the system.
 *      ENOMEM          Insufficient memory was available.
 *      ENOSR           There were insufficient STREAMS resources available.
 *      EOPNOTSUPP      The socket protocol does not support listen().
 *      EPROTONOSUPPORT The system doesn't support TCP.
 */
static int create_ldm_tcp_svc(
        int* sockp,
        in_addr_t localIpAddr,
        unsigned localPort)
{
    int error = 0; /* success */
    int sock;

    /*
     * Get a TCP socket.
     */
    udebug("create_ldm_tcp_svc(): Getting TCP socket");
    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock < 0) {
        error = errno;

        serror("Couldn't get socket for server");
    }
    else {
        unsigned short port = (unsigned short) localPort;
        struct sockaddr_in addr;
        socklen_t len = sizeof(addr);

        /*
         * Eliminate problem with EADDRINUSE for reserved socket.
         * We get this if an upstream data source hasn't tried to
         * write on the other end and we are in FIN_WAIT_2
         */
        udebug("create_ldm_tcp_svc(): Eliminating EADDRINUSE problem.");
        {
            int on = 1;

            (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on,
                    sizeof(on));
        }

        (void) memset(&addr, 0, len);
        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = localIpAddr;
        addr.sin_port = (short) htons((short) port);

        /*
         * If privilege available, set it so we can bind to the port for LDM
         * services.  Also needed for the pmap_set() call.
         */
        udebug("create_ldm_tcp_svc(): Getting root privs");
        rootpriv();

        udebug("create_ldm_tcp_svc(): Binding socket");
        if (bind(sock, (struct sockaddr *) &addr, len) < 0) {
            error = errno;

            serror("Couldn't obtain local address %s:%u for server",
                    inet_ntoa(addr.sin_addr), (unsigned) port);

            if (error == EACCES) {
                error = 0;
                addr.sin_port = 0; /* let system assign port */

                if (bind(sock, (struct sockaddr *) &addr, len) < 0) {
                    error = errno;

                    serror("Couldn't obtain local address %s:* for server",
                            inet_ntoa(addr.sin_addr));
                }
            } /* requested port is reserved */
        } /* couldn't bind to requested port */

        if (!error) {
            /*
             * Get the local address associated with the bound socket.
             */
            udebug("create_ldm_tcp_svc(): Calling getsockname()");
            if (getsockname(sock, (struct sockaddr *) &addr, &len) < 0) {
                error = errno;

                serror("Couldn't get local address of server's socket");
            }
            else {
                port = (short) ntohs((short) addr.sin_port);

                unotice("Using local address %s:%u", inet_ntoa(addr.sin_addr),
                        (unsigned) port);

                udebug("create_ldm_tcp_svc(): Calling listen()");
                if (listen(sock, 32) != 0) {
                    error = errno;

                    serror("Couldn't listen() on server's socket");
                }
                else {
                    /*
                     * Register with the portmapper if it's running.  The
                     * check to see if it's running is made because on a
                     * FreeBSD 4.7-STABLE system, a pmap_set() call takes
                     * one minute even if the portmapper isn't running.
                     */
                    udebug("create_ldm_tcp_svc(): Checking portmapper");
                    if (local_portmapper_running()) {
                        udebug("create_ldm_tcp_svc(): Registering");

                        if (pmap_set(LDMPROG, 6, IPPROTO_TCP, port) == 0) {
                            uwarn("Can't register TCP service %lu on "
                                    "port %u", LDMPROG, (unsigned) port);
                            uwarn("Downstream LDMs won't be able to "
                                    "connect via the RPC portmapper daemon "
                                    "(rpcbind(8), portmap(8), etc.)");
                        }
                        else {
                            portIsMapped = 1;

                            (void) pmap_set(LDMPROG, 5, IPPROTO_TCP, port);
                        }
                    } /* a local portmapper is running */

                    /*
                     * Done with the need for privilege.
                     */
                    udebug("create_ldm_tcp_svc(): Releasing root privs");
                    unpriv();

                    *sockp = sock;
                } /* listen() success */
            } /* getsockname() success */
        } /* "sock" is bound to local address */

        if (error)
            (void) close(sock);
    } /* "sock" is open */

    return error;
}
Esempio n. 25
0
hiya_reply_t*
hiya_6_svc(
        prod_class_t *offered,
        struct svc_req *rqstp)
{
    const char* const pqfname = getQueuePath();
    static hiya_reply_t reply;
    SVCXPRT * const xprt = rqstp->rq_xprt;
    struct sockaddr_in *upAddr = (struct sockaddr_in*) svc_getcaller(xprt);
    const char *upName = hostbyaddr(upAddr);
    int error;
    int isPrimary;
    unsigned int maxHereis;
    static prod_class_t *accept;

    /*
     * Open the product-queue for writing.  It will be closed by cleanup()
     * during process termination.
     */
    if (pq) {
        (void) pq_close(pq);
        pq = NULL;
    }
    error = pq_open(pqfname, PQ_DEFAULT, &pq);
    if (error) {
        err_log_and_free(ERR_NEW2(error, NULL,
                "Couldn't open product-queue \"%s\" for writing: %s",
                pqfname,
                PQ_CORRUPT == error
                ? "The product-queue is inconsistent"
                : strerror(error)), ERR_FAILURE);
        svcerr_systemerr(xprt);
        svc_destroy(xprt);
        exit(error);
    }

    /* else */

    error = down6_init(upName, upAddr, pqfname, pq);
    if (error) {
        uerror("Couldn't initialize downstream LDM");
        svcerr_systemerr(xprt);
        svc_destroy(xprt);
        exit(error);
    }
    else {
        uinfo("Downstream LDM initialized");
    }

    /*
     * The previous "accept" is freed here -- rather than freeing the
     * soon-to-be-allocated "accept" at the end of its block -- because it can
     * be used in the reply.
     */
    if (accept) {
        free_prod_class(accept); /* NULL safe */
        accept = NULL;
    }

    error = lcf_reduceToAcceptable(upName, inet_ntoa(upAddr->sin_addr), offered,
            &accept, &isPrimary);

    maxHereis = isPrimary ? UINT_MAX : 0;

    if (error) {
        serror("Couldn't validate HIYA");
        svcerr_systemerr(xprt);
        svc_destroy(xprt);
        exit(error);
    }
    else {
        if (ulogIsDebug())
            udebug("intersection: %s", s_prod_class(NULL, 0, accept));

        if (accept->psa.psa_len == 0) {
            uwarn("Empty intersection of HIYA offer from %s (%s) and ACCEPT "
                    "entries", upName, s_prod_class(NULL, 0, offered));
            svcerr_weakauth(xprt);
            svc_destroy(xprt);
            exit(0);
        }
        else {
            error = down6_set_prod_class(accept);

            if (error) {
                if (DOWN6_SYSTEM_ERROR == error) {
                    serror("Couldn't set product class: %s",
                            s_prod_class(NULL, 0, accept));
                }
                else {
                    uerror("Couldn't set product class: %s",
                            s_prod_class(NULL, 0, accept));
                }

                svcerr_systemerr(xprt);
                svc_destroy(xprt);
                exit(EXIT_FAILURE);
            }

            /* else */

            if (clss_eq(offered, accept)) {
                unotice("hiya6: %s", s_prod_class(NULL, 0, offered));

                reply.code = OK;
                reply.hiya_reply_t_u.max_hereis = maxHereis;
            }
            else {
                if (ulogIsVerbose()) {
                    char off[512];
                    char acc[512];

                    (void) s_prod_class(off, sizeof(off), offered), (void) s_prod_class(
                            acc, sizeof(acc), accept);

                    uinfo("hiya6: RECLASS: %s -> %s", off, acc);
                }

                reply.code = RECLASS;
                reply.hiya_reply_t_u.feedPar.prod_class = accept;
                reply.hiya_reply_t_u.feedPar.max_hereis = maxHereis;
            }
        } /* product-intersection != empty set */
    } /* successful acl_check_hiya() */

    return &reply;
}
Esempio n. 26
0
int main(
        int ac,
        char* av[])
{
    const char* pqfname = getQueuePath();
    int sock = -1;
    int status;
    int doSomething = 1;
    in_addr_t locIpAddr = (in_addr_t) htonl(INADDR_ANY );
    unsigned ldmPort = LDM_PORT;

    ensureDumpable();

    /*
     * 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_WARNING)
                | LOG_MASK(LOG_NOTICE);

        opterr = 1;

        while ((ch = getopt(ac, av, "I:vxl:nq:o:P:M:m:t:")) != EOF) {
            switch (ch) {
            case 'I': {
                in_addr_t ipAddr = inet_addr(optarg);

                if ((in_addr_t) -1 == ipAddr) {
                    (void) fprintf(stderr, "Interface specification \"%s\" "
                            "isn't an IP address\n", optarg);
                    exit(1);
                }

                locIpAddr = ipAddr;

                break;
            }
            case 'v':
                logmask |= LOG_MASK(LOG_INFO);
                break;
            case 'x':
                logmask |= LOG_MASK(LOG_DEBUG);
                break;
            case 'l':
                logfname = optarg;
                break;
            case 'q':
                pqfname = optarg;
                setQueuePath(optarg);
                break;
            case 'o':
                toffset = atoi(optarg);
                if (toffset == 0 && *optarg != '0') {
                    (void) fprintf(stderr, "%s: invalid offset %s\n", av[0],
                            optarg);
                    usage(av[0]);
                }
                break;
            case 'P': {
                char* suffix = "";
                long port;

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

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

                    (void) fprintf(stderr, "%s: invalid port %s\n", av[0],
                            optarg);
                    usage(av[0]);
                }

                ldmPort = (unsigned) port;

                break;
            }
            case 'M': {
                int max = atoi(optarg);
                if (max < 0) {
                    (void) fprintf(stderr,
                            "%s: invalid maximum number of clients %s\n", av[0],
                            optarg);
                    usage(av[0]);
                }
                maxClients = max;
                break;
            }
            case 'm':
                max_latency = atoi(optarg);
                if (max_latency <= 0) {
                    (void) fprintf(stderr, "%s: invalid max_latency %s\n",
                            av[0], optarg);
                    usage(av[0]);
                }
                break;
            case 'n':
                doSomething = 0;
                break;
            case 't':
                rpctimeo = (unsigned) atoi(optarg);
                if (rpctimeo == 0 || rpctimeo > 32767) {
                    (void) fprintf(stderr, "%s: invalid timeout %s", av[0],
                            optarg);
                    usage(av[0]);
                }
                break;
            case '?':
                usage(av[0]);
                break;
            } /* "switch" statement */
        } /* argument loop */

        if (ac - optind == 1)
            setLdmdConfigPath(av[optind]);
        (void) setulogmask(logmask);

        if (toffset != TOFFSET_NONE && toffset > max_latency) {
            (void) fprintf(stderr,
                    "%s: invalid toffset (%d) > max_latency (%d)\n", av[0],
                    toffset, max_latency);
            usage(av[0]);
        }
    } /* command-line argument decoding */

#ifndef DONTFORK
    /* 
     * daemon behavior
     *
     * Background the process unless we are logging to stderr, in which
     * case we assume interactive.
     */
    if (logfname == NULL || *logfname != '-') {
        /* detach */
        pid_t pid;
        pid = ldmfork();
        if (pid == -1) {
            log_add("Couldn't fork LDM daemon");
            log_log(LOG_ERR);
            exit(2);
        }

        if (pid > 0) {
            /* parent */
            (void) printf("%ld\n", (long) pid);
            exit(0);
        }

        /* detach the child from parents process group ?? */
        (void) setsid();
    }
#endif

    /*
     * Initialize logger.
     * (Close fd 2 to remap stderr to the logfile, when
     * appropriate. I know, this is anal.)
     */
    if (logfname == NULL )
        (void) fclose(stderr);
    else if (!(logfname[0] == '-' && logfname[1] == 0))
        (void) close(2);
    (void) openulog(ubasename(av[0]), (LOG_CONS | LOG_PID), LOG_LDM, logfname);
    unotice("Starting Up (version: %s; built: %s %s)", PACKAGE_VERSION,
            __DATE__, __TIME__);

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

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

    /*
     * Close the standard input and standard output streams because they won't
     * be used (more anality :-)
     */
    (void) fclose(stdout);
    (void) fclose(stdin);

    if (!doSomething) {
        /*
         * Vet the configuration file.
         */
        udebug("main(): Vetting configuration-file");
        if (read_conf(getLdmdConfigPath(), doSomething, ldmPort) != 0) {
            log_log(LOG_ERR);
            exit(1);
        }
    }
    else {
        /*
         * Create a service portal. This should be done before anything is
         * created because this is the function that relinquishes superuser
         * privileges.
         */
        udebug("main(): Creating service portal");
        if (create_ldm_tcp_svc(&sock, locIpAddr, ldmPort) != ENOERR) {
            /* error reports are emitted from create_ldm_tcp_svc() */
            exit(1);
        }
        udebug("tcp sock: %d", sock);

        /*
         * Verify that the product-queue can be open for writing.
         */
        udebug("main(): Opening product-queue");
        if (status = pq_open(pqfname, PQ_DEFAULT, &pq)) {
            if (PQ_CORRUPT == status) {
                uerror("The product-queue \"%s\" is inconsistent", pqfname);
            }
            else {
                uerror("pq_open failed: %s: %s", pqfname, strerror(status));
            }
            exit(1);
        }
        (void) pq_close(pq);
        pq = NULL;

        /*
         * Create the sharable database of upstream LDM metadata.
         */
        udebug("main(): Creating shared upstream LDM database");
        if (status = uldb_delete(NULL)) {
            if (ULDB_EXIST == status) {
                log_clear();
            }
            else {
                LOG_ADD0(
                        "Couldn't delete existing shared upstream LDM database");
                log_log(LOG_ERR);
                exit(1);
            }
        }
        if (uldb_create(NULL, maxClients * 1024)) {
            LOG_ADD0("Couldn't create shared upstream LDM database");
            log_log(LOG_ERR);
            exit(1);
        }

        /*
         * Read the configuration file (downstream LDM-s are started).
         */
        udebug("main(): Reading configuration-file");
        if (read_conf(getLdmdConfigPath(), doSomething, ldmPort) != 0) {
            log_log(LOG_ERR);
            exit(1);
        }

        /*
         * Serve
         */
        udebug("main(): Serving socket");
        sock_svc(sock);
    } /* "doSomething" is true */

    return (0);
}
Esempio n. 27
0
sta_struct *decode_fsl2(int cdfid, long miss, int *iret)
{
int ndims,nvars,natts,nunlim;
int tmpint[20];
int ier,i,j,unlimsiz;
int wmoStaNum_id,wmoStaNum,staName_id;
char staName[20];
int staLat_id,staLon_id,staElev_id,timeObs_id,levels_id;
int uwnd_id,vwnd_id,wwnd_id,uv_qual_id,w_qual_id,levelMode_id;
int sigma_uv_id,sigma_w_id;
int sfc_sped_id,sfc_drct_id,sfc_pres_id,sfc_temp_id,sfc_relh_id,sfc_rain_id;
float staLat,staLon,staElev,level;
float uwnd,vwnd,wwnd,sigma_uv,sigma_w;
int uv_qual,w_qual,levelMode;
float sfc_sped,sfc_drct,sfc_pres,sfc_temp,sfc_relh,sfc_rain;
double timeObs;
nc_type xtype;
int nvdims,nvatts,time_interval;
size_t dimsiz,var_i[5],vc[5],namelen;
float ufill,vfill,wfill;
float pfill,tfill,dfill,sfill,rfill,rrfill;
float fmiss,e;

time_t obs_time;
char timestr[80],*atttext;
int year,month,day,hour,minute;
struct tm *gmt_time=NULL,new_time;
sta_struct *stadat,*head=NULL;
prof_data *plev,*plast;


udebug("decoding fsl2\0");
fmiss = (float)miss;

ier = nc_inq(cdfid,&ndims,&nvars,&natts,&nunlim);

ier = nc_inq_atttype(cdfid,NC_GLOBAL,"avgTimePeriod",&xtype);
if(xtype == NC_CHAR)
   {
   ier = nc_inq_attlen(cdfid,NC_GLOBAL,"avgTimePeriod",&namelen);
   udebug("AvgTimPeriod name len is %d",namelen);
   atttext = (char *)malloc(namelen + 1);
   ier = nc_get_att_text(cdfid,NC_GLOBAL,"avgTimePeriod",atttext);
   sscanf(atttext,"%d",tmpint);
   udebug("AvgTimPeriod type is NC_CHAR %s VAL %d",atttext,tmpint[0]);
   free(atttext);
   }
else
   {
   ier = nc_get_att_int(cdfid,NC_GLOBAL,"avgTimePeriod",tmpint);
   }
udebug("AvgTimPeriod is %d\0",tmpint[0]);
time_interval = tmpint[0];

ier = 0;
ier += nc_inq_varid(cdfid,"wmoStaNum",&wmoStaNum_id);
ier += nc_inq_varid(cdfid,"staName",&staName_id);
ier += nc_inq_varid(cdfid,"staLat",&staLat_id);
ier += nc_inq_varid(cdfid,"staLon",&staLon_id);
ier += nc_inq_varid(cdfid,"staElev",&staElev_id);
ier += nc_inq_varid(cdfid,"timeObs",&timeObs_id);
ier += nc_inq_varid(cdfid,"levels",&levels_id);
ier += nc_inq_varid(cdfid,"uComponent",&uwnd_id);
ier += nc_inq_varid(cdfid,"vComponent",&vwnd_id);
ier += nc_inq_varid(cdfid,"wComponent",&wwnd_id);
ier += nc_get_att_float(cdfid,uwnd_id,"_FillValue",&ufill);
ier += nc_get_att_float(cdfid,vwnd_id,"_FillValue",&vfill);
ier += nc_get_att_float(cdfid,wwnd_id,"_FillValue",&wfill);

ier += nc_inq_varid(cdfid,"uvQualityCode",&uv_qual_id);
ier += nc_inq_varid(cdfid,"wQualityCode",&w_qual_id);
ier += nc_inq_varid(cdfid,"windSpeedStdDev",&sigma_uv_id);
ier += nc_inq_varid(cdfid,"wStdDev",&sigma_w_id);
ier += nc_inq_varid(cdfid,"levelMode",&levelMode_id);

ier += nc_inq_varid(cdfid,"windSpeedSfc",&sfc_sped_id);
ier += nc_inq_varid(cdfid,"windDirSfc",&sfc_drct_id);
ier += nc_inq_varid(cdfid,"pressure",&sfc_pres_id);
ier += nc_inq_varid(cdfid,"temperature",&sfc_temp_id);
ier += nc_inq_varid(cdfid,"relHumidity",&sfc_relh_id);
ier += nc_inq_varid(cdfid,"rainRate",&sfc_rain_id);
ier += nc_get_att_float(cdfid,sfc_sped_id,"_FillValue",&sfill);
ier += nc_get_att_float(cdfid,sfc_drct_id,"_FillValue",&dfill);
ier += nc_get_att_float(cdfid,sfc_pres_id,"_FillValue",&pfill);
ier += nc_get_att_float(cdfid,sfc_temp_id,"_FillValue",&tfill);
ier += nc_get_att_float(cdfid,sfc_relh_id,"_FillValue",&rfill);
ier += nc_get_att_float(cdfid,sfc_rain_id,"_FillValue",&rrfill);

if(ier != 0)
   {
   uerror("could not get station information\0");
   *iret = -1;
   return(NULL);
   }

ier = nc_inq_vardimid(cdfid,staName_id,tmpint);
ier += nc_inq_dimlen(cdfid,tmpint[1],&namelen);

tmpint[0] = 0;tmpint[1] = 0;
ier += nc_inq_var(cdfid,wmoStaNum_id,NULL, &xtype, &nvdims, tmpint, &nvatts);
ier += nc_inq_dimlen(cdfid,tmpint[0],&dimsiz);
if(ier == 0)
   unlimsiz = dimsiz;
   for(i=0;i<unlimsiz;i++)
      {
      var_i[0] = i; var_i[1] = 0; vc[0] = 1; vc[1] = namelen-1;
      memset(staName,'\0',20);
      ier = nc_get_vara_text(cdfid,staName_id,var_i,vc,staName);
      ier = nc_get_var1_int(cdfid,wmoStaNum_id,var_i,&wmoStaNum);
      ier = nc_get_var1_float(cdfid,staLat_id,var_i,&staLat);
      ier = nc_get_var1_float(cdfid,staLon_id,var_i,&staLon);
      ier = nc_get_var1_float(cdfid,staElev_id,var_i,&staElev);
      ier = nc_get_var1_float(cdfid,sfc_sped_id,var_i,&sfc_sped);
      ier = nc_get_var1_float(cdfid,sfc_drct_id,var_i,&sfc_drct);
      ier = nc_get_var1_float(cdfid,sfc_pres_id,var_i,&sfc_pres);
      ier = nc_get_var1_float(cdfid,sfc_temp_id,var_i,&sfc_temp);
      ier = nc_get_var1_float(cdfid,sfc_relh_id,var_i,&sfc_relh);
      ier = nc_get_var1_float(cdfid,sfc_rain_id,var_i,&sfc_rain);
      ier = nc_get_var1_double(cdfid,timeObs_id,var_i,&timeObs);
      obs_time = (time_t) timeObs;
      gmt_time = gmtime(&obs_time);
      new_time = *gmt_time;
      timestr[0] = '\0';
      strftime(timestr,80,"%Y %m %d %H %M",&new_time);
      sscanf(timestr,"%d %d %d %d %d",&year,&month,&day,&hour,&minute);
      udebug("Station %3d %8d %s = %6.2f %7.2f %5.0f %s\0",i,wmoStaNum,
         staName,staLat,staLon,staElev,timestr);

      stadat = (sta_struct *)malloc(sizeof(sta_struct));
      if(stadat == NULL)
         {
         uerror("Could not allocate station data structure\0");
         exit(-2);
         }
      stadat->wmoStaNum = wmoStaNum;
      stadat->staName = (char *)malloc(strlen(staName)+1);
      strcpy(stadat->staName,staName);
      stadat->staLat = staLat;      
      stadat->staLon = staLon;      
      stadat->staElev = staElev;      
      stadat->timeObs = timeObs;      
      stadat->year = year;
      stadat->month = month;
      stadat->day = day;
      stadat->hour = hour;
      stadat->minute = minute;
      stadat->time_interval = time_interval;
      stadat->pdata = NULL;
      stadat->rdata = NULL;
      stadat->sfc_pres = fmiss;
      stadat->sfc_temp = fmiss;
      stadat->sfc_sped = fmiss;
      stadat->sfc_drct = fmiss;
      stadat->sfc_relh = fmiss;
      stadat->sfc_rain_rate = fmiss;
      stadat->sfc_rain_amt = fmiss;
      stadat->sfc_dwpc = fmiss;
      if(sfc_pres != pfill) stadat->sfc_pres = sfc_pres;
      if(sfc_temp != tfill) stadat->sfc_temp = sfc_temp - 273.15;
      if(sfc_sped != sfill) stadat->sfc_sped = sfc_sped;
      if(sfc_drct != dfill) stadat->sfc_drct = sfc_drct;
      if(sfc_relh != rfill) stadat->sfc_relh = sfc_relh;
      if(sfc_rain != rrfill) stadat->sfc_rain_rate = sfc_rain;
      if((stadat->sfc_temp != fmiss)&&(stadat->sfc_relh != fmiss))
         {
         VAPOR_PRES(stadat->sfc_temp+273.15,&e);
         e = e * (stadat->sfc_relh / 100.);
         t_from_e(e,&stadat->sfc_dwpc);
         stadat->sfc_dwpc = stadat->sfc_dwpc - 273.15;
         }

      ier = nc_inq_var(cdfid,levels_id,NULL, &xtype, &nvdims, tmpint, &nvatts);
      if(ier == 0)
         {
         ier = nc_inq_dimlen(cdfid,tmpint[0],&dimsiz);
         stadat->numlevs = dimsiz;
         plast = stadat->pdata;
         for(j=0;j<stadat->numlevs;j++)
            {
            var_i[0] = j;
            ier = nc_get_var1_float(cdfid,levels_id,var_i,&level);
            ier = nc_get_var1_int(cdfid,levelMode_id,var_i,&levelMode);
            var_i[0] = i;
            var_i[1] = j;
            ier = nc_get_var1_float(cdfid,uwnd_id,var_i,&uwnd);
            ier = nc_get_var1_float(cdfid,vwnd_id,var_i,&vwnd);
            ier = nc_get_var1_float(cdfid,wwnd_id,var_i,&wwnd);
            ier = nc_get_var1_int(cdfid,uv_qual_id,var_i,&uv_qual);
            ier = nc_get_var1_int(cdfid,w_qual_id,var_i,&w_qual);
            ier = nc_get_var1_float(cdfid,sigma_uv_id,var_i,&sigma_uv);
            ier = nc_get_var1_float(cdfid,sigma_w_id,var_i,&sigma_w);
            plev = (prof_data *)malloc(sizeof(prof_data));
            if(plev != NULL)
               {
               plev->level = level;
               if(uwnd == ufill) uwnd = fmiss;
               if(vwnd == vfill) vwnd = fmiss;
               if(wwnd == wfill) wwnd = fmiss;
               if(uv_qual != 0) 
                  {
                  uwnd = fmiss;
                  vwnd = fmiss;
                  }
               if(w_qual != 0) wwnd = fmiss;
               if((uwnd == fmiss)||(vwnd == fmiss))
                  sigma_uv = fmiss;
               if(wwnd == fmiss) sigma_w = fmiss;
               plev->u = uwnd; plev->v = vwnd; plev->w = wwnd;
               plev->sigma_uv = sigma_uv;
               plev->sigma_w = sigma_w;
               plev->levmode = levelMode;
               plev->nextlev = NULL;
               if(plast == NULL)
                  stadat->pdata = plev;
               else
                  plast->nextlev = plev;
               plast = plev;
               }
            }
         }
      else
         stadat->numlevs = 0;

      stadat->next = head;
      head = stadat;
      }

return(head);

} 
Esempio n. 28
0
/**
 * @retval LDM7_INVAL  No multicast sender child process exists.
 */
static int
sender_terminate(void)
{
    int retval = 0;
    int status;

#if CANCEL_SENDER
    udebug("Canceling sender thread");
    status = pthread_cancel(sender.thread);
    if (status) {
        LOG_ERRNUM0(status, "Couldn't cancel sender thread");
        retval = status;
    }
#else
    udebug("Writing to termination pipe");
    status = write(sender.fds[1], &status, sizeof(int));
    if (status == -1) {
        LOG_SERROR0("Couldn't write to termination pipe");
        retval = status;
    }
#endif

    void* statusPtr;

    udebug("Joining sender thread");
    status = pthread_join(sender.thread, &statusPtr);
    if (status) {
        LOG_ERRNUM0(status, "Couldn't join sender thread");
        retval = status;
    }

    if (statusPtr != PTHREAD_CANCELED) {
        status = *(int*)statusPtr;
        if (status) {
            LOG_START1("Sender task exit-status was %d", status);
            retval = status;
        }
    }

    (void)close(sender.sock);

    udebug("Terminating multicast sender");
    status = terminateMcastSender();
    if (status) {
        LOG_ADD0("Couldn't terminate multicast sender process");
        retval = status;
    }

    udebug("Clearing multicast LDM sender manager");
    status = mlsm_clear();
    if (status) {
        LOG_ADD0("mlsm_clear() failure");
        retval = status;
    }

    status = pq_close(pq);
    if (status) {
        LOG_ADD0("pq_close() failure");
        retval = status;
    }

    status = deleteProductQueue(UP7_PQ_PATHNAME);
    if (status) {
        LOG_ADD0("deleteProductQueue() failure");
        retval = status;
    }

    return retval;
}
Esempio n. 29
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. 30
0
/**
 * Might call `svc_destroy(up7->xprt)`.
 *
 * @param[in] up7  Upstream LDM-7.
 * @retval    0    Success.
 */
static int
up7_run(
    Up7* const up7)
{
    const int     sock = up7->xprt->xp_sock;
    int           status;

    struct pollfd fds;
    fds.fd = sock;
    fds.events = POLLRDNORM;

    pthread_cleanup_push(funcCancelled, "up7_run");

    int initCancelState;
    (void)pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &initCancelState);

    for (;;) {
        udebug("up7_run(): Calling poll()");
        status = poll(&fds, 1, -1); // `-1` => indefinite timeout

        int cancelState;
        // (void)pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelState);

        if (0 > status) {
            svc_destroy(up7->xprt);
            break;
        }
        if ((fds.revents & POLLERR) || (fds.revents & POLLNVAL)) {
            status = EIO;
            break;
        }
        if (fds.revents & POLLHUP) {
            status = 0;
            break;
        }
        if (fds.revents & POLLRDNORM) {
            udebug("up7_run(): Calling svc_getreqsock()");
            svc_getreqsock(sock); // calls `ldmprog_7()`
        }
        if (!FD_ISSET(sock, &svc_fdset)) {
            /*
             * The connection to the receiver was closed by the RPC layer =>
             * `svc_destroy(up7->xprt)` was called.
             */
            up7->xprt = NULL; // so others don't try to destroy it
            status = 0;
            break;
        }

        (void)pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &cancelState);
    }

    /*
     * In order to play nice with the caller, the cancelability state is
     * reverted to its value on entry.
     */
    (void)pthread_setcancelstate(initCancelState, &initCancelState);

    pthread_cleanup_pop(0);

    udebug("up7_run(): Returning %d", status);
    return status;
}