int argv_prepend_nosize(char ***argv, const char *arg) { int argc; int i; /* Create new argv. */ if (NULL == *argv) { *argv = (char**) malloc(2 * sizeof(char *)); if (NULL == *argv) { return RT_FAILURE; } (*argv)[0] = strdup(arg); (*argv)[1] = NULL; } else { /* count how many entries currently exist */ argc = argv_count(*argv); *argv = (char**) realloc(*argv, (argc + 2) * sizeof(char *)); if (NULL == *argv) { return RT_FAILURE; } (*argv)[argc+1] = NULL; /* shift all existing elements down 1 */ for (i=argc; 0 < i; i--) { (*argv)[i] = (*argv)[i-1]; } (*argv)[0] = strdup(arg); } return RT_SUCCESS; }
/* * allocate resources for a job. * * The job will consist of at least one app, e.g., "allocate * jobid=100 return=all timeout=10:app=0 np=5 N=2 * node_list=vm2,vm3 flag=mandatory:app=1 N=2". * * IN: * new_fd: send allocation result to socket_fd * msg: resource requirement cmd */ extern void allocate_job_op(slurm_fd_t new_fd, const char *msg) { char orte_jobid[16] = ""; char return_flag[16] = ""; size_t job_timeout = 15; /* if not specified, by default */ char send_buf[SIZE]; char **app_argv = NULL, **tmp_app_argv; size_t app_timeout; uint32_t app_count = 1; char app_resp_msg[SIZE]; char **all_resp_msg_argv = NULL, **tmp_all_resp_msg_argv; app_argv = argv_split(msg, ':'); /* app_count dose not include the first part (job info) */ app_count = argv_count(app_argv) - 1; /* app_argv will be freed */ tmp_app_argv = app_argv; while (*tmp_app_argv) { if (strstr(*tmp_app_argv, "allocate")) { _parse_job_params(*tmp_app_argv, orte_jobid, return_flag, &job_timeout); } else if (strstr(*tmp_app_argv, "app")) { app_timeout = job_timeout / app_count; _allocate_app_op(*tmp_app_argv, app_timeout, app_resp_msg); if (0 == strcmp(return_flag, "all") && 0 != strlen(app_resp_msg)) { argv_append_nosize(&all_resp_msg_argv, app_resp_msg); } else if (0 != strlen(app_resp_msg)) { /* if return_flag != "all", * each app's allocation will be sent individually */ sprintf(send_buf, "jobid=%s:%s", orte_jobid, app_resp_msg); info("BBB: send to client: %s", send_buf); send_reply(new_fd, send_buf); } } tmp_app_argv++; } /* free app_argv */ argv_free(app_argv); if (0 == strcmp(return_flag, "all")) { sprintf(send_buf, "jobid=%s", orte_jobid); /* all_resp_msg_argv will be freed */ tmp_all_resp_msg_argv = all_resp_msg_argv; while (*tmp_all_resp_msg_argv) { sprintf(send_buf, "%s:%s", send_buf, *tmp_all_resp_msg_argv); tmp_all_resp_msg_argv++; } /* free all_resp_msg_argv */ argv_free(all_resp_msg_argv); info("BBB: send to client: %s", send_buf); send_reply(new_fd, send_buf); } }
int argv_insert(char ***target, int start, char **source) { int i, source_count, target_count; int suffix_count; /* Check for the bozo cases */ if (NULL == target || NULL == *target || start < 0) { return RT_FAILURE; } else if (NULL == source) { return RT_SUCCESS; } /* Easy case: appending to the end */ target_count = argv_count(*target); source_count = argv_count(source); if (start > target_count) { for (i = 0; i < source_count; ++i) { argv_append(&target_count, target, source[i]); } } /* Harder: insertting into the middle */ else { /* Alloc out new space */ *target = (char**) realloc(*target, sizeof(char *) * (target_count + source_count + 1)); /* Move suffix items down to the end */ suffix_count = target_count - start; for (i = suffix_count - 1; i >= 0; --i) { (*target)[start + source_count + i] = (*target)[start + i]; } (*target)[start + suffix_count + source_count] = NULL; /* Strdup in the source argv */ for (i = start; i < start + source_count; ++i) { (*target)[i] = strdup(source[i - start]); } } /* All done */ return RT_SUCCESS; }
/* * Append a string to the end of a new or existing argv array. */ int argv_append(int *argc, char ***argv, const char *arg) { int rc; /* add the new element */ if (RT_SUCCESS != (rc = argv_append_nosize(argv, arg))) { return rc; } *argc = argv_count(*argv); return RT_SUCCESS; }
int argv_delete(int *argc, char ***argv, int start, int num_to_delete) { int i; int count; int suffix_count; char **tmp; /* Check for the bozo cases */ if (NULL == argv || NULL == *argv || 0 == num_to_delete) { return RT_SUCCESS; } count = argv_count(*argv); if (start > count) { return RT_SUCCESS; } else if (start < 0 || num_to_delete < 0) { return RT_FAILURE; } /* Ok, we have some tokens to delete. Calculate the new length of * the argv array. */ suffix_count = count - (start + num_to_delete); if (suffix_count < 0) { suffix_count = 0; } /* Free all items that are being deleted */ for (i = start; i < count && i < start + num_to_delete; ++i) { free((*argv)[i]); } /* Copy the suffix over the deleted items */ for (i = start; i < start + suffix_count; ++i) { (*argv)[i] = (*argv)[i + num_to_delete]; } /* Add the trailing NULL */ (*argv)[i] = NULL; /* adjust the argv array */ tmp = (char**)realloc(*argv, sizeof(char**) * (i + 1)); if (NULL != tmp) *argv = tmp; /* adjust the argc */ (*argc) -= num_to_delete; return RT_SUCCESS; }
/* * Join all the elements of an argv array from within a * specified range into a single newly-allocated string. */ char *argv_join_range(char **argv, size_t start, size_t end, int delimiter) { char **p; char *pp; char *str; size_t str_len = 0; size_t i; /* Bozo case */ if (NULL == argv || NULL == argv[0] || (int)start > argv_count(argv)) { return strdup(""); } /* Find the total string length in argv including delimiters. The * last delimiter is replaced by the NULL character. */ for (p = &argv[start], i=start; *p && i < end; ++p, ++i) { str_len += strlen(*p) + 1; } /* Allocate the string. */ if (NULL == (str = (char*) malloc(str_len))) return NULL; /* Loop filling in the string. */ str[--str_len] = '\0'; p = &argv[start]; pp = *p; for (i = 0; i < str_len; ++i) { if ('\0' == *pp) { /* End of a string, fill in a delimiter and go to the * next string. */ str[i] = (char) delimiter; ++p; pp = *p; } else { str[i] = *pp++; } } /* All done */ return str; }
int argv_append_nosize(char ***argv, const char *arg) { int argc; /* Create new argv. */ if (NULL == *argv) { *argv = (char**) malloc(2 * sizeof(char *)); if (NULL == *argv) { return RT_FAILURE; } argc = 0; (*argv)[0] = NULL; (*argv)[1] = NULL; } /* Extend existing argv. */ else { /* count how many entries currently exist */ argc = argv_count(*argv); *argv = (char**) realloc(*argv, (argc + 2) * sizeof(char *)); if (NULL == *argv) { return RT_FAILURE; } } /* Set the newest element to point to a copy of the arg string */ (*argv)[argc] = strdup(arg); if (NULL == (*argv)[argc]) { return RT_FAILURE; } argc = argc + 1; (*argv)[argc] = NULL; return RT_SUCCESS; }
int argv_insert_element(char ***target, int location, char *source) { int i, target_count; int suffix_count; /* Check for the bozo cases */ if (NULL == target || NULL == *target || location < 0) { return RT_FAILURE; } else if (NULL == source) { return RT_SUCCESS; } /* Easy case: appending to the end */ target_count = argv_count(*target); if (location > target_count) { argv_append(&target_count, target, source); return RT_SUCCESS; } /* Alloc out new space */ *target = (char**) realloc(*target, sizeof(char*) * (target_count + 2)); /* Move suffix items down to the end */ suffix_count = target_count - location; for (i = suffix_count - 1; i >= 0; --i) { (*target)[location + 1 + i] = (*target)[location + i]; } (*target)[location + suffix_count + 1] = NULL; /* Strdup in the source */ (*target)[location] = strdup(source); /* All done */ return RT_SUCCESS; }
int getprop_main(const struct cmd_getprop_info* info) { const char* format = info->getprop.format; const char* format_not_found = info->getprop.format_not_found; bool null = info->getprop.null; if (null && format == NULL && format_not_found == NULL) usage_error("must supply --format or " "--format-not-found or both if using -0"); find_symbol_in_libc("__system_property_foreach", &property_foreach); if (property_foreach == NULL) property_foreach = compat_property_foreach; dbg("using %s for property enumeration", property_foreach == compat_property_foreach ? "compat_property_foreach" : "__system_property_foreach"); int exit_status = 0; struct json_writer* writer = NULL; if (format == NULL && format_not_found == NULL) { writer = json_writer_create(xstdout); json_begin_object(writer); } const char** properties = ARGV_CONCAT(info->properties); bool first = true; char sep = null ? '\0' : '\n'; if (*properties == NULL) { struct property_vector* pv = find_all_properties(); char prev_name[PROP_NAME_MAX]; for (size_t i = 0; i < pv->size; ++i) { char name[PROP_NAME_MAX]; char value[PROP_VALUE_MAX]; (void) __system_property_read(pv->props[i], name, value); if (i > 0 && strcmp(name, prev_name) == 0) continue; if (writer != NULL) { json_begin_field(writer, name); json_emit_string(writer, value); } else { output_property(&first, sep, format, name, value); } strcpy(prev_name, name); } } else { size_t nproperties = argv_count(properties); qsort(properties, nproperties, sizeof (properties[0]), property_argv_compare); const char* property; const char* prev_property = NULL; while ((property = *properties++)) { if (prev_property != NULL && !strcmp(prev_property, property)) continue; if (writer != NULL) json_begin_field(writer, property); const prop_info* pi = __system_property_find(property); if (pi) { char value[PROP_VALUE_MAX]; __system_property_read(pi, NULL, value); if (writer != NULL) json_emit_string(writer, value); else if (format != NULL) output_property(&first, sep, format, property, value); } else { if (writer != NULL) json_emit_null(writer); else if (format_not_found != NULL) output_property(&first, sep, format_not_found, property, NULL); exit_status = 4; } prev_property = property; } } if (writer == NULL && !first && !null) xputc(sep, xstdout); if (writer != NULL) json_end_object(writer); xflush(xstdout); return exit_status; }
static void read_cf(void) { char tmp[0x100], lv[0x20], rv[0x20]; struct conf_item *ci = NULL; FILE *fd; size_t len; int lnum, found, v_int; char *lp, *conv_err; bool file_needs_update = false; char *cfname = get_confname(); if (access(cfname, F_OK) != 0) goto done; fd = fopen(cfname, "r"); if (fd == NULL) err_sys("can not read configuration file '%s'", cfname); for (lnum = 1; fgets(tmp, sizeof(tmp), fd); lnum++) { lp = tmp + strspn(tmp, " "); if (*lp == '#' || *lp == '\n') continue; len = strcspn(lp, " ="); if (len > sizeof(lv)) err_quit("parse error in %s, line %d: identifier too long", cfname, lnum); strncpy(lv, lp, len); lv[len] = '\0'; lp += len; ll_reset(conf_items); for (found = 0; !found && (ci = ll_getall(conf_items)); ) found = (ci->type != t_sep && ci->type != t_func && strcasecmp(ci->cfname, lv) == 0); if (!found) { err_msg("%s, line %d: ignoring unknown identifier '%s'", cfname, lnum, lv); file_needs_update = true; continue; } lp += strspn(lp, " "); if (*lp++ != '=') err_quit("parse error in %s, line %d: missing '=' operator in assignment", cfname, lnum); lp += strspn(lp, " "); len = strcspn(lp, " \n"); if (len > sizeof(rv)) err_quit("parse error in %s, line %d: argument too long", cfname, lnum); else if (*lp == '\n') err_quit("parse error in %s, line %d: argument expected", cfname, lnum); strncpy(rv, lp, len); rv[len] = '\0'; switch (ci->type) { case t_int: v_int = strtol(rv, &conv_err, 10); if (*conv_err != '\0') { err_quit("parse error in %s, line %d: integer value expected, '%s' found instead", cfname, lnum, rv); } else if (v_int > ci->max) { err_msg("%s, line %d: value exceeds maximum of %d - using maximum", cfname, lnum, (int)ci->max); *ci->v.i = ci->max; file_needs_update = true; } else if (v_int < ci->min) { err_msg("%s, line %d: value is below minimum of %d - using minimum", cfname, lnum, (int)ci->min); *ci->v.i = ci->min; file_needs_update = true; } else { *ci->v.i = v_int; } break; case t_list: assert(ci->list != NULL); if (!argv_count(ci->list)) err_quit("no usable %s candidates available for '%s'", ci->name, rv); v_int = argv_find(ci->list, rv); if (v_int < 0) { err_msg("%s, line %d: '%s = %s' is not valid - using defaults", cfname, lnum, lv, rv); file_needs_update = true; } else { *ci->v.i = v_int; } case t_sep: case t_func: break; } } fclose(fd); done: free(cfname); if (file_needs_update) { write_cf(); } }
static void write_cf(void) { char tmp[0x100], rv[0x40]; struct conf_item *ci = NULL; char *lp, *cp; int add, i; char *cfname = get_confname(); int cfld = ll_create(); FILE *fd = fopen(cfname, "w"); if (fd == NULL) err_sys("failed to open configuration file '%s'", cfname); for (ll_reset(conf_items); (ci = ll_getall(conf_items)); ) { if (ci->type != t_sep && ci->type != t_func && (!ci->dep || (ci->dep && *ci->dep))) { switch (ci->type) { case t_int: sprintf(rv, "%d", *ci->v.i); break; case t_list: if (!argv_count(ci->list)) continue; sprintf(rv, "%s", ci->list[*ci->v.i]); str_tolower(rv); break; case t_sep: case t_func: break; } add = 1; for (i = 0; i < ll_size(cfld); i++) { lp = ll_get(cfld, i); cp = lp += strspn(lp, " "); if (!strncasecmp(cp, ci->cfname, strcspn(cp, " =")) && strlen(ci->cfname) == strcspn(cp, " =")) { add = 0; cp += strcspn(cp, "=") + 1; cp += strspn(cp, " "); strncpy(tmp, cp, strcspn(cp, " #\n")); if (strcasecmp(tmp, rv)) { strncpy(tmp, lp, strcspn(lp, " =")); tmp[strcspn(lp, " =")] = '\0'; strcat(tmp, " = "); strcat(tmp, rv); strcat(tmp, "\n"); ll_replace(cfld, i, "s", tmp); } } } if (add) { strcpy(tmp, ci->cfname); strcat(tmp, " = "); strcat(tmp, rv); strcat(tmp, "\n"); ll_push(cfld, "s", tmp); } } } for (ll_reset(cfld); (lp = ll_getall(cfld)); ) fputs(lp, fd); fclose(fd); ll_destroy(cfld); free(cfname); }