/* * Convert a string into a buffer of UTF-8 characters. Terminated by size == 0. * Caller frees. */ struct utf8_data * utf8_fromcstr(const char *src) { struct utf8_data *dst; size_t n; enum utf8_state more; dst = NULL; n = 0; while (*src != '\0') { dst = xreallocarray(dst, n + 1, sizeof *dst); if ((more = utf8_open(&dst[n], *src)) == UTF8_MORE) { while (*++src != '\0' && more == UTF8_MORE) more = utf8_append(&dst[n], *src); if (more == UTF8_DONE) { n++; continue; } src -= dst[n].have; } utf8_set(&dst[n], *src); n++; src++; } dst = xreallocarray(dst, n + 1, sizeof *dst); dst[n].size = 0; return (dst); }
static char * xreadall(int fd) { size_t nread = 0; size_t alloc = BUFSIZ; char *buf = xreallocarray(0, alloc, 1); for (;;) { ssize_t count = read(fd, buf + nread, alloc - nread); if (count == 0) break; if (count < 0) fatal_perror("read"); nread += (size_t)count; while (nread >= alloc) { alloc *= 2; buf = xreallocarray(buf, alloc, 1); } } buf = xreallocarray(buf, nread+1, 1); buf[nread] = '\0'; return buf; }
/* Scroll a region up, moving the top line into the history. */ void grid_scroll_history_region(struct grid *gd, u_int upper, u_int lower) { struct grid_line *gl_history, *gl_upper, *gl_lower; u_int yy; /* Create a space for a new line. */ yy = gd->hsize + gd->sy; gd->linedata = xreallocarray(gd->linedata, yy + 1, sizeof *gd->linedata); /* Move the entire screen down to free a space for this line. */ gl_history = &gd->linedata[gd->hsize]; memmove(gl_history + 1, gl_history, gd->sy * sizeof *gl_history); /* Adjust the region and find its start and end. */ upper++; gl_upper = &gd->linedata[upper]; lower++; gl_lower = &gd->linedata[lower]; /* Move the line into the history. */ memcpy(gl_history, gl_upper, sizeof *gl_history); /* Then move the region up and clear the bottom line. */ memmove(gl_upper, gl_upper + 1, (lower - upper) * sizeof *gl_upper); memset(gl_lower, 0, sizeof *gl_lower); /* Move the history offset down over the line. */ gd->hscrolled++; gd->hsize++; }
/* Join line data. */ void grid_reflow_join(struct grid *dst, u_int *py, struct grid_line *src_gl, u_int new_x) { struct grid_line *dst_gl = &dst->linedata[(*py) - 1]; u_int left, to_copy, ox, nx; /* How much is left on the old line? */ left = new_x - dst_gl->cellsize; /* Work out how much to append. */ to_copy = src_gl->cellsize; if (to_copy > left) to_copy = left; ox = dst_gl->cellsize; nx = ox + to_copy; /* Resize the destination line. */ dst_gl->celldata = xreallocarray(dst_gl->celldata, nx, sizeof *dst_gl->celldata); dst_gl->cellsize = nx; /* Append as much as possible. */ grid_reflow_copy(dst_gl, ox, src_gl, 0, to_copy); /* If there is any left in the source, split it. */ if (src_gl->cellsize > to_copy) { dst_gl->flags |= GRID_LINE_WRAPPED; src_gl->cellsize -= to_copy; grid_reflow_split(dst, py, src_gl, new_x, to_copy); } }
void doregexp(const char *argv[], int argc) { int error; regex_t re; regmatch_t *pmatch; const char *source; if (argc <= 3) { warnx("Too few arguments to regexp"); return; } /* special gnu case */ if (argv[3][0] == '\0' && mimic_gnu) { if (argc == 4 || argv[4] == NULL) return; else pbstr(argv[4]); } source = mimic_gnu ? twiddle(argv[3]) : argv[3]; error = regcomp(&re, source, REG_EXTENDED|REG_NEWLINE); if (error != 0) exit_regerror(error, &re, source); pmatch = xreallocarray(NULL, re.re_nsub+1, sizeof(regmatch_t), NULL); if (argc == 4 || argv[4] == NULL) do_regexpindex(argv[2], &re, source, pmatch); else do_regexp(argv[2], &re, source, argv[4], pmatch); free(pmatch); regfree(&re); }
static Char * dgoto(Char *cp) { Char *dp; if (*cp != '/') { Char *p, *q; int cwdlen; for (p = dcwd->di_name; *p++;) continue; if ((cwdlen = p - dcwd->di_name - 1) == 1) /* root */ cwdlen = 0; for (p = cp; *p++;) continue; dp = xreallocarray(NULL, (cwdlen + (p - cp) + 1), sizeof(Char)); for (p = dp, q = dcwd->di_name; (*p++ = *q++) != '\0';) continue; if (cwdlen) p[-1] = '/'; else p--; /* don't add a / after root */ for (q = cp; (*p++ = *q++) != '\0';) continue; free(cp); cp = dp; dp += cwdlen; } else dp = cp; cp = dcanon(cp, dp); return cp; }
static void vhttp_post_add_params(struct http_param_set *param_set, va_list args) { char **argv_ptr; char *arg; size_t count = 0; if (!param_set->argv) { param_set->n_alloced = 2; param_set->argv = xcalloc(param_set->n_alloced, sizeof(char *)); } argv_ptr = param_set->argv; while (*argv_ptr) { argv_ptr++; count++; } while ((arg = va_arg(args, char *))) { if (count == param_set->n_alloced - 1) { param_set->n_alloced += 2; param_set->argv = xreallocarray(param_set->argv, param_set->n_alloced, sizeof(char *)); argv_ptr = ¶m_set->argv[count]; } *argv_ptr++ = arg; count++; } *argv_ptr = 0; }
static int handle_new(int use, const char *name, int fd, int flags, DIR *dirp) { int i; if (first_unused_handle == -1) { if (num_handles + 1 <= num_handles) return -1; num_handles++; handles = xreallocarray(handles, num_handles, sizeof(Handle)); handle_unused(num_handles - 1); } i = first_unused_handle; first_unused_handle = handles[i].next_unused; handles[i].use = use; handles[i].dirp = dirp; handles[i].fd = fd; handles[i].flags = flags; handles[i].name = xstrdup(name); handles[i].bytes_read = handles[i].bytes_write = 0; return i; }
/* * Initialize group access list for user with primary (base) and * supplementary groups. Return the number of groups in the list. */ int ga_init(const char *user, gid_t base) { gid_t *groups_bygid; int i, j, retry = 0; struct group *gr; if (ngroups > 0) ga_free(); ngroups = NGROUPS_MAX; #if defined(HAVE_SYSCONF) && defined(_SC_NGROUPS_MAX) ngroups = MAX(NGROUPS_MAX, sysconf(_SC_NGROUPS_MAX)); #endif groups_bygid = xcalloc(ngroups, sizeof(*groups_bygid)); while (getgrouplist(user, base, groups_bygid, &ngroups) == -1) { if (retry++ > 0) fatal("getgrouplist: groups list too small"); groups_bygid = xreallocarray(groups_bygid, ngroups, sizeof(*groups_bygid)); } groups_byname = xcalloc(ngroups, sizeof(*groups_byname)); for (i = 0, j = 0; i < ngroups; i++) if ((gr = getgrgid(groups_bygid[i])) != NULL) groups_byname[j++] = xstrdup(gr->gr_name); free(groups_bygid); return (ngroups = j); }
/* * Duplicate a set of lines between two grids. If there aren't enough lines in * either source or destination, the number of lines is limited to the number * available. */ void grid_duplicate_lines(struct grid *dst, u_int dy, struct grid *src, u_int sy, u_int ny) { struct grid_line *dstl, *srcl; u_int yy; if (dy + ny > dst->hsize + dst->sy) ny = dst->hsize + dst->sy - dy; if (sy + ny > src->hsize + src->sy) ny = src->hsize + src->sy - sy; grid_clear_lines(dst, dy, ny); for (yy = 0; yy < ny; yy++) { srcl = &src->linedata[sy]; dstl = &dst->linedata[dy]; memcpy(dstl, srcl, sizeof *dstl); if (srcl->cellsize != 0) { dstl->celldata = xreallocarray(NULL, srcl->cellsize, sizeof *dstl->celldata); memcpy(dstl->celldata, srcl->celldata, srcl->cellsize * sizeof *dstl->celldata); } sy++; dy++; } }
int build_cmd(char ***cmd_argv, char **argv, int argc) { int cmd_argc, i, cur; char *cp, *rcsinit, *linebuf, *lp; if ((rcsinit = getenv("RCSINIT")) == NULL) { *cmd_argv = argv; return argc; } cur = argc + 2; cmd_argc = 0; *cmd_argv = xcalloc(cur, sizeof(char *)); (*cmd_argv)[cmd_argc++] = argv[0]; linebuf = xstrdup(rcsinit); for (lp = linebuf; lp != NULL;) { cp = strsep(&lp, " \t\b\f\n\r\t\v"); if (cp == NULL) break; if (*cp == '\0') continue; if (cmd_argc == cur) { cur += 8; *cmd_argv = xreallocarray(*cmd_argv, cur, sizeof(char *)); } (*cmd_argv)[cmd_argc++] = cp; } if (cmd_argc + argc > cur) { cur = cmd_argc + argc + 1; *cmd_argv = xreallocarray(*cmd_argv, cur, sizeof(char *)); } for (i = 1; i < argc; i++) (*cmd_argv)[cmd_argc++] = argv[i]; (*cmd_argv)[cmd_argc] = NULL; return cmd_argc; }
/* * The caller is responsible for putting value in a safe place */ void set(Char *var, Char *val) { Char **vec = xreallocarray(NULL, 2, sizeof(Char **)); vec[0] = val; vec[1] = 0; set1(var, vec, &shvhed); }
/* Clear the history. */ void grid_clear_history(struct grid *gd) { grid_clear_lines(gd, 0, gd->hsize); grid_move_lines(gd, 0, gd->hsize, gd->sy); gd->hsize = 0; gd->linedata = xreallocarray(gd->linedata, gd->sy, sizeof *gd->linedata); }
static struct window_buffer_itemdata * window_buffer_add_item(struct window_buffer_modedata *data) { struct window_buffer_itemdata *item; data->item_list = xreallocarray(data->item_list, data->item_size + 1, sizeof *data->item_list); item = data->item_list[data->item_size++] = xcalloc(1, sizeof *item); return (item); }
/* Convert from a buffer of UTF-8 characters into a string. Caller frees. */ char * utf8_tocstr(struct utf8_data *src) { char *dst; size_t n; dst = NULL; n = 0; for(; src->size != 0; src++) { dst = xreallocarray(dst, n + src->size, 1); memcpy(dst + n, src->data, src->size); n += src->size; } dst = xreallocarray(dst, n + 1, 1); dst[n] = '\0'; return (dst); }
static void process_readdir(u_int32_t id) { DIR *dirp; struct dirent *dp; char *path; int r, handle; if ((r = get_handle(iqueue, &handle)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("request %u: readdir \"%s\" (handle %d)", id, handle_to_name(handle), handle); dirp = handle_to_dir(handle); path = handle_to_name(handle); if (dirp == NULL || path == NULL) { send_status(id, SSH2_FX_FAILURE); } else { struct stat st; char pathname[PATH_MAX]; Stat *stats; int nstats = 10, count = 0, i; stats = xcalloc(nstats, sizeof(Stat)); while ((dp = readdir(dirp)) != NULL) { if (count >= nstats) { nstats *= 2; stats = xreallocarray(stats, nstats, sizeof(Stat)); } /* XXX OVERFLOW ? */ snprintf(pathname, sizeof pathname, "%s%s%s", path, strcmp(path, "/") ? "/" : "", dp->d_name); if (lstat(pathname, &st) < 0) continue; stat_to_attrib(&st, &(stats[count].attrib)); stats[count].name = xstrdup(dp->d_name); stats[count].long_name = ls_file(dp->d_name, &st, 0, 0); count++; /* send up to 100 entries in one message */ /* XXX check packet size instead */ if (count == 100) break; } if (count > 0) { send_names(id, count, stats); for (i = 0; i < count; i++) { free(stats[i].name); free(stats[i].long_name); } } else { send_status(id, SSH2_FX_EOF); } free(stats); } }
/* * resizedivs: allocate more diversion files */ void resizedivs(int n) { int i; outfile = xreallocarray(outfile, n, sizeof(FILE *), "too many diverts %d", n); for (i = maxout; i < n; i++) outfile[i] = NULL; maxout = n; }
static void enlarge_stack(void) { STACKMAX += STACKMAX/2; mstack = xreallocarray(mstack, STACKMAX, sizeof(stae), "Evaluation stack overflow (%lu)", (unsigned long)STACKMAX); sstack = xrealloc(sstack, STACKMAX, "Evaluation stack overflow (%lu)", (unsigned long)STACKMAX); }
/* Clear the history. */ void grid_clear_history(struct grid *gd) { grid_trim_history(gd, gd->hsize); gd->hscrolled = 0; gd->hsize = 0; gd->linedata = xreallocarray(gd->linedata, gd->sy, sizeof *gd->linedata); }
/* * Scroll the entire visible screen, moving one line into the history. Just * allocate a new line at the bottom and move the history size indicator. */ void grid_scroll_history(struct grid *gd) { u_int yy; yy = gd->hsize + gd->sy; gd->linedata = xreallocarray(gd->linedata, yy + 1, sizeof *gd->linedata); memset(&gd->linedata[yy], 0, sizeof gd->linedata[yy]); gd->hsize++; }
/* Get an extended cell. */ static void grid_get_extended_cell(struct grid_line *gl, struct grid_cell_entry *gce, int flags) { u_int at = gl->extdsize + 1; gl->extddata = xreallocarray(gl->extddata, at, sizeof *gl->extddata); gl->extdsize = at; gce->offset = at - 1; gce->flags = (flags | GRID_FLAG_EXTENDED); }
/* Add lines, return the first new one. */ static struct grid_line * grid_reflow_add(struct grid *gd, u_int n) { struct grid_line *gl; u_int sy = gd->sy + n; gd->linedata = xreallocarray(gd->linedata, sy, sizeof *gd->linedata); gl = &gd->linedata[gd->sy]; memset(gl, 0, n * (sizeof *gl)); gd->sy = sy; return (gl); }
/* Set cell at relative position. */ void grid_set_cell(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc) { struct grid_line *gl; struct grid_cell_entry *gce; struct grid_cell *gcp; int extended; if (grid_check_y(gd, py) != 0) return; grid_expand_line(gd, py, px + 1, 8); gl = &gd->linedata[py]; gce = &gl->celldata[px]; if (px + 1 > gl->cellused) gl->cellused = px + 1; extended = (gce->flags & GRID_FLAG_EXTENDED); if (!extended && (gc->data.size != 1 || gc->data.width != 1)) extended = 1; if (!extended && ((gc->fg & COLOUR_FLAG_RGB) || (gc->bg & COLOUR_FLAG_RGB))) extended = 1; if (extended) { gl->flags |= GRID_LINE_EXTENDED; if (~gce->flags & GRID_FLAG_EXTENDED) { gl->extddata = xreallocarray(gl->extddata, gl->extdsize + 1, sizeof *gl->extddata); gce->offset = gl->extdsize++; gce->flags = gc->flags | GRID_FLAG_EXTENDED; } if (gce->offset >= gl->extdsize) fatalx("offset too big"); gcp = &gl->extddata[gce->offset]; memcpy(gcp, gc, sizeof *gcp); return; } gce->flags = gc->flags; gce->data.attr = gc->attr; gce->data.fg = gc->fg & 0xff; if (gc->fg & COLOUR_FLAG_256) gce->flags |= GRID_FLAG_FG256; gce->data.bg = gc->bg & 0xff; if (gc->bg & COLOUR_FLAG_256) gce->flags |= GRID_FLAG_BG256; gce->data.data = gc->data.data[0]; }
/* * Scroll the entire visible screen, moving one line into the history. Just * allocate a new line at the bottom and move the history size indicator. */ void grid_scroll_history(struct grid *gd, u_int bg) { u_int yy; yy = gd->hsize + gd->sy; gd->linedata = xreallocarray(gd->linedata, yy + 1, sizeof *gd->linedata); grid_empty_line(gd, yy, bg); gd->hscrolled++; gd->hsize++; }
static void dset(Char *dp) { /* * Don't call set() directly cause if the directory contains ` or * other junk characters glob will fail. */ Char **vec = xreallocarray(NULL, 2, sizeof(*vec)); vec[0] = Strsave(dp); vec[1] = 0; setq(STRcwd, vec, &shvhed); Setenv(STRPWD, dp); }
static void strvec_append(strvec *v, const char *val) { if (v->used >= v->alloc) { if (v->alloc == 0) v->alloc = 8; else v->alloc *= 2; v->vec = xreallocarray(v->vec, v->alloc, sizeof(char *)); } v->vec[v->used++] = val; }
static void pidvec_append(pidvec *v, pid_t val) { if (v->used >= v->alloc) { if (v->alloc == 0) v->alloc = 8; else v->alloc *= 2; v->vec = xreallocarray(v->vec, v->alloc, sizeof(char *)); } v->vec[v->used++] = val; }
void cfg_add_cause(const char *fmt, ...) { va_list ap; char *msg; va_start(ap, fmt); xvasprintf(&msg, fmt, ap); va_end(ap); cfg_ncauses++; cfg_causes = xreallocarray(cfg_causes, cfg_ncauses, sizeof *cfg_causes); cfg_causes[cfg_ncauses - 1] = msg; }
/* * Sanitize a string, changing any UTF-8 characters to '_'. Caller should free * the returned string. Anything not valid printable ASCII or UTF-8 is * stripped. */ char * utf8_sanitize(const char *src) { char *dst; size_t n; enum utf8_state more; struct utf8_data ud; u_int i; dst = NULL; n = 0; while (*src != '\0') { dst = xreallocarray(dst, n + 1, sizeof *dst); if ((more = utf8_open(&ud, *src)) == UTF8_MORE) { while (*++src != '\0' && more == UTF8_MORE) more = utf8_append(&ud, *src); if (more == UTF8_DONE) { dst = xreallocarray(dst, n + ud.width, sizeof *dst); for (i = 0; i < ud.width; i++) dst[n++] = '_'; continue; } src -= ud.have; } if (*src > 0x1f && *src < 0x7f) dst[n++] = *src; else dst[n++] = '_'; src++; } dst = xreallocarray(dst, n + 1, sizeof *dst); dst[n] = '\0'; return (dst); }
/* Expand line to fit to cell. */ void grid_expand_line(struct grid *gd, u_int py, u_int sx) { struct grid_line *gl; u_int xx; gl = &gd->linedata[py]; if (sx <= gl->cellsize) return; gl->celldata = xreallocarray(gl->celldata, sx, sizeof *gl->celldata); for (xx = gl->cellsize; xx < sx; xx++) grid_clear_cell(gd, xx, py); gl->cellsize = sx; }