Пример #1
0
int get_user_reply(struct fdisk_context *cxt, const char *prompt,
			  char *buf, size_t bufsz)
{
	char *p;
	size_t sz;

	do {
#ifdef HAVE_LIBREADLINE
		if (isatty(STDIN_FILENO)) {
			if (!rl_fgets(buf, bufsz, stdout, prompt)) {
				if (fdisk_label_is_changed(fdisk_get_label(cxt, NULL))) {
					if (rl_fgets(buf, bufsz, stderr,
							_("\nDo you really want to quit? "))
							&& !rpmatch(buf))
						continue;
				}
				fdisk_unref_context(cxt);
				exit(EXIT_FAILURE);
			} else
				break;
		}
		else
#endif
		{
			fputs(prompt, stdout);
			fflush(stdout);
			if (!fgets(buf, bufsz, stdin)) {
				if (fdisk_label_is_changed(fdisk_get_label(cxt, NULL))) {
					fprintf(stderr, _("\nDo you really want to quit? "));

					if (fgets(buf, bufsz, stdin) && !rpmatch(buf))
						continue;
				}
				fdisk_unref_context(cxt);
				exit(EXIT_FAILURE);
			} else
				break;
		}
	} while (1);

	for (p = buf; *p && !isgraph(*p); p++);	/* get first non-blank */

	if (p > buf)
		memmove(buf, p, p - buf);		/* remove blank space */
	sz = strlen(buf);
	if (sz && *(buf + sz - 1) == '\n')
		*(buf + sz - 1) = '\0';

	DBG(ASK, ul_debug("user's reply: >>>%s<<<", buf));
	return 0;
}
Пример #2
0
/**
 * fdisk_unref_context:
 * @cxt: fdisk context
 *
 * Deallocates context struct.
 */
void fdisk_unref_context(struct fdisk_context *cxt)
{
	int i;

	if (!cxt)
		return;

	cxt->refcount--;
	if (cxt->refcount <= 0) {
		DBG(CXT, ul_debugobj(cxt, "freeing context %p for %s", cxt, cxt->dev_path));

		reset_context(cxt);	/* this is sensitive to parent<->child relationship! */

		/* deallocate label's private stuff */
		for (i = 0; i < cxt->nlabels; i++) {
			if (!cxt->labels[i])
				continue;
			if (cxt->labels[i]->op->free)
				cxt->labels[i]->op->free(cxt->labels[i]);
			else
				free(cxt->labels[i]);
		}

		fdisk_unref_context(cxt->parent);
		cxt->parent = NULL;

		free(cxt);
	}
}
Пример #3
0
static int sfdisk_deinit(struct sfdisk *sf)
{
	struct fdisk_context *parent;

	assert(sf);
	assert(sf->cxt);

	parent = fdisk_get_parent(sf->cxt);
	if (parent) {
		fdisk_unref_context(sf->cxt);
		sf->cxt = parent;
	}

	fdisk_unref_context(sf->cxt);
	memset(sf, 0, sizeof(*sf));

	return 0;
}
Пример #4
0
/**
 * fdisk_new_nested_context:
 * @parent: parental context
 * @name: optional label name (e.g. "bsd")
 *
 * Create a new nested fdisk context for nested disk labels (e.g. BSD or PMBR).
 * The function also probes for the nested label on the device if device is
 * already assigned to parent.
 *
 * The new context is initialized according to @parent and both context shares
 * some settings and file descriptor to the device. The child propagate some
 * changes (like fdisk_assign_device()) to parent, but it does not work
 * vice-versa. The behavior is undefined if you assign another device to
 * parent.
 *
 * Returns: new context for nested partition table.
 */
struct fdisk_context *fdisk_new_nested_context(struct fdisk_context *parent,
				const char *name)
{
	struct fdisk_context *cxt;
	struct fdisk_label *lb = NULL;

	assert(parent);

	cxt = calloc(1, sizeof(*cxt));
	if (!cxt)
		return NULL;

	DBG(CXT, ul_debugobj(parent, "alloc nested [%p] [name=%s]", cxt, name));
	cxt->refcount = 1;

	fdisk_ref_context(parent);
	cxt->parent = parent;

	if (init_nested_from_parent(cxt, 1) != 0) {
		cxt->parent = NULL;
		fdisk_unref_context(cxt);
		return NULL;
	}

	if (name) {
		if (strcasecmp(name, "bsd") == 0)
			lb = cxt->labels[ cxt->nlabels++ ] = fdisk_new_bsd_label(cxt);
		else if (strcasecmp(name, "dos") == 0 || strcasecmp(name, "mbr") == 0)
			lb = cxt->labels[ cxt->nlabels++ ] = fdisk_new_dos_label(cxt);
	}

	if (lb && parent->dev_fd >= 0) {
		DBG(CXT, ul_debugobj(cxt, "probing for nested %s", lb->name));

		cxt->label = lb;

		if (lb->op->probe(cxt) == 1)
			__fdisk_switch_label(cxt, lb);
		else {
			DBG(CXT, ul_debugobj(cxt, "not found %s label", lb->name));
			if (lb->op->deinit)
				lb->op->deinit(lb);
			cxt->label = NULL;
		}
	}

	return cxt;
}
Пример #5
0
static int test_listitems(struct fdisk_test *ts, int argc, char *argv[])
{
	const char *disk = argv[1];
	struct fdisk_context *cxt;
	struct fdisk_labelitem *item;
	int i = 0, rc;

	cxt = fdisk_new_context();
	item = fdisk_new_labelitem();

	fdisk_assign_device(cxt, disk, 1);

	do {
		rc = fdisk_get_disklabel_item(cxt, i++, item);
		switch (rc) {
		case 0:	/* success */
		{
			const char *name = fdisk_labelitem_get_name(item);
			const char *str;
			uint64_t num;

			if (fdisk_labelitem_is_string(item)
			    && fdisk_labelitem_get_data_string(item, &str) == 0)
				printf("%s: %s\n", name, str);
			else if (fdisk_labelitem_get_data_u64(item, &num) == 0)
				printf("%s: %ju\n", name, num);
			break;
		}
		case 1: /* item unsuported by label -- ignore */
			rc = 0;
			break;
		case 2:	/* end (out of range) */
			break;
		default: /* error */
			break;
		}
	} while (rc == 0);

	fdisk_unref_labelitem(item);
	fdisk_unref_context(cxt);
	return rc < 0 ? rc : 0;
}
Пример #6
0
/* usable for example in usage() */
void list_available_columns(FILE *out)
{
	size_t i;
	int termwidth;
	struct fdisk_label *lb = NULL;
	struct fdisk_context *cxt = fdisk_new_context();

	if (!cxt)
		return;

	termwidth = get_terminal_width();
	if (termwidth <= 0)
		termwidth = 80;

	fprintf(out, _("\nAvailable columns (for -o):\n"));

	while (fdisk_next_label(cxt, &lb) == 0) {
		size_t width = 6;	/* label name and separators */

		fprintf(out, " %s:", fdisk_label_get_name(lb));
		for (i = 1; i < FDISK_NFIELDS; i++) {
			const struct fdisk_field *fl = fdisk_label_get_field(lb, i);
			const char *name = fl ? fdisk_field_get_name(fl) : NULL;
			size_t len;

			if (!name)
				continue;
			len = strlen(name) + 1;
			if (width + len > (size_t) termwidth) {
				fputs("\n     ", out);
				width = 6;
			}
			fprintf(out, " %s", name);
			width += len;
		}
		fputc('\n', out);
	}

	fdisk_unref_context(cxt);
}