std::size_t GeoJSONFileParser::operator()() {
    rapidjson::IStreamWrapper stream_wrapper{m_file};

    rapidjson::Document doc;
    if (doc.ParseStream<rapidjson::kParseCommentsFlag | rapidjson::kParseTrailingCommasFlag>(stream_wrapper).HasParseError()) {
        error(std::string{"JSON error at offset "} +
              std::to_string(doc.GetErrorOffset()) +
              " : " +
              rapidjson::GetParseError_En(doc.GetParseError()));
    }

    if (!doc.IsObject()) {
        error("Top-level value must be an object.");
    }

    const std::string type{get_value_as_string(doc, "type")};
    if (type.empty()) {
        error("Expected 'type' name with the value 'Feature' or 'FeatureCollection'.");
    }

    if (type == "Feature") {
        return parse_top(doc);
    }

    if (type == "FeatureCollection") {
        const auto json_features = doc.FindMember("features");
        if (json_features == doc.MemberEnd()) {
            error("Missing 'features' name.");
        }

        if (!json_features->value.IsArray()) {
            error("Expected 'features' value to be an array.");
        }

        const auto json_features_array = json_features->value.GetArray();
        if (json_features_array.Empty()) {
            throw config_error{"Features array must contain at least one polygon."};
        }

        const auto& json_first_feature = json_features_array[0];
        if (!json_first_feature.IsObject()) {
            error("Expected values of 'features' array to be a objects.");
        }

        const std::string feature_type{get_value_as_string(json_first_feature, "type")};

        if (feature_type != "Feature") {
            error("Expected 'type' value to be 'Feature'.");
        }

        return parse_top(json_first_feature);
    }

    error("Expected 'type' value to be 'Feature'.");
}
Exemple #2
0
/********************************************************************
* FUNCTION conf_parse_from_filespec
* 
* Parse a file as an NCX text config file against
* a specific parmset definition.  Fill in an
* initialized parmset (and could be partially filled in)
*
* Error messages are printed by this function!!
*
* If a value is already set, and only one value is allowed
* then the 'keepvals' parameter will control whether that
* value will be kept or overwitten
*
* INPUTS:
*   filespec == absolute path or relative path
*               This string is used as-is without adjustment.
*   val       == value struct to fill in, must be initialized
*                already with val_new_value or val_init_value
*   keepvals == TRUE if old values should always be kept
*               FALSE if old vals should be overwritten
*   fileerr == TRUE to generate a missing file error
*              FALSE to return NO_ERR instead, if file not found
*
* RETURNS:
*   status of the operation
*********************************************************************/
status_t 
    conf_parse_val_from_filespec (const xmlChar *filespec,
                                  val_value_t *val,
                                  boolean keepvals,
                                  boolean fileerr)
{
    tk_chain_t    *tkc;
    FILE          *fp;
    xmlChar       *sourcespec;
    status_t       res;

#ifdef DEBUG
    if (!filespec || !val) {
        return SET_ERROR(ERR_INTERNAL_PTR);
    } 
#endif

    if (*filespec == 0) {
        log_error("\nError: no config file name specified");
        return ERR_NCX_INVALID_VALUE;
    }
        
    res = NO_ERR;
    sourcespec = ncx_get_source(filespec, &res);
    if (!sourcespec) {
        return res;
    }

    fp = fopen((const char *)sourcespec, "r");

    if (!fp) {
        m__free(sourcespec);
        if (fileerr) {
            log_error("\nError: config file '%s' could not be opened",
                      filespec);
            return ERR_FIL_OPEN;
        } else {
            return NO_ERR;
        }
    }

    if (LOGINFO) {
        log_info("\nLoading CLI parameters from '%s'", sourcespec);
    }

    m__free(sourcespec);
    sourcespec = NULL;

    /* get a new token chain */
    res = NO_ERR;
    tkc = tk_new_chain();
    if (!tkc) {
        res = ERR_INTERNAL_MEM;
        ncx_print_errormsg(NULL, NULL, res);
        fclose(fp);
        return res;
    }

    /* else setup the token chain and parse this config file */
    tk_setup_chain_conf(tkc, fp, filespec);

    res = tk_tokenize_input(tkc, NULL);

#ifdef CONF_TK_DEBUG
    if (LOGDEBUG3) {
        tk_dump_chain(tkc);
    }
#endif

    if (res == NO_ERR) {
        res = parse_top(tkc, val, keepvals);
    }

    fclose(fp);
    tkc->fp = NULL;
    tk_free_chain(tkc);

    if (res != NO_ERR) {
        log_error("\nError: invalid .conf file '%s' (%s)",
                  filespec,
                  get_error_string(res));
    }

    return res;

}  /* conf_parse_val_from_filespec */
Exemple #3
0
void
do_command(int fanout, char *username)
{
    struct sigaction signaler;
    FILE *fd, *fda, *in;
    char buf[MAXBUF], cbuf[MAXBUF], pipebuf[2048];
    char *command = TOP_COMMAND;
    int status, i, j, n, g, pollret, nrofargs, arg, slen, fdf;
    int tnodes, k, l;
    char *p, **q, **rsh, *cd, **cmd, *rshstring;
    char *scriptbase, *scriptdir;
    node_t *nodeptr, *nodehold;
    struct pollfd fds[2];
    
    maxnodelen = 0;
    j = i = 0;
    in = NULL;
    cd = pipebuf;
    exitflag = 0;
    sortedprocs = NULL;

    if (debug) {
	if (username != NULL)
	    (void)printf("As User: %s\n", username);
	(void)printf("On nodes:\n");
    }
    for (nodeptr = nodelink; nodeptr; nodeptr = nodeptr->next) {
	if (strlen(nodeptr->name) > maxnodelen)
	    maxnodelen = strlen(nodeptr->name);
	if (debug) {
	    if (!(j % 4) && j > 0)
		(void)printf("\n");
	    (void)printf("%s\t", nodeptr->name);
	}
	j++;
    }
    if (maxnodelen < 8)
	    maxnodelen = 8;
    
    i = j; /* side effect of above */
    tnodes = i;
    j = i / fanout;
    if (i % fanout)
	j++; /* compute the # of rungroups */

    nodedata = calloc(tnodes, sizeof(nodedata_t));
    sortnode = calloc(tnodes, sizeof(nodedata_t));
    if (nodedata == NULL || sortnode == NULL)
	    bailout();

    /* the per-node array of procs */
    procdata = calloc(tnodes, sizeof(procdata_t *));
    if (procdata == NULL)
	    bailout();
    
    if (debug) {
	(void)printf("\nDo Command: %s\n", command);
	(void)printf("Fanout: %d Groups:%d\n", fanout, j);
    }

#if 0
    /* XXX this is going to be a problem */
    close(STDIN_FILENO); /* DAMN this bug took awhile to find */
    if (open("/dev/null", O_RDONLY, NULL) != 0)
	    bailout();
#endif
    signaler.sa_handler = sig_handler;
    signaler.sa_flags = 0;
    sigaction(SIGTERM, &signaler, NULL);
    sigaction(SIGINT, &signaler, NULL);
    
    rsh = parse_rcmd("RCMD_CMD", "RCMD_CMD_ARGS", &nrofargs);
    rshstring = build_rshstring(rsh, nrofargs);

    if (!batchflag)
	    curses_setup();
    
    /* begin the processing loop */
    while (!exitflag) {
	g = 0;
        nodeptr = nodelink;
        for (n=0; n <= j; n++) { /* fanout group */
	    if (exitflag)
		    goto out;
	    nodehold = nodeptr;
	    for (i=0; (i < fanout && nodeptr != NULL); i++) {
		g++;
		if (exitflag)
			goto out;
		if (debug)
		    (void)printf("Working node: %d, fangroup %d,"
			" fanout part: %d\n", g, n, i);
/*
 * we set up pipes for each node, to prepare for the oncoming barrage of data.
 * Close on exec must be set here, otherwise children spawned after other
 * children, inherit the open file descriptors, and cause the pipes to remain
 * open forever.
 */
		if (pipe(nodeptr->out.fds) != 0)
		    bailout();
		if (pipe(nodeptr->err.fds) != 0)
		    bailout();
		if (fcntl(nodeptr->out.fds[0], F_SETFD, 1) == -1)
		    bailout();
		if (fcntl(nodeptr->out.fds[1], F_SETFD, 1) == -1)
		    bailout();
		if (fcntl(nodeptr->err.fds[0], F_SETFD, 1) == -1)
		    bailout();
		if (fcntl(nodeptr->err.fds[1], F_SETFD, 1) == -1)
		    bailout();
		nodeptr->childpid = fork();
		switch (nodeptr->childpid) {
		    /* its the ol fork and switch routine eh? */
		case -1:
		    bailout();
		    break;
		case 0:
		    /* remove from parent group to avoid kernel
		     * passing signals to children.
		     */
		    (void)setsid();
		    if (dup2(nodeptr->out.fds[1], STDOUT_FILENO) 
			!= STDOUT_FILENO) 
			bailout();
		    if (dup2(nodeptr->err.fds[1], STDERR_FILENO)
			!= STDERR_FILENO)
			bailout();
		    if (close(nodeptr->out.fds[0]) != 0)
			bailout();
		    if (close(nodeptr->err.fds[0]) != 0)
			bailout();
		    /* stdin & stderr non-blocking */
		    fdf = fcntl(nodeptr->out.fds[0], F_GETFL);
		    fcntl(nodeptr->out.fds[0], F_SETFL, fdf|O_NONBLOCK);
		    fdf = fcntl(nodeptr->err.fds[0], F_GETFL);
		    fcntl(nodeptr->err.fds[0], F_SETFL, fdf|O_NONBLOCK);
		    
		    if (username != NULL)
			(void)snprintf(buf, MAXBUF, "%s@%s", username,
				       nodeptr->name);
		    else
			(void)snprintf(buf, MAXBUF, "%s", nodeptr->name);
		    if (debug)
			    (void)printf("%s %s %s\n", rshstring,
				buf, command);
		    if (testflag && rshport > 0 && porttimeout > 0)
			if (!test_node_connection(rshport, porttimeout,
						  nodeptr))
			    _exit(EXIT_SUCCESS);
		    cmd = calloc(nrofargs+1, sizeof(char *));
		    arg = 0;
		    while (rsh[arg] != NULL) {
			    cmd[arg] = rsh[arg];
			    arg++;
		    }
		    cmd[arg++] = buf;
		    cmd[arg++] = command;
		    cmd[arg] = (char *)0;
		    execvp(rsh[0], cmd);
		    bailout();
		    break;
		default:
		    break;
		} /* switch */
		nodeptr = nodeptr->next;
	    } /* for i */
	    nodeptr = nodehold;
	    for (i=0; (i < fanout && nodeptr != NULL); i++) {
	        int pid=0;
		    
		if (exitflag)
			goto out;
		if (debug)
		    (void)printf("Printing node: %d, fangroup %d,"
				 " fanout part: %d\n", ((n) ? g-fanout+i : i),
				 n, i);
		currentchild = nodeptr->childpid;
		/* now close off the useless stuff, and read the goodies */
		if (close(nodeptr->out.fds[1]) != 0)
		    bailout();
		if (close(nodeptr->err.fds[1]) != 0)
		    bailout();
		fda = fdopen(nodeptr->out.fds[0], "r"); /* stdout */
		if (fda == NULL)
		    bailout();
		fd = fdopen(nodeptr->err.fds[0], "r"); /* stderr */
		if (fd == NULL)
		    bailout();
		fds[0].fd = nodeptr->out.fds[0];
		fds[1].fd = nodeptr->err.fds[0];
		fds[0].events = POLLIN|POLLPRI;
		fds[1].events = POLLIN|POLLPRI;
		pollret = 1;

//		DPRINTF("HELLO: n=%d %d %d - %d %d\n", n, g-fanout+i, i, g, fanout);
		DPRINTF("HELLO: %d\n", n*fanout + i);
		while (pollret >= 0) {
		    int gotdata;

		    pollret = poll(fds, 2, 5);
		    gotdata = 0;
		    if ((fds[0].revents&POLLIN) == POLLIN ||
			(fds[0].revents&POLLHUP) == POLLHUP ||
		        (fds[0].revents&POLLPRI) == POLLPRI) {
#ifdef __linux__
			cd = fgets(pipebuf, sizeof(pipebuf), fda);
			if (cd != NULL) {
#else
			while ((cd = fgets(pipebuf, sizeof(pipebuf), fda))) {
#endif
				pid += parse_top(cd, nodeptr,
				    n*fanout + i, pid);
			    gotdata++;
			}
		    }
		    if ((fds[1].revents&POLLIN) == POLLIN ||
			(fds[1].revents&POLLHUP) == POLLHUP ||
			(fds[1].revents&POLLPRI) == POLLPRI) {
#ifdef __linux__
			cd = fgets(pipebuf, sizeof(pipebuf), fd);
			if (cd != NULL) {
#else
			while ((cd = fgets(pipebuf, sizeof(pipebuf), fd))) {
#endif
			    gotdata++;
			}
		    }
		    if (!gotdata)
			if (((fds[0].revents&POLLHUP) == POLLHUP ||
			     (fds[0].revents&POLLERR) == POLLERR ||
			     (fds[0].revents&POLLNVAL) == POLLNVAL) &&
			    ((fds[1].revents&POLLHUP) == POLLHUP ||
			     (fds[1].revents&POLLERR) == POLLERR ||
			     (fds[1].revents&POLLNVAL) == POLLNVAL))
			    break;
		}
		fclose(fda);
		fclose(fd);
		(void)wait(&status);
		nodeptr = nodeptr->next;
	    } /* for pipe read */
	    totalpids = 0;
	    for (k=0; k < tnodes; k++) {
		    totalpids += nodedata[k].procs;
		    DPRINTF("k=%d procs=%d\n", k, nodedata[k].procs);
	    }
	    DPRINTF(" total of %d pids\n", totalpids);
	    if (sortedprocs != NULL)
		    free(sortedprocs);
	    sortedprocs = calloc(totalpids, sizeof(procdata_t *));
	    i = 0;
	    DPRINTF("tnodes=%d\n", tnodes);
	    for (k=0; k < tnodes; k++) {
		    DPRINTF("node %d procs==%d\n", k, nodedata[k].procs);
		    for (l=0; l < nodedata[k].procs; l++) {
			    if (procdata[k][l].node != NULL &&
				strcmp(procdata[k][l].command, "")) {
				    sortedprocs[i] = &procdata[k][l];
				    DPRINTF("pdata=%p\n", &procdata[k][l]);
				    i++;
			    }
		    }
	    }
	    qsort(sortedprocs, i, sizeof(procdata_t *), compare_proc);
#if 0
	    for (k=0; k < i; k++)
		    DPRINTF("node=%s, pid=%d, cpu=%f\n",
			sortedprocs[k]->node->name, sortedprocs[k]->pid,
			sortedprocs[k]->cpu);
#endif
	    if (!batchflag && !debug) {
		    curses_print(i, tnodes);
		    curses_getkey();
	    }
	} /* for n */
	DPRINTF("fanout done\n");
	if (batchflag == 1 || debug) {
		batch_print(i, tnodes);
		exitflag = 1;
	}
    } /* while loop */
out:
    if (!batchflag && !debug) {
	    move(LINES, 0);
	    endwin();
    }
    
    free(rshstring);
    for (i=0; rsh[i] != NULL; i++)
	    free(rsh[i]);
    free(rsh);
}

void
sig_handler(int i)
{
	switch (i) {
	case SIGINT:
	case SIGTERM:
		exitflag = 1;
		break;
	default:
		bailout();
		break;
	}
}