Example #1
0
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;
}
Example #2
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);
}
Example #3
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;
}
Example #4
0
__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

}
Example #5
0
/*
 * 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);
}
Example #6
0
File: pass1.c Project: cse451/os161
/*
 * 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);
}
Example #7
0
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);
}
Example #8
0
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;
	}
}
Example #9
0
/*
 * 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);
}
Example #10
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);
}
Example #12
0
File: ndp.c Project: ryo/netbsd-src
/*
 * 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));
}
Example #13
0
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 */
}
Example #14
0
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 */
}
Example #15
0
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);
}
Example #16
0
/*
 * 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);
}
Example #17
0
File: pass1.c Project: cse451/os161
/*
 * 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;
}
Example #18
0
/*================================================================
 *                    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 */
Example #19
0
File: pass1.c Project: cse451/os161
/*
 * 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);
		}
	}
}
Example #20
0
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);
}
Example #21
0
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);
}
Example #22
0
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);
}
Example #23
0
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;
}
Example #24
0
static void
unknown(void)
{
	int ch = bmachine.readstack[bmachine.readsp].lastchar;
	warnx("%c (0%o) is unimplemented", ch, ch);
}
Example #25
0
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 {
Example #26
0
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);
}
Example #27
0
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);
}
Example #28
0
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);
}
Example #29
0
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);
}
Example #30
0
File: audit.c Project: grembo/pkg
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);
		});