/* * load_all_part_state - load the partition state from file, recover on * slurmctld restart. execute this after loading the configuration * file data. * NOTE: READ lock_slurmctld config before entry */ int load_all_part_state(void) { char *part_name = NULL, *allow_groups = NULL, *nodes = NULL; char *state_file, *data = NULL; uint32_t max_time, default_time, max_nodes, min_nodes; uint32_t grace_time = 0; time_t time; uint16_t def_part_flag, flags, hidden, root_only; uint16_t max_share, preempt_mode, priority, state_up; struct part_record *part_ptr; uint32_t data_size = 0, name_len; int data_allocated, data_read = 0, error_code = 0, part_cnt = 0; int state_fd; Buf buffer; char *ver_str = NULL; char* allow_alloc_nodes = NULL; uint16_t protocol_version = (uint16_t)NO_VAL; char* alternate = NULL; /* read the file */ lock_state_files(); state_fd = _open_part_state_file(&state_file); if (state_fd < 0) { info("No partition state file (%s) to recover", state_file); error_code = ENOENT; } else { data_allocated = BUF_SIZE; data = xmalloc(data_allocated); while (1) { data_read = read(state_fd, &data[data_size], BUF_SIZE); if (data_read < 0) { if (errno == EINTR) continue; else { error("Read error on %s: %m", state_file); break; } } else if (data_read == 0) /* eof */ break; data_size += data_read; data_allocated += data_read; xrealloc(data, data_allocated); } close(state_fd); } xfree(state_file); unlock_state_files(); buffer = create_buf(data, data_size); safe_unpackstr_xmalloc( &ver_str, &name_len, buffer); debug3("Version string in part_state header is %s", ver_str); if(ver_str) { if (!strcmp(ver_str, PART_STATE_VERSION)) { protocol_version = SLURM_PROTOCOL_VERSION; } else if(!strcmp(ver_str, PART_2_1_STATE_VERSION)) { protocol_version = SLURM_2_1_PROTOCOL_VERSION; } } if (protocol_version == (uint16_t)NO_VAL) { error("**********************************************************"); error("Can not recover partition state, data version incompatible"); error("**********************************************************"); xfree(ver_str); free_buf(buffer); return EFAULT; } xfree(ver_str); safe_unpack_time(&time, buffer); while (remaining_buf(buffer) > 0) { if (protocol_version >= SLURM_2_3_PROTOCOL_VERSION) { safe_unpackstr_xmalloc(&part_name, &name_len, buffer); safe_unpack32(&grace_time, buffer); safe_unpack32(&max_time, buffer); safe_unpack32(&default_time, buffer); safe_unpack32(&max_nodes, buffer); safe_unpack32(&min_nodes, buffer); safe_unpack16(&flags, buffer); safe_unpack16(&max_share, buffer); safe_unpack16(&preempt_mode, buffer); safe_unpack16(&priority, buffer); if (priority > part_max_priority) part_max_priority = priority; safe_unpack16(&state_up, buffer); safe_unpackstr_xmalloc(&allow_groups, &name_len, buffer); safe_unpackstr_xmalloc(&allow_alloc_nodes, &name_len, buffer); safe_unpackstr_xmalloc(&alternate, &name_len, buffer); safe_unpackstr_xmalloc(&nodes, &name_len, buffer); if ((flags & PART_FLAG_DEFAULT_CLR) || (flags & PART_FLAG_HIDDEN_CLR) || (flags & PART_FLAG_NO_ROOT_CLR) || (flags & PART_FLAG_ROOT_ONLY_CLR)) { error("Invalid data for partition %s: flags=%u", part_name, flags); error_code = EINVAL; } } else if (protocol_version >= SLURM_2_2_PROTOCOL_VERSION) { safe_unpackstr_xmalloc(&part_name, &name_len, buffer); safe_unpack32(&max_time, buffer); safe_unpack32(&default_time, buffer); safe_unpack32(&max_nodes, buffer); safe_unpack32(&min_nodes, buffer); safe_unpack16(&flags, buffer); safe_unpack16(&max_share, buffer); safe_unpack16(&preempt_mode, buffer); safe_unpack16(&priority, buffer); if (priority > part_max_priority) part_max_priority = priority; safe_unpack16(&state_up, buffer); safe_unpackstr_xmalloc(&allow_groups, &name_len, buffer); safe_unpackstr_xmalloc(&allow_alloc_nodes, &name_len, buffer); safe_unpackstr_xmalloc(&alternate, &name_len, buffer); safe_unpackstr_xmalloc(&nodes, &name_len, buffer); if ((flags & PART_FLAG_DEFAULT_CLR) || (flags & PART_FLAG_HIDDEN_CLR) || (flags & PART_FLAG_NO_ROOT_CLR) || (flags & PART_FLAG_ROOT_ONLY_CLR)) { error("Invalid data for partition %s: flags=%u", part_name, flags); error_code = EINVAL; } } else { safe_unpackstr_xmalloc(&part_name, &name_len, buffer); safe_unpack32(&max_time, buffer); safe_unpack32(&default_time, buffer); safe_unpack32(&max_nodes, buffer); safe_unpack32(&min_nodes, buffer); safe_unpack16(&def_part_flag, buffer); safe_unpack16(&hidden, buffer); safe_unpack16(&root_only, buffer); safe_unpack16(&max_share, buffer); safe_unpack16(&priority, buffer); if (priority > part_max_priority) part_max_priority = priority; safe_unpack16(&state_up, buffer); if (state_up == 0) state_up = PARTITION_DOWN; else state_up = PARTITION_UP; safe_unpackstr_xmalloc(&allow_groups, &name_len, buffer); safe_unpackstr_xmalloc(&allow_alloc_nodes, &name_len, buffer); safe_unpackstr_xmalloc(&nodes, &name_len, buffer); flags = 0; if (def_part_flag) flags |= PART_FLAG_DEFAULT; if (hidden) flags |= PART_FLAG_HIDDEN; if (root_only); flags |= PART_FLAG_ROOT_ONLY; if ((def_part_flag > 1) || (root_only > 1) || (hidden > 1)) { error("Invalid data for partition %s: " "def_part_flag=%u hidden=%u root_only=%u", part_name, def_part_flag, hidden, root_only); error_code = EINVAL; } preempt_mode = (uint16_t) NO_VAL; } /* validity test as possible */ if (state_up > PARTITION_UP) { error("Invalid data for partition %s: state_up=%u", part_name, state_up); error_code = EINVAL; } if (error_code) { error("No more partition data will be processed from " "the checkpoint file"); xfree(allow_groups); xfree(allow_groups); xfree(part_name); xfree(nodes); error_code = EINVAL; break; } /* find record and perform update */ part_ptr = list_find_first(part_list, &list_find_part, part_name); part_cnt++; if (part_ptr == NULL) { info("load_all_part_state: partition %s missing from " "configuration file", part_name); part_ptr = create_part_record(); xfree(part_ptr->name); part_ptr->name = xstrdup(part_name); } part_ptr->flags = flags; if (part_ptr->flags & PART_FLAG_DEFAULT) { xfree(default_part_name); default_part_name = xstrdup(part_name); default_part_loc = part_ptr; } part_ptr->max_time = max_time; part_ptr->default_time = default_time; part_ptr->max_nodes = max_nodes; part_ptr->max_nodes_orig = max_nodes; part_ptr->min_nodes = min_nodes; part_ptr->min_nodes_orig = min_nodes; part_ptr->max_share = max_share; part_ptr->grace_time = grace_time; if (preempt_mode != (uint16_t) NO_VAL) part_ptr->preempt_mode = preempt_mode; part_ptr->priority = priority; part_ptr->state_up = state_up; xfree(part_ptr->allow_groups); part_ptr->allow_groups = allow_groups; xfree(part_ptr->allow_alloc_nodes); part_ptr->allow_alloc_nodes = allow_alloc_nodes; xfree(part_ptr->alternate); part_ptr->alternate = alternate; xfree(part_ptr->nodes); part_ptr->nodes = nodes; xfree(part_name); } info("Recovered state of %d partitions", part_cnt); free_buf(buffer); return error_code; unpack_error: error("Incomplete partition data checkpoint file"); info("Recovered state of %d partitions", part_cnt); free_buf(buffer); return EFAULT; }
int tail_main(int argc, char **argv) { long count = 10; unsigned int sleep_period = 1; int from_top = 0; int follow = 0; int header_threshhold = 1; #ifdef CONFIG_FEATURE_FANCY_TAIL int count_bytes = 0; #endif char *tailbuf; size_t tailbufsize; int taillen = 0; int newline = 0; int *fds, nfiles, nread, nwrite, seen, i, opt; char *s, *buf; const char *fmt; /* Allow legacy syntax of an initial numeric option without -n. */ if (argc >=2 && ((argv[1][0] == '+') || ((argv[1][0] == '-') /* && (isdigit)(argv[1][1]) */ && (((unsigned int)(argv[1][1] - '0')) <= 9)))) { optind = 2; optarg = argv[1]; goto GET_COUNT; } while ((opt = getopt(argc, argv, tail_opts)) > 0) { switch (opt) { case 'f': follow = 1; break; #ifdef CONFIG_FEATURE_FANCY_TAIL case 'c': count_bytes = 1; /* FALLS THROUGH */ #endif case 'n': GET_COUNT: count = bb_xgetlarg10_sfx(optarg, tail_suffixes); /* Note: Leading whitespace is an error trapped above. */ if (*optarg == '+') { from_top = 1; } else { from_top = 0; } if (count < 0) { count = -count; } break; #ifdef CONFIG_FEATURE_FANCY_TAIL case 'q': header_threshhold = INT_MAX; break; case 's': sleep_period =bb_xgetularg10_bnd(optarg, 0, UINT_MAX); break; case 'v': header_threshhold = 0; break; #endif default: bb_show_usage(); } } /* open all the files */ fds = (int *)xmalloc(sizeof(int) * (argc - optind + 1)); argv += optind; nfiles = i = 0; if ((argc -= optind) == 0) { struct stat statbuf; if (!fstat(STDIN_FILENO, &statbuf) && S_ISFIFO(statbuf.st_mode)) { follow = 0; } /* --argv; */ *argv = (char *) bb_msg_standard_input; goto DO_STDIN; } do { if ((argv[i][0] == '-') && !argv[i][1]) { DO_STDIN: fds[nfiles] = STDIN_FILENO; } else if ((fds[nfiles] = open(argv[i], O_RDONLY)) < 0) { bb_perror_msg("%s", argv[i]); status = EXIT_FAILURE; continue; } argv[nfiles] = argv[i]; ++nfiles; } while (++i < argc); if (!nfiles) { bb_error_msg_and_die("no files"); } tailbufsize = BUFSIZ; #ifdef CONFIG_FEATURE_FANCY_TAIL /* tail the files */ if (from_top < count_bytes) { /* Each is 0 or 1, so true iff 0 < 1. */ /* Hence, !from_top && count_bytes */ if (tailbufsize < count) { tailbufsize = count + BUFSIZ; } } #endif buf = tailbuf = xmalloc(tailbufsize); fmt = header_fmt + 1; /* Skip header leading newline on first output. */ i = 0; do { /* Be careful. It would be possible to optimize the count-bytes * case if the file is seekable. If you do though, remember that * starting file position may not be the beginning of the file. * Beware of backing up too far. See example in wc.c. */ if ((!(count|from_top)) && (lseek(fds[i], 0, SEEK_END) >= 0)) { continue; } if (nfiles > header_threshhold) { tail_xprint_header(fmt, argv[i]); fmt = header_fmt; } buf = tailbuf; taillen = 0; seen = 1; while ((nread = tail_read(fds[i], buf, tailbufsize-taillen)) > 0) { if (from_top) { nwrite = nread; if (seen < count) { #ifdef CONFIG_FEATURE_FANCY_TAIL if (count_bytes) { nwrite -= (count - seen); seen = count; } else #endif { s = buf; do { --nwrite; if ((*s++ == '\n') && (++seen == count)) { break; } } while (nwrite); } } tail_xbb_full_write(buf + nread - nwrite, nwrite); } else if (count) { #ifdef CONFIG_FEATURE_FANCY_TAIL if (count_bytes) { taillen += nread; if (taillen > count) { memmove(tailbuf, tailbuf + taillen - count, count); taillen = count; } } else #endif { int k = nread; int nbuf = 0; while (k) { --k; if (buf[k] == '\n') { ++nbuf; } } if (newline + nbuf < count) { newline += nbuf; taillen += nread; } else { int extra = 0; if (buf[nread-1] != '\n') { extra = 1; } k = newline + nbuf + extra - count; s = tailbuf; while (k) { if (*s == '\n') { --k; } ++s; } taillen += nread - (s - tailbuf); memmove(tailbuf, s, taillen); newline = count - extra; } if (tailbufsize < taillen + BUFSIZ) { tailbufsize = taillen + BUFSIZ; tailbuf = xrealloc(tailbuf, tailbufsize); } } buf = tailbuf + taillen; } } if (!from_top) { tail_xbb_full_write(tailbuf, taillen); } taillen = 0; } while (++i < nfiles); buf = xrealloc(tailbuf, BUFSIZ); fmt = NULL; while (follow) { sleep(sleep_period); i = 0; do { if (nfiles > header_threshhold) { fmt = header_fmt; } while ((nread = tail_read(fds[i], buf, sizeof(buf))) > 0) { if (fmt) { tail_xprint_header(fmt, argv[i]); fmt = NULL; } tail_xbb_full_write(buf, nread); } } while (++i < nfiles); } return status; }
static int _job_modify(uint32_t jobid, char *bank_ptr, char *depend_ptr, char *new_hostlist, uint32_t new_node_cnt, char *part_name_ptr, uint32_t new_time_limit, char *name_ptr, char *start_ptr, char *feature_ptr, char *env_ptr, char *comment_ptr, char *gres_ptr, char *wckey_ptr) { struct job_record *job_ptr; time_t now = time(NULL); bool update_accounting = false; job_ptr = find_job_record(jobid); if (job_ptr == NULL) { error("wiki: MODIFYJOB has invalid jobid %u", jobid); return ESLURM_INVALID_JOB_ID; } if (IS_JOB_FINISHED(job_ptr) || (job_ptr->details == NULL)) { info("wiki: MODIFYJOB jobid %u is finished", jobid); return ESLURM_DISABLED; } if (comment_ptr) { info("wiki: change job %u comment %s", jobid, comment_ptr); xfree(job_ptr->comment); job_ptr->comment = xstrdup(comment_ptr); last_job_update = now; } if (depend_ptr) { int rc = update_job_dependency(job_ptr, depend_ptr); if (rc == SLURM_SUCCESS) { info("wiki: changed job %u dependency to %s", jobid, depend_ptr); } else { error("wiki: changing job %u dependency to %s", jobid, depend_ptr); return EINVAL; } } if (env_ptr) { bool have_equal = false; char old_sep[1]; int begin = 0, i; if (job_ptr->batch_flag == 0) { error("wiki: attempt to set environment variables " "for non-batch job %u", jobid); return ESLURM_DISABLED; } for (i=0; ; i++) { if (env_ptr[i] == '=') { if (have_equal) { error("wiki: setting job %u invalid " "environment variables: %s", jobid, env_ptr); return EINVAL; } have_equal = true; if (env_ptr[i+1] == '\"') { for (i+=2; ; i++) { if (env_ptr[i] == '\0') { error("wiki: setting job %u " "invalid environment " "variables: %s", jobid, env_ptr); return EINVAL; } if (env_ptr[i] == '\"') { i++; break; } if (env_ptr[i] == '\\') { i++; } } } else if (env_ptr[i+1] == '\'') { for (i+=2; ; i++) { if (env_ptr[i] == '\0') { error("wiki: setting job %u " "invalid environment " "variables: %s", jobid, env_ptr); return EINVAL; } if (env_ptr[i] == '\'') { i++; break; } if (env_ptr[i] == '\\') { i++; } } } } if (isspace(env_ptr[i]) || (env_ptr[i] == ',')) { if (!have_equal) { error("wiki: setting job %u invalid " "environment variables: %s", jobid, env_ptr); return EINVAL; } old_sep[0] = env_ptr[i]; env_ptr[i] = '\0'; xrealloc(job_ptr->details->env_sup, sizeof(char *) * (job_ptr->details->env_cnt+1)); job_ptr->details->env_sup [job_ptr->details->env_cnt++] = xstrdup(&env_ptr[begin]); info("wiki: for job %u add env: %s", jobid, &env_ptr[begin]); env_ptr[i] = old_sep[0]; if (isspace(old_sep[0])) break; begin = i + 1; have_equal = false; } } } if (new_time_limit) { time_t old_time = job_ptr->time_limit; job_ptr->time_limit = new_time_limit; info("wiki: change job %u time_limit to %u", jobid, new_time_limit); /* Update end_time based upon change * to preserve suspend time info */ job_ptr->end_time = job_ptr->end_time + ((job_ptr->time_limit - old_time) * 60); last_job_update = now; } if (bank_ptr && (update_job_account("wiki", job_ptr, bank_ptr) != SLURM_SUCCESS)) { return EINVAL; } if (feature_ptr) { if (IS_JOB_PENDING(job_ptr) && (job_ptr->details)) { info("wiki: change job %u features to %s", jobid, feature_ptr); job_ptr->details->features = xstrdup(feature_ptr); last_job_update = now; } else { error("wiki: MODIFYJOB features of non-pending " "job %u", jobid); return ESLURM_DISABLED; } } if (start_ptr) { char *end_ptr; uint32_t begin_time = strtol(start_ptr, &end_ptr, 10); if (IS_JOB_PENDING(job_ptr) && (job_ptr->details)) { info("wiki: change job %u begin time to %u", jobid, begin_time); job_ptr->details->begin_time = begin_time; last_job_update = now; update_accounting = true; } else { error("wiki: MODIFYJOB begin_time of non-pending " "job %u", jobid); return ESLURM_DISABLED; } } if (name_ptr) { if (IS_JOB_PENDING(job_ptr)) { info("wiki: change job %u name %s", jobid, name_ptr); xfree(job_ptr->name); job_ptr->name = xstrdup(name_ptr); last_job_update = now; update_accounting = true; } else { error("wiki: MODIFYJOB name of non-pending job %u", jobid); return ESLURM_DISABLED; } } if (new_hostlist) { int rc = 0, task_cnt; hostlist_t hl; char *tasklist; if (!IS_JOB_PENDING(job_ptr) || !job_ptr->details) { /* Job is done, nothing to reset */ if (new_hostlist == '\0') goto host_fini; error("wiki: MODIFYJOB hostlist of non-pending " "job %u", jobid); return ESLURM_DISABLED; } xfree(job_ptr->details->req_nodes); FREE_NULL_BITMAP(job_ptr->details->req_node_bitmap); if (new_hostlist == '\0') goto host_fini; tasklist = moab2slurm_task_list(new_hostlist, &task_cnt); if (tasklist == NULL) { rc = 1; goto host_fini; } hl = hostlist_create(tasklist); if (hl == 0) { rc = 1; goto host_fini; } hostlist_uniq(hl); hostlist_sort(hl); job_ptr->details->req_nodes = hostlist_ranged_string_xmalloc(hl); hostlist_destroy(hl); if (job_ptr->details->req_nodes == NULL) { rc = 1; goto host_fini; } if (node_name2bitmap(job_ptr->details->req_nodes, false, &job_ptr->details->req_node_bitmap)) { rc = 1; goto host_fini; } host_fini: if (rc) { info("wiki: change job %u invalid hostlist %s", jobid, new_hostlist); xfree(job_ptr->details->req_nodes); return EINVAL; } else { info("wiki: change job %u hostlist %s", jobid, new_hostlist); update_accounting = true; } } if (part_name_ptr) { struct part_record *part_ptr; if (!IS_JOB_PENDING(job_ptr)) { error("wiki: MODIFYJOB partition of non-pending " "job %u", jobid); return ESLURM_DISABLED; } part_ptr = find_part_record(part_name_ptr); if (part_ptr == NULL) { error("wiki: MODIFYJOB has invalid partition %s", part_name_ptr); return ESLURM_INVALID_PARTITION_NAME; } info("wiki: change job %u partition %s", jobid, part_name_ptr); xfree(job_ptr->partition); job_ptr->partition = xstrdup(part_name_ptr); job_ptr->part_ptr = part_ptr; last_job_update = now; update_accounting = true; } if (new_node_cnt) { job_desc_msg_t job_desc; #ifdef HAVE_BG uint16_t geometry[SYSTEM_DIMENSIONS] = {(uint16_t) NO_VAL}; static uint16_t cpus_per_node = 0; if (!cpus_per_node) { select_g_alter_node_cnt(SELECT_GET_NODE_CPU_CNT, &cpus_per_node); } #endif if (!IS_JOB_PENDING(job_ptr) || !job_ptr->details) { error("wiki: MODIFYJOB node count of non-pending " "job %u", jobid); return ESLURM_DISABLED; } memset(&job_desc, 0, sizeof(job_desc_msg_t)); job_desc.min_nodes = new_node_cnt; job_desc.max_nodes = NO_VAL; job_desc.select_jobinfo = select_g_select_jobinfo_alloc(); select_g_alter_node_cnt(SELECT_SET_NODE_CNT, &job_desc); select_g_select_jobinfo_free(job_desc.select_jobinfo); job_ptr->details->min_nodes = job_desc.min_nodes; if (job_ptr->details->max_nodes && (job_ptr->details->max_nodes < job_desc.min_nodes)) job_ptr->details->max_nodes = job_desc.min_nodes; info("wiki: change job %u min_nodes to %u", jobid, new_node_cnt); #ifdef HAVE_BG job_ptr->details->min_cpus = job_desc.min_cpus; job_ptr->details->max_cpus = job_desc.max_cpus; job_ptr->details->pn_min_cpus = job_desc.pn_min_cpus; new_node_cnt = job_ptr->details->min_cpus; if (cpus_per_node) new_node_cnt /= cpus_per_node; /* This is only set up so accounting is set up correctly */ select_g_select_jobinfo_set(job_ptr->select_jobinfo, SELECT_JOBDATA_NODE_CNT, &new_node_cnt); /* reset geo since changing this makes any geo potentially invalid */ select_g_select_jobinfo_set(job_ptr->select_jobinfo, SELECT_JOBDATA_GEOMETRY, geometry); #endif last_job_update = now; update_accounting = true; } if (gres_ptr) { char *orig_gres; assoc_mgr_lock_t locks = { NO_LOCK, NO_LOCK, NO_LOCK, NO_LOCK, READ_LOCK, NO_LOCK, NO_LOCK }; if (!IS_JOB_PENDING(job_ptr)) { error("wiki: MODIFYJOB GRES of non-pending job %u", jobid); return ESLURM_DISABLED; } orig_gres = job_ptr->gres; job_ptr->gres = NULL; if (gres_ptr[0]) job_ptr->gres = xstrdup(gres_ptr); if (gres_plugin_job_state_validate(job_ptr->gres, &job_ptr->gres_list)) { error("wiki: MODIFYJOB Invalid GRES=%s", gres_ptr); xfree(job_ptr->gres); job_ptr->gres = orig_gres; return ESLURM_INVALID_GRES; } xfree(orig_gres); assoc_mgr_lock(&locks); gres_set_job_tres_cnt(job_ptr->gres_list, job_ptr->details ? job_ptr->details->min_nodes : 0, job_ptr->tres_req_cnt, true); xfree(job_ptr->tres_req_str); job_ptr->tres_req_str = assoc_mgr_make_tres_str_from_array( job_ptr->tres_req_cnt, TRES_STR_FLAG_SIMPLE, true); assoc_mgr_unlock(&locks); } if (wckey_ptr) { int rc = update_job_wckey("update_job", job_ptr, wckey_ptr); if (rc != SLURM_SUCCESS) { error("wiki: MODIFYJOB Invalid WCKEY=%s", wckey_ptr); return rc; } } if (update_accounting) { /* Update job record in accounting to reflect the changes */ jobacct_storage_job_start_direct(acct_db_conn, job_ptr); } return SLURM_SUCCESS; }
static void process_files(void) { char *pattern_space, *next_line; int linenum = 0; char last_puts_char = '\n'; char last_gets_char, next_gets_char; sed_cmd_t *sed_cmd; int substituted; /* Prime the pump */ next_line = get_next_line(&next_gets_char); /* go through every line in each file */ again: substituted = 0; /* Advance to next line. Stop if out of lines. */ pattern_space = next_line; if (!pattern_space) return; last_gets_char = next_gets_char; /* Read one line in advance so we can act on the last line, * the '$' address */ next_line = get_next_line(&next_gets_char); linenum++; restart: /* for every line, go through all the commands */ for (sed_cmd = G.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) { int old_matched, matched; old_matched = sed_cmd->in_match; /* Determine if this command matches this line: */ /* Are we continuing a previous multi-line match? */ sed_cmd->in_match = sed_cmd->in_match /* Or is no range necessary? */ || (!sed_cmd->beg_line && !sed_cmd->end_line && !sed_cmd->beg_match && !sed_cmd->end_match) /* Or did we match the start of a numerical range? */ || (sed_cmd->beg_line > 0 && (sed_cmd->beg_line == linenum)) /* Or does this line match our begin address regex? */ || (beg_match(sed_cmd, pattern_space)) /* Or did we match last line of input? */ || (sed_cmd->beg_line == -1 && next_line == NULL); /* Snapshot the value */ matched = sed_cmd->in_match; /* Is this line the end of the current match? */ if (matched) { sed_cmd->in_match = !( /* has the ending line come, or is this a single address command? */ (sed_cmd->end_line ? sed_cmd->end_line == -1 ? !next_line : (sed_cmd->end_line <= linenum) : !sed_cmd->end_match ) /* or does this line matches our last address regex */ || (sed_cmd->end_match && old_matched && (regexec(sed_cmd->end_match, pattern_space, 0, NULL, 0) == 0)) ); } /* Skip blocks of commands we didn't match. */ if (sed_cmd->cmd == '{') { if (sed_cmd->invert ? matched : !matched) { while (sed_cmd->cmd != '}') { sed_cmd = sed_cmd->next; if (!sed_cmd) bb_error_msg_and_die("unterminated {"); } } continue; } /* Okay, so did this line match? */ if (sed_cmd->invert ? !matched : matched) { /* Update last used regex in case a blank substitute BRE is found */ if (sed_cmd->beg_match) { G.previous_regex_ptr = sed_cmd->beg_match; } /* actual sedding */ switch (sed_cmd->cmd) { /* Print line number */ case '=': fprintf(G.nonstdout, "%d\n", linenum); break; /* Write the current pattern space up to the first newline */ case 'P': { char *tmp = strchr(pattern_space, '\n'); if (tmp) { *tmp = '\0'; /* TODO: explain why '\n' below */ sed_puts(pattern_space, '\n'); *tmp = '\n'; break; } /* Fall Through */ } /* Write the current pattern space to output */ case 'p': /* NB: we print this _before_ the last line * (of current file) is printed. Even if * that line is nonterminated, we print * '\n' here (gnu sed does the same) */ sed_puts(pattern_space, '\n'); break; /* Delete up through first newline */ case 'D': { char *tmp = strchr(pattern_space, '\n'); if (tmp) { tmp = xstrdup(tmp+1); free(pattern_space); pattern_space = tmp; goto restart; } } /* discard this line. */ case 'd': goto discard_line; /* Substitute with regex */ case 's': if (!do_subst_command(sed_cmd, &pattern_space)) break; substituted |= 1; /* handle p option */ if (sed_cmd->sub_p) sed_puts(pattern_space, last_gets_char); /* handle w option */ if (sed_cmd->sw_file) puts_maybe_newline( pattern_space, sed_cmd->sw_file, &sed_cmd->sw_last_char, last_gets_char); break; /* Append line to linked list to be printed later */ case 'a': append(sed_cmd->string); break; /* Insert text before this line */ case 'i': sed_puts(sed_cmd->string, '\n'); break; /* Cut and paste text (replace) */ case 'c': /* Only triggers on last line of a matching range. */ if (!sed_cmd->in_match) sed_puts(sed_cmd->string, NO_EOL_CHAR); goto discard_line; /* Read file, append contents to output */ case 'r': { FILE *rfile; rfile = fopen(sed_cmd->string, "r"); if (rfile) { char *line; while ((line = xmalloc_getline(rfile)) != NULL) append(line); xprint_and_close_file(rfile); } break; } /* Write pattern space to file. */ case 'w': puts_maybe_newline( pattern_space, sed_cmd->sw_file, &sed_cmd->sw_last_char, last_gets_char); break; /* Read next line from input */ case 'n': if (!G.be_quiet) sed_puts(pattern_space, last_gets_char); if (next_line) { free(pattern_space); pattern_space = next_line; last_gets_char = next_gets_char; next_line = get_next_line(&next_gets_char); linenum++; break; } /* fall through */ /* Quit. End of script, end of input. */ case 'q': /* Exit the outer while loop */ free(next_line); next_line = NULL; goto discard_commands; /* Append the next line to the current line */ case 'N': { int len; /* If no next line, jump to end of script and exit. */ if (next_line == NULL) { /* Jump to end of script and exit */ free(next_line); next_line = NULL; goto discard_line; /* append next_line, read new next_line. */ } len = strlen(pattern_space); pattern_space = realloc(pattern_space, len + strlen(next_line) + 2); pattern_space[len] = '\n'; strcpy(pattern_space + len+1, next_line); last_gets_char = next_gets_char; next_line = get_next_line(&next_gets_char); linenum++; break; } /* Test/branch if substitution occurred */ case 't': if (!substituted) break; substituted = 0; /* Fall through */ /* Test/branch if substitution didn't occur */ case 'T': if (substituted) break; /* Fall through */ /* Branch to label */ case 'b': if (!sed_cmd->string) goto discard_commands; else sed_cmd = branch_to(sed_cmd->string); break; /* Transliterate characters */ case 'y': { int i, j; for (i = 0; pattern_space[i]; i++) { for (j = 0; sed_cmd->string[j]; j += 2) { if (pattern_space[i] == sed_cmd->string[j]) { pattern_space[i] = sed_cmd->string[j + 1]; break; } } } break; } case 'g': /* Replace pattern space with hold space */ free(pattern_space); pattern_space = xstrdup(G.hold_space ? G.hold_space : ""); break; case 'G': /* Append newline and hold space to pattern space */ { int pattern_space_size = 2; int hold_space_size = 0; if (pattern_space) pattern_space_size += strlen(pattern_space); if (G.hold_space) hold_space_size = strlen(G.hold_space); pattern_space = xrealloc(pattern_space, pattern_space_size + hold_space_size); if (pattern_space_size == 2) pattern_space[0] = 0; strcat(pattern_space, "\n"); if (G.hold_space) strcat(pattern_space, G.hold_space); last_gets_char = '\n'; break; } case 'h': /* Replace hold space with pattern space */ free(G.hold_space); G.hold_space = xstrdup(pattern_space); break; case 'H': /* Append newline and pattern space to hold space */ { int hold_space_size = 2; int pattern_space_size = 0; if (G.hold_space) hold_space_size += strlen(G.hold_space); if (pattern_space) pattern_space_size = strlen(pattern_space); G.hold_space = xrealloc(G.hold_space, hold_space_size + pattern_space_size); if (hold_space_size == 2) *G.hold_space = 0; strcat(G.hold_space, "\n"); if (pattern_space) strcat(G.hold_space, pattern_space); break; } case 'x': /* Exchange hold and pattern space */ { char *tmp = pattern_space; pattern_space = G.hold_space ? : xzalloc(1); last_gets_char = '\n'; G.hold_space = tmp; break; } } } } /* * exit point from sedding... */ discard_commands: /* we will print the line unless we were told to be quiet ('-n') or if the line was suppressed (ala 'd'elete) */ if (!G.be_quiet) sed_puts(pattern_space, last_gets_char); /* Delete and such jump here. */ discard_line: flush_append(); free(pattern_space); goto again; }
/* Devilishly complex routine. * * Has to deal with EOF and EPIPE on input, * with line wrapping, with last line not ending in '\n' * (possibly not ending YET!), with backspace and tabs. * It reads input again if last time we got an EOF (thus supporting * growing files) or EPIPE (watching output of slow process like make). * * Variables used: * flines[] - array of lines already read. Linewrap may cause * one source file line to occupy several flines[n]. * flines[max_fline] - last line, possibly incomplete. * terminated - 1 if flines[max_fline] is 'terminated' * (if there was '\n' [which isn't stored itself, we just remember * that it was seen]) * max_lineno - last line's number, this one doesn't increment * on line wrap, only on "real" new lines. * readbuf[0..readeof-1] - small preliminary buffer. * readbuf[readpos] - next character to add to current line. * linepos - screen line position of next char to be read * (takes into account tabs and backspaces) * eof_error - < 0 error, == 0 EOF, > 0 not EOF/error */ static void read_lines(void) { #define readbuf bb_common_bufsiz1 char *current_line, *p; int w = width; char last_terminated = terminated; #if ENABLE_FEATURE_LESS_REGEXP unsigned old_max_fline = max_fline; time_t last_time = 0; unsigned seconds_p1 = 3; /* seconds_to_loop + 1 */ #endif if (option_mask32 & FLAG_N) w -= 8; USE_FEATURE_LESS_REGEXP(again0:) p = current_line = xmalloc(w); max_fline += last_terminated; if (!last_terminated) { const char *cp = flines[max_fline]; if (option_mask32 & FLAG_N) cp += 8; strcpy(current_line, cp); p += strlen(current_line); free((char*)flines[max_fline]); /* linepos is still valid from previous read_lines() */ } else { linepos = 0; } while (1) { /* read lines until we reach cur_fline or wanted_match */ *p = '\0'; terminated = 0; while (1) { /* read chars until we have a line */ char c; /* if no unprocessed chars left, eat more */ if (readpos >= readeof) { ndelay_on(0); eof_error = safe_read(0, readbuf, sizeof(readbuf)); ndelay_off(0); readpos = 0; readeof = eof_error; if (eof_error <= 0) goto reached_eof; } c = readbuf[readpos]; /* backspace? [needed for manpages] */ /* <tab><bs> is (a) insane and */ /* (b) harder to do correctly, so we refuse to do it */ if (c == '\x8' && linepos && p[-1] != '\t') { readpos++; /* eat it */ linepos--; /* was buggy (p could end up <= current_line)... */ *--p = '\0'; continue; } { size_t new_linepos = linepos + 1; if (c == '\t') { new_linepos += 7; new_linepos &= (~7); } if (new_linepos >= w) break; linepos = new_linepos; } /* ok, we will eat this char */ readpos++; if (c == '\n') { terminated = 1; linepos = 0; break; } /* NUL is substituted by '\n'! */ if (c == '\0') c = '\n'; *p++ = c; *p = '\0'; } /* end of "read chars until we have a line" loop */ /* Corner case: linewrap with only "" wrapping to next line */ /* Looks ugly on screen, so we do not store this empty line */ if (!last_terminated && !current_line[0]) { last_terminated = 1; max_lineno++; continue; } reached_eof: last_terminated = terminated; flines = xrealloc(flines, (max_fline+1) * sizeof(char *)); if (option_mask32 & FLAG_N) { /* Width of 7 preserves tab spacing in the text */ flines[max_fline] = xasprintf( (max_lineno <= 9999999) ? "%7u %s" : "%07u %s", max_lineno % 10000000, current_line); free(current_line); if (terminated) max_lineno++; } else { flines[max_fline] = xrealloc(current_line, strlen(current_line)+1); } if (max_fline >= MAXLINES) { eof_error = 0; /* Pretend we saw EOF */ break; } if (max_fline > cur_fline + max_displayed_line) { #if !ENABLE_FEATURE_LESS_REGEXP break; #else if (wanted_match >= num_matches) { /* goto_match called us */ fill_match_lines(old_max_fline); old_max_fline = max_fline; } if (wanted_match < num_matches) break; #endif } if (eof_error <= 0) { if (eof_error < 0) { if (errno == EAGAIN) { /* not yet eof or error, reset flag (or else * we will hog CPU - select() will return * immediately */ eof_error = 1; } else { print_statusline("read error"); } } #if !ENABLE_FEATURE_LESS_REGEXP break; #else if (wanted_match < num_matches) { break; } else { /* goto_match called us */ time_t t = time(NULL); if (t != last_time) { last_time = t; if (--seconds_p1 == 0) break; } sched_yield(); goto again0; /* go loop again (max 2 seconds) */ } #endif } max_fline++; current_line = xmalloc(w); p = current_line; linepos = 0; } /* end of "read lines until we reach cur_fline" loop */ fill_match_lines(old_max_fline); #if ENABLE_FEATURE_LESS_REGEXP /* prevent us from being stuck in search for a match */ wanted_match = -1; #endif #undef readbuf }
static int phase2_getc () { static char *buffer; static size_t bufmax; size_t buflen; int lineno; int c; bool last_was_star; if (phase2_pushback_length) return phase2_pushback[--phase2_pushback_length]; if (char_in_line == 0) { /* Eat whitespace, to recognize ^[\t ]*# pattern. */ do c = phase1_getc (); while (c == '\t' || c == ' '); if (c == '#') { /* sh comment. */ buflen = 0; lineno = line_number; for (;;) { c = phase1_getc (); if (c == '\n' || c == EOF) break; /* We skip all leading white space, but not EOLs. */ if (!(buflen == 0 && (c == ' ' || c == '\t'))) { if (buflen >= bufmax) { bufmax = 2 * bufmax + 10; buffer = xrealloc (buffer, bufmax); } buffer[buflen++] = c; } } if (buflen >= bufmax) { bufmax = 2 * bufmax + 10; buffer = xrealloc (buffer, bufmax); } buffer[buflen] = '\0'; xgettext_comment_add (buffer); last_comment_line = lineno; return '\n'; } } else c = phase1_getc (); if (c == '/') { c = phase1_getc (); switch (c) { default: phase1_ungetc (c); return '/'; case '*': /* C comment. */ buflen = 0; lineno = line_number; last_was_star = false; for (;;) { c = phase1_getc (); if (c == EOF) break; /* We skip all leading white space, but not EOLs. */ if (buflen == 0 && (c == ' ' || c == '\t')) continue; if (buflen >= bufmax) { bufmax = 2 * bufmax + 10; buffer = xrealloc (buffer, bufmax); } buffer[buflen++] = c; switch (c) { case '\n': --buflen; while (buflen >= 1 && (buffer[buflen - 1] == ' ' || buffer[buflen - 1] == '\t')) --buflen; buffer[buflen] = '\0'; xgettext_comment_add (buffer); buflen = 0; lineno = line_number; last_was_star = false; continue; case '*': last_was_star = true; continue; case '/': if (last_was_star) { buflen -= 2; while (buflen >= 1 && (buffer[buflen - 1] == ' ' || buffer[buflen - 1] == '\t')) --buflen; buffer[buflen] = '\0'; xgettext_comment_add (buffer); break; } /* FALLTHROUGH */ default: last_was_star = false; continue; } break; } last_comment_line = lineno; return ' '; case '/': /* C++ comment. */ buflen = 0; lineno = line_number; for (;;) { c = phase1_getc (); if (c == '\n' || c == EOF) break; /* We skip all leading white space, but not EOLs. */ if (!(buflen == 0 && (c == ' ' || c == '\t'))) { if (buflen >= bufmax) { bufmax = 2 * bufmax + 10; buffer = xrealloc (buffer, bufmax); } buffer[buflen++] = c; } } if (buflen >= bufmax) { bufmax = 2 * bufmax + 10; buffer = xrealloc (buffer, bufmax); } buffer[buflen] = '\0'; xgettext_comment_add (buffer); last_comment_line = lineno; return '\n'; } } else return c; }
int cmd_format_patch(int argc, const char **argv, const char *prefix) { struct commit *commit; struct commit **list = NULL; struct rev_info rev; int nr = 0, total, i, j; int use_stdout = 0; int start_number = -1; int keep_subject = 0; int numbered_files = 0; /* _just_ numbers */ int subject_prefix = 0; int ignore_if_in_upstream = 0; int cover_letter = 0; int boundary_count = 0; int no_binary_diff = 0; struct commit *origin = NULL, *head = NULL; const char *in_reply_to = NULL; struct patch_ids ids; char *add_signoff = NULL; struct strbuf buf = STRBUF_INIT; git_config(git_format_config, NULL); init_revisions(&rev, prefix); rev.commit_format = CMIT_FMT_EMAIL; rev.verbose_header = 1; rev.diff = 1; rev.combine_merges = 0; rev.ignore_merges = 1; DIFF_OPT_SET(&rev.diffopt, RECURSIVE); rev.subject_prefix = fmt_patch_subject_prefix; if (default_attach) { rev.mime_boundary = default_attach; rev.no_inline = 1; } /* * Parse the arguments before setup_revisions(), or something * like "git format-patch -o a123 HEAD^.." may fail; a123 is * possibly a valid SHA1. */ for (i = 1, j = 1; i < argc; i++) { if (!strcmp(argv[i], "--stdout")) use_stdout = 1; else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--numbered")) numbered = 1; else if (!strcmp(argv[i], "-N") || !strcmp(argv[i], "--no-numbered")) { numbered = 0; auto_number = 0; } else if (!prefixcmp(argv[i], "--start-number=")) start_number = strtol(argv[i] + 15, NULL, 10); else if (!strcmp(argv[i], "--numbered-files")) numbered_files = 1; else if (!strcmp(argv[i], "--start-number")) { i++; if (i == argc) die("Need a number for --start-number"); start_number = strtol(argv[i], NULL, 10); } else if (!prefixcmp(argv[i], "--cc=")) { ALLOC_GROW(extra_cc, extra_cc_nr + 1, extra_cc_alloc); extra_cc[extra_cc_nr++] = xstrdup(argv[i] + 5); } else if (!strcmp(argv[i], "-k") || !strcmp(argv[i], "--keep-subject")) { keep_subject = 1; rev.total = -1; } else if (!strcmp(argv[i], "--output-directory") || !strcmp(argv[i], "-o")) { i++; if (argc <= i) die("Which directory?"); if (output_directory) die("Two output directories?"); output_directory = argv[i]; } else if (!strcmp(argv[i], "--signoff") || !strcmp(argv[i], "-s")) { do_signoff = 1; } else if (!strcmp(argv[i], "--attach")) { rev.mime_boundary = git_version_string; rev.no_inline = 1; } else if (!prefixcmp(argv[i], "--attach=")) { rev.mime_boundary = argv[i] + 9; rev.no_inline = 1; } else if (!strcmp(argv[i], "--no-attach")) { rev.mime_boundary = NULL; rev.no_inline = 0; } else if (!strcmp(argv[i], "--inline")) { rev.mime_boundary = git_version_string; rev.no_inline = 0; } else if (!prefixcmp(argv[i], "--inline=")) { rev.mime_boundary = argv[i] + 9; rev.no_inline = 0; } else if (!strcmp(argv[i], "--ignore-if-in-upstream")) ignore_if_in_upstream = 1; else if (!strcmp(argv[i], "--thread") || !strcmp(argv[i], "--thread=shallow")) thread = THREAD_SHALLOW; else if (!strcmp(argv[i], "--thread=deep")) thread = THREAD_DEEP; else if (!strcmp(argv[i], "--no-thread")) thread = 0; else if (!prefixcmp(argv[i], "--in-reply-to=")) in_reply_to = argv[i] + 14; else if (!strcmp(argv[i], "--in-reply-to")) { i++; if (i == argc) die("Need a Message-Id for --in-reply-to"); in_reply_to = argv[i]; } else if (!prefixcmp(argv[i], "--subject-prefix=")) { subject_prefix = 1; rev.subject_prefix = argv[i] + 17; } else if (!prefixcmp(argv[i], "--suffix=")) fmt_patch_suffix = argv[i] + 9; else if (!strcmp(argv[i], "--cover-letter")) cover_letter = 1; else if (!strcmp(argv[i], "--no-binary")) no_binary_diff = 1; else if (!prefixcmp(argv[i], "--add-header=")) add_header(argv[i] + 13); else argv[j++] = argv[i]; } argc = j; if (do_signoff) { const char *committer; const char *endpos; committer = git_committer_info(IDENT_ERROR_ON_NO_NAME); endpos = strchr(committer, '>'); if (!endpos) die("bogus committer info %s", committer); add_signoff = xmemdupz(committer, endpos - committer + 1); } for (i = 0; i < extra_hdr_nr; i++) { strbuf_addstr(&buf, extra_hdr[i]); strbuf_addch(&buf, '\n'); } if (extra_to_nr) strbuf_addstr(&buf, "To: "); for (i = 0; i < extra_to_nr; i++) { if (i) strbuf_addstr(&buf, " "); strbuf_addstr(&buf, extra_to[i]); if (i + 1 < extra_to_nr) strbuf_addch(&buf, ','); strbuf_addch(&buf, '\n'); } if (extra_cc_nr) strbuf_addstr(&buf, "Cc: "); for (i = 0; i < extra_cc_nr; i++) { if (i) strbuf_addstr(&buf, " "); strbuf_addstr(&buf, extra_cc[i]); if (i + 1 < extra_cc_nr) strbuf_addch(&buf, ','); strbuf_addch(&buf, '\n'); } rev.extra_headers = strbuf_detach(&buf, 0); if (start_number < 0) start_number = 1; if (numbered && keep_subject) die ("-n and -k are mutually exclusive."); if (keep_subject && subject_prefix) die ("--subject-prefix and -k are mutually exclusive."); argc = setup_revisions(argc, argv, &rev, "HEAD"); if (argc > 1) die ("unrecognized argument: %s", argv[1]); if (!rev.diffopt.output_format || rev.diffopt.output_format == DIFF_FORMAT_PATCH) rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_PATCH; if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff) DIFF_OPT_SET(&rev.diffopt, BINARY); if (!use_stdout) output_directory = set_outdir(prefix, output_directory); if (output_directory) { if (use_stdout) die("standard output, or directory, which one?"); if (mkdir(output_directory, 0777) < 0 && errno != EEXIST) die("Could not create directory %s", output_directory); } if (rev.pending.nr == 1) { if (rev.max_count < 0 && !rev.show_root_diff) { /* * This is traditional behaviour of "git format-patch * origin" that prepares what the origin side still * does not have. */ rev.pending.objects[0].item->flags |= UNINTERESTING; add_head_to_pending(&rev); } /* * Otherwise, it is "format-patch -22 HEAD", and/or * "format-patch --root HEAD". The user wants * get_revision() to do the usual traversal. */ } /* * We cannot move this anywhere earlier because we do want to * know if --root was given explicitly from the comand line. */ rev.show_root_diff = 1; if (cover_letter) { /* remember the range */ int i; for (i = 0; i < rev.pending.nr; i++) { struct object *o = rev.pending.objects[i].item; if (!(o->flags & UNINTERESTING)) head = (struct commit *)o; } /* We can't generate a cover letter without any patches */ if (!head) return 0; } if (ignore_if_in_upstream) get_patch_ids(&rev, &ids, prefix); if (!use_stdout) realstdout = xfdopen(xdup(1), "w"); if (prepare_revision_walk(&rev)) die("revision walk setup failed"); rev.boundary = 1; while ((commit = get_revision(&rev)) != NULL) { if (commit->object.flags & BOUNDARY) { boundary_count++; origin = (boundary_count == 1) ? commit : NULL; continue; } /* ignore merges */ if (commit->parents && commit->parents->next) continue; if (ignore_if_in_upstream && has_commit_patch_id(commit, &ids)) continue; nr++; list = xrealloc(list, nr * sizeof(list[0])); list[nr - 1] = commit; } total = nr; if (!keep_subject && auto_number && total > 1) numbered = 1; if (numbered) rev.total = total + start_number - 1; if (in_reply_to || thread || cover_letter) rev.ref_message_ids = xcalloc(1, sizeof(struct string_list)); if (in_reply_to) { const char *msgid = clean_message_id(in_reply_to); string_list_append(msgid, rev.ref_message_ids); } rev.numbered_files = numbered_files; rev.patch_suffix = fmt_patch_suffix; if (cover_letter) { if (thread) gen_message_id(&rev, "cover"); make_cover_letter(&rev, use_stdout, numbered, numbered_files, origin, nr, list, head); total++; start_number--; } rev.add_signoff = add_signoff; while (0 <= --nr) { int shown; commit = list[nr]; rev.nr = total - nr + (start_number - 1); /* Make the second and subsequent mails replies to the first */ if (thread) { /* Have we already had a message ID? */ if (rev.message_id) { /* * For deep threading: make every mail * a reply to the previous one, no * matter what other options are set. * * For shallow threading: * * Without --cover-letter and * --in-reply-to, make every mail a * reply to the one before. * * With --in-reply-to but no * --cover-letter, make every mail a * reply to the <reply-to>. * * With --cover-letter, make every * mail but the cover letter a reply * to the cover letter. The cover * letter is a reply to the * --in-reply-to, if specified. */ if (thread == THREAD_SHALLOW && rev.ref_message_ids->nr > 0 && (!cover_letter || rev.nr > 1)) free(rev.message_id); else string_list_append(rev.message_id, rev.ref_message_ids); } gen_message_id(&rev, sha1_to_hex(commit->object.sha1)); } if (!use_stdout && reopen_stdout(numbered_files ? NULL : commit, &rev)) die("Failed to create output files"); shown = log_tree_commit(&rev, commit); free(commit->buffer); commit->buffer = NULL; /* We put one extra blank line between formatted * patches and this flag is used by log-tree code * to see if it needs to emit a LF before showing * the log; when using one file per patch, we do * not want the extra blank line. */ if (!use_stdout) rev.shown_one = 0; if (shown) { if (rev.mime_boundary) printf("\n--%s%s--\n\n\n", mime_boundary_leader, rev.mime_boundary); else printf("-- \n%s\n\n", git_version_string); } if (!use_stdout) fclose(stdout); } free(list); if (ignore_if_in_upstream) free_patch_ids(&ids); return 0; }
static void mi_parse_argv (char *args, struct mi_parse *parse) { char *chp = args; int argc = 0; char **argv = xmalloc ((argc + 1) * sizeof (char *)); argv[argc] = NULL; while (1) { char *arg; /* skip leading white space */ while (isspace (*chp)) chp++; /* Three possibilities: EOF, quoted string, or other text. */ switch (*chp) { case '\0': parse->argv = argv; parse->argc = argc; return; case '"': { /* A quoted string. */ int len; char *start = chp + 1; /* Determine the buffer size. */ chp = start; len = 0; while (*chp != '\0' && *chp != '"') { if (*chp == '\\') { chp++; if (parse_escape (&chp) <= 0) { /* Do not allow split lines or "\000" */ freeargv (argv); return; } } else chp++; len++; } /* Insist on a closing quote. */ if (*chp != '"') { freeargv (argv); return; } /* Insist on trailing white space. */ if (chp[1] != '\0' && !isspace (chp[1])) { freeargv (argv); return; } /* create the buffer. */ arg = xmalloc ((len + 1) * sizeof (char)); /* And copy the characters in. */ chp = start; len = 0; while (*chp != '\0' && *chp != '"') { if (*chp == '\\') { chp++; arg[len] = parse_escape (&chp); } else arg[len] = *chp++; len++; } arg[len] = '\0'; chp++; /* that closing quote. */ break; } default: { /* An unquoted string. Accumulate all non blank characters into a buffer. */ int len; char *start = chp; while (*chp != '\0' && !isspace (*chp)) { chp++; } len = chp - start; arg = xmalloc ((len + 1) * sizeof (char)); strncpy (arg, start, len); arg[len] = '\0'; break; } } /* Append arg to argv. */ argv = xrealloc (argv, (argc + 2) * sizeof (char *)); argv[argc++] = arg; argv[argc] = NULL; } }
int tgetent (char *bp, const char *name) { register char *termcap_name; register int fd; struct termcap_buffer buf; register char *bp1; char *tc_search_point; char *term; ptrdiff_t malloc_size = 0; register int c; char *tcenv = NULL; /* TERMCAP value, if it contains :tc=. */ char *indirect = NULL; /* Terminal type in :tc= in TERMCAP value. */ int filep; #ifdef INTERNAL_TERMINAL /* For the internal terminal we don't want to read any termcap file, so fake it. */ if (!strcmp (name, "internal")) { term = INTERNAL_TERMINAL; if (!bp) { malloc_size = 1 + strlen (term); bp = (char *) xmalloc (malloc_size); } strcpy (bp, term); goto ret; } #endif /* INTERNAL_TERMINAL */ /* For compatibility with programs like `less' that want to put data in the termcap buffer themselves as a fallback. */ if (bp) term_entry = bp; termcap_name = getenv ("TERMCAP"); if (termcap_name && *termcap_name == '\0') termcap_name = NULL; #if defined (MSDOS) && !defined (TEST) if (termcap_name && (*termcap_name == '\\' || *termcap_name == '/' || termcap_name[1] == ':')) dostounix_filename (termcap_name); #endif filep = termcap_name && valid_filename_p (termcap_name); /* If termcap_name is non-null and starts with / (in the un*x case, that is), it is a file name to use instead of /etc/termcap. If it is non-null and does not start with /, it is the entry itself, but only if the name the caller requested matches the TERM variable. */ if (termcap_name && !filep && !strcmp (name, getenv ("TERM"))) { indirect = tgetst1 (find_capability (termcap_name, "tc"), (char **) 0); if (!indirect) { if (!bp) bp = termcap_name; else strcpy (bp, termcap_name); goto ret; } else { /* It has tc=. Need to read /etc/termcap. */ tcenv = termcap_name; termcap_name = NULL; } } if (!termcap_name || !filep) termcap_name = TERMCAP_FILE; /* Here we know we must search a file and termcap_name has its name. */ #ifdef MSDOS fd = open (termcap_name, O_RDONLY|O_TEXT, 0); #else fd = open (termcap_name, O_RDONLY, 0); #endif if (fd < 0) return -1; buf.size = BUFSIZE; /* Add 1 to size to ensure room for terminating null. */ buf.beg = (char *) xmalloc (buf.size + 1); term = indirect ? indirect : (char *)name; if (!bp) { malloc_size = indirect ? strlen (tcenv) + 1 : buf.size; bp = (char *) xmalloc (malloc_size); } tc_search_point = bp1 = bp; if (indirect) /* Copy the data from the environment variable. */ { strcpy (bp, tcenv); bp1 += strlen (tcenv); } while (term) { /* Scan the file, reading it via buf, till find start of main entry. */ if (scan_file (term, fd, &buf) == 0) { close (fd); xfree (buf.beg); if (malloc_size) xfree (bp); return 0; } /* Free old `term' if appropriate. */ if (term != name) xfree (term); /* If BP is malloc'd by us, make sure it is big enough. */ if (malloc_size) { ptrdiff_t offset1 = bp1 - bp, offset2 = tc_search_point - bp; malloc_size = offset1 + buf.size; bp = termcap_name = (char *) xrealloc (bp, malloc_size); bp1 = termcap_name + offset1; tc_search_point = termcap_name + offset2; } /* Copy the line of the entry from buf into bp. */ termcap_name = buf.ptr; while ((*bp1++ = c = *termcap_name++) && c != '\n') /* Drop out any \ newline sequence. */ if (c == '\\' && *termcap_name == '\n') { bp1--; termcap_name++; } *bp1 = '\0'; /* Does this entry refer to another terminal type's entry? If something is found, copy it into heap and null-terminate it. */ tc_search_point = find_capability (tc_search_point, "tc"); term = tgetst1 (tc_search_point, (char **) 0); } close (fd); xfree (buf.beg); if (malloc_size) bp = (char *) xrealloc (bp, bp1 - bp + 1); ret: term_entry = bp; return 1; }
/* * Read and return a token. Tokens are string or character literals * or else delimited by whitespace or by [(),{}]. * The latter are all returned as single characters. */ static char * read_token(void) { int c, q; char *buf; unsigned int alc, off; const char* delims = "(),{}"; while (1) { c = getchar_skipping_comments(); if (c == EOF) return NULL; if (!isspace(c)) break; } alc = 16; buf = xmalloc(alc + 1); off = 0; if(c == '"' || c == '\'') { q = c; buf[off] = c; ++off; while (1) { if (off+2 >= alc) { // room for c and maybe next char alc *= 2; buf = xrealloc(buf, alc + 1); } c = getchar_no_eof(); buf[off] = c; ++off; if(c == q) break; if(c == '\\') { buf[off] = getchar_no_eof(); ++off; } } } else if (strchr(delims, c) != NULL) { buf[off] = c; ++off; } else { while (1) { if (off >= alc) { alc *= 2; buf = xrealloc(buf, alc + 1); } buf[off] = c; ++off; c = getchar_skipping_comments(); if (c == EOF) break; if (isspace(c) || strchr(delims, c) != NULL) { if (c == '\n') lineno--; ungetc(c, stdin); break; } } } buf[off] = '\0'; return buf; }
void initialize_current_architecture (void) { const char **arches = gdbarch_printable_names (); struct gdbarch_info info; /* determine a default architecture and byte order. */ gdbarch_info_init (&info); /* Find a default architecture. */ if (default_bfd_arch == NULL) { /* Choose the architecture by taking the first one alphabetically. */ const char *chosen = arches[0]; const char **arch; for (arch = arches; *arch != NULL; arch++) { if (strcmp (*arch, chosen) < 0) chosen = *arch; } if (chosen == NULL) internal_error (__FILE__, __LINE__, _("initialize_current_architecture: No arch")); default_bfd_arch = bfd_scan_arch (chosen); if (default_bfd_arch == NULL) internal_error (__FILE__, __LINE__, _("initialize_current_architecture: Arch not found")); } info.bfd_arch_info = default_bfd_arch; /* Take several guesses at a byte order. */ if (default_byte_order == BFD_ENDIAN_UNKNOWN && default_bfd_vec != NULL) { /* Extract BFD's default vector's byte order. */ switch (default_bfd_vec->byteorder) { case BFD_ENDIAN_BIG: default_byte_order = BFD_ENDIAN_BIG; break; case BFD_ENDIAN_LITTLE: default_byte_order = BFD_ENDIAN_LITTLE; break; default: break; } } if (default_byte_order == BFD_ENDIAN_UNKNOWN) { /* look for ``*el-*'' in the target name. */ const char *chp; chp = strchr (target_name, '-'); if (chp != NULL && chp - 2 >= target_name && strncmp (chp - 2, "el", 2) == 0) default_byte_order = BFD_ENDIAN_LITTLE; } if (default_byte_order == BFD_ENDIAN_UNKNOWN) { /* Wire it to big-endian!!! */ default_byte_order = BFD_ENDIAN_BIG; } info.byte_order = default_byte_order; info.byte_order_for_code = info.byte_order; if (! gdbarch_update_p (info)) internal_error (__FILE__, __LINE__, _("initialize_current_architecture: Selection of " "initial architecture failed")); /* Create the ``set architecture'' command appending ``auto'' to the list of architectures. */ { /* Append ``auto''. */ int nr; for (nr = 0; arches[nr] != NULL; nr++); arches = xrealloc (arches, sizeof (char*) * (nr + 2)); arches[nr + 0] = "auto"; arches[nr + 1] = NULL; add_setshow_enum_cmd ("architecture", class_support, arches, &set_architecture_string, _("Set architecture of target."), _("Show architecture of target."), NULL, set_architecture, show_architecture, &setlist, &showlist); add_alias_cmd ("processor", "architecture", class_support, 1, &setlist); } }
extern int container_p_create(uint32_t job_id) { #ifdef HAVE_NATIVE_CRAY rid_t resv_id = job_id; int rc; #endif int i, empty = -1, found = -1; DEF_TIMERS; START_TIMER; if (debug_flags & DEBUG_FLAG_JOB_CONT) info("%s: creating(%u)", plugin_type, job_id); slurm_mutex_lock(&context_lock); for (i = 0; i < job_id_count; i++) { if (job_id_array[i] == 0) { empty = i; } else if (job_id_array[i] == job_id) { found = i; break; } } if (found == -1) { if (empty == -1) { empty = job_id_count; job_id_count += 4; job_id_array = xrealloc(job_id_array, sizeof(uint32_t)*job_id_count); } job_id_array[empty] = job_id; _save_state(state_dir); } slurm_mutex_unlock(&context_lock); if (debug_flags & DEBUG_FLAG_TIME_CRAY) { END_TIMER; INFO_LINE("call took: %s", TIME_STR); } else { END_TIMER3("container_p_create: saving state took", 3000000); } #ifdef HAVE_NATIVE_CRAY START_TIMER; rc = job_create_reservation(resv_id, CREATE_FLAGS); if (debug_flags & DEBUG_FLAG_TIME_CRAY) { END_TIMER; INFO_LINE("call took: %s", TIME_STR); } else END_TIMER3("container_p_create: job_create_reservation took", 3000000); if ((rc == 0) || (errno == EEXIST)) { if ((found == -1) && (rc != 0) && (errno == EEXIST)) { error("%s: create(%u): Reservation already exists", plugin_type, job_id); } if (debug_flags & DEBUG_FLAG_JOB_CONT) _stat_reservation("create", resv_id); return SLURM_SUCCESS; } error("%s: create(%u): %m", plugin_type, job_id); return SLURM_ERROR; #else return SLURM_SUCCESS; #endif }
int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr) { const char * se; char quote = '\0'; size_t argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA; const char ** argv = (const char**) xmalloc(sizeof(*argv) * argvAlloced); unsigned int argc = 0; size_t ns = strlen(s); char * t = NULL; char * te; int rc = POPT_ERROR_MALLOC; assert(argv); /* XXX can't happen */ if (argv == NULL) return rc; te = t = (char*) xmalloc(ns + 1); assert(te); /* XXX can't happen */ if (te == NULL) { argv = _free(argv); return rc; } *te = '\0'; argv[argc] = te; for (se = s; *se != '\0'; se++) { if (quote == *se) { quote = '\0'; } else if (quote != '\0') { if (*se == '\\') { se++; if (*se == '\0') { rc = POPT_ERROR_BADQUOTE; goto exit; } if (*se != quote) *te++ = '\\'; } *te++ = *se; } else if (_isspaceptr(se)) { if (*argv[argc] != '\0') { *te++ = '\0', argc++; if (argc == argvAlloced) { argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA; argv = (const char**) xrealloc(argv, sizeof(*argv) * argvAlloced); assert(argv); /* XXX can't happen */ if (argv == NULL) goto exit; } *te = '\0'; argv[argc] = te; } } else switch (*se) { case '"': case '\'': quote = *se; /*@switchbreak@*/ break; case '\\': se++; if (*se == '\0') { rc = POPT_ERROR_BADQUOTE; goto exit; } /*@fallthrough@*/ default: *te++ = *se; /*@switchbreak@*/ break; } } if (strlen(argv[argc])) { argc++, *te++ = '\0'; } rc = poptDupArgv(argc, argv, argcPtr, argvPtr); exit: t = _free(t); argv = _free(argv); return rc; }
/* still in the dev stage. * return values, perhaps 1== file erro * 2== line to long * 3== umm.... more? */ int poptConfigFileToString(FILE *fp, char ** argstrp, /*@unused@*/ UNUSED(int flags)) { size_t nline = 8192; /* XXX configurable? */ char * line = (char*) alloca(nline); char * argstr; char * q; char * x; size_t t; size_t argvlen = 0; size_t maxargvlen = (size_t)480; if (argstrp) *argstrp = NULL; /* | this_is = our_line * p q x */ if (fp == NULL) return POPT_ERROR_NULLARG; argstr = (char*) xmalloc(maxargvlen * sizeof(*argstr)); assert(argstr); /* XXX can't happen */ if (argstr == NULL) return POPT_ERROR_MALLOC; argstr[0] = '\0'; while (fgets(line, (int)nline, fp) != NULL) { char * l = line; size_t nl; /* loop until first non-space char or EOL */ while( *l != '\0' && _isspaceptr(l) ) l++; nl = strlen(l); if (nl >= nline-1) { argstr = _free(argstr); return POPT_ERROR_OVERFLOW; /* XXX line too long */ } if (*l == '\0' || *l == '\n') continue; /* line is empty */ if (*l == '#') continue; /* comment line */ q = l; while (*q != '\0' && (!_isspaceptr(q)) && *q != '=') q++; if (_isspaceptr(q)) { /* a space after the name, find next non space */ *q++='\0'; while( *q != '\0' && _isspaceptr(q) ) q++; } if (*q == '\0') { /* single command line option (ie, no name=val, just name) */ q[-1] = '\0'; /* kill off newline from fgets() call */ argvlen += (t = (size_t)(q - l)) + (sizeof(" --")-1); if (argvlen >= maxargvlen) { maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; argstr = (char*) xrealloc(argstr, maxargvlen); assert(argstr); /* XXX can't happen */ if (argstr == NULL) return POPT_ERROR_MALLOC; } strcat(argstr, " --"); /* XXX stpcpy */ strcat(argstr, l); /* XXX stpcpy */ continue; } if (*q != '=') continue; /* XXX for now, silently ignore bogus line */ /* *q is an equal sign. */ *q++ = '\0'; /* find next non-space letter of value */ while (*q != '\0' && _isspaceptr(q)) q++; if (*q == '\0') continue; /* XXX silently ignore missing value */ /* now, loop and strip all ending whitespace */ x = l + nl; while (_isspaceptr(--x)) *x = '\0'; /* null out last char if space (including fgets() NL) */ /* rest of line accept */ t = (size_t)(x - l); argvlen += t + (sizeof("' --='")-1); if (argvlen >= maxargvlen) { maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; argstr = (char*) xrealloc(argstr, maxargvlen); assert(argstr); /* XXX can't happen */ if (argstr == NULL) return POPT_ERROR_MALLOC; } strcat(argstr, " --"); /* XXX stpcpy */ strcat(argstr, l); /* XXX stpcpy */ strcat(argstr, "=\""); /* XXX stpcpy */ strcat(argstr, q); /* XXX stpcpy */ strcat(argstr, "\""); /* XXX stpcpy */ } *argstrp = argstr; return 0; }
/* Convert cells into a string. */ char * grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx, struct grid_cell **lastgc, int with_codes, int escape_c0, int trim) { const struct grid_cell *gc; static struct grid_cell lastgc1; struct utf8_data ud; const char* data; char *buf, code[128]; size_t len, off, size, codelen; u_int xx; const struct grid_line *gl; GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx); if (lastgc != NULL && *lastgc == NULL) { memcpy(&lastgc1, &grid_default_cell, sizeof lastgc1); *lastgc = &lastgc1; } len = 128; buf = xmalloc(len); off = 0; gl = grid_peek_line(gd, py); for (xx = px; xx < px + nx; xx++) { if (gl == NULL || xx >= gl->cellsize) break; gc = &gl->celldata[xx]; if (gc->flags & GRID_FLAG_PADDING) continue; grid_cell_get(gc, &ud); if (with_codes) { grid_string_cells_code(*lastgc, gc, code, sizeof code, escape_c0); codelen = strlen(code); memcpy(*lastgc, gc, sizeof *gc); } else codelen = 0; data = ud.data; size = ud.size; if (escape_c0 && size == 1 && *data == '\\') { data = "\\\\"; size = 2; } while (len < off + size + codelen + 1) { buf = xrealloc(buf, 2, len); len *= 2; } if (codelen != 0) { memcpy(buf + off, code, codelen); off += codelen; } memcpy(buf + off, data, size); off += size; } if (trim) { while (off > 0 && buf[off - 1] == ' ') off--; } buf[off] = '\0'; return (buf); }
static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) { enum { NOTOKAY, USEBCNT, USEPREC } sokay; PR *pr, **nextpr = NULL; FU *fu; char *p1, *p2, *p3; char savech, *fmtp; const char *byte_count_str; int nconv, prec = 0; for (fu = fs->nextfu; fu; fu = fu->nextfu) { /* * break each format unit into print units; each * conversion character gets its own. */ for (nconv = 0, fmtp = fu->fmt; *fmtp; nextpr = &pr->nextpr) { /* NOSTRICT */ /* DBU:[[email protected]] zalloc so that forward ptrs start out NULL*/ pr = xzalloc(sizeof(PR)); if (!fu->nextpr) fu->nextpr = pr; /* ignore nextpr -- its unused inside the loop and is * uninitialized 1st time through. */ /* skip preceding text and up to the next % sign */ for (p1 = fmtp; *p1 && *p1 != '%'; ++p1) continue; /* only text in the string */ if (!*p1) { pr->fmt = fmtp; pr->flags = F_TEXT; break; } /* * get precision for %s -- if have a byte count, don't * need it. */ if (fu->bcnt) { sokay = USEBCNT; /* skip to conversion character */ for (++p1; strchr(index_str, *p1); ++p1) continue; } else { /* skip any special chars, field width */ while (strchr(index_str + 1, *++p1)) continue; if (*p1 == '.' && isdigit(*++p1)) { sokay = USEPREC; prec = atoi(p1); while (isdigit(*++p1)) continue; } else sokay = NOTOKAY; } p2 = p1 + 1; /* set end pointer */ /* * figure out the byte count for each conversion; * rewrite the format as necessary, set up blank- * pbb_dump_adding for end of data. */ if (*p1 == 'c') { pr->flags = F_CHAR; DO_BYTE_COUNT_1: byte_count_str = "\001"; DO_BYTE_COUNT: if (fu->bcnt) { do { if (fu->bcnt == *byte_count_str) { break; } } while (*++byte_count_str); } /* Unlike the original, output the remainder of the format string. */ if (!*byte_count_str) { bb_error_msg_and_die("bad byte count for conversion character %s", p1); } pr->bcnt = *byte_count_str; } else if (*p1 == 'l') { ++p2; ++p1; DO_INT_CONV: { const char *e; e = strchr(lcc, *p1); if (!e) { goto DO_BAD_CONV_CHAR; } pr->flags = F_INT; if (e > lcc + 1) { pr->flags = F_UINT; } byte_count_str = "\004\002\001"; goto DO_BYTE_COUNT; } /* NOTREACHED */ } else if (strchr(lcc, *p1)) { goto DO_INT_CONV; } else if (strchr("eEfgG", *p1)) { pr->flags = F_DBL; byte_count_str = "\010\004"; goto DO_BYTE_COUNT; } else if (*p1 == 's') { pr->flags = F_STR; if (sokay == USEBCNT) { pr->bcnt = fu->bcnt; } else if (sokay == USEPREC) { pr->bcnt = prec; } else { /* NOTOKAY */ bb_error_msg_and_die("%%s requires a precision or a byte count"); } } else if (*p1 == '_') { ++p2; switch (p1[1]) { case 'A': dumper->endfu = fu; fu->flags |= F_IGNORE; /* FALLTHROUGH */ case 'a': pr->flags = F_ADDRESS; ++p2; if ((p1[2] != 'd') && (p1[2] != 'o') && (p1[2] != 'x')) { goto DO_BAD_CONV_CHAR; } *p1 = p1[2]; break; case 'c': pr->flags = F_C; /* *p1 = 'c'; set in conv_c */ goto DO_BYTE_COUNT_1; case 'p': pr->flags = F_P; *p1 = 'c'; goto DO_BYTE_COUNT_1; case 'u': pr->flags = F_U; /* *p1 = 'c'; set in conv_u */ goto DO_BYTE_COUNT_1; default: goto DO_BAD_CONV_CHAR; } } else { DO_BAD_CONV_CHAR: bb_error_msg_and_die("bad conversion character %%%s", p1); } /* * copy to PR format string, set conversion character * pointer, update original. */ savech = *p2; p1[1] = '\0'; pr->fmt = xstrdup(fmtp); *p2 = savech; //Too early! xrealloc can move pr->fmt! //pr->cchar = pr->fmt + (p1 - fmtp); /* DBU:[[email protected]] w/o this, trailing fmt text, space is lost. * Skip subsequent text and up to the next % sign and tack the * additional text onto fmt: eg. if fmt is "%x is a HEX number", * we lose the " is a HEX number" part of fmt. */ for (p3 = p2; *p3 && *p3 != '%'; p3++) continue; if (p3 > p2) { savech = *p3; *p3 = '\0'; pr->fmt = xrealloc(pr->fmt, strlen(pr->fmt) + (p3-p2) + 1); strcat(pr->fmt, p2); *p3 = savech; p2 = p3; } pr->cchar = pr->fmt + (p1 - fmtp); fmtp = p2; /* only one conversion character if byte count */ if (!(pr->flags & F_ADDRESS) && fu->bcnt && nconv++) { bb_error_msg_and_die("byte count with multiple conversion characters"); } } /* * if format unit byte count not specified, figure it out * so can adjust rep count later. */ if (!fu->bcnt) for (pr = fu->nextpr; pr; pr = pr->nextpr) fu->bcnt += pr->bcnt; } /* * if the format string interprets any data at all, and it's * not the same as the blocksize, and its last format unit * interprets any data at all, and has no iteration count, * repeat it as necessary. * * if, rep count is greater than 1, no trailing whitespace * gets output from the last iteration of the format unit. */ for (fu = fs->nextfu; fu; fu = fu->nextfu) { if (!fu->nextfu && fs->bcnt < dumper->blocksize && !(fu->flags & F_SETREP) && fu->bcnt ) { fu->reps += (dumper->blocksize - fs->bcnt) / fu->bcnt; } if (fu->reps > 1) { for (pr = fu->nextpr;; pr = pr->nextpr) if (!pr->nextpr) break; for (p1 = pr->fmt, p2 = NULL; *p1; ++p1) p2 = isspace(*p1) ? p1 : NULL; if (p2) pr->nospace = p2; } if (!fu->nextfu) break; } }
/* pat_exec: * Execute a compiled pattern at position 'at' in the given tokens sequences * in order to produce an observation string. The string is returned as a * newly allocated memory block and the caller is responsible to free it when * not needed anymore. */ char *pat_exec(const pat_t *pat, const tok_t *tok, uint32_t at) { static char *bval[] = {"_x-1", "_x-2", "_x-3", "_x-4", "_x-#"}; static char *eval[] = {"_x+1", "_x+2", "_x+3", "_x+4", "_x+#"}; const uint32_t T = tok->len; // Prepare the buffer who will hold the result uint32_t size = 16, pos = 0; char *buffer = xmalloc(sizeof(char) * size); // And loop over the compiled items for (uint32_t it = 0; it < pat->nitems; it++) { const pat_item_t *item = &(pat->items[it]); char *value = NULL; uint32_t len = 0; // First, if needed, we retrieve the token at the referenced // position in the sequence. We store it in value and let the // command handler do what it need with it. if (item->type != 's') { int pos = item->offset; if (item->absolute) { if (item->offset < 0) pos += T; else pos--; } else { pos += at; } uint32_t col = item->column; if (pos < 0) value = bval[min(-pos - 1, 4)]; else if (pos >= (int32_t)T) value = eval[min( pos - (int32_t)T, 4)]; else if (col >= tok->cnts[pos]) fatal("missing tokens, cannot apply pattern"); else value = tok->toks[pos][col]; } // Next, we handle the command, 's' and 'x' are very simple but // 't' and 'm' require us to call the regexp matcher. if (item->type == 's') { value = item->value; len = strlen(value); } else if (item->type == 'x') { len = strlen(value); } else if (item->type == 't') { if (rex_match(item->value, value, &len) == -1) value = "false"; else value = "true"; len = strlen(value); } else if (item->type == 'm') { int32_t pos = rex_match(item->value, value, &len); if (pos == -1) len = 0; value += pos; } // And we add it to the buffer, growing it if needed. If the // user requested it, we also remove caps from the string. if (pos + len >= size - 1) { while (pos + len >= size - 1) size = size * 1.4; buffer = xrealloc(buffer, sizeof(char) * size); } memcpy(buffer + pos, value, len); if (item->caps) for (uint32_t i = pos; i < pos + len; i++) buffer[i] = tolower(buffer[i]); pos += len; } // Adjust the result and return it. buffer[pos++] = '\0'; buffer = xrealloc(buffer, sizeof(char) * pos); return buffer; }
/* Examine the directories under directory_name and delete any files that were not there at the time of the back-up. */ static bool try_purge_directory (char const *directory_name) { char *current_dir; char *cur, *arc, *p; char *temp_stub = NULL; struct dumpdir *dump; if (!is_dumpdir (¤t_stat_info)) return false; current_dir = savedir (directory_name); if (!current_dir) /* The directory doesn't exist now. It'll be created. In any case, we don't have to delete any files out of it. */ return false; /* Verify if dump directory is sane */ if (!dumpdir_ok (current_stat_info.dumpdir)) return false; /* Process renames */ for (arc = current_stat_info.dumpdir; *arc; arc += strlen (arc) + 1) { if (*arc == 'X') { #define TEMP_DIR_TEMPLATE "tar.XXXXXX" size_t len = strlen (arc + 1); temp_stub = xrealloc (temp_stub, len + 1 + sizeof TEMP_DIR_TEMPLATE); memcpy (temp_stub, arc + 1, len); temp_stub[len] = '/'; memcpy (temp_stub + len + 1, TEMP_DIR_TEMPLATE, sizeof TEMP_DIR_TEMPLATE); if (!mkdtemp (temp_stub)) { ERROR ((0, errno, _("Cannot create temporary directory using template %s"), quote (temp_stub))); free (temp_stub); free (current_dir); return false; } } else if (*arc == 'R') { char *src, *dst; src = arc + 1; arc += strlen (arc) + 1; dst = arc + 1; /* Ensure that neither source nor destination are absolute file names (unless permitted by -P option), and that they do not contain dubious parts (e.g. ../). This is an extra safety precaution. Besides, it might be necessary to extract from archives created with tar versions prior to 1.19. */ if (*src) src = safer_name_suffix (src, false, absolute_names_option); if (*dst) dst = safer_name_suffix (dst, false, absolute_names_option); if (*src == 0) src = temp_stub; else if (*dst == 0) dst = temp_stub; if (!rename_directory (src, dst)) { free (temp_stub); free (current_dir); /* FIXME: Make sure purge_directory(dst) will return immediately */ return false; } } } free (temp_stub); /* Process deletes */ dump = dumpdir_create (current_stat_info.dumpdir); p = NULL; for (cur = current_dir; *cur; cur += strlen (cur) + 1) { const char *entry; struct stat st; if (p) free (p); p = new_name (directory_name, cur); if (deref_stat (false, p, &st)) { if (errno != ENOENT) /* FIXME: Maybe keep a list of renamed dirs and check it here? */ { stat_diag (p); WARN ((0, 0, _("%s: Not purging directory: unable to stat"), quotearg_colon (p))); } continue; } if (!(entry = dumpdir_locate (dump, cur)) || (*entry == 'D' && !S_ISDIR (st.st_mode)) || (*entry == 'Y' && S_ISDIR (st.st_mode))) { if (one_file_system_option && st.st_dev != root_device) { WARN ((0, 0, _("%s: directory is on a different device: not purging"), quotearg_colon (p))); continue; } if (! interactive_option || confirm ("delete", p)) { if (verbose_option) fprintf (stdlis, _("%s: Deleting %s\n"), program_name, quote (p)); if (! remove_any_file (p, RECURSIVE_REMOVE_OPTION)) { int e = errno; ERROR ((0, e, _("%s: Cannot remove"), quotearg_colon (p))); } } } } free (p); dumpdir_free (dump); free (current_dir); return true; }
static void x_ycp_lex (token_ty *tp) { static char *buffer; static int bufmax; int bufpos; int c; for (;;) { tp->line_number = line_number; c = phase2_getc (); switch (c) { case EOF: tp->type = token_type_eof; return; case '\n': if (last_non_comment_line > last_comment_line) xgettext_comment_reset (); /* FALLTHROUGH */ case '\r': case '\t': case ' ': /* Ignore whitespace and comments. */ continue; } last_non_comment_line = tp->line_number; switch (c) { case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '_': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* Symbol, or part of a number. */ bufpos = 0; for (;;) { if (bufpos >= bufmax) { bufmax = 2 * bufmax + 10; buffer = xrealloc (buffer, bufmax); } buffer[bufpos++] = c; c = phase2_getc (); switch (c) { case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '_': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': continue; default: if (bufpos == 1 && buffer[0] == '_' && c == '(') { tp->type = token_type_i18n; return; } phase2_ungetc (c); break; } break; } if (bufpos >= bufmax) { bufmax = 2 * bufmax + 10; buffer = xrealloc (buffer, bufmax); } buffer[bufpos] = '\0'; tp->string = xstrdup (buffer); tp->type = token_type_symbol; return; case '"': bufpos = 0; for (;;) { c = phase7_getc (); if (c == EOF || c == P7_QUOTES) break; if (bufpos >= bufmax) { bufmax = 2 * bufmax + 10; buffer = xrealloc (buffer, bufmax); } buffer[bufpos++] = c; } if (bufpos >= bufmax) { bufmax = 2 * bufmax + 10; buffer = xrealloc (buffer, bufmax); } buffer[bufpos] = '\0'; tp->string = xstrdup (buffer); tp->type = token_type_string_literal; return; case '(': tp->type = token_type_lparen; return; case ')': tp->type = token_type_rparen; return; case ',': tp->type = token_type_comma; return; default: /* We could carefully recognize each of the 2 and 3 character operators, but it is not necessary, as we only need to recognize gettext invocations. Don't bother. */ tp->type = token_type_other; return; } } }
/* Recursively scan the given directory. */ static const char * scan_directory (char *dir, dev_t device) { char *dirp = savedir (dir); /* for scanning directory */ char *name_buffer; /* directory, `/', and directory member */ size_t name_buffer_size; /* allocated size of name_buffer, minus 2 */ size_t name_length; /* used length in name_buffer */ struct stat stat_data; struct directory *directory; if (! dirp) savedir_error (dir); name_buffer_size = strlen (dir) + NAME_FIELD_SIZE; name_buffer = xmalloc (name_buffer_size + 2); strcpy (name_buffer, dir); if (! ISSLASH (dir[strlen (dir) - 1])) strcat (name_buffer, "/"); name_length = strlen (name_buffer); if (deref_stat (dereference_option, name_buffer, &stat_data)) { stat_diag (name_buffer); /* FIXME: used to be children = CHANGED_CHILDREN; but changed to: */ free (name_buffer); free (dirp); return NULL; } directory = procdir (name_buffer, &stat_data, device, 0, NULL); if (dirp && directory->children != NO_CHILDREN) { char *entry; /* directory entry being scanned */ size_t entrylen; /* length of directory entry */ dumpdir_iter_t itr; makedumpdir (directory, dirp); for (entry = dumpdir_first (directory->dump, 1, &itr); entry; entry = dumpdir_next (itr)) { entrylen = strlen (entry); if (name_buffer_size <= entrylen - 1 + name_length) { do name_buffer_size += NAME_FIELD_SIZE; while (name_buffer_size <= entrylen - 1 + name_length); name_buffer = xrealloc (name_buffer, name_buffer_size + 2); } strcpy (name_buffer + name_length, entry + 1); if (*entry == 'I') /* Ignored entry */ *entry = 'N'; else if (excluded_name (name_buffer)) *entry = 'N'; else { if (deref_stat (dereference_option, name_buffer, &stat_data)) { stat_diag (name_buffer); *entry = 'N'; continue; } if (S_ISDIR (stat_data.st_mode)) { int pd_flag = (verbose_option ? PD_VERBOSE : 0); if (!recursion_option) pd_flag |= PD_FORCE_CHILDREN | NO_CHILDREN; else if (directory->children == ALL_CHILDREN) pd_flag |= PD_FORCE_CHILDREN | ALL_CHILDREN; *entry = 'D'; procdir (name_buffer, &stat_data, device, pd_flag, entry); } else if (one_file_system_option && device != stat_data.st_dev) *entry = 'N'; else if (*entry == 'Y') /* New entry, skip further checks */; /* FIXME: if (S_ISHIDDEN (stat_data.st_mode))?? */ else if (OLDER_STAT_TIME (stat_data, m) && (!after_date_option || OLDER_STAT_TIME (stat_data, c))) *entry = 'N'; else *entry = 'Y'; } } free (itr); } free (name_buffer); if (dirp) free (dirp); return directory->dump ? directory->dump->contents : NULL; }
static void add_input_file(FILE *file) { G.input_file_list = xrealloc(G.input_file_list, (G.input_file_count + 1) * sizeof(FILE *)); G.input_file_list[G.input_file_count++] = file; }
/* dfu /dev/self0(bootloader)sr,/dev/nand0.root.bb(root) * * s = save mode (download whole image before flashing) * r = read back (firmware image can be downloaded back from host) */ static int do_dfu(struct command *cmdtp, int argc, char *argv[]) { int opt, n = 0; struct usb_dfu_pdata pdata; char *endptr, *argstr; struct usb_dfu_dev *dfu_alts = NULL; char *manufacturer = "barebox"; char *productname = CONFIG_BOARDINFO; u16 idVendor = 0, idProduct = 0; while((opt = getopt(argc, argv, "m:p:V:P:")) > 0) { switch(opt) { case 'm': manufacturer = optarg; break; case 'p': productname = optarg; break; case 'V': idVendor = simple_strtoul(optarg, NULL, 0); break; case 'P': idProduct = simple_strtoul(optarg, NULL, 0); break; } } if (argc != optind + 1) return COMMAND_ERROR_USAGE; argstr = argv[optind]; if (!idProduct || !idVendor) { printf("productid or vendorid not given\n"); return 1; } for (n = 0; *argstr; n++) { dfu_alts = xrealloc(dfu_alts, sizeof(*dfu_alts) * (n + 1)); if (dfu_do_parse_one(argstr, &endptr, &dfu_alts[n])) { printf("parse error\n"); goto out; } argstr = endptr; } pdata.alts = dfu_alts; pdata.num_alts = n; pdata.manufacturer = manufacturer; pdata.productname = productname; pdata.idVendor = idVendor; pdata.idProduct = idProduct; usb_dfu_register(&pdata); out: while (n) { n--; free(dfu_alts[n].name); free(dfu_alts[n].dev); }; free(dfu_alts); return 1; }
static int _load_fed_parts(slurm_msg_t *req_msg, partition_info_msg_t **part_info_msg_pptr, uint16_t show_flags, char *cluster_name, slurmdb_federation_rec_t *fed) { int cluster_inx = 0, i; load_part_resp_struct_t *part_resp; partition_info_msg_t *orig_msg = NULL, *new_msg = NULL; uint32_t new_rec_cnt; slurmdb_cluster_rec_t *cluster; ListIterator iter; int pthread_count = 0; pthread_t *load_thread = 0; load_part_req_struct_t *load_args; List resp_msg_list; *part_info_msg_pptr = NULL; /* Spawn one pthread per cluster to collect partition information */ resp_msg_list = list_create(NULL); load_thread = xmalloc(sizeof(pthread_t) * list_count(fed->cluster_list)); iter = list_iterator_create(fed->cluster_list); while ((cluster = (slurmdb_cluster_rec_t *) list_next(iter))) { if ((cluster->control_host == NULL) || (cluster->control_host[0] == '\0')) continue; /* Cluster down */ load_args = xmalloc(sizeof(load_part_req_struct_t)); load_args->cluster = cluster; load_args->cluster_inx = cluster_inx++; load_args->req_msg = req_msg; load_args->resp_msg_list = resp_msg_list; load_args->show_flags = show_flags; slurm_thread_create(&load_thread[pthread_count], _load_part_thread, load_args); pthread_count++; } list_iterator_destroy(iter); /* Wait for all pthreads to complete */ for (i = 0; i < pthread_count; i++) pthread_join(load_thread[i], NULL); xfree(load_thread); /* Maintain a consistent cluster/node ordering */ list_sort(resp_msg_list, _sort_by_cluster_inx); /* Merge the responses into a single response message */ iter = list_iterator_create(resp_msg_list); while ((part_resp = (load_part_resp_struct_t *) list_next(iter))) { new_msg = part_resp->new_msg; if (!orig_msg) { orig_msg = new_msg; *part_info_msg_pptr = orig_msg; } else { /* Merge the node records */ orig_msg->last_update = MIN(orig_msg->last_update, new_msg->last_update); new_rec_cnt = orig_msg->record_count + new_msg->record_count; if (new_msg->record_count) { orig_msg->partition_array = xrealloc(orig_msg->partition_array, sizeof(partition_info_t) * new_rec_cnt); (void) memcpy(orig_msg->partition_array + orig_msg->record_count, new_msg->partition_array, sizeof(partition_info_t) * new_msg->record_count); orig_msg->record_count = new_rec_cnt; } xfree(new_msg->partition_array); xfree(new_msg); } xfree(part_resp); } list_iterator_destroy(iter); FREE_NULL_LIST(resp_msg_list); if (!orig_msg) slurm_seterrno_ret(SLURM_ERROR); return SLURM_PROTOCOL_SUCCESS; }
static void * format_parse (const char *format, bool translated, char **invalid_reason) { struct spec spec; struct spec *result; bool seen_numbered_arg; bool seen_unnumbered_arg; unsigned int number; spec.directives = 0; spec.numbered_arg_count = 0; spec.allocated = 0; spec.numbered = NULL; seen_numbered_arg = false; seen_unnumbered_arg = false; number = 1; for (; *format != '\0';) if (*format++ == '%') { /* A directive. */ spec.directives++; if (*format != '%') { bool is_numbered_arg; bool short_flag; enum format_arg_type type; is_numbered_arg = false; if (isdigit (*format)) { const char *f = format; unsigned int m = 0; do { m = 10 * m + (*f - '0'); f++; } while (isdigit (*f)); if (*f == '$') { if (m == 0) { *invalid_reason = INVALID_ARGNO_0 (spec.directives); goto bad_format; } number = m; format = ++f; /* Numbered and unnumbered specifications are exclusive. */ if (seen_unnumbered_arg) { *invalid_reason = INVALID_MIXES_NUMBERED_UNNUMBERED (); goto bad_format; } is_numbered_arg = true; seen_numbered_arg = true; } } /* Numbered and unnumbered specifications are exclusive. */ if (!is_numbered_arg) { if (seen_numbered_arg) { *invalid_reason = INVALID_MIXES_NUMBERED_UNNUMBERED (); goto bad_format; } seen_unnumbered_arg = true; } /* Parse flags. */ while (*format == ' ' || *format == '+' || *format == '-' || *format == '#' || *format == '0') format++; /* Parse width. */ if (*format == '*') { format++; if (spec.allocated == spec.numbered_arg_count) { spec.allocated = 2 * spec.allocated + 1; spec.numbered = (struct numbered_arg *) xrealloc (spec.numbered, spec.allocated * sizeof (struct numbered_arg)); } spec.numbered[spec.numbered_arg_count].number = number; spec.numbered[spec.numbered_arg_count].type = FAT_INTEGER; spec.numbered_arg_count++; number++; } else if (isdigit (*format)) { do format++; while (isdigit (*format)); } /* Parse precision. */ if (*format == '.') { format++; if (*format == '*') { format++; if (spec.allocated == spec.numbered_arg_count) { spec.allocated = 2 * spec.allocated + 1; spec.numbered = (struct numbered_arg *) xrealloc (spec.numbered, spec.allocated * sizeof (struct numbered_arg)); } spec.numbered[spec.numbered_arg_count].number = number; spec.numbered[spec.numbered_arg_count].type = FAT_INTEGER; spec.numbered_arg_count++; number++; } else if (isdigit (*format)) { do format++; while (isdigit (*format)); } } /* Parse optional size specification. */ short_flag = false; if (*format == 'h') short_flag = true, format++; else if (*format == 'l') format++; switch (*format) { case 'c': type = FAT_CHARACTER; break; case 's': type = FAT_STRING; break; case 'i': case 'd': type = (short_flag ? FAT_SHORT_INTEGER : FAT_INTEGER); break; case 'u': case 'o': case 'x': case 'X': type = (short_flag ? FAT_SHORT_UNSIGNED_INTEGER : FAT_UNSIGNED_INTEGER); break; case 'e': case 'E': case 'f': case 'g': case 'G': type = FAT_FLOAT; break; default: *invalid_reason = (*format == '\0' ? INVALID_UNTERMINATED_DIRECTIVE () : INVALID_CONVERSION_SPECIFIER (spec.directives, *format)); goto bad_format; } if (spec.allocated == spec.numbered_arg_count) { spec.allocated = 2 * spec.allocated + 1; spec.numbered = (struct numbered_arg *) xrealloc (spec.numbered, spec.allocated * sizeof (struct numbered_arg)); } spec.numbered[spec.numbered_arg_count].number = number; spec.numbered[spec.numbered_arg_count].type = type; spec.numbered_arg_count++; number++; } format++; } /* Sort the numbered argument array, and eliminate duplicates. */ if (spec.numbered_arg_count > 1) { unsigned int i, j; bool err; qsort (spec.numbered, spec.numbered_arg_count, sizeof (struct numbered_arg), numbered_arg_compare); /* Remove duplicates: Copy from i to j, keeping 0 <= j <= i. */ err = false; for (i = j = 0; i < spec.numbered_arg_count; i++) if (j > 0 && spec.numbered[i].number == spec.numbered[j-1].number) { enum format_arg_type type1 = spec.numbered[i].type; enum format_arg_type type2 = spec.numbered[j-1].type; enum format_arg_type type_both; if (type1 == type2) type_both = type1; else { /* Incompatible types. */ type_both = FAT_NONE; if (!err) *invalid_reason = INVALID_INCOMPATIBLE_ARG_TYPES (spec.numbered[i].number); err = true; } spec.numbered[j-1].type = type_both; } else { if (j < i) { spec.numbered[j].number = spec.numbered[i].number; spec.numbered[j].type = spec.numbered[i].type; } j++; } spec.numbered_arg_count = j; if (err) /* *invalid_reason has already been set above. */ goto bad_format; } result = (struct spec *) xmalloc (sizeof (struct spec)); *result = spec; return result; bad_format: if (spec.numbered != NULL) free (spec.numbered); return NULL; }
/* Execute a script, wait for termination and return its stdout. * script_name IN - Name of program being run (e.g. "StartStageIn") * script_path IN - Fully qualified program of the program to execute * script_args IN - Arguments to the script * max_wait IN - Maximum time to wait in milliseconds, * -1 for no limit (asynchronous) * data_in IN - data to use as program STDIN (NULL if not STDIN) * status OUT - Job exit code * Return stdout+stderr of spawned program, value must be xfreed. */ extern char *power_run_script(char *script_name, char *script_path, char **script_argv, int max_wait, char *data_in, int *status) { int i, new_wait, resp_size = 0, resp_offset = 0; int send_size = 0, send_offset = 0; pid_t cpid; char *resp = NULL; int fd_stdout[2] = { -1, -1 }; int fd_stdin[2] = { -1, -1 }; if ((script_path == NULL) || (script_path[0] == '\0')) { error("%s: no script specified", __func__); *status = 127; resp = xstrdup("Slurm burst buffer configuration error"); return resp; } if (slurm_get_debug_flags() & DEBUG_FLAG_POWER) { for (i = 0; i < 10; i++) { if (!script_argv[i]) break; } if (i == 0) { info("%s:", __func__); } else if (i == 1) { info("%s: %s", __func__, script_name); } else if (i == 2) { info("%s: %s %s", __func__, script_name, script_argv[1]); } else if (i == 3) { info("%s: %s %s %s", __func__, script_name, script_argv[1], script_argv[2]); } else if (i == 4) { info("%s: %s %s %s %s", __func__, script_name, script_argv[1], script_argv[2], script_argv[3]); } else if (i == 5) { info("%s: %s %s %s %s %s", __func__, script_name, script_argv[1], script_argv[2], script_argv[3], script_argv[4]); } else if (i == 6) { info("%s: %s %s %s %s %s %s", __func__, script_name, script_argv[1], script_argv[2], script_argv[3], script_argv[4], script_argv[5]); } else if (i == 7) { info("%s: %s %s %s %s %s %s %s", __func__, script_name, script_argv[1], script_argv[2], script_argv[3], script_argv[4], script_argv[5], script_argv[6]); } else { /* 8 or more args here, truncate as needed */ info("%s: %s %s %s %s %s %s %s %s", __func__, script_name, script_argv[1], script_argv[2], script_argv[3], script_argv[4], script_argv[5], script_argv[6], script_argv[7]); } if (data_in) info("%s: %s", __func__, data_in); } if (script_path[0] != '/') { error("%s: %s is not fully qualified pathname (%s)", __func__, script_name, script_path); *status = 127; resp = xstrdup("Slurm burst buffer configuration error"); return resp; } if (access(script_path, R_OK | X_OK) < 0) { error("%s: %s can not be executed (%s) %m", __func__, script_name, script_path); *status = 127; resp = xstrdup("Slurm burst buffer configuration error"); return resp; } if (data_in) { if (pipe(fd_stdin) != 0) { error("%s: pipe(): %m", __func__); *status = 127; resp = xstrdup("System error"); return resp; } } if (max_wait != -1) { if (pipe(fd_stdout) != 0) { error("%s: pipe(): %m", __func__); *status = 127; resp = xstrdup("System error"); return resp; } } if ((cpid = fork()) == 0) { int cc; cc = sysconf(_SC_OPEN_MAX); if (data_in) dup2(fd_stdin[0], STDIN_FILENO); if (max_wait != -1) { dup2(fd_stdout[1], STDERR_FILENO); dup2(fd_stdout[1], STDOUT_FILENO); for (i = 0; i < cc; i++) { if ((i != STDERR_FILENO) && (i != STDIN_FILENO) && (i != STDOUT_FILENO)) close(i); } } else { for (i = 0; i < cc; i++) { if (!data_in || (i != STDERR_FILENO)) close(i); } if ((cpid = fork()) < 0) exit(127); else if (cpid > 0) exit(0); } setpgid(0, 0); execv(script_path, script_argv); error("%s: execv(%s): %m", __func__, script_path); exit(127); } else if (cpid < 0) { if (data_in) { close(fd_stdin[0]); close(fd_stdin[1]); } if (max_wait != -1) { close(fd_stdout[0]); close(fd_stdout[1]); } error("%s: fork(): %m", __func__); } else if (max_wait != -1) { struct pollfd fds; time_t start_time = time(NULL); if (data_in) { close(fd_stdin[0]); send_size = strlen(data_in); while (send_size > send_offset) { i = write(fd_stdin[1], data_in + send_offset, send_size - send_offset); if (i == 0) { break; } else if (i < 0) { if (errno == EAGAIN) continue; error("%s: write(%s): %m", __func__, script_path); break; } else { send_offset += i; } } close(fd_stdin[1]); } resp_size = 1024; resp = xmalloc(resp_size); close(fd_stdout[1]); while (1) { fds.fd = fd_stdout[0]; fds.events = POLLIN | POLLHUP | POLLRDHUP; fds.revents = 0; if (max_wait <= 0) { new_wait = -1; } else { new_wait = (time(NULL) - start_time) * 1000 + max_wait; if (new_wait <= 0) break; } i = poll(&fds, 1, new_wait); if (i == 0) { error("%s: %s poll timeout", __func__, script_name); break; } else if (i < 0) { error("%s: %s poll:%m", __func__, script_name); break; } if ((fds.revents & POLLIN) == 0) break; i = read(fd_stdout[0], resp + resp_offset, resp_size - resp_offset); if (i == 0) { break; } else if (i < 0) { if (errno == EAGAIN) continue; error("%s: read(%s): %m", __func__, script_path); break; } else { resp_offset += i; if (resp_offset + 1024 >= resp_size) { resp_size *= 2; resp = xrealloc(resp, resp_size); } } } killpg(cpid, SIGKILL); waitpid(cpid, status, 0); close(fd_stdout[0]); } else { waitpid(cpid, status, 0); } return resp; }
static void CheckMaxSize(int wi) { uint32_t *oldnull = null; uint32_t *oldblank = blank; Window *p; int i; struct mline *ml; if (wi > MAXWIDTH) wi = MAXWIDTH; if (wi <= maxwidth) return; maxwidth = wi + 1; blank = xrealloc(blank, maxwidth * 4); null = xrealloc(null, maxwidth * 4); mline_old.image = xrealloc(mline_old.image, maxwidth * 4); mline_old.attr = xrealloc(mline_old.attr, maxwidth * 4); mline_old.font = xrealloc(mline_old.font, maxwidth * 4); mline_old.fontx = xrealloc(mline_old.fontx, maxwidth * 4); mline_old.colorbg = xrealloc(mline_old.colorbg, maxwidth * 4); mline_old.colorfg = xrealloc(mline_old.colorfg, maxwidth * 4); if (!(blank && null && mline_old.image && mline_old.attr && mline_old.font && mline_old.fontx && mline_old.colorbg && mline_old.colorfg)) Panic(0, "%s", strnomem); MakeBlankLine(blank, maxwidth); memset(null, 0, maxwidth * 4); mline_blank.image = blank; mline_blank.attr = null; mline_null.image = null; mline_null.attr = null; mline_blank.font = null; mline_null.font = null; mline_blank.fontx = null; mline_null.fontx = null; mline_blank.colorbg = null; mline_null.colorbg = null; mline_blank.colorfg = null; mline_null.colorfg = null; #define RESET_AFC(x, bl) do { if (x == old##bl) x = bl; } while (0) #define RESET_LINES(lines, count) \ do { \ ml = lines; \ for (i = 0; i < count; i++, ml++) \ { \ RESET_AFC(ml->image, blank); \ RESET_AFC(ml->attr, null); \ RESET_AFC(ml->font, null); \ RESET_AFC(ml->fontx, null); \ RESET_AFC(ml->colorbg, null); \ RESET_AFC(ml->colorfg, null); \ } \ } while (0) /* We have to run through all windows to substitute * the null and blank references. */ for (p = windows; p; p = p->w_next) { RESET_LINES(p->w_mlines, p->w_height); RESET_LINES(p->w_hlines, p->w_histheight); RESET_LINES(p->w_alt.hlines, p->w_alt.histheight); RESET_LINES(p->w_alt.mlines, p->w_alt.height); } }
void rcv_chat_join (struct htlc_conn *htlc) { u_int32_t ref = 0; u_int16_t passlen = 0; u_int16_t uid, icon16, color; u_int8_t *pass = 0; struct htlc_chat *chat; dh_start(htlc) switch (dh_type) { case HTLC_DATA_CHAT_ID: dh_getint(ref); break; case HTLC_DATA_PASSWORD: passlen = dh_len > 31 ? 31 : dh_len; pass = dh_data; break; } dh_end() if (!ref) { send_taskerror(htlc, "huh?!?"); return; } chat = chat_lookup_ref(ref); if (!chat) { send_taskerror(htlc, "who?!?"); return; } if (!chat_isset(htlc, chat, 1)) { if (chat->passwordlen && (passlen != chat->passwordlen || memcmp(chat->password, pass, passlen))) { send_taskerror(htlc, "Uh, no."); return; } } else chat_clr(htlc, chat, 1); chat_set(htlc, chat, 0); { struct qbuf *q = &htlc->out; u_int32_t this_off = q->pos + q->len, pos = this_off + SIZEOF_HL_HDR; u_int32_t len; struct hl_hdr h; struct hl_userlist_hdr uh; u_int16_t nlen; struct htlc_conn *htlcp; struct hl_data_hdr dh; u_int16_t slen; q->len += SIZEOF_HL_HDR; q->buf = xrealloc(q->buf, q->pos + q->len); ref = htonl(ref); uid = htons(htlc->uid); icon16 = htons(htlc->icon); color = htons(htlc->color); for (htlcp = htlc_list->next; htlcp; htlcp = htlcp->next) { if (!chat_isset(htlcp, chat, 0)) continue; if (htlcp != htlc) hlwrite(htlcp, HTLS_HDR_CHAT_USER_CHANGE, 0, 5, HTLS_DATA_CHAT_ID, sizeof(ref), &ref, HTLS_DATA_UID, sizeof(uid), &uid, HTLS_DATA_ICON, sizeof(icon16), &icon16, HTLS_DATA_COLOUR, sizeof(color), &color, HTLS_DATA_NAME, strlen(htlc->name), htlc->name); nlen = strlen(htlcp->name); uh.type = htons(HTLS_DATA_USER_LIST); uh.len = htons(8 + nlen); uh.uid = htons(htlcp->uid); uh.icon = htons(htlcp->icon); uh.color = htons(htlcp->color); uh.nlen = htons(nlen); q->len += SIZEOF_HL_USERLIST_HDR + nlen; q->buf = xrealloc(q->buf, q->pos + q->len); memcpy(&q->buf[pos], &uh, SIZEOF_HL_USERLIST_HDR); pos += SIZEOF_HL_USERLIST_HDR; memcpy(&q->buf[pos], htlcp->name, nlen); pos += nlen; } slen = chat->subjectlen; q->len += SIZEOF_HL_DATA_HDR + slen; q->buf = xrealloc(q->buf, q->pos + q->len); dh.type = htons(HTLS_DATA_CHAT_SUBJECT); dh.len = htons(slen); memcpy(&q->buf[pos], &dh, SIZEOF_HL_DATA_HDR); pos += SIZEOF_HL_DATA_HDR; memcpy(&q->buf[pos], chat->subject, slen); pos += slen; h.type = htonl(HTLS_HDR_TASK); h.trans = htonl(htlc->trans); htlc->trans++; h.flag = 0; len = pos - this_off; h.len = h.len2 = htonl(len - (SIZEOF_HL_HDR - sizeof(h.hc))); h.hc = htons(chat->nusers + 1); memory_copy(q->buf + this_off, &h, SIZEOF_HL_HDR); FD_SET(htlc->fd, &hxd_wfds); #ifdef CONFIG_COMPRESS if (htlc->compress_encode_type != COMPRESS_NONE) len = compress_encode(htlc, this_off, len); #endif #ifdef CONFIG_CIPHER if (htlc->cipher_encode_type != CIPHER_NONE) cipher_encode(htlc, this_off, len); #endif } }
int ChangeWindowSize(Window *p, int wi, int he, int hi) { struct mline *mlf = 0, *mlt = 0, *ml, *nmlines, *nhlines; int fy, ty, l, lx, lf, lt, yy, oty, addone; int ncx, ncy, naka, t; int y, shift; if (wi <= 0 || he <= 0) wi = he = hi = 0; if (p->w_type == W_TYPE_GROUP) return 0; if (wi > MAXWIDTH) { Msg(0, "Window width too large. Truncated to %d.", MAXWIDTH); wi = MAXWIDTH; } if (he > MAXWIDTH) { Msg(0, "Window height too large. Truncated to %d.", MAXWIDTH); he = MAXWIDTH; } if (p->w_width == wi && p->w_height == he && p->w_histheight == hi) { return 0; } CheckMaxSize(wi); fy = p->w_histheight + p->w_height - 1; ty = hi + he - 1; nmlines = nhlines = 0; ncx = 0; ncy = 0; naka = 0; if (wi) { if (wi != p->w_width || he != p->w_height) { if ((nmlines = calloc(he, sizeof(struct mline))) == 0) { KillWindow(p); Msg(0, "%s", strnomem); return -1; } } else { nmlines = p->w_mlines; fy -= he; ty -= he; ncx = p->w_x; ncy = p->w_y; naka = p->w_autoaka; } } if (hi) { if ((nhlines = calloc(hi, sizeof(struct mline))) == 0) { Msg(0, "No memory for history buffer - turned off"); hi = 0; ty = he - 1; } } /* special case: cursor is at magic margin position */ addone = 0; if (p->w_width && p->w_x == p->w_width) { addone = 1; p->w_x--; } /* handle the cursor and autoaka lines now if the widths are equal */ if (p->w_width == wi) { ncx = p->w_x + addone; ncy = p->w_y + he - p->w_height; /* never lose sight of the line with the cursor on it */ shift = -ncy; for (yy = p->w_y + p->w_histheight - 1; yy >= 0 && ncy + shift < he; yy--) { ml = OLDWIN(yy); if (!ml->image) break; if (ml->image[p->w_width] == ' ') break; shift++; } if (shift < 0) shift = 0; ncy += shift; if (p->w_autoaka > 0) { naka = p->w_autoaka + he - p->w_height + shift; if (naka < 1 || naka > he) naka = 0; } while (shift-- > 0) { ml = OLDWIN(fy); FreeMline(ml); fy--; } } if (fy >= 0) mlf = OLDWIN(fy); if (ty >= 0) mlt = NEWWIN(ty); while (fy >= 0 && ty >= 0) { if (p->w_width == wi) { /* here is a simple shortcut: just copy over */ *mlt = *mlf; *mlf = mline_zero; if (--fy >= 0) mlf = OLDWIN(fy); if (--ty >= 0) mlt = NEWWIN(ty); continue; } /* calculate lenght */ for (l = p->w_width - 1; l > 0; l--) if (mlf->image[l] != ' ' || mlf->attr[l]) break; if (fy == p->w_y + p->w_histheight && l < p->w_x) l = p->w_x; /* cursor is non blank */ l++; lf = l; /* add wrapped lines to length */ for (yy = fy - 1; yy >= 0; yy--) { ml = OLDWIN(yy); if (ml->image[p->w_width] == ' ') break; l += p->w_width; } /* rewrap lines */ lt = (l - 1) % wi + 1; /* lf is set above */ oty = ty; while (l > 0 && fy >= 0 && ty >= 0) { lx = lt > lf ? lf : lt; if (mlt->image == 0) { if (AllocMline(mlt, wi + 1)) goto nomem; MakeBlankLine(mlt->image + lt, wi - lt); mlt->image[wi] = ((oty == ty) ? ' ' : 0); } if (BcopyMline(mlf, lf - lx, mlt, lt - lx, lx, wi + 1)) goto nomem; /* did we copy the cursor ? */ if (fy == p->w_y + p->w_histheight && lf - lx <= p->w_x && lf > p->w_x) { ncx = p->w_x + lt - lf + addone; ncy = ty - hi; shift = wi ? -ncy + (l - lx) / wi : 0; if (ty + shift > hi + he - 1) shift = hi + he - 1 - ty; if (shift > 0) { for (y = hi + he - 1; y >= ty; y--) { mlt = NEWWIN(y); FreeMline(mlt); if (y - shift < ty) continue; ml = NEWWIN(y - shift); *mlt = *ml; *ml = mline_zero; } ncy += shift; ty += shift; mlt = NEWWIN(ty); if (naka > 0) naka = naka + shift > he ? 0 : naka + shift; } } /* did we copy autoaka line ? */ if (p->w_autoaka > 0 && fy == p->w_autoaka - 1 + p->w_histheight && lf - lx <= 0) naka = ty - hi >= 0 ? 1 + ty - hi : 0; lf -= lx; lt -= lx; l -= lx; if (lf == 0) { FreeMline(mlf); lf = p->w_width; if (--fy >= 0) mlf = OLDWIN(fy); } if (lt == 0) { lt = wi; if (--ty >= 0) mlt = NEWWIN(ty); } } } while (fy >= 0) { FreeMline(mlf); if (--fy >= 0) mlf = OLDWIN(fy); } while (ty >= 0) { if (AllocMline(mlt, wi + 1)) goto nomem; MakeBlankLine(mlt->image, wi + 1); if (--ty >= 0) mlt = NEWWIN(ty); } if (p->w_mlines && p->w_mlines != nmlines) free((char *)p->w_mlines); p->w_mlines = nmlines; if (p->w_hlines && p->w_hlines != nhlines) free((char *)p->w_hlines); p->w_hlines = nhlines; /* change tabs */ if (p->w_width != wi) { if (wi) { t = p->w_tabs ? p->w_width : 0; p->w_tabs = xrealloc(p->w_tabs, (wi + 1) * 4); if (p->w_tabs == 0) { nomem: if (nmlines) { for (ty = he + hi - 1; ty >= 0; ty--) { mlt = NEWWIN(ty); FreeMline(mlt); } if (nmlines && p->w_mlines != nmlines) free((char *)nmlines); if (nhlines && p->w_hlines != nhlines) free((char *)nhlines); } KillWindow(p); Msg(0, "%s", strnomem); if (nmlines) free(nmlines); if (nhlines) free(nhlines); return -1; } for (; t < wi; t++) p->w_tabs[t] = t && !(t & 7) ? 1 : 0; p->w_tabs[wi] = 0; } else { if (p->w_tabs) free(p->w_tabs); p->w_tabs = 0; } } /* Change w_saved.y - this is only an estimate... */ p->w_saved.y += ncy - p->w_y; p->w_x = ncx; p->w_y = ncy; if (p->w_autoaka > 0) p->w_autoaka = naka; /* do sanity checks */ if (p->w_x > wi) p->w_x = wi; if (p->w_y >= he) p->w_y = he - 1; if (p->w_saved.x > wi) p->w_saved.x = wi; if (p->w_saved.y >= he) p->w_saved.y = he - 1; if (p->w_saved.y < 0) p->w_saved.y = 0; if (p->w_alt.cursor.x > wi) p->w_alt.cursor.x = wi; if (p->w_alt.cursor.y >= he) p->w_alt.cursor.y = he - 1; if (p->w_alt.cursor.y < 0) p->w_alt.cursor.y = 0; /* reset scrolling region */ p->w_top = 0; p->w_bot = he - 1; /* signal new size to window */ if (wi && (p->w_width != wi || p->w_height != he) && p->w_width != 0 && p->w_height != 0 && p->w_ptyfd >= 0 && p->w_pid) { glwz.ws_col = wi; glwz.ws_row = he; ioctl(p->w_ptyfd, TIOCSWINSZ, (char *)&glwz); } /* store new size */ p->w_width = wi; p->w_height = he; p->w_histidx = 0; p->w_histheight = hi; #ifdef ENABLE_TELNET if (p->w_type == W_TYPE_TELNET) TelWindowSize(p); #endif return 0; }
void rpmRelocateFileList(rpmRelocation *relocations, int numRelocations, rpmfs fs, Header h) { static int _printed = 0; char ** baseNames; char ** dirNames; uint32_t * dirIndexes; rpm_count_t fileCount, dirCount; int nrelocated = 0; int fileAlloced = 0; char * fn = NULL; int haveRelocatedBase = 0; size_t maxlen = 0; int i, j; struct rpmtd_s bnames, dnames, dindexes, fmodes; addPrefixes(h, relocations, numRelocations); if (!_printed) { _printed = 1; rpmlog(RPMLOG_DEBUG, "========== relocations\n"); for (i = 0; i < numRelocations; i++) { if (relocations[i].oldPath == NULL) continue; /* XXX can't happen */ if (relocations[i].newPath == NULL) rpmlog(RPMLOG_DEBUG, "%5d exclude %s\n", i, relocations[i].oldPath); else rpmlog(RPMLOG_DEBUG, "%5d relocate %s -> %s\n", i, relocations[i].oldPath, relocations[i].newPath); } } for (i = 0; i < numRelocations; i++) { if (relocations[i].newPath == NULL) continue; size_t len = strlen(relocations[i].newPath); if (len > maxlen) maxlen = len; } headerGet(h, RPMTAG_BASENAMES, &bnames, HEADERGET_MINMEM); headerGet(h, RPMTAG_DIRINDEXES, &dindexes, HEADERGET_ALLOC); headerGet(h, RPMTAG_DIRNAMES, &dnames, HEADERGET_MINMEM); headerGet(h, RPMTAG_FILEMODES, &fmodes, HEADERGET_MINMEM); /* TODO XXX ugh.. use rpmtd iterators & friends instead */ baseNames = bnames.data; dirIndexes = dindexes.data; fileCount = rpmtdCount(&bnames); dirCount = rpmtdCount(&dnames); /* XXX TODO: use rpmtdDup() instead */ dirNames = dnames.data = duparray(dnames.data, dirCount); dnames.flags |= RPMTD_PTR_ALLOCED; /* * For all relocations, we go through sorted file/relocation lists * backwards so that /usr/local relocations take precedence over /usr * ones. */ /* Relocate individual paths. */ for (i = fileCount - 1; i >= 0; i--) { rpmFileTypes ft; int fnlen; size_t len = maxlen + strlen(dirNames[dirIndexes[i]]) + strlen(baseNames[i]) + 1; if (len >= fileAlloced) { fileAlloced = len * 2; fn = xrealloc(fn, fileAlloced); } assert(fn != NULL); /* XXX can't happen */ *fn = '\0'; fnlen = stpcpy( stpcpy(fn, dirNames[dirIndexes[i]]), baseNames[i]) - fn; /* * See if this file path needs relocating. */ /* * XXX FIXME: Would a bsearch of the (already sorted) * relocation list be a good idea? */ for (j = numRelocations - 1; j >= 0; j--) { if (relocations[j].oldPath == NULL) /* XXX can't happen */ continue; len = !rstreq(relocations[j].oldPath, "/") ? strlen(relocations[j].oldPath) : 0; if (fnlen < len) continue; /* * Only subdirectories or complete file paths may be relocated. We * don't check for '\0' as our directory names all end in '/'. */ if (!(fn[len] == '/' || fnlen == len)) continue; if (!rstreqn(relocations[j].oldPath, fn, len)) continue; break; } if (j < 0) continue; rpmtdSetIndex(&fmodes, i); ft = rpmfiWhatis(rpmtdGetNumber(&fmodes)); /* On install, a relocate to NULL means skip the path. */ if (relocations[j].newPath == NULL) { if (ft == XDIR) { /* Start with the parent, looking for directory to exclude. */ for (j = dirIndexes[i]; j < dirCount; j++) { len = strlen(dirNames[j]) - 1; while (len > 0 && dirNames[j][len-1] == '/') len--; if (fnlen != len) continue; if (!rstreqn(fn, dirNames[j], fnlen)) continue; break; } } rpmfsSetAction(fs, i, FA_SKIPNSTATE); rpmlog(RPMLOG_DEBUG, "excluding %s %s\n", ftstring(ft), fn); continue; } /* Relocation on full paths only, please. */ if (fnlen != len) continue; rpmlog(RPMLOG_DEBUG, "relocating %s to %s\n", fn, relocations[j].newPath); nrelocated++; strcpy(fn, relocations[j].newPath); { char * te = strrchr(fn, '/'); if (te) { if (te > fn) te++; /* root is special */ fnlen = te - fn; } else te = fn + strlen(fn); if (!rstreq(baseNames[i], te)) { /* basename changed too? */ if (!haveRelocatedBase) { /* XXX TODO: use rpmtdDup() instead */ bnames.data = baseNames = duparray(baseNames, fileCount); bnames.flags |= RPMTD_PTR_ALLOCED; haveRelocatedBase = 1; } free(baseNames[i]); baseNames[i] = xstrdup(te); } *te = '\0'; /* terminate new directory name */ } /* Does this directory already exist in the directory list? */ for (j = 0; j < dirCount; j++) { if (fnlen != strlen(dirNames[j])) continue; if (!rstreqn(fn, dirNames[j], fnlen)) continue; break; } if (j < dirCount) { dirIndexes[i] = j; continue; } /* Creating new paths is a pita */ dirNames = dnames.data = xrealloc(dnames.data, sizeof(*dirNames) * (dirCount + 1)); dirNames[dirCount] = xstrdup(fn); dirIndexes[i] = dirCount; dirCount++; dnames.count++; } /* Finish off by relocating directories. */ for (i = dirCount - 1; i >= 0; i--) { for (j = numRelocations - 1; j >= 0; j--) { if (relocations[j].oldPath == NULL) /* XXX can't happen */ continue; size_t len = !rstreq(relocations[j].oldPath, "/") ? strlen(relocations[j].oldPath) : 0; if (len && !rstreqn(relocations[j].oldPath, dirNames[i], len)) continue; /* * Only subdirectories or complete file paths may be relocated. We * don't check for '\0' as our directory names all end in '/'. */ if (dirNames[i][len] != '/') continue; if (relocations[j].newPath) { /* Relocate the path */ char *t = NULL; rstrscat(&t, relocations[j].newPath, (dirNames[i] + len), NULL); /* Unfortunatly rpmCleanPath strips the trailing slash.. */ (void) rpmCleanPath(t); rstrcat(&t, "/"); rpmlog(RPMLOG_DEBUG, "relocating directory %s to %s\n", dirNames[i], t); free(dirNames[i]); dirNames[i] = t; nrelocated++; } } } /* Save original filenames in header and replace (relocated) filenames. */ if (nrelocated) { saveRelocs(h, &bnames, &dnames, &dindexes); } rpmtdFreeData(&bnames); rpmtdFreeData(&dnames); rpmtdFreeData(&dindexes); rpmtdFreeData(&fmodes); free(fn); }
/* * _build_part_bitmap - update the total_cpus, total_nodes, and node_bitmap * for the specified partition, also reset the partition pointers in * the node back to this partition. * IN part_ptr - pointer to the partition * RET 0 if no error, errno otherwise * global: node_record_table_ptr - pointer to global node table * NOTE: this does not report nodes defined in more than one partition. this * is checked only upon reading the configuration file, not on an update */ static int _build_part_bitmap(struct part_record *part_ptr) { char *this_node_name; bitstr_t *old_bitmap; struct node_record *node_ptr; /* pointer to node_record */ hostlist_t host_list; part_ptr->total_cpus = 0; part_ptr->total_nodes = 0; if (part_ptr->node_bitmap == NULL) { part_ptr->node_bitmap = bit_alloc(node_record_count); if (part_ptr->node_bitmap == NULL) fatal("bit_alloc malloc failure"); old_bitmap = NULL; } else { old_bitmap = bit_copy(part_ptr->node_bitmap); if (old_bitmap == NULL) fatal("bit_copy malloc failure"); bit_nclear(part_ptr->node_bitmap, 0, node_record_count - 1); } if (part_ptr->nodes == NULL) { /* no nodes in partition */ _unlink_free_nodes(old_bitmap, part_ptr); FREE_NULL_BITMAP(old_bitmap); return 0; } if ((host_list = hostlist_create(part_ptr->nodes)) == NULL) { FREE_NULL_BITMAP(old_bitmap); error("hostlist_create error on %s, %m", part_ptr->nodes); return ESLURM_INVALID_NODE_NAME; } while ((this_node_name = hostlist_shift(host_list))) { node_ptr = find_node_record(this_node_name); if (node_ptr == NULL) { error("_build_part_bitmap: invalid node name %s", this_node_name); free(this_node_name); FREE_NULL_BITMAP(old_bitmap); hostlist_destroy(host_list); return ESLURM_INVALID_NODE_NAME; } part_ptr->total_nodes++; if (slurmctld_conf.fast_schedule) part_ptr->total_cpus += node_ptr->config_ptr->cpus; else part_ptr->total_cpus += node_ptr->cpus; node_ptr->part_cnt++; xrealloc(node_ptr->part_pptr, (node_ptr->part_cnt * sizeof(struct part_record *))); node_ptr->part_pptr[node_ptr->part_cnt-1] = part_ptr; if (old_bitmap) bit_clear(old_bitmap, (int) (node_ptr - node_record_table_ptr)); bit_set(part_ptr->node_bitmap, (int) (node_ptr - node_record_table_ptr)); free(this_node_name); } hostlist_destroy(host_list); _unlink_free_nodes(old_bitmap, part_ptr); last_node_update = time(NULL); FREE_NULL_BITMAP(old_bitmap); return 0; }