int main(int argc, char *argv[]) { size_t len, lineno = 0; char *line, *eptr, *longopt, *ptr, *optstring = NULL, *result = NULL; char buf[1024]; char *args[128]; char arg[256]; int nargs = -1; int c; int nlongopts = 0; int maxnlongopts = 0; int *longopt_flags = NULL; struct option *longopts = NULL; while ((line = fparseln(stdin, &len, &lineno, NULL, 0)) != NULL) { if (strncmp(line, "optstring:", 10) == 0) { if (optstring) free(optstring); optstring = strtok(&line[11], WS); if (optstring == NULL) errx(1, "missing optstring at line %ld", (unsigned long)lineno); optstring = strdup(optstring); } else if (strncmp(line, "longopts:", 9) == 0) { if (longopts) { int i; for (i = 0; i < nlongopts; i++) if (longopts[i].name != NULL) free(__UNCONST(longopts[i].name)); free(longopts); } if (longopt_flags) free(longopt_flags); nlongopts = 0; ptr = strtok(&line[10], WS); if (ptr == NULL) errx(1, "missing longopts at line %ld", (unsigned long)lineno); maxnlongopts = strtoul(ptr, &eptr, 10); if (*eptr != '\0') warnx("garbage in longopts at line %ld", (unsigned long)lineno); maxnlongopts++; /* space for trailer */ longopts = (struct option *)calloc(sizeof(struct option), maxnlongopts); if (longopts == NULL) err(1, "calloc"); longopt_flags = (int *)calloc(sizeof(int), maxnlongopts); if (longopt_flags == NULL) err(1, "calloc"); } else if (strncmp(line, "longopt:", 8) == 0) { if (longopts == NULL) errx(1, "longopt: without longopts at line %ld", (unsigned long)lineno); if (nlongopts >= maxnlongopts) errx(1, "longopt: too many options at line %ld", (unsigned long)lineno); /* name */ ptr = &line[9]; SKIPWS(ptr); longopt = strsep(&ptr, ","); if (longopt == NULL) errx(1, "missing longopt at line %ld", (unsigned long)lineno); longopts[nlongopts].name = strdup(longopt); /* has_arg */ SKIPWS(ptr); longopt = strsep(&ptr, ","); if (*longopt != '\0') { if (strncmp(longopt, "0", 1) == 0 || strncmp(longopt, "no_argument", 2) == 0) longopts[nlongopts].has_arg = no_argument; else if (strncmp(longopt, "1", 1) == 0 || strncmp(longopt, "required_argument", 8) == 0) longopts[nlongopts].has_arg = required_argument; else if (strncmp(longopt, "2", 1) == 0 || strncmp(longopt, "optional_argument", 8) == 0) longopts[nlongopts].has_arg = optional_argument; else errx(1, "unknown has_arg %s at line %ld", longopt, (unsigned long)lineno); } /* flag */ SKIPWS(ptr); longopt = strsep(&ptr, ","); if (*longopt != '\0' && strncmp(longopt, "NULL", 4) != 0) longopts[nlongopts].flag = &longopt_flags[nlongopts]; /* val */ SKIPWS(ptr); longopt = strsep(&ptr, ","); if (*longopt == '\0') errx(1, "missing val at line %ld", (unsigned long)lineno); if (*longopt != '\'') { longopts[nlongopts].val = (int)strtoul(longopt, &eptr, 10); if (*eptr != '\0') errx(1, "invalid val at line %ld", (unsigned long)lineno); } else longopts[nlongopts].val = (int)longopt[1]; nlongopts++; } else if (strncmp(line, "args:", 5) == 0) { for (; nargs >= 0; nargs--) { if (args[nargs] != NULL) free(args[nargs]); } args[nargs = 0] = strtok(&line[6], WS); if (args[nargs] == NULL) errx(1, "Missing args"); args[nargs] = strdup(args[nargs]); while ((args[++nargs] = strtok(NULL, WS)) != NULL) args[nargs] = strdup(args[nargs]); } else if (strncmp(line, "result:", 7) == 0) { int li; buf[0] = '\0'; optind = optreset = 1; if (result) free(result); result = strtok(&line[8], WS); if (result == NULL) errx(1, "missing result at line %ld", (unsigned long)lineno); if (optstring == NULL) errx(1, "result: without optstring"); if (longopts == NULL || nlongopts == 0) errx(1, "result: without longopts"); result = strdup(result); if (nargs == -1) errx(1, "result: without args"); li = -2; while ((c = getopt_long(nargs, args, optstring, longopts, &li)) != -1) { if (c == ':') errx(1, "`:' found as argument char"); if (li == -2) { ptr = strchr(optstring, c); if (ptr == NULL) { snprintf(arg, sizeof(arg), "!%c,", c); strcat(buf, arg); continue; } if (ptr[1] != ':') snprintf(arg, sizeof(arg), "%c,", c); else snprintf(arg, sizeof(arg), "%c=%s,", c, optarg); } else { switch (longopts[li].has_arg) { case no_argument: snprintf(arg, sizeof(arg), "-%s,", longopts[li].name); break; case required_argument: snprintf(arg, sizeof(arg), "-%s=%s,", longopts[li].name, optarg); break; case optional_argument: snprintf(arg, sizeof(arg), "-%s%s%s,", longopts[li].name, (optarg)? "=" : "", (optarg)? optarg : ""); break; default: errx(1, "internal error"); } } strcat(buf, arg); li = -2; } len = strlen(buf); if (len > 0) { buf[len - 1] = '|'; buf[len] = '\0'; } else { buf[0] = '|'; buf[1] = '\0'; } snprintf(arg, sizeof(arg), "%d", nargs - optind); strcat(buf, arg); if (strcmp(buf, result) != 0) errx(1, "`%s' != `%s'", buf, result); } else errx(1, "unknown directive at line %ld", (unsigned long)lineno); free(line); } return 0; }
int main(int argc __unused, char *argv[]) { long cols, i, inc, j, margin, nstops, stops[NSTOPS]; const char *cr, *ct, *st, *ML; char area[1024], *ap, *arg, *end; setlocale(LC_ALL, ""); inc = 8; margin = 0; nstops = -1; while ((arg = *++argv) != NULL && (*arg == '-' || *arg == '+')) { if (*arg == '+') { /* +m[n] or +[n] */ if (*++arg == 'm') arg++; if (*arg != '\0') { errno = 0; margin = strtol(arg, &end, 10); if (errno != 0 || *end != '\0' || margin < 0) errx(1, "%s: invalid margin width", arg); } else margin = 10; } else if (isdigit(arg[1])) { /* -n */ errno = 0; inc = strtol(arg + 1, &end, 10); if (errno != 0 || *end != '\0' || inc < 0) errx(1, "%s: invalid increment", arg + 1); } else if (arg[1] == 'T') { /* -Ttype or -T type */ if (arg[2] != '\0') setenv("TERM", arg + 2, 1); else { if ((arg = *++argv) == NULL) usage(); setenv("TERM", arg, 1); } } else if (arg[1] == '-') { arg = *++argv; break; } else { /* Predefined format */ for (i = 0; i < (int)NELEMS(formats); i++) if (strcmp(formats[i].name, arg + 1) == 0) break; if (i == NELEMS(formats)) usage(); for (j = nstops = 0; j < NSTOPS && formats[i].stops[j] != 0; j++) stops[nstops++] = formats[i].stops[j]; } } if (arg != NULL) { if (nstops != -1) usage(); gettabs(arg, stops, &nstops); } /* Initialise terminal, get the strings we need */ setupterm(NULL, 1, NULL); ap = area; if ((ct = tgetstr("ct", &ap)) == NULL) errx(1, "terminal cannot clear tabs"); if ((st = tgetstr("st", &ap)) == NULL) errx(1, "terminal cannot set tabs"); if ((cr = tgetstr("cr", &ap)) == NULL) cr = "\r"; ML = tgetstr("ML", &ap); cols = ttywidth(); /* Clear all tabs. */ putp(cr); putp(ct); /* * Set soft margin. * XXX Does this actually work? */ if (ML != NULL) { printf("%*s", (int)margin, ""); putp(ML); } else if (margin != 0) warnx("terminal cannot set left margin"); /* Optionally output new tab stops. */ if (nstops >= 0) { printf("%*s", (int)stops[0] - 1, ""); putp(st); for (i = 1; i < nstops; i++) { printf("%*s", (int)(stops[i] - stops[i - 1]), ""); putp(st); } } else if (inc > 0) { for (i = 0; i < cols / inc; i++) { putp(st); printf("%*s", (int)inc, ""); } putp(st); } putp(cr); exit(0); }
int main(int argc, char **argv) { char *font, *type, *termmode; const char *opts; int dumpmod, dumpopt, opt; int reterr; vt4_mode = is_vt4(); init(); info.size = sizeof(info); if (ioctl(0, CONS_GETINFO, &info) == -1) err(1, "must be on a virtual console"); dumpmod = 0; dumpopt = DUMP_FBF; termmode = NULL; if (vt4_mode) opts = "b:Cc:fg:h:Hi:M:m:pPr:S:s:T:t:x"; else opts = "b:Cc:dfg:h:Hi:l:LM:m:pPr:S:s:T:t:x"; while ((opt = getopt(argc, argv, opts)) != -1) switch(opt) { case 'b': set_border_color(optarg); break; case 'C': clear_history(); break; case 'c': set_cursor_type(optarg); break; case 'd': if (vt4_mode) break; print_scrnmap(); break; case 'f': optarg = nextarg(argc, argv, &optind, 'f', 0); if (optarg != NULL) { font = nextarg(argc, argv, &optind, 'f', 0); if (font == NULL) { type = NULL; font = optarg; } else type = optarg; load_font(type, font); } else { if (!vt4_mode) usage(); /* Switch syscons to ROM? */ load_default_vt4font(); } break; case 'g': if (sscanf(optarg, "%dx%d", &vesa_cols, &vesa_rows) != 2) { revert(); warnx("incorrect geometry: %s", optarg); usage(); } break; case 'h': set_history(optarg); break; case 'H': dumpopt = DUMP_ALL; break; case 'i': show_info(optarg); break; case 'l': if (vt4_mode) break; load_scrnmap(optarg); break; case 'L': if (vt4_mode) break; load_default_scrnmap(); break; case 'M': set_mouse_char(optarg); break; case 'm': set_mouse(optarg); break; case 'p': dumpmod = DUMP_FMT_RAW; break; case 'P': dumpmod = DUMP_FMT_TXT; break; case 'r': get_reverse_colors(argc, argv, &optind); break; case 'S': set_lockswitch(optarg); break; case 's': set_console(optarg); break; case 'T': if (strcmp(optarg, "xterm") != 0 && strcmp(optarg, "cons25") != 0) usage(); termmode = optarg; break; case 't': set_screensaver_timeout(optarg); break; case 'x': hex = 1; break; default: usage(); } if (dumpmod != 0) dump_screen(dumpmod, dumpopt); reterr = video_mode(argc, argv, &optind); get_normal_colors(argc, argv, &optind); if (optind < argc && !strcmp(argv[optind], "show")) { test_frame(); optind++; } video_mode(argc, argv, &optind); if (termmode != NULL) set_terminal_mode(termmode); get_normal_colors(argc, argv, &optind); if (colors_changed || video_mode_changed) { if (!(new_mode_info.vi_flags & V_INFO_GRAPHICS)) { if ((normal_back_color < 8) && (revers_back_color < 8)) { set_colors(); } else { revert(); errx(1, "bg color for text modes must be < 8"); } } else { set_colors(); } } if ((optind != argc) || (argc == 1)) usage(); return reterr; }
__EXPORT void board_spi_reset(int ms) { /* disable SPI bus */ px4_arch_configgpio(GPIO_SPI_CS_OFF_MPU9250); px4_arch_configgpio(GPIO_SPI_CS_OFF_HMC5983); px4_arch_configgpio(GPIO_SPI_CS_OFF_MS5611); px4_arch_configgpio(GPIO_SPI_CS_OFF_ICM_20608_G); px4_arch_gpiowrite(GPIO_SPI_CS_OFF_MPU9250, 0); px4_arch_gpiowrite(GPIO_SPI_CS_OFF_HMC5983, 0); px4_arch_gpiowrite(GPIO_SPI_CS_OFF_MS5611, 0); px4_arch_gpiowrite(GPIO_SPI_CS_OFF_ICM_20608_G, 0); px4_arch_configgpio(GPIO_SPI1_SCK_OFF); px4_arch_configgpio(GPIO_SPI1_MISO_OFF); px4_arch_configgpio(GPIO_SPI1_MOSI_OFF); px4_arch_gpiowrite(GPIO_SPI1_SCK_OFF, 0); px4_arch_gpiowrite(GPIO_SPI1_MISO_OFF, 0); px4_arch_gpiowrite(GPIO_SPI1_MOSI_OFF, 0); px4_arch_configgpio(GPIO_DRDY_OFF_MPU9250); px4_arch_configgpio(GPIO_DRDY_OFF_HMC5983); px4_arch_configgpio(GPIO_DRDY_OFF_ICM_20608_G); px4_arch_gpiowrite(GPIO_DRDY_OFF_MPU9250, 0); px4_arch_gpiowrite(GPIO_DRDY_OFF_HMC5983, 0); px4_arch_gpiowrite(GPIO_DRDY_OFF_ICM_20608_G, 0); /* set the sensor rail off */ px4_arch_configgpio(GPIO_VDD_3V3_SENSORS_EN); px4_arch_gpiowrite(GPIO_VDD_3V3_SENSORS_EN, 0); /* wait for the sensor rail to reach GND */ usleep(ms * 1000); warnx("reset done, %d ms", ms); /* re-enable power */ /* switch the sensor rail back on */ px4_arch_gpiowrite(GPIO_VDD_3V3_SENSORS_EN, 1); /* wait a bit before starting SPI, different times didn't influence results */ usleep(100); /* reconfigure the SPI pins */ #ifdef CONFIG_STM32_SPI1 px4_arch_configgpio(GPIO_SPI_CS_MPU9250); px4_arch_configgpio(GPIO_SPI_CS_HMC5983); px4_arch_configgpio(GPIO_SPI_CS_MS5611); px4_arch_configgpio(GPIO_SPI_CS_ICM_20608_G); /* De-activate all peripherals, * required for some peripheral * state machines */ px4_arch_gpiowrite(GPIO_SPI_CS_MPU9250, 1); px4_arch_gpiowrite(GPIO_SPI_CS_HMC5983, 1); px4_arch_gpiowrite(GPIO_SPI_CS_MS5611, 1); px4_arch_gpiowrite(GPIO_SPI_CS_ICM_20608_G, 1); px4_arch_configgpio(GPIO_SPI1_SCK); px4_arch_configgpio(GPIO_SPI1_MISO); px4_arch_configgpio(GPIO_SPI1_MOSI); // // XXX bring up the EXTI pins again // px4_arch_configgpio(GPIO_GYRO_DRDY); // px4_arch_configgpio(GPIO_MAG_DRDY); // px4_arch_configgpio(GPIO_ACCEL_DRDY); // px4_arch_configgpio(GPIO_EXTI_MPU_DRDY); #endif }
/* * Copy password file from one descriptor to another, replacing, deleting * or adding a single record on the way. */ int pw_copy(int ffd, int tfd, const struct passwd *pw, struct passwd *old_pw) { char buf[8192], *end, *line, *p, *q, *r, t; struct passwd *fpw; const struct passwd *spw; size_t len; int eof, readlen; if (old_pw == NULL && pw == NULL) return (-1); spw = old_pw; /* deleting a user */ if (pw == NULL) { line = NULL; } else { if ((line = pw_make(pw)) == NULL) return (-1); } /* adding a user */ if (spw == NULL) spw = pw; eof = 0; len = 0; p = q = end = buf; for (;;) { /* find the end of the current line */ for (p = q; q < end && *q != '\0'; ++q) if (*q == '\n') break; /* if we don't have a complete line, fill up the buffer */ if (q >= end) { if (eof) break; if ((size_t)(q - p) >= sizeof(buf)) { warnx("passwd line too long"); errno = EINVAL; /* hack */ goto err; } if (p < end) { q = memmove(buf, p, end - p); end -= p - buf; } else { p = q = end = buf; } readlen = read(ffd, end, sizeof(buf) - (end - buf)); if (readlen == -1) goto err; else len = (size_t)readlen; if (len == 0 && p == buf) break; end += len; len = end - buf; if (len < (ssize_t)sizeof(buf)) { eof = 1; if (len > 0 && buf[len - 1] != '\n') ++len, *end++ = '\n'; } continue; } /* is it a blank line or a comment? */ for (r = p; r < q && isspace(*r); ++r) /* nothing */ ; if (r == q || *r == '#') { /* yep */ if (write(tfd, p, q - p + 1) != q - p + 1) goto err; ++q; continue; } /* is it the one we're looking for? */ t = *q; *q = '\0'; fpw = pw_scan(r, PWSCAN_MASTER); /* * fpw is either the struct passwd for the current line, * or NULL if the line is malformed. */ *q = t; if (fpw == NULL || strcmp(fpw->pw_name, spw->pw_name) != 0) { /* nope */ if (fpw != NULL) free(fpw); if (write(tfd, p, q - p + 1) != q - p + 1) goto err; ++q; continue; } if (old_pw && !pw_equal(fpw, old_pw)) { warnx("entry inconsistent"); free(fpw); errno = EINVAL; /* hack */ goto err; } free(fpw); /* it is, replace or remove it */ if (line != NULL) { len = strlen(line); if (write(tfd, line, len) != (int)len) goto err; } else { /* when removed, avoid the \n */ q++; } /* we're done, just copy the rest over */ for (;;) { if (write(tfd, q, end - q) != end - q) goto err; q = buf; readlen = read(ffd, buf, sizeof(buf)); if (readlen == 0) break; else len = (size_t)readlen; if (readlen == -1) goto err; end = buf + len; } goto done; } /* if we got here, we didn't find the old entry */ if (line == NULL) { errno = ENOENT; goto err; } len = strlen(line); if ((size_t)write(tfd, line, len) != len || write(tfd, "\n", 1) != 1) goto err; done: if (line != NULL) free(line); return (0); err: if (line != NULL) free(line); return (-1); }
/* * Check a directory. INO is the inode number; PATHSOFAR is the path * to this directory. This traverses the volume directory tree * recursively. */ static void pass1_dir(uint32_t ino, const char *pathsofar) { struct sfs_dinode sfi; struct sfs_dir *direntries; uint32_t ndirentries, i; int ichanged=0, dchanged=0; sfs_readinode(ino, &sfi); if (sfi.sfi_size % sizeof(struct sfs_dir) != 0) { setbadness(EXIT_RECOV); warnx("Directory %s has illegal size %lu (fixed)", pathsofar, (unsigned long) sfi.sfi_size); sfi.sfi_size = SFS_ROUNDUP(sfi.sfi_size, sizeof(struct sfs_dir)); ichanged = 1; } count_dirs++; if (pass1_inode(ino, &sfi, ichanged)) { /* been here before; crosslinked dir, sort it out in pass 2 */ return; } ndirentries = sfi.sfi_size/sizeof(struct sfs_dir); direntries = domalloc(sfi.sfi_size); sfs_readdir(&sfi, direntries, ndirentries); for (i=0; i<ndirentries; i++) { if (pass1_direntry(pathsofar, i, &direntries[i])) { dchanged = 1; } } for (i=0; i<ndirentries; i++) { if (direntries[i].sfd_ino == SFS_NOINO) { /* nothing */ } else if (!strcmp(direntries[i].sfd_name, ".")) { /* nothing */ } else if (!strcmp(direntries[i].sfd_name, "..")) { /* nothing */ } else { char path[strlen(pathsofar)+SFS_NAMELEN+1]; struct sfs_dinode subsfi; uint32_t subino; subino = direntries[i].sfd_ino; sfs_readinode(subino, &subsfi); snprintf(path, sizeof(path), "%s/%s", pathsofar, direntries[i].sfd_name); switch (subsfi.sfi_type) { case SFS_TYPE_FILE: if (pass1_inode(subino, &subsfi, 0)) { /* been here before */ break; } count_files++; break; case SFS_TYPE_DIR: pass1_dir(subino, path); break; default: setbadness(EXIT_RECOV); warnx("Object %s: Invalid inode type " "(removed)", path); direntries[i].sfd_ino = SFS_NOINO; direntries[i].sfd_name[0] = 0; dchanged = 1; break; } } } if (dchanged) { sfs_writedir(&sfi, direntries, ndirentries); } free(direntries); }
int exec_upgrade(int argc, char **argv) { struct pkgdb *db = NULL; struct pkg_jobs *jobs = NULL; const char *reponame = NULL; int retcode; int updcode; int ch; bool yes; bool dry_run = false; bool auto_update; nbactions = nbdone = 0; pkg_flags f = PKG_FLAG_NONE | PKG_FLAG_PKG_VERSION_TEST; pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes); pkg_config_bool(PKG_CONFIG_REPO_AUTOUPDATE, &auto_update); while ((ch = getopt(argc, argv, "fInqFr:Uy")) != -1) { switch (ch) { case 'f': f |= PKG_FLAG_FORCE; break; case 'I': f |= PKG_FLAG_NOSCRIPT; break; case 'U': auto_update = false; break; case 'n': f |= PKG_FLAG_DRY_RUN; dry_run = true; break; case 'F': f |= PKG_FLAG_SKIP_INSTALL; break; case 'q': quiet = true; break; case 'r': reponame = optarg; break; case 'y': yes = true; break; default: usage_upgrade(); return (EX_USAGE); /* NOTREACHED */ } } argc -= optind; argv += optind; if (argc != 0) { usage_upgrade(); return (EX_USAGE); } if (dry_run && !auto_update) retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL|PKGDB_DB_REPO); else retcode = pkgdb_access(PKGDB_MODE_READ | PKGDB_MODE_WRITE | PKGDB_MODE_CREATE, PKGDB_DB_LOCAL|PKGDB_DB_REPO); if (retcode == EPKG_ENOACCESS && dry_run) { auto_update = false; retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL|PKGDB_DB_REPO); } if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privilege to upgrade packages"); return (EX_NOPERM); } else if (retcode != EPKG_OK) return (EX_IOERR); else retcode = EX_SOFTWARE; /* first update the remote repositories if needed */ if (auto_update && (updcode = pkgcli_update(false)) != EPKG_OK) return (updcode); if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK) return (EX_IOERR); if (pkg_jobs_new(&jobs, PKG_JOBS_UPGRADE, db) != EPKG_OK) goto cleanup; if (reponame != NULL && pkg_jobs_set_repository(jobs, reponame) != EPKG_OK) goto cleanup; pkg_jobs_set_flags(jobs, f); if (pkg_jobs_solve(jobs) != EPKG_OK) goto cleanup; if ((nbactions = pkg_jobs_count(jobs)) == 0) { if (!quiet) printf("Nothing to do\n"); retcode = EXIT_SUCCESS; goto cleanup; } if (!quiet || dry_run) { print_jobs_summary(jobs, "Upgrades have been requested for the following %d " "packages:\n\n", nbactions); if (!yes && !dry_run) yes = query_yesno("\nProceed with upgrading " "packages [y/N]: "); if (dry_run) yes = false; } if (yes && pkg_jobs_apply(jobs) != EPKG_OK) goto cleanup; if (messages != NULL) { sbuf_finish(messages); printf("%s", sbuf_data(messages)); } retcode = EXIT_SUCCESS; cleanup: pkg_jobs_free(jobs); pkgdb_close(db); if (!yes && newpkgversion) newpkgversion = false; return (retcode); }
static void sctp_process_tcb(struct xsctp_tcb *xstcb, char *buf, const size_t buflen, size_t *offset, int *indent) { int i, xl_total = 0, xr_total = 0, x_max; struct xsctp_raddr *xraddr; struct xsctp_laddr *xladdr; struct xladdr_entry *prev_xl = NULL, *xl = NULL, *xl_tmp; struct xraddr_entry *prev_xr = NULL, *xr = NULL, *xr_tmp; LIST_INIT(&xladdr_head); LIST_INIT(&xraddr_head); /* * Make `struct xladdr_list' list and `struct xraddr_list' list * to handle the address flexibly. */ while (*offset < buflen) { xladdr = (struct xsctp_laddr *)(buf + *offset); *offset += sizeof(struct xsctp_laddr); if (xladdr->last == 1) break; prev_xl = xl; xl = malloc(sizeof(struct xladdr_entry)); if (xl == NULL) { warnx("malloc %lu bytes", (u_long)sizeof(struct xladdr_entry)); goto out; } xl->xladdr = xladdr; if (prev_xl == NULL) LIST_INSERT_HEAD(&xladdr_head, xl, xladdr_entries); else LIST_INSERT_AFTER(prev_xl, xl, xladdr_entries); xl_total++; } while (*offset < buflen) { xraddr = (struct xsctp_raddr *)(buf + *offset); *offset += sizeof(struct xsctp_raddr); if (xraddr->last == 1) break; prev_xr = xr; xr = malloc(sizeof(struct xraddr_entry)); if (xr == NULL) { warnx("malloc %lu bytes", (u_long)sizeof(struct xraddr_entry)); goto out; } xr->xraddr = xraddr; if (prev_xr == NULL) LIST_INSERT_HEAD(&xraddr_head, xr, xraddr_entries); else LIST_INSERT_AFTER(prev_xr, xr, xraddr_entries); xr_total++; } /* * Let's print the address infos. */ xl = LIST_FIRST(&xladdr_head); xr = LIST_FIRST(&xraddr_head); x_max = (xl_total > xr_total) ? xl_total : xr_total; for (i = 0; i < x_max; i++) { if (((*indent == 0) && i > 0) || *indent > 0) printf("%-12s ", " "); if (xl != NULL) { sctp_print_address(&(xl->xladdr->address), htons(xstcb->local_port), numeric_port); } else { if (Wflag) { printf("%-45s ", " "); } else { printf("%-22s ", " "); } } if (xr != NULL && !Lflag) { sctp_print_address(&(xr->xraddr->address), htons(xstcb->remote_port), numeric_port); } if (xl != NULL) xl = LIST_NEXT(xl, xladdr_entries); if (xr != NULL) xr = LIST_NEXT(xr, xraddr_entries); if (i == 0 && !Lflag) sctp_statesprint(xstcb->state); if (i < x_max) putchar('\n'); } out: /* * Free the list which be used to handle the address. */ xl = LIST_FIRST(&xladdr_head); while (xl != NULL) { xl_tmp = LIST_NEXT(xl, xladdr_entries); free(xl); xl = xl_tmp; } xr = LIST_FIRST(&xraddr_head); while (xr != NULL) { xr_tmp = LIST_NEXT(xr, xraddr_entries); free(xr); xr = xr_tmp; } }
/* * Scan the specified file system to check quota(s) present on it. */ int chkquota(const char *vfstype, const char *fsname, const char *mntpt, void *auxarg, pid_t *pidp) { struct quotaname *qnp = auxarg; struct fileusage *fup; union dinode *dp; int cg, i, mode, errs = 0, status; ino_t ino, inosused; pid_t pid; char *cp; switch (pid = fork()) { case -1: /* error */ warn("fork"); return 1; case 0: /* child */ if ((fi = open(fsname, O_RDONLY, 0)) < 0) err(1, "%s", fsname); sync(); dev_bsize = 1; for (i = 0; sblock_try[i] != -1; i++) { bread(sblock_try[i], (char *)&sblock, (long)SBLOCKSIZE); if ((sblock.fs_magic == FS_UFS1_MAGIC || (sblock.fs_magic == FS_UFS2_MAGIC && sblock.fs_sblockloc == sblock_try[i])) && sblock.fs_bsize <= MAXBSIZE && sblock.fs_bsize >= sizeof(struct fs)) break; } if (sblock_try[i] == -1) { warn("Cannot find file system superblock"); return (1); } dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1); maxino = sblock.fs_ncg * sblock.fs_ipg; for (cg = 0; cg < sblock.fs_ncg; cg++) { ino = cg * sblock.fs_ipg; setinodebuf(ino); bread(fsbtodb(&sblock, cgtod(&sblock, cg)), (char *)(&cgblk), sblock.fs_cgsize); if (sblock.fs_magic == FS_UFS2_MAGIC) inosused = cgblk.cg_initediblk; else inosused = sblock.fs_ipg; /* * If we are using soft updates, then we can trust the * cylinder group inode allocation maps to tell us which * inodes are allocated. We will scan the used inode map * to find the inodes that are really in use, and then * read only those inodes in from disk. */ if (sblock.fs_flags & FS_DOSOFTDEP) { if (!cg_chkmagic(&cgblk)) errx(1, "CG %d: BAD MAGIC NUMBER\n", cg); cp = &cg_inosused(&cgblk)[(inosused - 1) / CHAR_BIT]; for ( ; inosused > 0; inosused -= CHAR_BIT, cp--) { if (*cp == 0) continue; for (i = 1 << (CHAR_BIT - 1); i > 0; i >>= 1) { if (*cp & i) break; inosused--; } break; } if (inosused <= 0) continue; } for (i = 0; i < inosused; i++, ino++) { if ((dp = getnextinode(ino)) == NULL || ino < ROOTINO || (mode = DIP(dp, di_mode) & IFMT) == 0) continue; if (qnp->flags & HASGRP) { fup = addid(DIP(dp, di_gid), GRPQUOTA, NULL); fup->fu_curinodes++; if (mode == IFREG || mode == IFDIR || mode == IFLNK) fup->fu_curblocks += DIP(dp, di_blocks); } if (qnp->flags & HASUSR) { fup = addid(DIP(dp, di_uid), USRQUOTA, NULL); fup->fu_curinodes++; if (mode == IFREG || mode == IFDIR || mode == IFLNK) fup->fu_curblocks += DIP(dp, di_blocks); } } } freeinodebuf(); if (flags&(CHECK_DEBUG|CHECK_VERBOSE)) { (void)printf("*** Checking "); if (qnp->flags & HASUSR) { (void)printf("%s", qfextension[USRQUOTA]); if (qnp->flags & HASGRP) (void)printf(" and "); } if (qnp->flags & HASGRP) (void)printf("%s", qfextension[GRPQUOTA]); (void)printf(" quotas for %s (%s), %swait\n", fsname, mntpt, pidp? "no" : ""); } if (qnp->flags & HASUSR) errs += update(mntpt, qnp->usrqfname, USRQUOTA); if (qnp->flags & HASGRP) errs += update(mntpt, qnp->grpqfname, GRPQUOTA); close(fi); exit (errs); break; default: /* parent */ if (pidp != NULL) { *pidp = pid; return 0; } if (waitpid(pid, &status, 0) < 0) { warn("waitpid"); return 1; } if (WIFEXITED(status)) { if (WEXITSTATUS(status) != 0) return WEXITSTATUS(status); } else if (WIFSIGNALED(status)) { warnx("%s: %s", fsname, strsignal(WTERMSIG(status))); return 1; } break; } return (0); }
int main(int argc, char **argv) { struct archive *a1; struct archive *a2; struct archive_entry *e1; struct archive_entry *e2; const char *tc; char *buf1; char *buf2; char checkcont; char checklen; char checkname; char checksize; char checktime; char a1end; size_t size1; size_t size2; int opt, r; /* * Parse command line options. */ checkcont = 0; checklen = 0; checkname = 0; checksize = 0; checktime = 0; tc = NULL; while ((opt = getopt(argc, argv, "cilnst:")) != -1) { switch(opt) { case 'c': checkcont = 1; break; case 'i': checktime = 1; break; case 'l': checklen = 1; break; case 'n': checkname = 1; break; case 's': checksize = 1; case 't': tc = optarg; break; default: usage(); } } argc -= optind; argv += optind; if (argc != 2) usage(); /* Open file 1 */ a1 = archive_read_new(); archive_read_support_format_ar(a1); if (archive_read_open_filename(a1, argv[0], 1024*10)) { warnx("%s", archive_error_string(a1)); filediff(tc, "archive open failed", NULL); } /* Open file 2 */ a2 = archive_read_new(); archive_read_support_format_ar(a2); if (archive_read_open_filename(a2, argv[1], 1024*10)) { warnx("%s", archive_error_string(a2)); filediff(tc, "archive open failed", NULL); } /* Main loop */ a1end = 0; size1 = 0; size2 = 0; for (;;) { /* * Read header from each archive, compare length. */ r = archive_read_next_header(a1, &e1); if (r == ARCHIVE_EOF) a1end = 1; if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY || r == ARCHIVE_FATAL) { warnx("%s", archive_error_string(a1)); filediff(tc, "archive data error", NULL); } r = archive_read_next_header(a2, &e2); if (r == ARCHIVE_EOF) { if (a1end > 0) break; else { if (checklen) filediff(tc, "length differ", NULL); break; } } if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY || r == ARCHIVE_FATAL) { warnx("%s", archive_error_string(a2)); filediff(tc, "archive data error", NULL); } if (a1end > 0) { if (checklen) filediff(tc, "length differ", NULL); break; } /* * Check member name if required. */ if (checkname) { if (strcmp(archive_entry_pathname(e1), archive_entry_pathname(e2)) != 0) filediff(tc, "member name differ", archive_entry_pathname(e1)); } /* * Compare time if required. */ if (checktime) { if (archive_entry_mtime(e1) != archive_entry_mtime(e2)) filediff(tc, "member mtime differ", archive_entry_pathname(e1)); } /* * Compare member size if required. */ if (checksize || checkcont) { size1 = (size_t) archive_entry_size(e1); size2 = (size_t) archive_entry_size(e2); if (size1 != size2) filediff(tc, "member size differ", archive_entry_pathname(e1)); } /* * Compare member content if required. */ if (checkcont) { if ((buf1 = malloc(size1)) == NULL) filediff(tc, "not enough memory", NULL); if ((buf2 = malloc(size2)) == NULL) filediff(tc, "not enough memory", NULL); if ((size_t) archive_read_data(a1, buf1, size1) != size1) filediff(tc, "archive_read_data failed", archive_entry_pathname(e1)); if ((size_t) archive_read_data(a2, buf2, size2) != size2) filediff(tc, "archive_read_data failed", archive_entry_pathname(e1)); if (memcmp(buf1, buf2, size1) != 0) filediff(tc, "member content differ", archive_entry_pathname(e1)); free(buf1); free(buf2); } /* Proceed to next header. */ } /* Passed! */ filesame(tc); exit(EXIT_SUCCESS); }
char * get_pkcs_key(char *arg, char *saltopt) { char passphrase[128]; char saltbuf[128], saltfilebuf[PATH_MAX]; char *key = NULL; char *saltfile; const char *errstr; int rounds; rounds = strtonum(arg, 1000, INT_MAX, &errstr); if (errstr) err(1, "rounds: %s", errstr); bzero(passphrase, sizeof(passphrase)); if (readpassphrase("Encryption key: ", passphrase, sizeof(passphrase), RPP_REQUIRE_TTY) == NULL) errx(1, "Unable to read passphrase"); if (saltopt) saltfile = saltopt; else { printf("Salt file: "); fflush(stdout); saltfile = fgets(saltfilebuf, sizeof(saltfilebuf), stdin); if (saltfile) saltfile[strcspn(saltfile, "\n")] = '\0'; } if (!saltfile || saltfile[0] == '\0') { warnx("Skipping salt file, insecure"); memset(saltbuf, 0, sizeof(saltbuf)); } else { int fd; fd = open(saltfile, O_RDONLY); if (fd == -1) { int *s; fprintf(stderr, "Salt file not found, attempting to " "create one\n"); fd = open(saltfile, O_RDWR|O_CREAT|O_EXCL, 0600); if (fd == -1) err(1, "Unable to create salt file: '%s'", saltfile); for (s = (int *)saltbuf; s < (int *)(saltbuf + sizeof(saltbuf)); s++) *s = arc4random(); if (write(fd, saltbuf, sizeof(saltbuf)) != sizeof(saltbuf)) err(1, "Unable to write salt file: '%s'", saltfile); fprintf(stderr, "Salt file created as '%s'\n", saltfile); } else { if (read(fd, saltbuf, sizeof(saltbuf)) != sizeof(saltbuf)) err(1, "Unable to read salt file: '%s'", saltfile); } close(fd); } if ((key = calloc(1, BLF_MAXUTILIZED)) == NULL) err(1, NULL); if (pkcs5_pbkdf2(passphrase, sizeof(passphrase), saltbuf, sizeof (saltbuf), key, BLF_MAXUTILIZED, rounds)) errx(1, "pkcs5_pbkdf2 failed"); memset(passphrase, 0, sizeof(passphrase)); return (key); }
/* * Set an individual neighbor cache entry */ static int set(int argc, char **argv) { register struct sockaddr_in6 *mysin = &sin_m; register struct sockaddr_dl *sdl; register struct rt_msghdr *rtm = &(m_rtmsg.m_rtm); struct addrinfo hints, *res; int gai_error; u_char *ea; char *host = argv[0], *eaddr = argv[1]; getsocket(); argc -= 2; argv += 2; sdl_m = blank_sdl; sin_m = blank_sin; (void)memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; gai_error = getaddrinfo(host, NULL, &hints, &res); if (gai_error) { warnx("%s: %s", host, gai_strerror(gai_error)); return 1; } makeaddr(mysin, res->ai_addr); ea = (u_char *)LLADDR(&sdl_m); if (ndp_ether_aton(eaddr, ea) == 0) sdl_m.sdl_alen = 6; flags = expire_time = 0; while (argc-- > 0) { if (strncmp(argv[0], "temp", 4) == 0) { struct timeval tim; (void)gettimeofday(&tim, 0); expire_time = tim.tv_sec + 20 * 60; } else if (strncmp(argv[0], "proxy", 5) == 0) flags |= RTF_ANNOUNCE; argv++; } if (rtmsg(RTM_GET) < 0) { errx(1, "RTM_GET(%s) failed", host); /* NOTREACHED */ } mysin = (struct sockaddr_in6 *)(void *)(rtm + 1); sdl = (struct sockaddr_dl *)(void *)(RT_ROUNDUP(mysin->sin6_len) + (char *)(void *)mysin); if (IN6_ARE_ADDR_EQUAL(&mysin->sin6_addr, &sin_m.sin6_addr)) { if (sdl->sdl_family == AF_LINK && !(rtm->rtm_flags & RTF_GATEWAY)) { switch (sdl->sdl_type) { case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023: case IFT_ISO88024: case IFT_ISO88025: goto overwrite; } } /* * IPv4 arp command retries with sin_other = SIN_PROXY here. */ (void)fprintf(stderr, "set: cannot configure a new entry\n"); return 1; } overwrite: if (sdl->sdl_family != AF_LINK) { warnx("cannot intuit interface index and type for %s", host); return (1); } sdl_m.sdl_type = sdl->sdl_type; sdl_m.sdl_index = sdl->sdl_index; return (rtmsg(RTM_ADD)); }
int main(int argc, char *argv[]) { int errors; intmax_t numsig, pid; char *ep; setprogname(argv[0]); setlocale(LC_ALL, ""); if (argc < 2) usage(); numsig = SIGTERM; argc--, argv++; if (strcmp(*argv, "-l") == 0) { argc--, argv++; if (argc > 1) usage(); if (argc == 1) { if (isdigit((unsigned char)**argv) == 0) usage(); numsig = strtoimax(*argv, &ep, 10); /* check for correctly parsed number */ if (*ep != '\0' || numsig == INTMAX_MIN || numsig == INTMAX_MAX) { errx(EXIT_FAILURE, "illegal signal number: %s", *argv); /* NOTREACHED */ } if (numsig >= 128) numsig -= 128; /* and whether it fits into signals range */ if (numsig <= 0 || numsig >= NSIG) nosig(*argv); printf("%s\n", sys_signame[(int) numsig]); exit(0); } printsignals(stdout); exit(0); } if (!strcmp(*argv, "-s")) { argc--, argv++; if (argc < 1) { warnx("option requires an argument -- s"); usage(); } if (strcmp(*argv, "0")) { if ((numsig = signame_to_signum(*argv)) < 0) nosig(*argv); } else numsig = 0; argc--, argv++; } else if (**argv == '-') { char *sn = *argv + 1; if (isalpha((unsigned char)*sn)) { if ((numsig = signame_to_signum(sn)) < 0) nosig(sn); } else if (isdigit((unsigned char)*sn)) { numsig = strtoimax(sn, &ep, 10); /* check for correctly parsed number */ if (*ep || numsig == INTMAX_MIN || numsig == INTMAX_MAX ) { errx(EXIT_FAILURE, "illegal signal number: %s", sn); /* NOTREACHED */ } /* and whether it fits into signals range */ if (numsig < 0 || numsig >= NSIG) nosig(sn); } else nosig(sn); argc--, argv++; } if (argc == 0) usage(); for (errors = 0; argc; argc--, argv++) { #ifdef SHELL extern int getjobpgrp(const char *); if (*argv[0] == '%') { pid = getjobpgrp(*argv); if (pid == 0) { warnx("illegal job id: %s", *argv); errors = 1; continue; } } else #endif { pid = strtoimax(*argv, &ep, 10); /* make sure the pid is a number and fits into pid_t */ if (!**argv || *ep || pid == INTMAX_MIN || pid == INTMAX_MAX || pid != (pid_t) pid) { warnx("illegal process id: %s", *argv); errors = 1; continue; } } if (kill((pid_t) pid, (int) numsig) == -1) { warn("%s", *argv); errors = 1; } #ifdef SHELL /* Wakeup the process if it was suspended, so it can exit without an explicit 'fg'. */ if (numsig == SIGTERM || numsig == SIGHUP) kill((pid_t) pid, SIGCONT); #endif } exit(errors); /* NOTREACHED */ }
int main(int argc, char **argv) { struct passwd *pw; struct group *gptr; char *arg, *cp; char buf[MAXPATHLEN]; int i, f, ch; struct stat stb; /* * Simulate setuid daemon w/ PRIV_END called. * We don't want lpr to actually be setuid daemon since that * requires that the lpr binary be owned by user daemon, which * is potentially unsafe. */ if ((pw = getpwuid(DEFUID)) == NULL) errx(1, "daemon uid (%u) not in password file", DEFUID); effective_uid = pw->pw_uid; real_uid = getuid(); effective_gid = pw->pw_gid; real_gid = getgid(); setresgid(real_gid, real_gid, effective_gid); setresuid(real_uid, real_uid, effective_uid); if (signal(SIGHUP, SIG_IGN) != SIG_IGN) signal(SIGHUP, cleanup); if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, cleanup); if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) signal(SIGQUIT, cleanup); if (signal(SIGTERM, SIG_IGN) != SIG_IGN) signal(SIGTERM, cleanup); gethostname(host, sizeof (host)); openlog("lpr", 0, LOG_LPR); while ((ch = getopt(argc, argv, ":#:1:2:3:4:C:J:P:T:U:cdfghi:lmnpqrstvw:")) != -1) { switch (ch) { case '#': /* n copies */ if (isdigit(*optarg)) { i = atoi(optarg); if (i > 0) ncopies = i; } case '4': /* troff fonts */ case '3': case '2': case '1': fonts[ch - '1'] = optarg; break; case 'C': /* classification spec */ hdr++; class = optarg; break; case 'J': /* job name */ hdr++; jobname = optarg; break; case 'P': /* specifiy printer name */ printer = optarg; break; case 'T': /* pr's title line */ title = optarg; break; case 'U': /* user name */ hdr++; person = optarg; break; case 'c': /* print cifplot output */ case 'd': /* print tex output (dvi files) */ case 'g': /* print graph(1G) output */ case 'l': /* literal output */ case 'n': /* print ditroff output */ case 'p': /* print using ``pr'' */ case 't': /* print troff output (cat files) */ case 'v': /* print vplot output */ format = ch; break; case 'f': /* print fortran output */ format = 'r'; break; case 'h': /* toggle want of header page */ hdr = !hdr; break; case 'i': /* indent output */ iflag++; indent = atoi(optarg); if (indent < 0) indent = 8; break; case 'm': /* send mail when done */ mailflg++; break; case 'q': /* just q job */ qflag++; break; case 'r': /* remove file when done */ rflag++; break; case 's': /* try to link files */ sflag++; break; case 'w': /* versatec page width */ width = optarg; break; case ':': /* catch "missing argument" error */ if (optopt == 'i') { iflag++; /* -i without args is valid */ indent = 8; } else usage(); break; default: usage(); } } argc -= optind; argv += optind; if (printer == NULL && (printer = getenv("PRINTER")) == NULL) printer = DEFLP; chkprinter(printer); if (SC && ncopies > 1) errx(1, "multiple copies are not allowed"); if (MC > 0 && ncopies > MC) errx(1, "only %ld copies are allowed", MC); /* * Get the identity of the person doing the lpr using the same * algorithm as lprm. */ if (real_uid != DU || person == NULL) { if ((pw = getpwuid(real_uid)) == NULL) errx(1, "Who are you?"); if ((person = strdup(pw->pw_name)) == NULL) err(1, NULL); } /* * Check for restricted group access. */ if (RG != NULL && real_uid != DU) { if ((gptr = getgrnam(RG)) == NULL) errx(1, "Restricted group specified incorrectly"); if (gptr->gr_gid != getgid()) { while (*gptr->gr_mem != NULL) { if ((strcmp(person, *gptr->gr_mem)) == 0) break; gptr->gr_mem++; } if (*gptr->gr_mem == NULL) errx(1, "Not a member of the restricted group"); } } /* * Check to make sure queuing is enabled if real_uid is not root. */ (void)snprintf(buf, sizeof(buf), "%s/%s", SD, LO); if (real_uid && stat(buf, &stb) == 0 && (stb.st_mode & 010)) errx(1, "Printer queue is disabled"); /* * Initialize the control file. */ mktemps(); tfd = nfile(tfname); card('H', host); card('P', person); if (hdr) { if (jobname == NULL) { if (argc == 0) jobname = "stdin"; else jobname = (arg = strrchr(argv[0], '/')) ? arg + 1 : argv[0]; } card('J', jobname); card('C', class); if (!SH) card('L', person); } if (iflag) card('I', itoa(indent)); if (mailflg) card('M', person); if (format == 't' || format == 'n' || format == 'd') for (i = 0; i < 4; i++) if (fonts[i] != NULL) card('1'+i, fonts[i]); if (width != NULL) card('W', width); /* * Read the files and spool them. */ if (argc == 0) copy(0, " "); else while (argc--) { if (argv[0][0] == '-' && argv[0][1] == '\0') { /* use stdin */ copy(0, " "); argv++; continue; } if ((f = test(arg = *argv++)) < 0) continue; /* file unreasonable */ if (sflag && (cp = linked(arg)) != NULL) { (void)snprintf(buf, sizeof(buf), "%d %d", statb.st_dev, statb.st_ino); card('S', buf); if (format == 'p') card('T', title ? title : arg); for (i = 0; i < ncopies; i++) card(format, &dfname[inchar-2]); card('U', &dfname[inchar-2]); if (f) card('U', cp); card('N', arg); dfname[inchar]++; nact++; continue; } if (sflag) warnx("%s: not linked, copying instead", arg); if ((i = safe_open(arg, O_RDONLY, 0)) < 0) warn("%s", arg); else { copy(i, arg); (void)close(i); if (f && unlink(arg) < 0) warnx("%s: not removed", arg); } } if (nact) { (void)close(tfd); tfname[inchar]--; /* * Touch the control file to fix position in the queue. */ PRIV_START; if ((tfd = safe_open(tfname, O_RDWR|O_NOFOLLOW, 0)) >= 0) { char c; if (read(tfd, &c, 1) == 1 && lseek(tfd, (off_t)0, SEEK_SET) == 0 && write(tfd, &c, 1) != 1) { warn("%s", tfname); tfname[inchar]++; cleanup(0); } (void)close(tfd); } if (link(tfname, cfname) < 0) { warn("cannot rename %s", cfname); tfname[inchar]++; cleanup(0); } unlink(tfname); PRIV_END; if (qflag) /* just q things up */ exit(0); if (!startdaemon(printer)) printf("jobs queued, but cannot start daemon.\n"); exit(0); } cleanup(0); return (1); /* NOTREACHED */ }
int journal_alloc(int64_t size) { struct ufs1_dinode *dp1; struct ufs2_dinode *dp2; ufs2_daddr_t blk; void *ip; struct cg *cgp; int resid; ino_t ino; int blks; int mode; time_t utime; int i; cgp = &disk.d_cg; ino = 0; /* * If the journal file exists we can't allocate it. */ ino = journal_findfile(); if (ino == (ino_t)-1) return (-1); if (ino > 0) { warnx("Journal file %s already exists, please remove.", SUJ_FILE); return (-1); } /* * If the user didn't supply a size pick one based on the filesystem * size constrained with hardcoded MIN and MAX values. We opt for * 1/1024th of the filesystem up to MAX but not exceeding one CG and * not less than the MIN. */ if (size == 0) { size = (sblock.fs_size * sblock.fs_bsize) / 1024; size = MIN(SUJ_MAX, size); if (size / sblock.fs_fsize > sblock.fs_fpg) size = sblock.fs_fpg * sblock.fs_fsize; size = MAX(SUJ_MIN, size); /* fsck does not support fragments in journal files. */ size = roundup(size, sblock.fs_bsize); } resid = blocks = size / sblock.fs_bsize; if (sblock.fs_cstotal.cs_nbfree < blocks) { warn("Insufficient free space for %jd byte journal", size); return (-1); } /* * Find a cg with enough blocks to satisfy the journal * size. Presently the journal does not span cgs. */ while (cgread(&disk) == 1) { if (cgp->cg_cs.cs_nifree == 0) continue; ino = cgialloc(&disk); if (ino <= 0) break; printf("Using inode %d in cg %d for %jd byte journal\n", ino, cgp->cg_cgx, size); if (getino(&disk, &ip, ino, &mode) != 0) { warn("Failed to get allocated inode"); sbdirty(); goto out; } /* * We leave fields unrelated to the number of allocated * blocks and size uninitialized. This causes legacy * fsck implementations to clear the inode. */ dp2 = ip; dp1 = ip; time(&utime); if (sblock.fs_magic == FS_UFS1_MAGIC) { bzero(dp1, sizeof(*dp1)); dp1->di_size = size; dp1->di_mode = IFREG | IREAD; dp1->di_nlink = 1; dp1->di_flags = SF_IMMUTABLE | SF_NOUNLINK | UF_NODUMP; dp1->di_atime = utime; dp1->di_mtime = utime; dp1->di_ctime = utime; } else { bzero(dp2, sizeof(*dp2)); dp2->di_size = size; dp2->di_mode = IFREG | IREAD; dp2->di_nlink = 1; dp2->di_flags = SF_IMMUTABLE | SF_NOUNLINK | UF_NODUMP; dp2->di_atime = utime; dp2->di_mtime = utime; dp2->di_ctime = utime; dp2->di_birthtime = utime; } for (i = 0; i < NDADDR && resid; i++, resid--) { blk = journal_balloc(); if (blk <= 0) goto out; if (sblock.fs_magic == FS_UFS1_MAGIC) { dp1->di_db[i] = blk; dp1->di_blocks++; } else { dp2->di_db[i] = blk; dp2->di_blocks++; } } for (i = 0; i < NIADDR && resid; i++) { blk = journal_balloc(); if (blk <= 0) goto out; blks = indir_fill(blk, i, &resid) + 1; if (blks <= 0) { sbdirty(); goto out; } if (sblock.fs_magic == FS_UFS1_MAGIC) { dp1->di_ib[i] = blk; dp1->di_blocks += blks; } else { dp2->di_ib[i] = blk; dp2->di_blocks += blks; } } if (sblock.fs_magic == FS_UFS1_MAGIC) dp1->di_blocks *= sblock.fs_bsize / disk.d_bsize; else dp2->di_blocks *= sblock.fs_bsize / disk.d_bsize; if (putino(&disk) < 0) { warn("Failed to write inode"); sbdirty(); return (-1); } if (cgwrite(&disk) < 0) { warn("Failed to write updated cg"); sbdirty(); return (-1); } if (journal_insertfile(ino) < 0) { sbdirty(); return (-1); } sblock.fs_sujfree = 0; return (0); } warnx("Insufficient free space for the journal."); out: return (-1); }
/* * Update a specified quota file. */ int update(const char *fsname, const char *quotafile, int type) { struct fileusage *fup; FILE *qfi, *qfo; u_int32_t id, lastid; struct dqblk dqbuf; static int warned = 0; static struct dqblk zerodqbuf; static struct fileusage zerofileusage; if (flags&CHECK_DEBUG) printf("updating: %s\n", quotafile); if ((qfo = fopen(quotafile, (flags&CHECK_DEBUG)? "r" : "r+")) == NULL) { if (errno == ENOENT) qfo = fopen(quotafile, "w+"); if (qfo) { warnx("creating quota file: %s", quotafile); #define MODE (S_IRUSR|S_IWUSR|S_IRGRP) (void) fchown(fileno(qfo), getuid(), getquotagid()); (void) fchmod(fileno(qfo), MODE); } else { warn("%s", quotafile); return (1); } } if ((qfi = fopen(quotafile, "r")) == NULL) { warn("%s", quotafile); (void) fclose(qfo); return (1); } if (quotactl(fsname, QCMD(Q_SYNC, type), 0, (caddr_t)0) < 0 && errno == EOPNOTSUPP && !warned && (flags&(CHECK_DEBUG|CHECK_VERBOSE))) { warned++; (void)printf("*** Warning: %s\n", "Quotas are not compiled into this kernel"); } for (lastid = highid[type], id = 0; id <= lastid; id++) { if (fread((char *)&dqbuf, sizeof(struct dqblk), 1, qfi) == 0) dqbuf = zerodqbuf; if ((fup = lookup(id, type)) == 0) fup = &zerofileusage; if (dqbuf.dqb_curinodes == fup->fu_curinodes && dqbuf.dqb_curblocks == fup->fu_curblocks) { fup->fu_curinodes = 0; fup->fu_curblocks = 0; fseek(qfo, (long)sizeof(struct dqblk), SEEK_CUR); continue; } if (flags&(CHECK_DEBUG|CHECK_VERBOSE)) { if (flags&CHECK_PREEN) printf("%s: ", fsname); printf("%-8s fixed:", fup->fu_name); if (dqbuf.dqb_curinodes != fup->fu_curinodes) (void)printf("\tinodes %d -> %u", dqbuf.dqb_curinodes, fup->fu_curinodes); if (dqbuf.dqb_curblocks != fup->fu_curblocks) (void)printf("\tblocks %u -> %u", dqbuf.dqb_curblocks, fup->fu_curblocks); (void)printf("\n"); } /* * Reset time limit if have a soft limit and were * previously under it, but are now over it. */ if (dqbuf.dqb_bsoftlimit && dqbuf.dqb_curblocks < dqbuf.dqb_bsoftlimit && fup->fu_curblocks >= dqbuf.dqb_bsoftlimit) dqbuf.dqb_btime = 0; if (dqbuf.dqb_isoftlimit && dqbuf.dqb_curblocks < dqbuf.dqb_isoftlimit && fup->fu_curblocks >= dqbuf.dqb_isoftlimit) dqbuf.dqb_itime = 0; dqbuf.dqb_curinodes = fup->fu_curinodes; dqbuf.dqb_curblocks = fup->fu_curblocks; if (!(flags & CHECK_DEBUG)) { fwrite((char *)&dqbuf, sizeof(struct dqblk), 1, qfo); (void) quotactl(fsname, QCMD(Q_SETUSE, type), id, (caddr_t)&dqbuf); } fup->fu_curinodes = 0; fup->fu_curblocks = 0; } fclose(qfi); fflush(qfo); if (!(flags & CHECK_DEBUG)) ftruncate(fileno(qfo), (off_t)((highid[type] + 1) * sizeof(struct dqblk))); fclose(qfo); return (0); }
/* * Check the blocks belonging to inode INO, whose inode has already * been loaded into SFI. ISDIR is a shortcut telling us if the inode * is a directory. * * Returns nonzero if SFI has been modified and needs to be written * back. */ static int check_inode_blocks(uint32_t ino, struct sfs_dinode *sfi, int isdir) { struct ibstate ibs; uint32_t size, datablock; int changed; int i; size = SFS_ROUNDUP(sfi->sfi_size, SFS_BLOCKSIZE); ibs.ino = ino; /*ibs.curfileblock = 0;*/ ibs.fileblocks = size/SFS_BLOCKSIZE; ibs.volblocks = sb_totalblocks(); ibs.pasteofcount = 0; ibs.usagetype = isdir ? B_DIRDATA : B_DATA; changed = 0; for (ibs.curfileblock=0; ibs.curfileblock<NUM_D; ibs.curfileblock++) { datablock = GET_D(sfi, ibs.curfileblock); if (datablock >= ibs.volblocks) { warnx("Inode %lu: direct block pointer for " "block %lu outside of volume " "(cleared)\n", (unsigned long)ibs.ino, (unsigned long)ibs.curfileblock); SET_D(sfi, ibs.curfileblock) = 0; changed = 1; } else if (datablock > 0) { if (ibs.curfileblock < ibs.fileblocks) { bitmap_blockinuse(datablock, ibs.usagetype, ibs.ino); } else { ibs.pasteofcount++; changed = 1; bitmap_blockfree(datablock); SET_D(sfi, ibs.curfileblock) = 0; } } } for (i=0; i<NUM_I; i++) { check_indirect_block(&ibs, &SET_I(sfi, i), &changed, 1); } for (i=0; i<NUM_II; i++) { check_indirect_block(&ibs, &SET_II(sfi, i), &changed, 2); } for (i=0; i<NUM_III; i++) { check_indirect_block(&ibs, &SET_III(sfi, i), &changed, 3); } if (ibs.pasteofcount > 0) { warnx("Inode %lu: %u blocks after EOF (freed)", (unsigned long) ibs.ino, ibs.pasteofcount); setbadness(EXIT_RECOV); } return changed; }
/*================================================================ * mkfs - make filesystem *===============================================================*/ int main(int argc, char *argv[]) { int nread, mode, usrid, grpid, ch, extra_space_percent; block_t blocks, maxblocks; ino_t inodes, root_inum; time_t bin_time; char *token[MAX_TOKENS], line[LINE_LEN], *sfx; struct stat statbuf; struct fs_size fssize; progname = argv[0]; /* Get two times, the current time and the mod time of the binary of * mkfs itself. When the -d flag is used, the later time is put into * the i_mtimes of all the files. This feature is useful when * producing a set of file systems, and one wants all the times to be * identical. First you set the time of the mkfs binary to what you * want, then go. */ current_time = time((time_t *) 0); /* time mkfs is being run */ if (stat(progname, &statbuf)) { perror("stat of itself"); bin_time = current_time; /* provide some default value */ } else bin_time = statbuf.st_mtime; /* time when mkfs binary was last modified */ /* Process switches. */ blocks = 0; inodes = 0; #ifndef MFS_STATIC_BLOCK_SIZE block_size = 0; #endif zone_shift = 0; extra_space_percent = 0; while ((ch = getopt(argc, argv, "B:b:di:ltvx:z:")) != EOF) switch (ch) { #ifndef MFS_STATIC_BLOCK_SIZE case 'B': block_size = strtoul(optarg, &sfx, 0); switch(*sfx) { case 'b': case 'B': /* bytes; NetBSD-compatible */ case '\0': break; case 'K': case 'k': block_size*=1024; break; case 's': block_size*=SECTOR_SIZE; break; default: usage(); } break; #else case 'B': if (block_size != strtoul(optarg, (char **) NULL, 0)) errx(4, "block size must be exactly %d bytes", MFS_STATIC_BLOCK_SIZE); break; (void)sfx; /* shut up warnings about unused variable...*/ #endif case 'b': blocks = strtoul(optarg, (char **) NULL, 0); break; case 'd': dflag = 1; current_time = bin_time; break; case 'i': inodes = strtoul(optarg, (char **) NULL, 0); break; case 'l': print = 1; break; case 't': donttest = 1; break; case 'v': ++verbose; break; case 'x': extra_space_percent = atoi(optarg); break; case 'z': zone_shift = atoi(optarg); break; default: usage(); } if (argc == optind) usage(); /* Percentage of extra size must be nonnegative. * It can legitimately be bigger than 100 but has to make some sort of sense. */ if(extra_space_percent < 0 || extra_space_percent > 2000) usage(); #ifdef DEFAULT_BLOCK_SIZE if(!block_size) block_size = DEFAULT_BLOCK_SIZE; #endif if (block_size % SECTOR_SIZE) errx(4, "block size must be multiple of sector (%d bytes)", SECTOR_SIZE); #ifdef MIN_BLOCK_SIZE if (block_size < MIN_BLOCK_SIZE) errx(4, "block size must be at least %d bytes", MIN_BLOCK_SIZE); #endif #ifdef MAX_BLOCK_SIZE if (block_size > MAX_BLOCK_SIZE) errx(4, "block size must be at most %d bytes", MAX_BLOCK_SIZE); #endif if(block_size%INODE_SIZE) errx(4, "block size must be a multiple of inode size (%d bytes)", INODE_SIZE); if(zone_shift < 0 || zone_shift > 14) errx(4, "zone_shift must be a small non-negative integer"); zone_per_block = 1 << zone_shift; /* nr of blocks per zone */ inodes_per_block = INODES_PER_BLOCK(block_size); indir_per_block = INDIRECTS(block_size); indir_per_zone = INDIRECTS(block_size) << zone_shift; /* number of file zones we can address directly and with a single indirect*/ nr_indirzones = NR_DZONES + indir_per_zone; zone_size = block_size << zone_shift; /* Checks for an overflow: only with very big block size */ if (zone_size <= 0) errx(4, "Zones are too big for this program; smaller -B or -z, please!"); /* now that the block size is known, do buffer allocations where * possible. */ zero = alloc_block(); /* Determine the size of the device if not specified as -b or proto. */ maxblocks = sizeup(argv[optind]); if (argc - optind == 1 && blocks == 0) { blocks = maxblocks; /* blocks == 0 is checked later, but leads to a funny way of * reporting a 0-sized device (displays usage). */ if(blocks < 1) { errx(1, "zero size device."); } } /* The remaining args must be 'special proto', or just 'special' if the * no. of blocks has already been specified. */ if (argc - optind != 2 && (argc - optind != 1 || blocks == 0)) usage(); if (maxblocks && blocks > maxblocks) { errx(1, "%s: number of blocks too large for device.", argv[optind]); } /* Check special. */ check_mtab(argv[optind]); /* Check and start processing proto. */ optarg = argv[++optind]; if (optind < argc && (proto = fopen(optarg, "r")) != NULL) { /* Prototype file is readable. */ lct = 1; get_line(line, token); /* skip boot block info */ /* Read the line with the block and inode counts. */ get_line(line, token); blocks = strtol(token[0], (char **) NULL, 10); inodes = strtol(token[1], (char **) NULL, 10); /* Process mode line for root directory. */ get_line(line, token); mode = mode_con(token[0]); usrid = atoi(token[1]); grpid = atoi(token[2]); if(blocks <= 0 && inodes <= 0){ detect_fs_size(&fssize); blocks = fssize.blockcount; inodes = fssize.inocount; blocks += blocks*extra_space_percent/100; inodes += inodes*extra_space_percent/100; /* XXX is it OK to write on stdout? Use warn() instead? Also consider using verbose */ printf("dynamically sized filesystem: %u blocks, %u inodes\n", (unsigned int) blocks, (unsigned int) inodes); } } else { lct = 0; if (optind < argc) { /* Maybe the prototype file is just a size. Check. */ blocks = strtoul(optarg, (char **) NULL, 0); if (blocks == 0) errx(2, "Can't open prototype file"); } if (inodes == 0) { long long kb = ((unsigned long long)blocks*block_size) / 1024; inodes = kb / 2; if (kb >= 100000) inodes = kb / 4; if (kb >= 1000000) inodes = kb / 6; if (kb >= 10000000) inodes = kb / 8; if (kb >= 100000000) inodes = kb / 10; if (kb >= 1000000000) inodes = kb / 12; /* XXX check overflow: with very large number of blocks, this results in insanely large number of inodes */ /* XXX check underflow (if/when ino_t is signed), else the message below will look strange */ /* round up to fill inode block */ inodes += inodes_per_block - 1; inodes = inodes / inodes_per_block * inodes_per_block; } if (blocks < 5) errx(1, "Block count too small"); if (inodes < 1) errx(1, "Inode count too small"); /* Make simple file system of the given size, using defaults. */ mode = 040777; usrid = BIN; grpid = BINGRP; simple = 1; } nrblocks = blocks; nrinodes = inodes; umap_array_elements = 1 + blocks/8; if(!(umap_array = malloc(umap_array_elements))) err(1, "can't allocate block bitmap (%u bytes).", (unsigned)umap_array_elements); /* Open special. */ special(argv[--optind]); if (!donttest) { uint16_t *testb; ssize_t w; testb = alloc_block(); /* Try writing the last block of partition or diskette. */ if(lseek64(fd, mul64u(blocks - 1, block_size), SEEK_SET, NULL) < 0) { err(1, "couldn't seek to last block to test size (1)"); } testb[0] = 0x3245; testb[1] = 0x11FF; testb[block_size/2-1] = 0x1F2F; if ((w=write(fd, testb, block_size)) != block_size) err(1, "File system is too big for minor device (write1 %d/%u)", w, block_size); sync(); /* flush write, so if error next read fails */ if(lseek64(fd, mul64u(blocks - 1, block_size), SEEK_SET, NULL) < 0) { err(1, "couldn't seek to last block to test size (2)"); } testb[0] = 0; testb[1] = 0; testb[block_size/2-1] = 0; nread = read(fd, testb, block_size); if (nread != block_size || testb[0] != 0x3245 || testb[1] != 0x11FF || testb[block_size/2-1] != 0x1F2F) { warn("nread = %d\n", nread); warnx("testb = 0x%x 0x%x 0x%x\n", testb[0], testb[1], testb[block_size-1]); errx(1, "File system is too big for minor device (read)"); } lseek64(fd, mul64u(blocks - 1, block_size), SEEK_SET, NULL); testb[0] = 0; testb[1] = 0; testb[block_size/2-1] = 0; if (write(fd, testb, block_size) != block_size) err(1, "File system is too big for minor device (write2)"); lseek(fd, 0L, SEEK_SET); free(testb); } /* Make the file-system */ put_block(BOOT_BLOCK, zero); /* Write a null boot block. */ put_block(BOOT_BLOCK+1, zero); /* Write another null block. */ super(nrblocks >> zone_shift, inodes); root_inum = alloc_inode(mode, usrid, grpid); rootdir(root_inum); if (simple == 0) eat_dir(root_inum); if (print) print_fs(); else if (verbose > 1) { if (zone_shift) fprintf(stderr, "%d inodes used. %u zones (%u blocks) used.\n", (int)next_inode-1, next_zone, next_zone*zone_per_block); else fprintf(stderr, "%d inodes used. %u zones used.\n", (int)next_inode-1, next_zone); } return(0); /* NOTREACHED */ } /* end main */
/* * Traverse an indirect block, recording blocks that are in use, * dropping any entries that are past EOF, and clearing any entries * that point outside the volume. * * XXX: this should be extended to be able to recover from crosslinked * blocks. Currently it just complains in bitmap.c and sets * EXIT_UNRECOV. * * The traversal is recursive; the state is maintained in IBS (as * described above). IENTRY is a pointer to the entry in the parent * indirect block (or the inode) that names the block we're currently * scanning. IECHANGEDP should be set to 1 if *IENTRY is changed. * INDIRECTION is the indirection level of this block (1, 2, or 3). */ static void check_indirect_block(struct ibstate *ibs, uint32_t *ientry, int *iechangedp, int indirection) { uint32_t entries[SFS_DBPERIDB]; uint32_t i, ct; uint32_t coveredblocks; int localchanged = 0; int j; if (*ientry > 0 && *ientry < ibs->volblocks) { sfs_readindirect(*ientry, entries); bitmap_blockinuse(*ientry, B_IBLOCK, ibs->ino); } else { if (*ientry >= ibs->volblocks) { warnx("Inode %lu: indirect block pointer (level %d) " "for block %lu outside of volume " "(cleared)\n", (unsigned long)ibs->ino, indirection, (unsigned long)ibs->curfileblock); *ientry = 0; *iechangedp = 1; } coveredblocks = 1; for (j=0; j<indirection; j++) { coveredblocks *= SFS_DBPERIDB; } ibs->curfileblock += coveredblocks; return; } if (indirection > 1) { for (i=0; i<SFS_DBPERIDB; i++) { check_indirect_block(ibs, &entries[i], &localchanged, indirection-1); } } else { assert(indirection==1); for (i=0; i<SFS_DBPERIDB; i++) { if (entries[i] >= ibs->volblocks) { warnx("Inode %lu: direct block pointer for " "block %lu outside of volume " "(cleared)\n", (unsigned long)ibs->ino, (unsigned long)ibs->curfileblock); entries[i] = 0; localchanged = 1; } else if (entries[i] != 0) { if (ibs->curfileblock < ibs->fileblocks) { bitmap_blockinuse(entries[i], ibs->usagetype, ibs->ino); } else { ibs->pasteofcount++; bitmap_blockfree(entries[i]); entries[i] = 0; localchanged = 1; } } ibs->curfileblock++; } } ct=0; for (i=ct=0; i<SFS_DBPERIDB; i++) { if (entries[i]!=0) ct++; } if (ct==0) { if (*ientry != 0) { /* this is not necessarily correct */ /*ibs->pasteofcount++;*/ *iechangedp = 1; bitmap_blockfree(*ientry); *ientry = 0; } } else { assert(*ientry != 0); if (localchanged) { sfs_writeindirect(*ientry, entries); } } }
int main(int argc, char *argv[]) { int errors, numsig, pid; char *ep; if (argc < 2) usage(); numsig = SIGTERM; argc--, argv++; if (!strcmp(*argv, "-l")) { argc--, argv++; if (argc > 1) usage(); if (argc == 1) { if (!isdigit(**argv)) usage(); numsig = strtol(*argv, &ep, 10); if (!**argv || *ep) errx(1, "illegal signal number: %s", *argv); if (numsig >= 128) numsig -= 128; if (numsig <= 0 || numsig >= sys_nsig) nosig(*argv); printf("%s\n", sys_signame[numsig]); exit(0); } printsignals(stdout); exit(0); } if (!strcmp(*argv, "-s")) { argc--, argv++; if (argc < 1) { warnx("option requires an argument -- s"); usage(); } if (strcmp(*argv, "0")) { if ((numsig = signame_to_signum(*argv)) < 0) nosig(*argv); } else numsig = 0; argc--, argv++; } else if (**argv == '-' && *(*argv + 1) != '-') { ++*argv; if (isalpha(**argv)) { if ((numsig = signame_to_signum(*argv)) < 0) nosig(*argv); } else if (isdigit(**argv)) { numsig = strtol(*argv, &ep, 10); if (!**argv || *ep) errx(1, "illegal signal number: %s", *argv); if (numsig < 0) nosig(*argv); } else nosig(*argv); argc--, argv++; } if (argc > 0 && strncmp(*argv, "--", 2) == 0) argc--, argv++; if (argc == 0) usage(); for (errors = 0; argc; argc--, argv++) { pid = strtol(*argv, &ep, 10); if (!**argv || *ep) { warnx("illegal process id: %s", *argv); errors = 1; } else if (kill(pid, numsig) == -1) { warn("%s", *argv); errors = 1; } } exit(errors); }
static void read_groups(perf_event_desc_t *fds, int num) { uint64_t *values = NULL; size_t new_sz, sz = 0; int i, evt, ret; /* * { u64 nr; * { u64 time_enabled; } && PERF_FORMAT_ENABLED * { u64 time_running; } && PERF_FORMAT_RUNNING * { u64 value; * { u64 id; } && PERF_FORMAT_ID * } cntr[nr]; * } && PERF_FORMAT_GROUP * * we do not use FORMAT_ID in this program */ for (evt = 0; evt < num; ) { int num_evts_to_read; if (options.format_group) { num_evts_to_read = perf_get_group_nevents(fds, num, evt); new_sz = sizeof(uint64_t) * (3 + num_evts_to_read); } else { num_evts_to_read = 1; new_sz = sizeof(uint64_t) * 3; } if (new_sz > sz) { sz = new_sz; values = realloc(values, sz); } if (!values) err(1, "cannot allocate memory for values\n"); ret = read(fds[evt].fd, values, new_sz); if (ret != new_sz) { /* unsigned */ if (ret == -1) err(1, "cannot read values event %s", fds[evt].name); /* likely pinned and could not be loaded */ warnx("could not read event %d, tried to read %zu bytes, but got %d", evt, new_sz, ret); } /* * propagate to save area */ for (i = evt; i < (evt + num_evts_to_read); i++) { if (options.format_group) values[0] = values[3 + (i - evt)]; /* * scaling because we may be sharing the PMU and * thus may be multiplexed */ fds[i].prev_value = fds[i].value; fds[i].value = perf_scale(values); fds[i].enabled = values[1]; fds[i].running = values[2]; } evt += num_evts_to_read; } if (values) free(values); }
static void bexp(void) { struct number *a, *p; struct number *r; bool neg; u_int scale; p = pop_number(); if (p == NULL) { return; } a = pop_number(); if (a == NULL) { push_number(p); return; } if (p->scale != 0) warnx("Runtime warning: non-zero scale in exponent"); normalize(p, 0); neg = false; if (BN_cmp(p->number, &zero) < 0) { neg = true; negate(p); scale = bmachine.scale; } else { /* Posix bc says min(a.scale * b, max(a.scale, scale) */ u_long b; u_int m; b = BN_get_word(p->number); m = max(a->scale, bmachine.scale); scale = a->scale * b; if (scale > m || b == BN_MASK2) scale = m; } if (BN_is_zero(p->number)) { r = new_number(); bn_check(BN_one(r->number)); normalize(r, scale); } else { while (!BN_is_bit_set(p->number, 0)) { bmul_number(a, a, a); bn_check(BN_rshift1(p->number, p->number)); } r = dup_number(a); normalize(r, scale); bn_check(BN_rshift1(p->number, p->number)); while (!BN_is_zero(p->number)) { bmul_number(a, a, a); if (BN_is_bit_set(p->number, 0)) bmul_number(r, r, a); bn_check(BN_rshift1(p->number, p->number)); } if (neg) { BN_CTX *ctx; BIGNUM *one; one = BN_new(); bn_checkp(one); BN_one(one); ctx = BN_CTX_new(); bn_checkp(ctx); scale_number(one, r->scale + scale); normalize(r, scale); bn_check(BN_div(r->number, NULL, one, r->number, ctx)); BN_free(one); BN_CTX_free(ctx); } else normalize(r, scale); } push_number(r); free_number(a); free_number(p); }
int cmdloop(void) { char *line; const char *elline; int cmd_argc, rval = 0, known; #define scratch known char **cmd_argv; struct cmdtable *cmdp; History *hist; EditLine *elptr; HistEvent he; curinode = ginode(ROOTINO); curinum = ROOTINO; printactive(0); hist = history_init(); history(hist, &he, H_SETSIZE, 100); /* 100 elt history buffer */ elptr = el_init("fsdb", stdin, stdout, stderr); el_set(elptr, EL_EDITOR, "emacs"); el_set(elptr, EL_PROMPT, prompt); el_set(elptr, EL_HIST, history, hist); el_source(elptr, NULL); while ((elline = el_gets(elptr, &scratch)) != NULL && scratch != 0) { if (debug) printf("command `%s'\n", elline); history(hist, &he, H_ENTER, elline); line = strdup(elline); cmd_argv = crack(line, &cmd_argc); /* * el_parse returns -1 to signal that it's not been handled * internally. */ if (el_parse(elptr, cmd_argc, (const char **)cmd_argv) != -1) continue; if (cmd_argc) { known = 0; for (cmdp = cmds; cmdp->cmd; cmdp++) { if (!strcmp(cmdp->cmd, cmd_argv[0])) { if ((cmdp->flags & FL_WR) == FL_WR && nflag) warnx("`%s' requires write access", cmd_argv[0]), rval = 1; else if (cmd_argc >= cmdp->minargc && cmd_argc <= cmdp->maxargc) rval = (*cmdp->handler)(cmd_argc, cmd_argv); else if (cmd_argc >= cmdp->minargc && (cmdp->flags & FL_ST) == FL_ST) { strcpy(line, elline); cmd_argv = recrack(line, &cmd_argc, cmdp->maxargc); rval = (*cmdp->handler)(cmd_argc, cmd_argv); } else rval = argcount(cmdp, cmd_argc, cmd_argv); known = 1; break; } } if (!known) warnx("unknown command `%s'", cmd_argv[0]), rval = 1; } else rval = 0; free(line); if (rval < 0) /* user typed "quit" */ return 0; if (rval) warnx("rval was %d", rval); } el_end(elptr); history_end(hist); return rval; }
static void unknown(void) { int ch = bmachine.readstack[bmachine.readsp].lastchar; warnx("%c (0%o) is unimplemented", ch, ch); }
int make_lfs(int devfd, uint secsize, struct dkwedge_info *dkw, int minfree, int block_size, int frag_size, int seg_size, int minfreeseg, int resvseg, int version, daddr_t start, int ibsize, int interleave, u_int32_t roll_id) { struct ufs1_dinode *dip; /* Pointer to a disk inode */ CLEANERINFO *cip; /* Segment cleaner information table */ IFILE *ip; /* Pointer to array of ifile structures */ IFILE_V1 *ip_v1 = NULL; struct lfs *fs; /* Superblock */ SEGUSE *segp; /* Segment usage table */ daddr_t sb_addr; /* Address of superblocks */ daddr_t seg_addr; /* Address of current segment */ int bsize; /* Block size */ int fsize; /* Fragment size */ int db_per_blk; /* Disk blocks per file block */ int i, j; int sb_interval; /* number of segs between super blocks */ int ssize; /* Segment size */ double fssize; int warned_segtoobig=0; int label_fsb, sb_fsb; int curw, ww; char tbuf[BUFSIZ]; struct ubuf *bp; struct uvnode *vp, *save_devvp; int bb, ubb, dmeta, labelskew; u_int64_t tsepb, tnseg; /* * Initialize buffer cache. Use a ballpark guess of the length of * the segment table for the number of hash chains. */ tnseg = dkw->dkw_size / ((seg_size ? seg_size : DFL_LFSSEG) / secsize); tsepb = (block_size ? block_size : DFL_LFSBLOCK) / sizeof(SEGSUM); if (tnseg == 0) fatal("zero size partition"); bufinit(tnseg / tsepb); /* Initialize LFS subsystem with blank superblock and ifile. */ fs = lfs_init(devfd, start, (ufs_daddr_t)0, 1, 1/* XXX debug*/); save_devvp = fs->lfs_devvp; vp = fs->lfs_ivnode; *fs = lfs_default; fs->lfs_ivnode = vp; fs->lfs_devvp = save_devvp; /* Set version first of all since it is used to compute other fields */ fs->lfs_version = version; /* If partition is not an LFS partition, warn that that is the case */ if (strcmp(dkw->dkw_ptype, DKW_PTYPE_LFS) != 0) { fatal("partition label indicated fs type \"%s\", " "expected \"%s\"", dkw->dkw_ptype, DKW_PTYPE_LFS); } if (!(bsize = block_size)) bsize = DFL_LFSBLOCK; if (!(fsize = frag_size)) fsize = DFL_LFSFRAG; if (!(ssize = seg_size)) { ssize = DFL_LFSSEG; } if (version > 1) { if (ibsize == 0) ibsize = fsize; if (ibsize <= 0 || ibsize % fsize) fatal("illegal inode block size: %d\n", ibsize); } else if (ibsize && ibsize != bsize) fatal("cannot specify inode block size when version == 1\n"); /* Sanity check: fsize<=bsize<ssize */ if (fsize > bsize) { /* Only complain if fsize was explicitly set */ if(frag_size) fatal("fragment size must be <= block size %d", bsize); fsize = bsize; } if (bsize >= ssize) { /* Only fatal if ssize was explicitly set */ if(seg_size) fatal("block size must be < segment size"); warnx("%s: disklabel segment size (%d) too small, using default (%d)", progname, ssize, DFL_LFSSEG); ssize = DFL_LFSSEG; } if (start < 0 || start >= dkw->dkw_size) fatal("filesystem offset %ld out of range", (long)start); if (version == 1) { if (start) warnx("filesystem offset ignored for version 1 filesystem"); start = LFS_LABELPAD / secsize; } tryagain: /* Modify parts of superblock overridden by command line arguments */ if (bsize != DFL_LFSBLOCK || fsize != DFL_LFSFRAG) { fs->lfs_bshift = lfs_log2(bsize); if (1 << fs->lfs_bshift != bsize) fatal("%d: block size not a power of 2", bsize); fs->lfs_bsize = bsize; fs->lfs_fsize = fsize; fs->lfs_bmask = bsize - 1; fs->lfs_ffmask = fsize - 1; fs->lfs_ffshift = lfs_log2(fsize); if (1 << fs->lfs_ffshift != fsize) fatal("%d: frag size not a power of 2", fsize); fs->lfs_frag = numfrags(fs, bsize); fs->lfs_fbmask = fs->lfs_frag - 1; fs->lfs_fbshift = lfs_log2(fs->lfs_frag); fs->lfs_ifpb = bsize / sizeof(IFILE); /* XXX ondisk32 */ fs->lfs_nindir = bsize / sizeof(int32_t); } if (fs->lfs_version == 1) { fs->lfs_sumsize = LFS_V1_SUMMARY_SIZE; fs->lfs_segshift = lfs_log2(ssize); if (1 << fs->lfs_segshift != ssize) fatal("%d: segment size not power of 2", ssize); fs->lfs_segmask = ssize - 1; fs->lfs_ifpb = fs->lfs_bsize / sizeof(IFILE_V1); fs->lfs_ibsize = fs->lfs_bsize; fs->lfs_sepb = bsize / sizeof(SEGUSE_V1); fs->lfs_ssize = ssize >> fs->lfs_bshift; } else {
void printfs(void) { warnx("POSIX.1e ACLs: (-a) %s", (sblock.fs_flags & FS_ACLS)? "enabled" : "disabled"); warnx("NFSv4 ACLs: (-N) %s", (sblock.fs_flags & FS_NFS4ACLS)? "enabled" : "disabled"); warnx("MAC multilabel: (-l) %s", (sblock.fs_flags & FS_MULTILABEL)? "enabled" : "disabled"); warnx("soft updates: (-n) %s", (sblock.fs_flags & FS_DOSOFTDEP)? "enabled" : "disabled"); warnx("soft update journaling: (-j) %s", (sblock.fs_flags & FS_SUJ)? "enabled" : "disabled"); warnx("gjournal: (-J) %s", (sblock.fs_flags & FS_GJOURNAL)? "enabled" : "disabled"); warnx("trim: (-t) %s", (sblock.fs_flags & FS_TRIM)? "enabled" : "disabled"); warnx("maximum blocks per file in a cylinder group: (-e) %d", sblock.fs_maxbpg); warnx("average file size: (-f) %d", sblock.fs_avgfilesize); warnx("average number of files in a directory: (-s) %d", sblock.fs_avgfpdir); warnx("minimum percentage of free space: (-m) %d%%", sblock.fs_minfree); warnx("optimization preference: (-o) %s", sblock.fs_optim == FS_OPTSPACE ? "space" : "time"); if (sblock.fs_minfree >= MINFREE && sblock.fs_optim == FS_OPTSPACE) warnx(OPTWARN, "time", ">=", MINFREE); if (sblock.fs_minfree < MINFREE && sblock.fs_optim == FS_OPTTIME) warnx(OPTWARN, "space", "<", MINFREE); warnx("volume label: (-L) %s", sblock.fs_volname); }
int main(int argc, char **argv) { int errors, numsig; pid_t pid; char *ep; if (argc < 2) usage(); numsig = SIGTERM; argc--, argv++; if (strcmp(*argv, "-l") == 0) { argc--, argv++; if (argc > 1) usage(); if (argc == 1) { if (!isdigit(**argv)) usage(); numsig = strtol(*argv, &ep, 10); if (**argv == '\0' || *ep != '\0') errx(2, "illegal signal number: %s", *argv); if (numsig >= 128) numsig -= 128; if (numsig <= 0 || numsig >= sys_nsig) nosig(*argv); printf("%s\n", sys_signame[numsig]); return (0); } printsignals(stdout); return (0); } if (strcmp(*argv, "-s") == 0) { argc--, argv++; if (argc < 1) { warnx("option requires an argument -- s"); usage(); } if (strcmp(*argv, "0") != 0) { if ((numsig = signame_to_signum(*argv)) < 0) nosig(*argv); } else numsig = 0; argc--, argv++; } else if (**argv == '-' && *(*argv + 1) != '-') { ++*argv; if (isalpha(**argv)) { if ((numsig = signame_to_signum(*argv)) < 0) nosig(*argv); } else if (isdigit(**argv)) { numsig = strtol(*argv, &ep, 10); if (**argv == '\0' || *ep != '\0') errx(2, "illegal signal number: %s", *argv); if (numsig < 0) nosig(*argv); } else nosig(*argv); argc--, argv++; } if (argc > 0 && strncmp(*argv, "--", 2) == 0) argc--, argv++; if (argc == 0) usage(); for (errors = 0; argc; argc--, argv++) { #ifdef SHELL if (**argv == '%') pid = getjobpgrp(*argv); else #endif { pid = (pid_t)strtol(*argv, &ep, 10); if (**argv == '\0' || *ep != '\0') errx(2, "illegal process id: %s", *argv); } if (kill(pid, numsig) == -1) { warn("%s", *argv); errors = 1; } } return (errors); }
int main(int argc, char *argv[]) { char *avalue, *jvalue, *Jvalue, *Lvalue, *lvalue, *Nvalue, *nvalue; char *tvalue; const char *special, *on; const char *name; int active; int Aflag, aflag, eflag, evalue, fflag, fvalue, jflag, Jflag, Lflag; int lflag, mflag, mvalue, Nflag, nflag, oflag, ovalue, pflag, sflag; int tflag; int svalue, Sflag, Svalue; int ch, found_arg, i; const char *chg[2]; struct ufs_args args; struct statfs stfs; if (argc < 3) usage(); Aflag = aflag = eflag = fflag = jflag = Jflag = Lflag = lflag = 0; mflag = Nflag = nflag = oflag = pflag = sflag = tflag = 0; avalue = jvalue = Jvalue = Lvalue = lvalue = Nvalue = nvalue = NULL; evalue = fvalue = mvalue = ovalue = svalue = Svalue = 0; active = 0; found_arg = 0; /* At least one arg is required. */ while ((ch = getopt(argc, argv, "Aa:e:f:j:J:L:l:m:N:n:o:ps:S:t:")) != -1) switch (ch) { case 'A': found_arg = 1; Aflag++; break; case 'a': found_arg = 1; name = "POSIX.1e ACLs"; avalue = optarg; if (strcmp(avalue, "enable") && strcmp(avalue, "disable")) { errx(10, "bad %s (options are %s)", name, "`enable' or `disable'"); } aflag = 1; break; case 'e': found_arg = 1; name = "maximum blocks per file in a cylinder group"; evalue = atoi(optarg); if (evalue < 1) errx(10, "%s must be >= 1 (was %s)", name, optarg); eflag = 1; break; case 'f': found_arg = 1; name = "average file size"; fvalue = atoi(optarg); if (fvalue < 1) errx(10, "%s must be >= 1 (was %s)", name, optarg); fflag = 1; break; case 'j': found_arg = 1; name = "softdep journaled file system"; jvalue = optarg; if (strcmp(jvalue, "enable") && strcmp(jvalue, "disable")) { errx(10, "bad %s (options are %s)", name, "`enable' or `disable'"); } jflag = 1; break; case 'J': found_arg = 1; name = "gjournaled file system"; Jvalue = optarg; if (strcmp(Jvalue, "enable") && strcmp(Jvalue, "disable")) { errx(10, "bad %s (options are %s)", name, "`enable' or `disable'"); } Jflag = 1; break; case 'L': found_arg = 1; name = "volume label"; Lvalue = optarg; i = -1; while (isalnum(Lvalue[++i])); if (Lvalue[i] != '\0') { errx(10, "bad %s. Valid characters are alphanumerics.", name); } if (strlen(Lvalue) >= MAXVOLLEN) { errx(10, "bad %s. Length is longer than %d.", name, MAXVOLLEN - 1); } Lflag = 1; break; case 'l': found_arg = 1; name = "multilabel MAC file system"; lvalue = optarg; if (strcmp(lvalue, "enable") && strcmp(lvalue, "disable")) { errx(10, "bad %s (options are %s)", name, "`enable' or `disable'"); } lflag = 1; break; case 'm': found_arg = 1; name = "minimum percentage of free space"; mvalue = atoi(optarg); if (mvalue < 0 || mvalue > 99) errx(10, "bad %s (%s)", name, optarg); mflag = 1; break; case 'N': found_arg = 1; name = "NFSv4 ACLs"; Nvalue = optarg; if (strcmp(Nvalue, "enable") && strcmp(Nvalue, "disable")) { errx(10, "bad %s (options are %s)", name, "`enable' or `disable'"); } Nflag = 1; break; case 'n': found_arg = 1; name = "soft updates"; nvalue = optarg; if (strcmp(nvalue, "enable") != 0 && strcmp(nvalue, "disable") != 0) { errx(10, "bad %s (options are %s)", name, "`enable' or `disable'"); } nflag = 1; break; case 'o': found_arg = 1; name = "optimization preference"; if (strcmp(optarg, "space") == 0) ovalue = FS_OPTSPACE; else if (strcmp(optarg, "time") == 0) ovalue = FS_OPTTIME; else errx(10, "bad %s (options are `space' or `time')", name); oflag = 1; break; case 'p': found_arg = 1; pflag = 1; break; case 's': found_arg = 1; name = "expected number of files per directory"; svalue = atoi(optarg); if (svalue < 1) errx(10, "%s must be >= 1 (was %s)", name, optarg); sflag = 1; break; case 'S': found_arg = 1; name = "Softdep Journal Size"; Svalue = atoi(optarg); if (Svalue < SUJ_MIN) errx(10, "%s must be >= %d (was %s)", name, SUJ_MIN, optarg); Sflag = 1; break; case 't': found_arg = 1; name = "trim"; tvalue = optarg; if (strcmp(tvalue, "enable") != 0 && strcmp(tvalue, "disable") != 0) { errx(10, "bad %s (options are %s)", name, "`enable' or `disable'"); } tflag = 1; break; default: usage(); } argc -= optind; argv += optind; if (found_arg == 0 || argc != 1) usage(); on = special = argv[0]; if (ufs_disk_fillout(&disk, special) == -1) goto err; if (disk.d_name != special) { if (statfs(special, &stfs) != 0) warn("Can't stat %s", special); if (strcmp(special, stfs.f_mntonname) == 0) active = 1; } if (pflag) { printfs(); exit(0); } if (Lflag) { name = "volume label"; strlcpy(sblock.fs_volname, Lvalue, MAXVOLLEN); } if (aflag) { name = "POSIX.1e ACLs"; if (strcmp(avalue, "enable") == 0) { if (sblock.fs_flags & FS_ACLS) { warnx("%s remains unchanged as enabled", name); } else if (sblock.fs_flags & FS_NFS4ACLS) { warnx("%s and NFSv4 ACLs are mutually " "exclusive", name); } else { sblock.fs_flags |= FS_ACLS; warnx("%s set", name); } } else if (strcmp(avalue, "disable") == 0) { if ((~sblock.fs_flags & FS_ACLS) == FS_ACLS) { warnx("%s remains unchanged as disabled", name); } else { sblock.fs_flags &= ~FS_ACLS; warnx("%s cleared", name); } } } if (eflag) { name = "maximum blocks per file in a cylinder group"; if (sblock.fs_maxbpg == evalue) warnx("%s remains unchanged as %d", name, evalue); else { warnx("%s changes from %d to %d", name, sblock.fs_maxbpg, evalue); sblock.fs_maxbpg = evalue; } } if (fflag) { name = "average file size"; if (sblock.fs_avgfilesize == (unsigned)fvalue) { warnx("%s remains unchanged as %d", name, fvalue); } else { warnx("%s changes from %d to %d", name, sblock.fs_avgfilesize, fvalue); sblock.fs_avgfilesize = fvalue; } } if (jflag) { name = "soft updates journaling"; if (strcmp(jvalue, "enable") == 0) { if ((sblock.fs_flags & (FS_DOSOFTDEP | FS_SUJ)) == (FS_DOSOFTDEP | FS_SUJ)) { warnx("%s remains unchanged as enabled", name); } else if (sblock.fs_clean == 0) { warnx("%s cannot be enabled until fsck is run", name); } else if (journal_alloc(Svalue) != 0) { warnx("%s can not be enabled", name); } else { sblock.fs_flags |= FS_DOSOFTDEP | FS_SUJ; warnx("%s set", name); } } else if (strcmp(jvalue, "disable") == 0) { if ((~sblock.fs_flags & FS_SUJ) == FS_SUJ) { warnx("%s remains unchanged as disabled", name); } else { journal_clear(); sblock.fs_flags &= ~FS_SUJ; sblock.fs_sujfree = 0; warnx("%s cleared but soft updates still set.", name); warnx("remove .sujournal to reclaim space"); } } } if (Jflag) { name = "gjournal"; if (strcmp(Jvalue, "enable") == 0) { if (sblock.fs_flags & FS_GJOURNAL) { warnx("%s remains unchanged as enabled", name); } else { sblock.fs_flags |= FS_GJOURNAL; warnx("%s set", name); } } else if (strcmp(Jvalue, "disable") == 0) { if ((~sblock.fs_flags & FS_GJOURNAL) == FS_GJOURNAL) { warnx("%s remains unchanged as disabled", name); } else { sblock.fs_flags &= ~FS_GJOURNAL; warnx("%s cleared", name); } } } if (lflag) { name = "multilabel"; if (strcmp(lvalue, "enable") == 0) { if (sblock.fs_flags & FS_MULTILABEL) { warnx("%s remains unchanged as enabled", name); } else { sblock.fs_flags |= FS_MULTILABEL; warnx("%s set", name); } } else if (strcmp(lvalue, "disable") == 0) { if ((~sblock.fs_flags & FS_MULTILABEL) == FS_MULTILABEL) { warnx("%s remains unchanged as disabled", name); } else { sblock.fs_flags &= ~FS_MULTILABEL; warnx("%s cleared", name); } } } if (mflag) { name = "minimum percentage of free space"; if (sblock.fs_minfree == mvalue) warnx("%s remains unchanged as %d%%", name, mvalue); else { warnx("%s changes from %d%% to %d%%", name, sblock.fs_minfree, mvalue); sblock.fs_minfree = mvalue; if (mvalue >= MINFREE && sblock.fs_optim == FS_OPTSPACE) warnx(OPTWARN, "time", ">=", MINFREE); if (mvalue < MINFREE && sblock.fs_optim == FS_OPTTIME) warnx(OPTWARN, "space", "<", MINFREE); } } if (Nflag) { name = "NFSv4 ACLs"; if (strcmp(Nvalue, "enable") == 0) { if (sblock.fs_flags & FS_NFS4ACLS) { warnx("%s remains unchanged as enabled", name); } else if (sblock.fs_flags & FS_ACLS) { warnx("%s and POSIX.1e ACLs are mutually " "exclusive", name); } else { sblock.fs_flags |= FS_NFS4ACLS; warnx("%s set", name); } } else if (strcmp(Nvalue, "disable") == 0) { if ((~sblock.fs_flags & FS_NFS4ACLS) == FS_NFS4ACLS) { warnx("%s remains unchanged as disabled", name); } else { sblock.fs_flags &= ~FS_NFS4ACLS; warnx("%s cleared", name); } } } if (nflag) { name = "soft updates"; if (strcmp(nvalue, "enable") == 0) { if (sblock.fs_flags & FS_DOSOFTDEP) warnx("%s remains unchanged as enabled", name); else if (sblock.fs_clean == 0) { warnx("%s cannot be enabled until fsck is run", name); } else { sblock.fs_flags |= FS_DOSOFTDEP; warnx("%s set", name); } } else if (strcmp(nvalue, "disable") == 0) { if ((~sblock.fs_flags & FS_DOSOFTDEP) == FS_DOSOFTDEP) warnx("%s remains unchanged as disabled", name); else { sblock.fs_flags &= ~FS_DOSOFTDEP; warnx("%s cleared", name); } } } if (oflag) { name = "optimization preference"; chg[FS_OPTSPACE] = "space"; chg[FS_OPTTIME] = "time"; if (sblock.fs_optim == ovalue) warnx("%s remains unchanged as %s", name, chg[ovalue]); else { warnx("%s changes from %s to %s", name, chg[sblock.fs_optim], chg[ovalue]); sblock.fs_optim = ovalue; if (sblock.fs_minfree >= MINFREE && ovalue == FS_OPTSPACE) warnx(OPTWARN, "time", ">=", MINFREE); if (sblock.fs_minfree < MINFREE && ovalue == FS_OPTTIME) warnx(OPTWARN, "space", "<", MINFREE); } } if (sflag) { name = "expected number of files per directory"; if (sblock.fs_avgfpdir == (unsigned)svalue) { warnx("%s remains unchanged as %d", name, svalue); } else { warnx("%s changes from %d to %d", name, sblock.fs_avgfpdir, svalue); sblock.fs_avgfpdir = svalue; } } if (tflag) { name = "issue TRIM to the disk"; if (strcmp(tvalue, "enable") == 0) { if (sblock.fs_flags & FS_TRIM) warnx("%s remains unchanged as enabled", name); else { sblock.fs_flags |= FS_TRIM; warnx("%s set", name); } } else if (strcmp(tvalue, "disable") == 0) { if ((~sblock.fs_flags & FS_TRIM) == FS_TRIM) warnx("%s remains unchanged as disabled", name); else { sblock.fs_flags &= ~FS_TRIM; warnx("%s cleared", name); } } } if (sbwrite(&disk, Aflag) == -1) goto err; ufs_disk_close(&disk); if (active) { bzero(&args, sizeof(args)); if (mount("ufs", on, stfs.f_flags | MNT_UPDATE | MNT_RELOAD, &args) < 0) err(9, "%s: reload", special); warnx("file system reloaded"); } exit(0); err: if (disk.d_error != NULL) errx(11, "%s: %s", special, disk.d_error); else err(12, "%s", special); }
static void load_font(const char *type, const char *filename) { FILE *fd; int h, i, size, w; unsigned long io = 0; /* silence stupid gcc(1) in the Wall mode */ char *name, *fontmap, size_sufx[6]; const char *a[] = {"", FONT_PATH, NULL}; const char *vt4a[] = {"", VT_FONT_PATH, NULL}; const char *b[] = {filename, NULL}; const char *c[] = {"", size_sufx, NULL}; const char *d[] = {"", ".fnt", NULL}; vid_info_t _info; struct sizeinfo { int w; int h; unsigned long io; } sizes[] = {{8, 16, PIO_FONT8x16}, {8, 14, PIO_FONT8x14}, {8, 8, PIO_FONT8x8}, {0, 0, 0}}; if (vt4_mode) { size_sufx[0] = '\0'; } else { _info.size = sizeof(_info); if (ioctl(0, CONS_GETINFO, &_info) == -1) { revert(); warn("failed to obtain current video mode parameters"); return; } snprintf(size_sufx, sizeof(size_sufx), "-8x%d", _info.font_size); } fd = openguess((vt4_mode == 0) ? a : vt4a, b, c, d, &name); if (fd == NULL) { revert(); errx(1, "%s: can't load font file", filename); } if (vt4_mode) { if(load_vt4font(fd)) warn("failed to load font \"%s\"", filename); fclose(fd); return; } if (type != NULL) { size = 0; if (sscanf(type, "%dx%d", &w, &h) == 2) { for (i = 0; sizes[i].w != 0; i++) { if (sizes[i].w == w && sizes[i].h == h) { size = DATASIZE(sizes[i]); io = sizes[i].io; font_height = sizes[i].h; } } } if (size == 0) { fclose(fd); revert(); errx(1, "%s: bad font size specification", type); } } else { /* Apply heuristics */ int j; int dsize[2]; size = DATASIZE(sizes[0]); fontmap = (char*) malloc(size); dsize[0] = decode(fd, fontmap, size); dsize[1] = fsize(fd); free(fontmap); size = 0; for (j = 0; j < 2; j++) { for (i = 0; sizes[i].w != 0; i++) { if (DATASIZE(sizes[i]) == dsize[j]) { size = dsize[j]; io = sizes[i].io; font_height = sizes[i].h; j = 2; /* XXX */ break; } } } if (size == 0) { fclose(fd); revert(); errx(1, "%s: can't guess font size", filename); } rewind(fd); } fontmap = (char*) malloc(size); if (decode(fd, fontmap, size) != size) { rewind(fd); if (fsize(fd) != size || fread(fontmap, 1, size, fd) != (size_t)size) { warnx("%s: bad font file", filename); fclose(fd); free(fontmap); revert(); errx(1, "%s: bad font file", filename); } } if (ioctl(0, io, fontmap) == -1) { revert(); errc(1, errno, "loading font"); } fclose(fd); free(fontmap); }
int exec_audit(int argc, char **argv) { struct pkg_audit *audit; struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; const char *db_dir; char *name; char *version; char audit_file_buf[MAXPATHLEN]; char *audit_file = audit_file_buf; unsigned int vuln = 0; bool fetch = false, recursive = false; int ch, i; int ret = EX_OK; const char *portaudit_site = NULL; struct sbuf *sb; kh_pkgs_t *check = NULL; db_dir = pkg_object_string(pkg_config_get("PKG_DBDIR")); snprintf(audit_file_buf, sizeof(audit_file_buf), "%s/vuln.xml", db_dir); struct option longopts[] = { { "fetch", no_argument, NULL, 'F' }, { "file", required_argument, NULL, 'f' }, { "recursive", no_argument, NULL, 'r' }, { "quiet", no_argument, NULL, 'q' }, { NULL, 0, NULL, 0 }, }; while ((ch = getopt_long(argc, argv, "+Ff:qr", longopts, NULL)) != -1) { switch (ch) { case 'F': fetch = true; break; case 'f': audit_file = optarg; break; case 'q': quiet = true; break; case 'r': recursive = true; break; default: usage_audit(); return(EX_USAGE); } } argc -= optind; argv += optind; audit = pkg_audit_new(); if (fetch == true) { portaudit_site = pkg_object_string(pkg_config_get("VULNXML_SITE")); if (pkg_audit_fetch(portaudit_site, audit_file) != EPKG_OK) { pkg_audit_free(audit); return (EX_IOERR); } } if (pkg_audit_load(audit, audit_file) != EPKG_OK) { if (errno == ENOENT) warnx("vulnxml file %s does not exist. " "Try running 'pkg audit -F' first", audit_file); else warn("unable to open vulnxml file %s", audit_file); pkg_audit_free(audit); return (EX_DATAERR); } check = kh_init_pkgs(); if (argc >= 1) { for (i = 0; i < argc; i ++) { name = argv[i]; version = strrchr(name, '-'); if (version != NULL) { version[0] = '\0'; version++; } if (pkg_new(&pkg, PKG_FILE) != EPKG_OK) err(EX_OSERR, "malloc"); if (version != NULL) pkg_set(pkg, PKG_NAME, name, PKG_VERSION, version); else pkg_set(pkg, PKG_NAME, name); /* Fake uniqueid */ pkg_set(pkg, PKG_UNIQUEID, name); add_to_check(check, pkg); pkg = NULL; } } else { /* * if the database doesn't exist it just means there are no * packages to audit. */ ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL); if (ret == EPKG_ENODB) { pkg_audit_free(audit); kh_destroy_pkgs(check); return (EX_OK); } else if (ret == EPKG_ENOACCESS) { warnx("Insufficient privileges to read the package database"); pkg_audit_free(audit); kh_destroy_pkgs(check); return (EX_NOPERM); } else if (ret != EPKG_OK) { warnx("Error accessing the package database"); pkg_audit_free(audit); kh_destroy_pkgs(check); return (EX_IOERR); } if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) { pkg_audit_free(audit); kh_destroy_pkgs(check); return (EX_IOERR); } if (pkgdb_obtain_lock(db, PKGDB_LOCK_READONLY) != EPKG_OK) { pkgdb_close(db); pkg_audit_free(audit); kh_destroy_pkgs(check); warnx("Cannot get a read lock on a database, it is locked by another process"); return (EX_TEMPFAIL); } if ((it = pkgdb_query(db, NULL, MATCH_ALL)) == NULL) { warnx("Error accessing the package database"); ret = EX_IOERR; } else { while ((ret = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC|PKG_LOAD_RDEPS)) == EPKG_OK) { add_to_check(check, pkg); pkg = NULL; } ret = EX_OK; } if (db != NULL) { pkgdb_it_free(it); pkgdb_release_lock(db, PKGDB_LOCK_READONLY); pkgdb_close(db); } if (ret != EX_OK) { pkg_audit_free(audit); kh_destroy_pkgs(check); return (ret); } } /* Now we have vulnxml loaded and check list formed */ #ifdef HAVE_CAPSICUM if (cap_enter() < 0 && errno != ENOSYS) { warn("cap_enter() failed"); pkg_audit_free(audit); kh_destroy_pkgs(check); return (EPKG_FATAL); } #endif if (pkg_audit_process(audit) == EPKG_OK) { kh_foreach_value(check, pkg, { if (pkg_audit_is_vulnerable(audit, pkg, quiet, &sb)) { vuln ++; printf("%s", sbuf_data(sb)); if (recursive) { const char *name; kh_pkgs_t *seen = kh_init_pkgs(); pkg_get(pkg, PKG_NAME, &name); sbuf_clear(sb); sbuf_printf(sb, "Packages that depend on %s: ", name); print_recursive_rdeps(check, pkg , sb, seen, true); sbuf_finish(sb); printf("%s\n\n", sbuf_data(sb)); kh_destroy_pkgs(seen); } sbuf_delete(sb); } pkg_free(pkg); });