Beispiel #1
0
static int append_rrsection(const jdns_list_t *src, int at, int left, unsigned char **bufp, jdns_list_t *lookup)
{
	unsigned char *buf, *start, *last, *rdlengthp;
	int n, i, rdlength;

	buf = *bufp;
	start = buf - at;
	last = buf + left;
	for(n = 0; n < src->count; ++n)
	{
		jdns_packet_resource_t *r = (jdns_packet_resource_t *)src->item[n];

		if(!writelabel(r->qname, buf - start, last - buf, &buf, lookup))
			goto error;

		if(buf + 10 > last)
			goto error;

		short2net(r->qtype, &buf);
		short2net(r->qclass, &buf);
		long2net(r->ttl, &buf);

		// skip over rdlength
		rdlengthp = buf;
		buf += 2;

		// play write log
		rdlength = 0;
		for(i = 0; i < r->writelog->count; ++i)
		{
			jdns_packet_write_t *write = (jdns_packet_write_t *)r->writelog->item[i];
			if(write->type == JDNS_PACKET_WRITE_RAW)
			{
				if(buf + write->value->size > last)
					goto error;

				memcpy(buf, write->value->data, write->value->size);
				buf += write->value->size;
			}
			else // JDNS_PACKET_WRITE_NAME
			{
				if(!writelabel(write->value, buf - start, last - buf, &buf, lookup))
					goto error;
			}
		}

		i = buf - rdlengthp; // should be rdata size + 2
		short2net((unsigned short int)(i - 2), &rdlengthp);
	}

	*bufp = buf;
	return 1;

error:
	return 0;
}
Beispiel #2
0
static int append_qsection(const jdns_list_t *src, int at, int left, unsigned char **bufp, jdns_list_t *lookup)
{
	unsigned char *buf, *start, *last;
	int n;

	buf = *bufp;
	start = buf - at;
	last = buf + left;
	for(n = 0; n < src->count; ++n)
	{
		jdns_packet_question_t *q = (jdns_packet_question_t *)src->item[n];

		if(!writelabel(q->qname, buf - start, last - buf, &buf, lookup))
			goto error;

		if(buf + 4 > last)
			goto error;

		short2net(q->qtype, &buf);
		short2net(q->qclass, &buf);
	}

	*bufp = buf;
	return 1;

error:
	return 0;
}
Beispiel #3
0
static int
edit(void)
{
	int c, fd;
	struct disklabel label;
	FILE *fp;

	if ((fd = mkstemp(tmpfil)) == -1 ||
	    (fp = fdopen(fd, "w")) == NULL) {
		warnx("can't create %s", tmpfil);
		return (1);
	}
	display(fp, NULL);
	fclose(fp);
	for (;;) {
		if (!editit())
			break;
		fp = fopen(tmpfil, "r");
		if (fp == NULL) {
			warnx("can't reopen %s for reading", tmpfil);
			break;
		}
		bzero((char *)&label, sizeof(label));
		c = getasciilabel(fp, &label);
		fclose(fp);
		if (c) {
			lab = label;
			if (writelabel() == 0) {
				(void) unlink(tmpfil);
				return (0);
			}
		}
		printf("re-edit the label? [y]: ");
		fflush(stdout);
		c = getchar();
		if (c != EOF && c != (int)'\n')
			while (getchar() != (int)'\n')
				;
		if  (c == (int)'n')
			break;
	}
	(void) unlink(tmpfil);
	return (1);
}
Beispiel #4
0
static void
cmd_label(struct disklabel *lp, char *s, int fd)
{
	char	line[BUFSIZ];
	int	i;

	i = getinput(line, "Label disk [n]?");
	if (i <= 0 || (*line != 'y' && *line != 'Y') )
		return;

	if (checklabel(lp) != 0) {
		printf("Label not written\n");
		return;
	}

	if (writelabel(fd, lp) != 0) {
		printf("Label not written\n");
		return;
	}
	printf("Label written\n");
}
Beispiel #5
0
int
edit(struct disklabel *lp, int f)
{
	int first, ch, fd, error = 0;
	struct disklabel label;
	FILE *fp;
	u_int64_t total_sectors, starting_sector, ending_sector;

	if ((fd = mkstemp(tmpfil)) == -1 || (fp = fdopen(fd, "w")) == NULL) {
		if (fd != -1)
			close(fd);
		warn("%s", tmpfil);
		return (1);
	}
	display(fp, lp, 0, 1);
	fprintf(fp, "\n# Notes:\n");
	fprintf(fp,
"# Up to 16 partitions are valid, named from 'a' to 'p'.  Partition 'a' is\n"
"# your root filesystem, 'b' is your swap, and 'c' should cover your whole\n"
"# disk. Any other partition is free for any use.  'size' and 'offset' are\n"
"# in 512-byte blocks. fstype should be '4.2BSD', 'swap', or 'none' or some\n"
"# other values.  fsize/bsize/cpg should typically be '2048 16384 16' for a\n"
"# 4.2BSD filesystem (or '512 4096 16' except on alpha, sun4, ...)\n");
	fclose(fp);
	for (;;) {
		if (editit(tmpfil) == -1)
			break;
		fp = fopen(tmpfil, "r");
		if (fp == NULL) {
			warn("%s", tmpfil);
			break;
		}
		/* Get values set by OS and not the label. */
		if (ioctl(f, DIOCGPDINFO, &label) < 0)
			err(4, "ioctl DIOCGPDINFO");
		ending_sector = DL_GETBEND(&label);
		starting_sector = DL_GETBSTART(&label);
		total_sectors = DL_GETDSIZE(&label);
		memset(&label, 0, sizeof(label));
		error = getasciilabel(fp, &label);
		DL_SETBEND(&label, ending_sector);
		DL_SETBSTART(&label, starting_sector);
		DL_SETDSIZE(&label, total_sectors);

		if (error == 0) {
			if (cmplabel(lp, &label) == 0) {
				puts("No changes.");
				fclose(fp);
				(void) unlink(tmpfil);
				return (0);
			}
			*lp = label;
			if (writelabel(f, bootarea, lp) == 0) {
				fclose(fp);
				(void) unlink(tmpfil);
				return (0);
			}
		}
		fclose(fp);
		printf("re-edit the label? [y]: ");
		fflush(stdout);
		first = ch = getchar();
		while (ch != '\n' && ch != EOF)
			ch = getchar();
		if (first == 'n' || first == 'N')
			break;
	}
	(void)unlink(tmpfil);
	return (1);
}
Beispiel #6
0
int
main(int argc, char *argv[])
{
	int ch, f, error = 0;
	struct disklabel *lp;
	FILE *t;

	while ((ch = getopt(argc, argv, "ABEf:F:hRb:cdenp:tvw")) != -1)
		switch (ch) {
		case 'A':
			++aflag;
			break;
#if NUMBOOT > 0
		case 'B':
			++installboot;
			break;
		case 'b':
			xxboot = optarg;
			break;
#endif
		case 'R':
			if (op != UNSPEC)
				usage();
			op = RESTORE;
			break;
		case 'c':
			++cflag;
			break;
		case 'd':
			++dflag;
			break;
		case 'e':
			if (op != UNSPEC)
				usage();
			op = EDIT;
			break;
		case 'E':
			if (op != UNSPEC)
				usage();
			op = EDITOR;
			break;
		case 'f':
			fstabfile = optarg;
			uidflag = 0;
			break;
		case 'F':
			fstabfile = optarg;
			++uidflag;
			break;
		case 'h':
			print_unit = '*';
			break;
		case 't':
			++tflag;
			break;
		case 'w':
			if (op != UNSPEC)
				usage();
			op = WRITE;
			break;
		case 'p':
			if (strchr("bckmgtBCKMGT", optarg[0]) == NULL ||
			    optarg[1] != '\0') {
				fprintf(stderr, "Valid units are bckmgt\n");
				exit(1);
			}
			print_unit = tolower((unsigned char)optarg[0]);
			break;
		case 'n':
			donothing++;
			break;
		case 'v':
			verbose++;
			break;
		case '?':
		default:
			usage();
	}
	argc -= optind;
	argv += optind;

#if NUMBOOT > 0
	if (installboot) {
		if (op == UNSPEC)
			op = WRITEBOOT;
	} else {
		if (op == UNSPEC)
			op = READ;
	}
#else
	if (op == UNSPEC)
		op = READ;
#endif

	if (argc < 1 || (fstabfile && !(op == EDITOR || aflag)))
		usage();

	dkname = argv[0];
	f = opendev(dkname, (op == READ ? O_RDONLY : O_RDWR), OPENDEV_PART,
	    &specname);
	if (f < 0)
		err(4, "%s", specname);

	switch (op) {
	case EDIT:
		if (argc != 1)
			usage();
		readlabel(f);
		error = edit(&lab, f);
		break;
	case EDITOR:
		if (argc != 1)
			usage();
		readlabel(f);
		error = editor(f);
		break;
	case READ:
		if (argc != 1)
			usage();
		readlabel(f);
		if (tflag)
			makedisktab(stdout, &lab);
		else
			display(stdout, &lab, print_unit, 1);
		error = checklabel(&lab);
		break;
	case RESTORE:
		if (argc < 2 || argc > 3)
			usage();
		readlabel(f);
#if NUMBOOT > 0
		if (installboot && argc == 3)
			makelabel(argv[2], NULL, &lab);
#endif
		lp = makebootarea(bootarea, &lab);
		*lp = lab;
		if (!(t = fopen(argv[1], "r")))
			err(4, "%s", argv[1]);
		error = getasciilabel(t, lp);
		bzero(lp->d_uid, sizeof(lp->d_uid));
		if (error == 0)
			error = writelabel(f, bootarea, lp);
		fclose(t);
		break;
	case WRITE:
		if (dflag || aflag) {
			readlabel(f);
		} else if (argc < 2 || argc > 3)
			usage();
		else
			makelabel(argv[1], argc == 3 ? argv[2] : NULL, &lab);
		lp = makebootarea(bootarea, &lab);
		*lp = lab;
		error = checklabel(&lab);
		if (error == 0)
			error = writelabel(f, bootarea, lp);
		break;
#if NUMBOOT > 0
	case WRITEBOOT:
	{
		struct disklabel tlab;

		readlabel(f);
		tlab = lab;
		if (argc == 2)
			makelabel(argv[1], NULL, &lab);
		lp = makebootarea(bootarea, &lab);
		*lp = tlab;
		error = checklabel(&lab);
		if (error == 0)
			error = writelabel(f, bootarea, lp);
		break;
	}
#endif
	default:
		break;
	}
	exit(error);
}
Beispiel #7
0
int
main(int argc, char **argv)
{
    int		sts;
    char	*msg;
    pmResult	*irp;		/* input pmResult */
    pmResult	*orp;		/* output pmResult */
    __pmPDU	*pb;		/* pdu buffer */
    struct timeval	unused;
    unsigned long	peek_offset;

    /* process cmd line args */
    if (parseargs(argc, argv) < 0) {
	pmUsageMessage(&opts);
	exit(1);
    }

    /* input  archive name is argv[opts.optind] */
    /* output archive name is argv[argc-1]) */

    /* output archive */
    oname = argv[argc-1];

    /* input archive */
    iname = argv[opts.optind];

    /*
     * This is the interp mode context
     */
    if ((ictx_a = pmNewContext(PM_CONTEXT_ARCHIVE, iname)) < 0) {
	fprintf(stderr, "%s: Error: cannot open archive \"%s\" (ctx_a): %s\n",
		pmProgname, iname, pmErrStr(ictx_a));
	exit(1);
    }

    if ((sts = pmGetArchiveLabel(&ilabel)) < 0) {
	fprintf(stderr, "%s: Error: cannot get archive label record (%s): %s\n", pmProgname, iname, pmErrStr(sts));
	exit(1);
    }

    /* start time */
    logstart_tval.tv_sec = ilabel.ll_start.tv_sec;
    logstart_tval.tv_usec = ilabel.ll_start.tv_usec;

    /* end time */
    if ((sts = pmGetArchiveEnd(&logend_tval)) < 0) {
	fprintf(stderr, "%s: Error: cannot get end of archive (%s): %s\n",
		pmProgname, iname, pmErrStr(sts));
	exit(1);
    }

    if (zarg) {
	/* use TZ from metrics source (input-archive) */
	if ((sts = pmNewZone(ilabel.ll_tz)) < 0) {
	    fprintf(stderr, "%s: Cannot set context timezone: %s\n",
		    pmProgname, pmErrStr(sts));
            exit(1);
	}
	printf("Note: timezone set to local timezone of host \"%s\" from archive\n\n", ilabel.ll_hostname);
    }
    else if (tz != NULL) {
	/* use TZ as specified by user */
	if ((sts = pmNewZone(tz)) < 0) {
	    fprintf(stderr, "%s: Cannot set timezone to \"%s\": %s\n",
		    pmProgname, tz, pmErrStr(sts));
	    exit(1);
	}
	printf("Note: timezone set to \"TZ=%s\"\n\n", tz);
    }
    else {
	char	*tz;
        tz = __pmTimezone();
	/* use TZ from local host */
	if ((sts = pmNewZone(tz)) < 0) {
	    fprintf(stderr, "%s: Cannot set local host's timezone: %s\n",
		    pmProgname, pmErrStr(sts));
	    exit(1);
	}
    }

    /* set winstart and winend timevals */
    sts = pmParseTimeWindow(Sarg, Targ, Aarg, Oarg,
			    &logstart_tval, &logend_tval,
			    &winstart_tval, &winend_tval, &unused, &msg);
    if (sts < 0) {
	fprintf(stderr, "%s: Invalid time window specified: %s\n",
		pmProgname, msg);
	exit(1);
    }
#if PCP_DEBUG
    if (pmDebug & DBG_TRACE_APPL0) {
	char	buf[26];
	pmCtime((const time_t *)&winstart_tval.tv_sec, buf);
	fprintf(stderr, "Start time: %s", buf);
	pmCtime((const time_t *)&winend_tval.tv_sec, buf);
	fprintf(stderr, "End time: %s", buf);
    }
#endif

    if ((sts = pmSetMode(PM_MODE_INTERP | PM_XTB_SET(PM_TIME_SEC),
                         &winstart_tval, (int)targ)) < 0) {
	fprintf(stderr, "%s: pmSetMode(PM_MODE_INTERP ...) failed: %s\n",
		pmProgname, pmErrStr(sts));
	exit(1);
    }

    /* create output log - must be done before writing label */
    if ((sts = __pmLogCreate("", oname, PM_LOG_VERS02, &logctl)) < 0) {
	fprintf(stderr, "%s: Error: __pmLogCreate: %s\n",
		pmProgname, pmErrStr(sts));
	exit(1);
    }

    /* This must be done after log is created:
     *		- checks that archive version, host, and timezone are ok
     *		- set archive version, host, and timezone of output archive
     *		- set start time
     *		- write labels
     */
    newlabel();
    current.tv_sec = logctl.l_label.ill_start.tv_sec = winstart_tval.tv_sec;
    current.tv_usec = logctl.l_label.ill_start.tv_usec = winstart_tval.tv_usec;
    /* write label record */
    writelabel();
    /*
     * Supress any automatic label creation in libpcp at the first
     * pmResult write.
     */
    logctl.l_state = PM_LOG_STATE_INIT;

    /*
     * Traverse the PMNS to get all the metrics and their metadata
     */
    if ((sts = pmTraversePMNS ("", dometric)) < 0) {
	fprintf(stderr, "%s: Error traversing namespace ... %s\n",
		pmProgname, pmErrStr(sts));
	goto cleanup;
    }

    /*
     * All the initial metadata has been generated, add timestamp
     */
    fflush(logctl.l_mdfp);
    __pmLogPutIndex(&logctl, &current);

    written = 0;

    /*
     * main loop
     */
    while (sarg == -1 || written < sarg) {
	/*
	 * do stuff
	 */
	if ((sts = pmUseContext(ictx_a)) < 0) {
	    fprintf(stderr, "%s: Error: cannot use context (%s): %s\n",
		    pmProgname, iname, pmErrStr(sts));
	    goto cleanup;
	}
	if ((sts = pmFetch(numpmid, pmidlist, &irp)) < 0) {
	    if (sts == PM_ERR_EOL)
		break;
	    fprintf(stderr,
		"%s: Error: pmFetch failed: %s\n", pmProgname, pmErrStr(sts));
	    exit(1);
	}
	if (irp->timestamp.tv_sec > winend_tval.tv_sec ||
	    (irp->timestamp.tv_sec == winend_tval.tv_sec &&
	     irp->timestamp.tv_usec > winend_tval.tv_usec)) {
	    /* past end time as per -T */
	    break;
	}
#if PCP_DEBUG
	if (pmDebug & DBG_TRACE_APPL2) {
	    fprintf(stderr, "input record ...\n");
	    __pmDumpResult(stderr, irp);
	}
#endif

	/*
	 * traverse the interval, looking at every archive record ...
	 * we are particularly interested in:
	 * 	- metric-values that are interpolated but not present in
	 * 	  this interval
	 * 	- counter wraps
	 *	- mark records
	 */
	doscan(&irp->timestamp);

	if ((sts = pmUseContext(ictx_a)) < 0) {
	    fprintf(stderr, "%s: Error: cannot use context (%s): %s\n",
		    pmProgname, iname, pmErrStr(sts));
	    goto cleanup;
	}

	orp = rewrite(irp);
#if PCP_DEBUG
	if (pmDebug & DBG_TRACE_APPL2) {
	    if (orp == NULL)
		fprintf(stderr, "output record ... none!\n");
	    else {
		fprintf(stderr, "output record ...\n");
		__pmDumpResult(stderr, orp);
	    }
	}
#endif
	if (orp == NULL)
	    goto next;

	/*
	 * convert log record to a PDU, and enforce V2 encoding semantics,
	 * then write it out
	 */
	sts = __pmEncodeResult(PDU_OVERRIDE2, orp, &pb);
	if (sts < 0) {
	    fprintf(stderr, "%s: Error: __pmEncodeResult: %s\n",
		    pmProgname, pmErrStr(sts));
	    goto cleanup;
	}

	/* switch volumes if required */
	if (varg > 0) {
	    if (written > 0 && (written % varg) == 0) {
		__pmTimeval	next_stamp;
		next_stamp.tv_sec = irp->timestamp.tv_sec;
		next_stamp.tv_usec = irp->timestamp.tv_usec;
		newvolume(oname, &next_stamp);
	    }
	}
	/*
	 * Even without a -v option, we may need to switch volumes
	 * if the data file exceeds 2^31-1 bytes
	 */
	peek_offset = ftell(logctl.l_mfp);
	peek_offset += ((__pmPDUHdr *)pb)->len - sizeof(__pmPDUHdr) + 2*sizeof(int);
	if (peek_offset > 0x7fffffff) {
	    __pmTimeval	next_stamp;
	    next_stamp.tv_sec = irp->timestamp.tv_sec;
	    next_stamp.tv_usec = irp->timestamp.tv_usec;
	    newvolume(oname, &next_stamp);
	}

	current.tv_sec = orp->timestamp.tv_sec;
	current.tv_usec = orp->timestamp.tv_usec;

	doindom(orp);

	/* write out log record */
	sts = __pmLogPutResult2(&logctl, pb);
	__pmUnpinPDUBuf(pb);
	if (sts < 0) {
	    fprintf(stderr, "%s: Error: __pmLogPutResult2: log data: %s\n",
		    pmProgname, pmErrStr(sts));
	    goto cleanup;
	}
	written++;

	rewrite_free();

next:
	pmFreeResult(irp);
    }

    /* write the last time stamp */
    fflush(logctl.l_mfp);
    fflush(logctl.l_mdfp);
    __pmLogPutIndex(&logctl, &current);

    exit(exit_status);

cleanup:
    {
	char    fname[MAXNAMELEN];
	fprintf(stderr, "Archive \"%s\" not created.\n", oname);
	snprintf(fname, sizeof(fname), "%s.0", oname);
	unlink(fname);
	snprintf(fname, sizeof(fname), "%s.meta", oname);
	unlink(fname);
	snprintf(fname, sizeof(fname), "%s.index", oname);
	unlink(fname);
	exit(1);
    }
}
Beispiel #8
0
int
main(int argc, char *argv[])
{
	FILE *t;
	int ch, error, fd;
	const char *name;
	
	error = 0;
	name = NULL;

	while ((ch = getopt(argc, argv, "ABb:efm:nRrw")) != -1)
		switch (ch) {
			case 'A':
				allfields = 1;
				break;
			case 'B':
				++installboot;
				break;
			case 'b':
				xxboot = optarg;
				break;
			case 'f':
				is_file=1;
				break;
			case 'm':
				if (!strcmp(optarg, "i386") ||
				    !strcmp(optarg, "amd64") ||
				    !strcmp(optarg, "ia64") ||
				    !strcmp(optarg, "pc98")) {
					labelsoffset = 1;
					labeloffset = 0;
					bbsize = 8192;
				} else {
					errx(1, "Unsupported architecture");
				}
				break;
			case 'n':
				disable_write = 1;
				break;
			case 'R':
				if (op != UNSPEC)
					usage();
				op = RESTORE;
				break;
			case 'e':
				if (op != UNSPEC)
					usage();
				op = EDIT;
				break;
			case 'r':
				/*
				 * We accept and ignore -r for compatibility with
				 * historical disklabel usage.
				 */
				break;
			case 'w':
				if (op != UNSPEC)
					usage();
				op = WRITE;
				break;
			case '?':
			default:
				usage();
		}
	argc -= optind;
	argv += optind;

	if (argc < 1)
		usage();
	if (labelsoffset < 0 || labeloffset < 0)
		errx(1, "a -m <architecture> option must be specified");

	/* Figure out the names of the thing we're working on */
	if (is_file) {
		specname = argv[0];
	} else {
		specname = g_device_path(argv[0]);
		if (specname == NULL) {
			warn("unable to get correct path for %s", argv[0]);
			return(1);
		}
		fd = open(specname, O_RDONLY);
		if (fd < 0) {
			warn("error opening %s", specname);
			return(1);
		}
		pname = g_providername(fd);
		if (pname == NULL) {
			warn("error getting providername for %s", specname);
			close(fd);
			return(1);
		}
		close(fd);
	}

	if (installboot && op == UNSPEC)
		op = WRITEBOOT;
	else if (op == UNSPEC)
		op = READ;

	switch(op) {

	case UNSPEC:
		break;

	case EDIT:
		if (argc != 1)
			usage();
		readlabel(1);
		fixlabel(&lab);
		error = edit();
		break;

	case READ:
		if (argc != 1)
			usage();
		readlabel(1);
		display(stdout, NULL);
		error = checklabel(NULL);
		break;

	case RESTORE:
		if (argc != 2)
			usage();
		if (!(t = fopen(argv[1], "r")))
			err(4, "fopen %s", argv[1]);
		readlabel(0);
		if (!getasciilabel(t, &lab))
			exit(1);
		error = writelabel();
		break;

	case WRITE:
		if (argc == 2)
			name = argv[1];
		else if (argc == 1)
			name = "auto";
		else
			usage();
		readlabel(0);
		makelabel(name, &lab);
		fixlabel(&lab);
		if (checklabel(NULL) == 0)
			error = writelabel();
		break;

	case WRITEBOOT:

		readlabel(1);
		fixlabel(&lab);
		if (argc == 2)
			makelabel(argv[1], &lab);
		if (checklabel(NULL) == 0)
			error = writelabel();
		break;
	}
	exit(error);
}
Beispiel #9
0
int
main(int argc, char *argv[])
{
	struct disklabel32 *lp;
	FILE *t;
	int ch, f = 0, flag, error = 0;
	char *name = NULL;

	while ((ch = getopt(argc, argv, OPTIONS)) != -1)
		switch (ch) {
#if NUMBOOT > 0
			case 'B':
				++installboot;
				break;
			case 'b':
				xxboot = optarg;
				break;

			case 'f':
				forceflag = 1;
				slice_start_lba = strtoul(optarg, NULL, 0);
				break;
#if NUMBOOT > 1
			case 's':
				bootxx = optarg;
				break;
#endif
#endif
			case 'N':
				if (op != UNSPEC)
					usage();
				op = NOWRITE;
				break;
			case 'n':
				disable_write = 1;
				break;
			case 'R':
				if (op != UNSPEC)
					usage();
				op = RESTORE;
				break;
			case 'W':
				if (op != UNSPEC)
					usage();
				op = WRITEABLE;
				break;
			case 'e':
				if (op != UNSPEC)
					usage();
				op = EDIT;
				break;
			case 'r':
				++rflag;
				break;
			case 'w':
				if (op != UNSPEC)
					usage();
				op = WRITE;
				break;
#ifdef DEBUG
			case 'd':
				debug++;
				break;
#endif
			case '?':
			default:
				usage();
		}
	argc -= optind;
	argv += optind;
#if NUMBOOT > 0
	if (installboot) {
		rflag++;
		if (op == UNSPEC)
			op = WRITEBOOT;
	} else {
		if (op == UNSPEC)
			op = READ;
		xxboot = bootxx = NULL;
	}
#else
	if (op == UNSPEC)
		op = READ;
#endif
	if (argc < 1)
		usage();

	dkname = getdevpath(argv[0], 0);
	specname = dkname;
	f = open(specname, op == READ ? O_RDONLY : O_RDWR);
	if (f < 0)
		err(4, "%s", specname);

	switch(op) {

	case UNSPEC:
		break;

	case EDIT:
		if (argc != 1)
			usage();
		lp = readlabel(f);
		error = edit(lp, f);
		break;

	case NOWRITE:
		flag = 0;
		if (ioctl(f, DIOCWLABEL, (char *)&flag) < 0)
			err(4, "ioctl DIOCWLABEL");
		break;

	case READ:
		if (argc != 1)
			usage();
		lp = readlabel(f);
		display(stdout, lp);
		error = checklabel(lp);
		if (checkoldboot(f, NULL))
			warnx("Warning, old bootblocks detected, install new bootblocks & reinstall the disklabel");
		break;

	case RESTORE:
#if NUMBOOT > 0
		if (installboot && argc == 3) {
			makelabel(argv[2], 0, &lab);
			argc--;

			/*
			 * We only called makelabel() for its side effect
			 * of setting the bootstrap file names.  Discard
			 * all changes to `lab' so that all values in the
			 * final label come from the ASCII label.
			 */
			bzero((char *)&lab, sizeof(lab));
		}
#endif
		if (argc != 2)
			usage();
		if (!(t = fopen(argv[1], "r")))
			err(4, "%s", argv[1]);
		if (!getasciilabel(t, &lab))
			exit(1);
		lp = makebootarea(bootarea, &lab, f);
		*lp = lab;
		error = writelabel(f, bootarea, lp);
		break;

	case WRITE:
		if (argc == 3) {
			name = argv[2];
			argc--;
		}
		if (argc != 2)
			usage();
		makelabel(argv[1], name, &lab);
		lp = makebootarea(bootarea, &lab, f);
		*lp = lab;
		if (checklabel(lp) == 0)
			error = writelabel(f, bootarea, lp);
		break;

	case WRITEABLE:
		flag = 1;
		if (ioctl(f, DIOCWLABEL, (char *)&flag) < 0)
			err(4, "ioctl DIOCWLABEL");
		break;

#if NUMBOOT > 0
	case WRITEBOOT:
	{
		struct disklabel32 tlab;

		lp = readlabel(f);
		tlab = *lp;
		if (argc == 2)
			makelabel(argv[1], 0, &lab);
		lp = makebootarea(bootarea, &lab, f);
		*lp = tlab;
		if (checklabel(lp) == 0)
			error = writelabel(f, bootarea, lp);
		break;
	}
#endif
	}
	exit(error);
}
Beispiel #10
0
int
main(int argc, char *argv[])
{
	int ch, f, error = 0;
	FILE *t;
	char *autotable = NULL;

	getphysmem();

	while ((ch = getopt(argc, argv, "AEf:F:hRcdenp:tT:vw")) != -1)
		switch (ch) {
		case 'A':
			aflag = 1;
			break;
		case 'R':
			if (op != UNSPEC)
				usage();
			op = RESTORE;
			break;
		case 'c':
			cflag = 1;
			break;
		case 'd':
			dflag = 1;
			break;
		case 'e':
			if (op != UNSPEC)
				usage();
			op = EDIT;
			break;
		case 'E':
			if (op != UNSPEC)
				usage();
			op = EDITOR;
			break;
		case 'f':
			fstabfile = optarg;
			uidflag = 0;
			break;
		case 'F':
			fstabfile = optarg;
			uidflag = 1;
			break;
		case 'h':
			print_unit = '*';
			break;
		case 't':
			tflag = 1;
			break;
		case 'T':
			autotable = optarg;
			break;
		case 'w':
			if (op != UNSPEC)
				usage();
			op = WRITE;
			break;
		case 'p':
			if (strchr("bckmgtBCKMGT", optarg[0]) == NULL ||
			    optarg[1] != '\0') {
				fprintf(stderr, "Valid units are bckmgt\n");
				return 1;
			}
			print_unit = tolower((unsigned char)optarg[0]);
			break;
		case 'n':
			donothing = 1;
			break;
		case 'v':
			verbose = 1;
			break;
		case '?':
		default:
			usage();
	}
	argc -= optind;
	argv += optind;

	if (op == UNSPEC)
		op = READ;

	if (argc < 1 || (fstabfile && !(op == EDITOR || op == RESTORE ||
		    aflag)))
		usage();

	if (argv[0] == NULL)
		usage();
	dkname = argv[0];
	f = opendev(dkname, (op == READ ? O_RDONLY : O_RDWR), OPENDEV_PART,
	    &specname);
	if (f < 0)
		err(4, "%s", specname);

	if (op != WRITE || aflag || dflag) {
		readlabel(f);

		if (op == EDIT || op == EDITOR || aflag) {
			if (pledge("stdio rpath wpath cpath disklabel proc "
			    "exec", NULL) == -1)
				err(1, "pledge");
		} else if (fstabfile) {
			if (pledge("stdio rpath wpath cpath disklabel", NULL)
			    == -1)
				err(1, "pledge");
		} else {
			if (pledge("stdio rpath wpath disklabel", NULL) == -1)
				err(1, "pledge");
		}

		if (autotable != NULL)
			parse_autotable(autotable);
		parselabel();
	} else if (argc == 2 || argc == 3) {
		/* Ensure f is a disk device before pledging. */
		if (ioctl(f, DIOCGDINFO, &lab) < 0)
			err(4, "ioctl DIOCGDINFO");

		if (pledge("stdio rpath wpath disklabel", NULL) == -1)
			err(1, "pledge");

		makelabel(argv[1], argc == 3 ? argv[2] : NULL, &lab);
	} else
		usage();

	switch (op) {
	case EDIT:
		if (argc != 1)
			usage();
		error = edit(&lab, f);
		break;
	case EDITOR:
		if (argc != 1)
			usage();
		error = editor(f);
		break;
	case READ:
		if (argc != 1)
			usage();

		if (pledge("stdio", NULL) == -1)
			err(1, "pledge");

		if (tflag)
			makedisktab(stdout, &lab);
		else
			display(stdout, &lab, print_unit, 1);
		error = checklabel(&lab);
		break;
	case RESTORE:
		if (argc < 2 || argc > 3)
			usage();
		if (!(t = fopen(argv[1], "r")))
			err(4, "%s", argv[1]);
		error = getasciilabel(t, &lab);
		memset(&lab.d_uid, 0, sizeof(lab.d_uid));
		if (error == 0) {
			error = writelabel(f, &lab);
			if (error == 0) {
				if (ioctl(f, DIOCGDINFO, &lab) < 0)
					err(4, "ioctl DIOCGDINFO");
				mpsave(&lab);
			}
		}
		fclose(t);
		break;
	case WRITE:
		error = checklabel(&lab);
		if (error == 0)
			error = writelabel(f, &lab);
		break;
	default:
		break;
	}
	return error;
}