Ejemplo n.º 1
0
/*
 * Prints to the standard output stream all values in the registry whose path
 * name starts with a given prefix.
 *
 * Arguments:
 *      path            Pointer to a registry pathname to be printed.  Shall
 *                      not be NULL.
 *      quiet           Whether or not to be quiet about a pathname not
 *                      existing.
 * Returns:
 *      0               Success
 *      NO_SUCH_ENTRY   No such value or node.  "log_flush()" called iff "quiet
 *                      == 0".
 *      SYSTEM_ERROR    Failure.  "log_flush()" called.
 */
static Status printPath(
    const char*         path,
    const int           quiet)
{
    Status      status = 0;             /* success */
    RegStatus   regStatus;
    char*       value;

    log_debug("%s printing path \"%s\"", quiet ? "Quietly" : "Non-quietly", path);

    /*
     * The path name is first assumed to reference an existing value;
     * otherwise, the value wouldn't be printed.
     */ 
    if (0 == (regStatus = reg_getString(path, &value))) {
        if (NULL != value) {
            (void)printf("%s\n", value);
            free(value);
        }                               /* "value" allocated */
    }                                   /* got value-string */
    else {
        if (ENOENT != regStatus) {
            log_flush_error();
            status = SYSTEM_ERROR;
        }
        else {
            /*
             * The path must reference a node.
             */
            RegNode*    node;

            log_clear();

            if (0 != (regStatus = reg_getNode(path, &node, 0))) {
                if (ENOENT == regStatus) {
                    if (!quiet) {
                        log_error("No such value or node: \"%s\"", path);
                    }
                    status = NO_SUCH_ENTRY;
                }
                else {
                    log_flush_error();
                    status = SYSTEM_ERROR;
                }
            }                           /* didn't get node */
            else {
                _pathPrefix = path;

                if (0 != reg_visitNodes(node, printNodeValues)) {
                    log_flush_error();
                    status = SYSTEM_ERROR;
                }                       /* error visiting nodes */
            }                           /* got node */
        }                               /* no such value */
    }                                   /* didn't get value-string */

    return status;
}
Ejemplo n.º 2
0
static void usage(const char* progname)
{
    log_add(
"Usages:\n"
"  Create Registry:     %s [-v|-x] [-d dir] -c\n"
"  Reset Registry:      %s [-v|-x] [-d dir] -R\n"
"  Print Parameters:    %s [-v|-x] [-d dir] [-q] [path ...]\n"
"  Remove Parameter(s): %s [-v|-x] [-d dir] [-q] -r path ...\n"
"  Set Parameter:       %s [-v|-x] [-d dir] (-b bool|-h sig|-s string|-t time|-u uint) "
    "valpath\n"
"Where:\n"
"  -b bool      Boolean registry value: TRUE, FALSE\n"
"  -d dir       Path name of registry directory. Default=\"%s\"\n"
"  -h sig       Data-product signature as 32 hexadecimal characters\n"
"  -q           Be quiet about missing values or nodes\n"
"  -s string    String registry value\n"
"  -t time      Time registry value as YYYYMMDDThhmmss[.uuuuuu]\n"
"  -u uint      Unsigned integer registry value\n"
"  -v           Log INFO messages\n"
"  -x           Log DEBUG messages\n"
"  path         Absolute pathname of registry node or value\n"
"  valpath      Absolute pathname of value\n",
        progname, progname, progname, progname, progname, getRegistryDirPath());
    log_flush_error();
}
Ejemplo n.º 3
0
Archivo: fxbuf.c Proyecto: Unidata/LDM
/**
 * There is data available on the feed. Read it into the buffer
 * then deal with what we got.
 *
 * @param ifd           [in] File-descriptor of the input data-feed
 * @retval 0            Success
 * @retval ENOMEM       Out of memory
 * @retval ENODATA      End of input data-feed
 */
int
feedTheXbuf(const int ifd)
{
	int status;
	size_t nn = 0;
	/* space available in buffer */
	ptrdiff_t remaining = (ptrdiff_t)theBuf->bufsiz - (theBuf->get - theBuf->base);

	if (remaining <= CHUNKSIZE) {
		if (theBuf->bufsiz >= maxProductSize) {
			log_warning_q(
			        "Data-product would exceed %lu bytes. Resetting input buffer.",
				maxProductSize);
			justify_xbuf(theBuf, 0);
		}

		log_info_q("Expanding input buffer size to %lu\n",
			(unsigned long)(2 * theBuf->bufsiz));

		theBuf = expand_xbuf(theBuf, theBuf->bufsiz);

		if (theBuf == NULL) {
			status = errno == 0 ? ENOMEM : errno;
			log_add_syserr("expand_xbuf");
                        log_flush_error();
			return status;
		}
	}

	status = (*read_feed)(ifd, (char *)theBuf->put, CHUNKSIZE, &nn);
	if(status != ENOERR)
	{
		log_add_errno(status, "read_feed");
                log_flush_error();
		return status;
	}
	/* else */
	if(nn == 0)
		return ENODATA; /* end of file */
	/* else */
	/* usual case */
	/* assert(nn > 0); */
	theBuf->cnt += nn;
	theBuf->put += nn;
	return ENOERR;
}
Ejemplo n.º 4
0
static void
test_add_get(void)
{
    FmtpProdIndex     fileA = 1;
    FmtpProdIndex     fileB;
    int                status;

    status = piq_add(rq, fileA);
    log_flush_error();
    CU_ASSERT_EQUAL_FATAL(status, 0);
    CU_ASSERT_EQUAL(piq_count(rq), 1);

    status = piq_removeNoWait(rq, &fileB);
    log_flush_error();
    CU_ASSERT_EQUAL_FATAL(status, 0);
    CU_ASSERT_EQUAL_FATAL(fileB, fileA);
    CU_ASSERT_EQUAL(piq_count(rq), 0);
}
Ejemplo n.º 5
0
/*
 * Removes the values referenced by an absolute registry pathname.
 *
 * Arguments:
 *      path            Pointer to a an absolute registry pathname.  Shall not
 *                      be NULL.  If the pathname refers to a node, then the
 *                      node and all its subnodes are recursively removed.
 *      quiet           Whether or not to be quiet about a pathname not
 *                      existing.
 * Returns:
 *      0               Success.
 *      NO_SUCH_ENTRY   No such entry in the registry.  "log_flush()" called iff
 *                      "quiet == 0".
 *      SYSTEM_ERROR    System error.  "log_flush()" called.
 */
static Status deletePath(
    const char* const   path,
    const int           quiet)
{
    log_debug("%s deleting path \"%s\"", quiet ? "Quietly" : "Non-quietly", path);

    switch (reg_deleteValue(path)) {
        case 0:
            return 0;

        case ENOENT: {
            RegNode*        node;

            switch (reg_getNode(path, &node, 0)) {
                case 0:
                    reg_deleteNode(node);

                    if (reg_flushNode(node)) {
                        log_flush_error();
                        return SYSTEM_ERROR;
                    }

                    return 0;
                case ENOENT:
                    if (!quiet) {
                        log_error("No such value or node: \"%s\"", path);
                    }
                    return NO_SUCH_ENTRY;
                default:
                    log_flush_error();
                    return SYSTEM_ERROR;
            }
        }
        /* FALLTHROUGH */
        /* no break */

        default:
            log_flush_error();
            return SYSTEM_ERROR;
    }
}
Ejemplo n.º 6
0
static void
test_sa_parseWithDefaults(void)
{
    ServiceAddr* sa;
    int          status;
    const char*  hostId = "uni14.unidata.ucar.edu";
    const short  port = 388;

    status = sa_parseWithDefaults(&sa, hostId, NULL, 388);
    log_flush_error();
    CU_ASSERT_EQUAL_FATAL(status, 0);
    CU_ASSERT_STRING_EQUAL(sa_getInetId(sa), hostId);
    CU_ASSERT_EQUAL(sa_getPort(sa), port);
    sa_free(sa);
}
Ejemplo n.º 7
0
static void
sa_parse_test(
    const char* const inetId,
    const unsigned short port)
{
    ServiceAddr* sa;
    char*        buf = ldm_format(80, strchr(inetId, ':') ? "[%s]:%d" : "%s:%d",
                                  inetId, port);
    int          status;

    CU_ASSERT_PTR_NOT_NULL_FATAL(buf);
    status = sa_parse(&sa, buf);
    log_flush_error();
    CU_ASSERT_EQUAL_FATAL(status, 0);
    CU_ASSERT_STRING_EQUAL(sa_getInetId(sa), inetId);
    CU_ASSERT_EQUAL(sa_getPort(sa), port);
    sa_free(sa);
}
Ejemplo n.º 8
0
/**
 * Sets an LDM product-identifier from a GRIB message.
 *
 * Not Atomic,
 * Idempotent,
 * Thread-safe
 *
 * @param[out] ident      Product-identifier buffer.
 * @param[in]  identSize  Size of product-identifier buffer in bytes.
 * @param[in]  decoded    Decoded GRIB message.
 * @param[in]  wmoHead    WMO header associated with the GRIB message.
 * @retval     0          Success. \c *ident is set.
 * @retval     1          GRIB message has no data.
 * @retval     3          System error.
 */
static int setIdent(
    char* const            ident,
    const size_t           identSize,
    DecodedGrib2Msg* const decoded,
    const char* const      wmoHead)
{
    const size_t   numFields = g2d_getNumFields(decoded);
    int            status;

    if (0 == numFields) {
        log_add("GRIB message has no fields");
        status = 1;
    }
    else {
        StringBuf* const prods = strBuf_new(127); /* initially empty */

        if (NULL == prods) {
            log_add_syserr("Couldn't allocate string-buffer for products");
            log_flush_error();
            status = 3;
        }
        else {
            Gribmsg          gribMsg;
            Geminfo          gemInfo;
            int              modelId;

            status = appendParameterNames(prods, decoded, &gribMsg, &gemInfo);

            if (0 == status) {
                status = getModelId(decoded, &modelId);

                if (0 == status)
                    composeIdent(ident, identSize, decoded, &gribMsg, &gemInfo,
                            prods, wmoHead, modelId);
            }

            strBuf_free(prods);
        } /* "prods" allocated */
    } /* numFields > 0 */

    return status;
}
Ejemplo n.º 9
0
Archivo: fxbuf.c Proyecto: Unidata/LDM
/**
 * Initializes this module.
 * 
 * @param readfunct     [in] The function that reads the data
 * @param maxProdSize   [in] The size, in bytes, of the largest expected 
 *                      data-product
 * @retval 0            Success
 * @retval ENOMEM       Out of memory
 */
int
initTheXbuf(
        int (*readfunct)(int ifd, char *buf, size_t nbytes, size_t *ngotp),
        const unsigned long maxProdSize)
{
	read_feed = readfunct;
    maxProductSize = maxProdSize > INIT_CIRCBUFSIZE ? maxProdSize : INIT_CIRCBUFSIZE;

	if(theBuf == NULL)
	{
		theBuf = new_xbuf(INIT_CIRCBUFSIZE);
		if(theBuf == NULL)
		{
			const int status = errno == 0 ? ENOMEM : errno;
			log_add_syserr("new_xbuf");
                        log_flush_error();
			return status;
		}
	}
	return ENOERR;
}
Ejemplo n.º 10
0
static void
usage(
        const char* const   progname /*  id string */
)
{
    log_add(
"Usage: %s [options] filename ...\n"
"    Options:\n"
"    -v            Verbose, tell me about each product\n"
"    -l dest       Log to `dest`. One of: \"\" (system logging daemon), \"-\"\n"
"                  (standard error), or file `dest`. Default is \"%s\"\n"
"    -q queue      Use <queue> as product-queue. Default:\n"
"                  \"%s\"\n"
"    -s seqno      Set initial product sequence number to <seqno>.\n"
"                  Default: 0\n"
"    -f feedtype   Assert your feed type as <feedtype>. Default: \"EXP\"\n"
"    -p productID  Assert product-ID as <productID>. Default is the \n"
"                  filename. With multiple files, product-ID becomes\n"
"                  <productID>.<seqno>\n"
"    -i            Compute product signature (MD5 checksum) from product ID\n",
            progname, log_get_default_destination(), getDefaultQueuePath());
    log_flush_error();
    exit(1);
}
Ejemplo n.º 11
0
static void
test_order(void)
{
    FmtpProdIndex fileA = 1;
    FmtpProdIndex fileB = 2;
    FmtpProdIndex fileC = 3;
    FmtpProdIndex fileD;
    int            status;

    status = piq_add(rq, fileA);
    log_flush_error();
    CU_ASSERT_EQUAL_FATAL(status, 0);
    CU_ASSERT_EQUAL(piq_count(rq), 1);
    status = piq_add(rq, fileB);
    log_flush_error();
    CU_ASSERT_EQUAL_FATAL(status, 0);
    CU_ASSERT_EQUAL(piq_count(rq), 2);
    status = piq_add(rq, fileC);
    log_flush_error();
    CU_ASSERT_EQUAL_FATAL(status, 0);
    CU_ASSERT_EQUAL(piq_count(rq), 3);

    status = piq_removeNoWait(rq, &fileD);
    log_flush_error();
    CU_ASSERT_EQUAL_FATAL(status, 0);
    CU_ASSERT_EQUAL_FATAL(fileD, fileA);
    CU_ASSERT_EQUAL(piq_count(rq), 2);

    status = piq_removeNoWait(rq, &fileD);
    log_flush_error();
    CU_ASSERT_EQUAL_FATAL(status, 0);
    CU_ASSERT_EQUAL_FATAL(fileD, fileB);
    CU_ASSERT_EQUAL(piq_count(rq), 1);

    status = piq_removeNoWait(rq, &fileD);
    log_flush_error();
    CU_ASSERT_EQUAL_FATAL(status, 0);
    CU_ASSERT_EQUAL_FATAL(fileD, fileC);
    CU_ASSERT_EQUAL(piq_count(rq), 0);
}
Ejemplo n.º 12
0
/*
 * Returns:
 *      0       Success
 *      1       Incorrect usage (i.e., command-line syntax error).
 *      2       No such parameter or node.  Error message written.
 *      3       System error.  Error message written.
 */
int main(
    int         argc,
    char*       argv[])
{
    int                 status;
    const char* const   progname = basename(argv[0]);

    (void)log_init(progname);

    if ((status = sb_new(&_valuePath, 80))) {
        log_error("Couldn't initialize utility");
        status = SYSTEM_ERROR;
    }
    else {
        enum {
            UNKNOWN,
            CREATE,
            PRINT,
            PUT_BOOL,
            PUT_STRING,
            PUT_UINT,
            PUT_SIGNATURE,
            PUT_TIME,
            RESET,
            REMOVE
        }               action = UNKNOWN;
        const char*     string;
        signaturet      signature;
        timestampt      timestamp;
        unsigned long   uint;
        int             boolean;
        int             ch;
        int             quiet = 0;

        opterr = 0;                     /* supress getopt(3) error messages */

        while (0 == status && (ch = getopt(argc, argv, ":b:cd:h:qRrs:t:u:vx"))
                != -1) {
            switch (ch) {
            case 'b': {
                if (strcasecmp(optarg, "TRUE") == 0) {
                    boolean = 1;
                }
                else if (strcasecmp(optarg, "FALSE") == 0) {
                    boolean = 0;
                }
                else {
                    log_add("Not a boolean value: \"%s\"", optarg);
                    status = COMMAND_SYNTAX;
                }

                if (status == 0) {
                    if (CREATE == action) {
                        log_error("Create option ignored");
                    }
                    action = PUT_BOOL;
                }
                break;
            }
            case 'c': {
                if (UNKNOWN != action) {
                    log_add("Can't mix create action with other actions");
                    status = COMMAND_SYNTAX;
                }
                else {
                    action = CREATE;
                }
                break;
            }
            case 'd': {
                if ((status = reg_setDirectory(optarg)))
                    status = SYSTEM_ERROR;
                break;
            }
            case 'h': {
                status = sigParse(optarg, &signature);

                if (0 > status || 0 != optarg[status]) {
                    log_add("Not a signature: \"%s\"", optarg);
                    status = COMMAND_SYNTAX;
                }
                else {
                    if (CREATE == action) {
                        log_info("Create action ignored");
                    }
                    action = PUT_SIGNATURE;
                    status = 0;
                }
                break;
            }
            case 'q': {
                quiet = 1;
                break;
            }
            case 'R': {
                if (UNKNOWN != action) {
                    log_add("Can't mix reset action with other actions");
                    status = COMMAND_SYNTAX;
                }
                else {
                    action = RESET;
                }
                break;
            }
            case 'r': {
                if (UNKNOWN != action) {
                    log_add("Can't mix remove action with other actions");
                    status = COMMAND_SYNTAX;
                }
                else {
                    action = REMOVE;
                }
                break;
            }
            case 's': {
                if (CREATE == action) {
                    log_info("Create action  ignored");
                }
                string = optarg;
                action = PUT_STRING;
                break;
            }
            case 't': {
                status = tsParse(optarg, &timestamp);

                if (0 > status || 0 != optarg[status]) {
                    log_add("Not a timestamp: \"%s\"", optarg);
                    status = COMMAND_SYNTAX;
                }
                else {
                    if (CREATE == action) {
                        log_info("Create action ignored");
                    }
                    action = PUT_TIME;
                    status = 0;
                }
                break;
            }
            case 'u': {
                char*   end;

                errno = 0;
                uint = strtoul(optarg, &end, 0);

                if (0 != *end || (0 == uint && 0 != errno)) {
                    log_add("Not an unsigned integer: \"%s\"", optarg);
                    status = COMMAND_SYNTAX;
                }
                else {
                    if (CREATE == action) {
                        log_info("Create option ignored");
                    }
                    action = PUT_UINT;
                }
                break;
            }
            case 'v': {
                if (!log_is_enabled_info)
                    (void)log_set_level(LOG_LEVEL_INFO);
                break;
            }
            case 'x': {
                (void)log_set_level(LOG_LEVEL_DEBUG);
                break;
            }
            case ':': {
                log_add("Option \"-%c\" requires an operand", optopt);
                status = COMMAND_SYNTAX;
                break;
            }
            default:
                log_add("Unknown option: \"%c\"", optopt);
                status = COMMAND_SYNTAX;
                /* no break */
            }
        }                               /* options loop */

        if (status) {
            log_flush_error();

            if (COMMAND_SYNTAX == status)
                usage(progname);
        }
        else {
            const int     argCount = argc - optind;

            if (UNKNOWN == action)
                action = PRINT;

            switch (action) {
                case CREATE: {
                    if (0 < argCount) {
                        log_error("Too many arguments");
                        usage(progname);
                        status = COMMAND_SYNTAX;
                    }
                    else {
                        status = createRegistry();
                    }
                    break;
                }
                case RESET: {
                    if (0 < argCount) {
                        log_error("Too many arguments");
                        usage(progname);
                        status = COMMAND_SYNTAX;
                    }
                    else {
                        status = resetRegistry();
                    }
                    break;
                }
                case REMOVE: {
                    if (0 == argCount) {
                        log_error(
                            "Removal action requires absolute pathname(s)");
                        usage(progname);
                        status = COMMAND_SYNTAX;
                    }
                    else {
                        log_debug("Removing registry");
                        status = actUponPathList(argv + optind, deletePath,
                            quiet);
                    }
                    break;
                }
                case PRINT: {
                    log_debug("Printing registry");
                    status = (0 == argCount)
                        ? printPath("/", quiet)
                        : actUponPathList(argv + optind, printPath, quiet);
                    break;
                }
                default: {
                    /*
                     * Must be some kind of "put".
                     */
                    if (0 == argCount) {
                        log_error("Put action requires value pathname");
                        usage(progname);
                        status = COMMAND_SYNTAX;
                    }
                    else {
                        switch (action) {
                        case PUT_BOOL:
                            status = reg_putBool(argv[optind], boolean);
                            break;
                        case PUT_UINT:
                            status = reg_putUint(argv[optind], uint);
                            break;
                        case PUT_STRING:
                            status = reg_putString(argv[optind], string);
                            break;
                        case PUT_TIME:
                            status = reg_putTime(argv[optind], &timestamp);
                            break;
                        case PUT_SIGNATURE:
                            status = reg_putSignature(argv[optind], signature);
                            break;
                        default:
                            abort();
                        }
                        if (status) {
                            log_flush_error();
                            status = SYSTEM_ERROR;
                        }
                    }
                }                       /* put switch */
                /* no break */
            }                           /* "action" switch */
        }                               /* decoded options */

        sb_free(_valuePath);
    }                                   /* "_valuePath" allocated */

    return status;
}
Ejemplo n.º 13
0
/**
 * Generates an LDM product-identifier from a GRIB edition 2 message.
 *
 * Atomic,
 * Idempotent,
 * Not thread-safe
 *
 * @param[in]  data             Pointer to the GRIB message.
 * @param[in]  sz               Length of the GRIB message in bytes.
 * @param[in]  wmohead          Pointer to the associated WMO header string.
 * @param[out] ident            Pointer to a buffer to receive the LDM
 *                              product-identifier.
 * @param[in]  identSize        Size of the \c ident buffer in bytes.
 * @retval     0                Success. \c ident is set and NUL-terminated.
 * @retval     1                Invalid GRIB message.
 * @retval     2                GRIB message isn't edition 2.
 * @retval     3                System error.
 */
int grib2name (
    char* const         data,
    const size_t        sz,
    const char* const   wmohead,
    char* const         ident,
    const size_t        identSize)
{
#if USE_GRIB2_DECODER
    int                 status;
    DecodedGrib2Msg*    decoded;

    if (status = g2d_new(&decoded, (unsigned char*)data, sz)) {
        log_add("Couldn't decode GRIB message");
        status = G2D_INVALID == status
                ? 1
                : G2D_NOT_2
                    ? 2
                    : 3;
    }
    else {
        if (status = setIdent(ident, identSize, decoded, wmohead)) {
            log_add("Couldn't set LDM product-identifier");
            status = 1;
        }

        g2d_free(decoded);
    } /* "decoded" allocated */

    return status;
#else
    static StringBuf*  paramNames;    /* Buffer for parameter name(s) */
    int                iField;        /* GRIB-2 field index */
    int                status;        /* Function return code */
    g2int              listsec0[3];   /* GRIB-2 section 0 parameters */
    g2int              listsec1[13];  /* GRIB-2 section 1 parameters */
    g2int              numlocal;      /* Number of GRIB section 2-s */
    int                model_id;      /* ID of model */
    int                grid_id;       /* ID of grid */
    char               fdats[80];     /* No idea */
    char               levelstmp[80]; /* Level? */
    Gribmsg            g2Msg;         /* GRIB-2 message structure */

    if (paramNames) {
        strBuf_clear(paramNames);
    }
    else {
        paramNames = strBuf_new(127);
        if (NULL == paramNames) {
            log_add("Couldn't allocate buffer for parameter name(s)");
            return 3;
        }
    }

    g2Msg.cgrib2 = (unsigned char*)data;
    g2Msg.mlength = sz;
    g2Msg.gfld = NULL;
    g2Msg.field_tot = 0;

    if ((status = g2_info(g2Msg.cgrib2, g2Msg.mlength, listsec0, listsec1,
            &(g2Msg.field_tot), &numlocal)) != 0)
        return (2 == status) ? 2 : 1;

    if (g2Msg.field_tot <= 0) {
        log_add("GRIB-2 message has no data fields");
        return 1;
    }

    for (iField = 0; iField < g2Msg.field_tot; iField++) {
        static char  g2tables[5][LLMXLN];  /* GRIB tables */
        static char* tbllist[5] = {g2tables[0], g2tables[1], g2tables[2],
                g2tables[3], g2tables[4]}; /* Addresses of GRIB tables */
        Geminfo      gemInfo;              /* GEMPAK structure */
        int const    lastField = iField == g2Msg.field_tot - 1;

        status = g2_getfld(g2Msg.cgrib2, g2Msg.mlength, iField+1, 0, 0,
                &g2Msg.gfld);

        if (status) {
            log_add("Invalid GRIB-2 message: g2_getfld() status=%d", status);
            return (2 == status) ? 2 : 1;
        }

        /* "g2Msg.gfld" is allocated */

        /* Initialize strings in Geminfo structure */
        (void)memset(gemInfo.cproj, 0, sizeof(gemInfo.cproj));
        (void)memset(gemInfo.parm, 0, sizeof(gemInfo.parm));
        (void)memset(gemInfo.gdattm1, 0, sizeof(gemInfo.gdattm1));
        (void)memset(gemInfo.gdattm2, 0, sizeof(gemInfo.gdattm2));

        /*
         * In the original code, the last field determined the model ID.
         */
        if (lastField)
            model_id = g2Msg.gfld->ipdtmpl[4];

        /*
         * This assignment to "grid_id" isn't under the above "lastField"
         * conditional because "decode_g2gnum()" might have side-effects upon
         * which "gb2_2gem()" depends.
         */
        grid_id = (g2Msg.gfld->griddef == 0)
            ? decode_g2gnum(g2Msg.gfld)
            : g2Msg.gfld->griddef;

        gb2_2gem(&g2Msg, &gemInfo, tbllist, &status);

        if (status) {
            log_add("Couldn't decode GRIB2 message. WMO header=\"%s\"",
                    wmohead);
            log_flush_error();

            if (lastField) {
                (void)strcpy(fdats, "FHRS"); /* safe */
                (void)strcpy(levelstmp, "LVL"); /* safe */
            }
        }
        else {
            char g2name[13];          /**< Name of product/parameter */
            int  ilen;                /**< Length of resulting string */

            (void)strcpy(g2name, gemInfo.parm); /* both 13 bytes */
            cst_rmbl(g2name, g2name, &ilen, &status);

            if (iField)
                strBuf_appendString(paramNames, ";");
            strBuf_appendString(paramNames, g2name);

            cst_rxbl(gemInfo.unit, gemInfo.unit, &ilen, &status);
            if (ilen == 0)
                (void)strcpy(gemInfo.unit, "-"); /* safe */

            cst_rmbl(gemInfo.gdattm1, gemInfo.gdattm1, &ilen, &status);
            cst_rmbl(gemInfo.gdattm2, gemInfo.gdattm2, &ilen, &status);

            /*
             * In the original code, the last field determined the following
             * parameters.
             */
            if (lastField) {
                static char  strBuf[5];       /* Holds 4-char string */
                static char* strptr = strBuf; /* For "cst_itoc()" */

                if (ilen > 0)
                    (void)snprintf(fdats, sizeof(fdats), "%s-%s",
                            gemInfo.gdattm1, gemInfo.gdattm2);
                else
                    (void)snprintf(fdats, sizeof(fdats), "%s",
                            gemInfo.gdattm1);

                for (ilen = 1; ilen > 0;
                        cst_rmst(fdats, "/", &ilen, fdats, &status));

                cst_itoc(&gemInfo.vcord, 1, &strptr, &status);

                if (gemInfo.level[1] == -1)
                    (void)snprintf(levelstmp, sizeof(levelstmp), "%d %s %s",
                            gemInfo.level[0], gemInfo.unit, strptr);
                else
                    (void)snprintf(levelstmp, sizeof(levelstmp), "%d-%d %s %s",
                            gemInfo.level[0], gemInfo.level[1], gemInfo.unit,
                            strptr);
            }
        }

        g2_free(g2Msg.gfld);
        g2Msg.gfld = NULL;
    }

    /*
     * See if the WMO header can be used for grid 0 products
     */
    if ((grid_id == 0) && (strlen(wmohead) > 11) && (wmohead[7] == 'K') &&
            (wmohead[8] == 'W')) {
        int wmoGridId = wmo_to_gridid(&wmohead[0], &wmohead[2]);

        if (wmoGridId > 0)
            grid_id = wmoGridId;
    }

    (void)snprintf(ident, identSize, "grib2/%s/%s/#%03d/%s/%s/%s",
            s_pds_center((int)listsec1[0], (int)listsec1[1]),
            s_pds_model((int)listsec1[0], model_id),
            grid_id,
            fdats,
            strBuf_toString(paramNames),
            levelstmp);

    return 0;
#endif
}
Ejemplo n.º 14
0
/*
 * Returns:
 *      0               Success
 *      SYSTEM_ERROR    O/S failure. "log_add()" called.
 *      LP_TIMEDOUT     The RPC call timed-out. "log_add()" called.
 *      LP_RPC_ERROR    RPC error. "log_add()" called.
 *      LP_LDM_ERROR    LDM error. "log_add()" called.
 */
int
main(
    int         ac,
    char*       av[])
{
    char            myname[_POSIX_HOST_NAME_MAX];
    char*           progname = av[0];
    prod_class_t    clss;
    prod_spec       spec;
    int             seq_start = 0;
    int             status;
    ErrorObj*       error;
    unsigned        remotePort = LDM_PORT;

    /*
     * Set up error logging
     */
    (void)log_init(progname);

    remote = "localhost";

    (void)set_timestamp(&clss.from);
    clss.to = TS_ENDT;
    clss.psa.psa_len = 1;
    clss.psa.psa_val = &spec;
    spec.feedtype = DEFAULT_FEEDTYPE;
    spec.pattern = ".*";

    {
        extern int optind;
        extern char *optarg;
        int ch;

        while ((ch = getopt(ac, av, "vxl:h:f:P:s:")) != EOF)
            switch (ch) {
            case 'v':
                if (!log_is_enabled_info)
                    (void)log_set_level(LOG_LEVEL_INFO);
                break;
            case 'x':
                (void)log_set_level(LOG_LEVEL_DEBUG);
                break;
            case 'l':
                (void)log_set_destination(optarg);
                break;
            case 'h':
                remote = optarg;
                break;
            case 'f':
                spec.feedtype = atofeedtypet(optarg);
                if(spec.feedtype == NONE)
                {
                    fprintf(stderr, "Unknown feedtype \"%s\"\n",
                            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) {

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

                remotePort = (unsigned)port;

                break;
            }
            case 's':
                seq_start = atoi(optarg);
                break;
            case '?':
                usage(progname);
                break;
            }

        ac -= optind; av += optind;

        if(ac < 1) usage(progname);
    }

    /*
     * Register the exit handler
     */
    if(atexit(cleanup) != 0)
    {
        log_syserr_q("atexit");
        exit(SYSTEM_ERROR);
    }

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

    (void) strncpy(myname, ghostname(), sizeof(myname));
    myname[sizeof(myname)-1] = 0;

    (void)exitIfDone(INTERRUPTED);

    /*
     * Connect to the LDM.
     */
    status = lp_new(remote, &ldmProxy);

    if (0 != status) {
        log_flush_error();
        status = (LP_SYSTEM == status)
            ? SYSTEM_ERROR
            : CONNECTION_ABORTED;
    }
    else {
        log_debug("version %u", lp_version(ldmProxy));

        status = ldmsend(ldmProxy, &clss, myname, seq_start, ac, av);

        if (0 != status)
            log_flush_error();

        lp_free(ldmProxy);
        ldmProxy = NULL;
    }                                       /* "ldmProxy" allocated */

    return status; 
}
Ejemplo n.º 15
0
int
main (int ac, char *av[])
{
  char *progname = av[0];
  int status;
  int seq_start = 0;
  stat_info *sinfo, *shead = NULL, *slast = NULL;
  int statusoff=0;

  /*
   * Set up error logging
   */
    if (log_init(progname)) {
        log_syserr("Couldn't initialize logging module");
        exit(1);
    }

  const char* pqfname = getQueuePath();

  /*
   * Check the environment for some options.
   * May be overridden by command line switches below.
   */
  {
    const char *ldmpqfname = getenv ("LDMPQFNAME");
    if (ldmpqfname != NULL)
      pqfname = ldmpqfname;
  }

  {
    extern int optind;
    extern int opterr;
    extern char *optarg;
    int ch;

    opterr = 1;

    while ((ch = getopt (ac, av, "vxl:q:f:s:S")) != EOF)
      switch (ch)
	{
	case 'v':
          if (!log_is_enabled_info)
            (void)log_set_level(LOG_LEVEL_INFO);
	  break;
	case 'x':
          (void)log_set_level(LOG_LEVEL_DEBUG);
	  break;
	case 'l':
          if (log_set_destination(optarg)) {
              log_syserr("Couldn't set logging destination to \"%s\"",
                      optarg);
              exit(1);
          }
	  break;
	case 'q':
	  pqfname = optarg;
	  break;
	case 's':
	  seq_start = atoi (optarg);
	  break;
	case 'f':
	  feedtype = atofeedtypet (optarg);
	  if (feedtype == NONE)
	    {
	      fprintf (stderr, "Unknown feedtype \"%s\"\n", optarg);
	      usage (progname);
	    }
	  break;
	case 'S':
	     statusoff=1;
	     break;
	case '?':
	  usage (progname);
	  break;
	}

    setQueuePath(pqfname);

    ac -= optind;
    av += optind;

    if (ac < 1)
      usage (progname);
  }

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

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

  /*
   * who am i, anyway
   */
  (void) strcpy (myname, ghostname ());

  /*
   * open the product queue
   */
  if ((status = pq_open (pqfname, PQ_DEFAULT, &pq)))
    {
      if (status > 0) {
          log_add_syserr("\"%s\" failed", pqfname);
          log_flush_error();
      }
      else {
          log_error_q("\"%s\" failed: %s", pqfname, "Internal error");
      }
      exit (2);
    }


  {
    char *filename;
    int fd;
    struct stat statb;
    product prod;
    unsigned char *prodmmap;
    MD5_CTX *md5ctxp = NULL;
    int gversion;

    /*
     * Allocate an MD5 context
     */
    md5ctxp = new_MD5_CTX ();
    if (md5ctxp == NULL)
      {
	log_syserr ("new_md5_CTX failed");
	exit (6);
      }

    /* These members are constant over the loop. */
    prod.info.origin = myname;
    prod.info.feedtype = feedtype;

    prod.info.seqno = seq_start;

    /*
     * Open the file to be inserted and process
     */
    while (ac > 0)
      {
        long insert_sum = 0;
	long sinfo_cnt = 0;
        long stat_size = 0;

	filename = *av;
	av++;
	ac--;

	log_notice_q ("open and memorymap %s\0", filename);

	fd = open (filename, O_RDONLY, 0);
	if (fd == -1)
	  {
	    log_syserr ("open: %s", filename);
	    continue;
	  }

	if (fstat (fd, &statb) == -1)
	  {
	    log_syserr ("fstat: %s", filename);
	    (void) close (fd);
	    continue;
	  }

	if ((prodmmap = (unsigned char *) mmap (0, statb.st_size,
				       PROT_READ, MAP_PRIVATE, fd,
				       0)) == MAP_FAILED)
	  {
	    log_syserr ("allocation failed");
	  }
	else
	  {
	    int GRIBDONE = 0;
	    off_t griboff = 0;
	    size_t griblen = 0;
	    log_notice_q ("%ld bytes memory mapped\0", (long) statb.st_size);

	    while (!GRIBDONE)
	      {
		log_debug("griboff %d\0", (int) griboff);
		/* get offset of next grib product */
		status =
		  get_grib_info (prodmmap, statb.st_size, &griboff, &griblen,
				 &gversion);

		switch (status)
		  {
		  case 0:
		    prod.data = prodmmap + griboff;
		    prod.info.sz = griblen;

		    /*
		     * revised MD5 calculation...using filename
		     * to allow duplicate products in different files.
		     */
		    MD5Init (md5ctxp);
  		    MD5Update (md5ctxp, (void *)filename, strlen(filename));
  		    /*MD5Update (md5ctxp, (void *)prod.data, prod.info.sz);*/
		    if ( prod.info.sz > 10000 )
  		       MD5Update (md5ctxp, (void *)prod.data, 10000);
		    else
  		       MD5Update (md5ctxp, (void *)prod.data, prod.info.sz);
  		    MD5Final (prod.info.signature, md5ctxp);

		    /*if (mm_md5 (md5ctxp, prod.data, prod.info.sz,
				prod.info.signature) != 0)
		      {
			log_error_q ("could not compute MD5\0");
		      }
		    else
		      { */
			prod.info.ident = (char *) malloc (KEYSIZE + 1);
			get_gribname (gversion, prod.data, prod.info.sz,
				      filename, prod.info.seqno,
				      prod.info.ident);
			/*
			 * Do the deed
			 */
			status = set_timestamp (&prod.info.arrival);
			if (status != ENOERR)
			  {
			    log_add_syserr("could not set timestamp");
                            log_flush_error();
			  }
			/*
			 * Insert the product
			 */
			status = pq_insert (pq, &prod);
			log_info_q ("%d %s\0", status, prod.info.ident);
                
			if ( status == ENOERR )
			   insert_sum += prod.info.sz;

			if (! statusoff )
			  {
			  /*
			   * Log this status
			   */
			    sinfo_cnt++;
			    sinfo = (stat_info *)malloc(sizeof(stat_info));
                   	    sinfo->insertstatus = status;
			    sinfo->prodname = (char *)malloc(strlen(prod.info.ident)+1);
                   	    strcpy(sinfo->prodname, prod.info.ident);
                   	    sinfo->seqno = prod.info.seqno;
                   	    sinfo->prodsz = prod.info.sz;
                   	    sinfo->next = NULL;
                   	    stat_size += strlen(sinfo->prodname);
                   	    if(shead == NULL)
			      {
                      	        shead = sinfo;
                      	        slast = sinfo;
                   	      }
                   	    else 
			      {
                      	        slast->next = sinfo;
                      	        slast = sinfo;
                   	      }
			  }
		      /*}*/
		    griboff += griblen;
		    prod.info.seqno++;
		    break;
		  case -1:
		    GRIBDONE = 1;
		    break;
		  case -2:
		    log_error_q ("truncated grib file at: %d", prod.info.seqno);
		    GRIBDONE = 1;
		    break;
		  case -7:
		    log_error_q ("End sequence 7777 not found where expected: %d",
			    prod.info.seqno);
		    griboff += griblen;
		    log_error_q("resume looking at %d\0",griboff);
		    break;
		  default:
		    log_error_q ("unknown error %d\0", status);
		    griboff += griblen;
		    if (griboff >= statb.st_size)
		      GRIBDONE = 1;
		    break;
		  }

		if (griboff >= statb.st_size)
		  GRIBDONE = 1;
	      }


	    log_notice_q ("munmap\0");
	    (void) munmap ((void *)prodmmap, statb.st_size);

	    if ( stat_size != 0 )
	    /*
	     * Add a status message to product queue
	     */
	      {
		char *statusmess;
		log_notice_q("stats_size %ld %ld\0",stat_size,sinfo_cnt);

		statusmess = calloc((30 * sinfo_cnt) + stat_size +
                        strlen(filename) + 128, sizeof(char));
                if(statusmess == NULL) 
		  {
              	    log_syserr("could not malloc status message %ld\0",
              	            stat_size);
           	  }
           	else
		  {
		    char tmpprod[512];
                    sinfo = shead; slast = NULL;

                    status = set_timestamp(&prod.info.arrival);
                    /* ctime ends with \n\0" */
                    sprintf(statusmess,"%s complete (%ld bytes) at %sInserted %ld of %ld\n",
                       filename,(long)statb.st_size, ctime(&prod.info.arrival.tv_sec),
                       insert_sum,(long)statb.st_size);

                    while(sinfo != NULL) 
		      {
                        sprintf(tmpprod,"%3d %5d %8d %s\n",sinfo->insertstatus,
                            sinfo->seqno,sinfo->prodsz,sinfo->prodname);
                        strcat(statusmess,tmpprod);

                        slast = sinfo;
                 	sinfo = sinfo->next;

                        free(slast->prodname);
                    	free(slast);

                      }

		    shead = NULL;

                    sprintf(tmpprod,".status.%s %06d",filename, prod.info.seqno);
                    prod.info.ident = tmpprod;
                    prod.data = statusmess;
                    prod.info.sz = strlen(statusmess);
                    status = mm_md5(md5ctxp, prod.data, prod.info.sz, prod.info.signature);
                    status = set_timestamp(&prod.info.arrival);
                    status = pq_insert(pq, &prod);
                    if(log_is_enabled_info)
                        log_info_q("%s", s_prod_info(NULL, 0, &prod.info,
                                log_is_enabled_debug)) ;
                    free(statusmess);
		    prod.info.seqno++;
		  }
	      }
	  }

	(void) close (fd);
      }
  }

exit(0);
}