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'."); }
/******************************************************************** * 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 */
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; } }