⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 libdm-report.c

📁 Linux Device Mapper Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved. * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. * * This file is part of the device-mapper userspace tools. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU Lesser General Public License v.2.1. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include "libdevmapper.h"#include "list.h"#include "log.h"/* * Internal flags */#define RH_SORT_REQUIRED	0x00000100#define RH_HEADINGS_PRINTED	0x00000200struct dm_report {	struct dm_pool *mem;	uint32_t report_types;	const char *field_prefix;	uint32_t flags;	const char *separator;	uint32_t keys_count;	/* Ordered list of fields needed for this report */	struct list field_props;	/* Rows of report data */	struct list rows;	/* Array of field definitions */	const struct dm_report_field_type *fields;	const struct dm_report_object_type *types;	/* To store caller private data */	void *private;};/* * Internal per-field flags */#define FLD_HIDDEN	0x00000100#define FLD_SORT_KEY	0x00000200#define FLD_ASCENDING	0x00000400#define FLD_DESCENDING	0x00000800struct field_properties {	struct list list;	uint32_t field_num;	uint32_t sort_posn;	int32_t width;	const struct dm_report_object_type *type;	uint32_t flags;};/* * Report data field */struct dm_report_field {	struct list list;	struct field_properties *props;	const char *report_string;	/* Formatted ready for display */	const void *sort_value;		/* Raw value for sorting */};struct row {	struct list list;	struct dm_report *rh;	struct list fields;			  /* Fields in display order */	struct dm_report_field *(*sort_fields)[]; /* Fields in sort order */};static const struct dm_report_object_type *_find_type(struct dm_report *rh,						      uint32_t report_type){	const struct dm_report_object_type *t;	for (t = rh->types; t->data_fn; t++)		if (t->id == report_type)			return t;	return NULL;}/* * Data-munging functions to prepare each data type for display and sorting */int dm_report_field_string(struct dm_report *rh,			   struct dm_report_field *field, const char **data){	char *repstr;	if (!(repstr = dm_pool_strdup(rh->mem, *data))) {		log_error("dm_report_field_string: dm_pool_strdup failed");		return 0;	}	field->report_string = repstr;	field->sort_value = (const void *) field->report_string;	return 1;}int dm_report_field_int(struct dm_report *rh,			struct dm_report_field *field, const int *data){	const int value = *data;	uint64_t *sortval;	char *repstr;	if (!(repstr = dm_pool_zalloc(rh->mem, 13))) {		log_error("dm_report_field_int: dm_pool_alloc failed");		return 0;	}	if (!(sortval = dm_pool_alloc(rh->mem, sizeof(int64_t)))) {		log_error("dm_report_field_int: dm_pool_alloc failed");		return 0;	}	if (dm_snprintf(repstr, 12, "%d", value) < 0) {		log_error("dm_report_field_int: int too big: %d", value);		return 0;	}	*sortval = (const uint64_t) value;	field->sort_value = sortval;	field->report_string = repstr;	return 1;}int dm_report_field_uint32(struct dm_report *rh,			   struct dm_report_field *field, const uint32_t *data){	const uint32_t value = *data;	uint64_t *sortval;	char *repstr;	if (!(repstr = dm_pool_zalloc(rh->mem, 12))) {		log_error("dm_report_field_uint32: dm_pool_alloc failed");		return 0;	}	if (!(sortval = dm_pool_alloc(rh->mem, sizeof(uint64_t)))) {		log_error("dm_report_field_uint32: dm_pool_alloc failed");		return 0;	}	if (dm_snprintf(repstr, 11, "%u", value) < 0) {		log_error("dm_report_field_uint32: uint32 too big: %u", value);		return 0;	}	*sortval = (const uint64_t) value;	field->sort_value = sortval;	field->report_string = repstr;	return 1;}int dm_report_field_int32(struct dm_report *rh,			  struct dm_report_field *field, const int32_t *data){	const int32_t value = *data;	uint64_t *sortval;	char *repstr;	if (!(repstr = dm_pool_zalloc(rh->mem, 13))) {		log_error("dm_report_field_int32: dm_pool_alloc failed");		return 0;	}	if (!(sortval = dm_pool_alloc(rh->mem, sizeof(int64_t)))) {		log_error("dm_report_field_int32: dm_pool_alloc failed");		return 0;	}	if (dm_snprintf(repstr, 12, "%d", value) < 0) {		log_error("dm_report_field_int32: int32 too big: %d", value);		return 0;	}	*sortval = (const uint64_t) value;	field->sort_value = sortval;	field->report_string = repstr;	return 1;}int dm_report_field_uint64(struct dm_report *rh,			   struct dm_report_field *field, const uint64_t *data){	const int value = *data;	uint64_t *sortval;	char *repstr;	if (!(repstr = dm_pool_zalloc(rh->mem, 22))) {		log_error("dm_report_field_uint64: dm_pool_alloc failed");		return 0;	}	if (!(sortval = dm_pool_alloc(rh->mem, sizeof(uint64_t)))) {		log_error("dm_report_field_uint64: dm_pool_alloc failed");		return 0;	}	if (dm_snprintf(repstr, 21, "%d", value) < 0) {		log_error("dm_report_field_uint64: uint64 too big: %d", value);		return 0;	}	*sortval = (const uint64_t) value;	field->sort_value = sortval;	field->report_string = repstr;	return 1;}/* * Helper functions for custom report functions */void dm_report_field_set_value(struct dm_report_field *field, const void *value, const void *sortvalue){	field->report_string = (const char *) value;	field->sort_value = sortvalue ? : value;}/* * show help message */static void _display_fields(struct dm_report *rh){	uint32_t f;	const struct dm_report_object_type *type;	const char *desc, *last_desc = "";	size_t id_len = 0;	for (f = 0; rh->fields[f].report_fn; f++)		if (strlen(rh->fields[f].id) > id_len)			id_len = strlen(rh->fields[f].id);	for (f = 0; rh->fields[f].report_fn; f++) {		if ((type = _find_type(rh, rh->fields[f].type)) && type->desc)			desc = type->desc;		else			desc = " ";		if (desc != last_desc) {			if (*last_desc)				log_print(" ");			log_print("%s Fields", desc);			log_print("%*.*s", (int) strlen(desc) + 7,				  (int) strlen(desc) + 7,				  "------------------------------------------");				  		}		/* FIXME Add line-wrapping at terminal width (or 80 cols) */		log_print("  %-*s - %s", (int) id_len, rh->fields[f].id, rh->fields[f].desc);		last_desc = desc;	}}/* * Initialise report handle */static int _copy_field(struct dm_report *rh, struct field_properties *dest,		       uint32_t field_num){	dest->field_num = field_num;	dest->width = rh->fields[field_num].width;	dest->flags = rh->fields[field_num].flags & DM_REPORT_FIELD_MASK;	/* set object type method */	dest->type = _find_type(rh, rh->fields[field_num].type);	if (!dest->type) {		log_error("dm_report: field not match: %s",			  rh->fields[field_num].id);		return 0;	}	return 1;}static struct field_properties * _add_field(struct dm_report *rh,					    uint32_t field_num, uint32_t flags){	struct field_properties *fp;	rh->report_types |= rh->fields[field_num].type;	if (!(fp = dm_pool_zalloc(rh->mem, sizeof(struct field_properties)))) {		log_error("dm_report: struct field_properties allocation "			  "failed");		return NULL;	}	if (!_copy_field(rh, fp, field_num)) {		stack;		dm_pool_free(rh->mem, fp);		return NULL;	}	fp->flags |= flags;	/*	 * Place hidden fields at the front so list_end() will	 * tell us when we've reached the last visible field.	 */	if (fp->flags & FLD_HIDDEN)		list_add_h(&rh->field_props, &fp->list);	else		list_add(&rh->field_props, &fp->list);	return fp;}/* * Compare name1 against name2 or prefix plus name2 * name2 is not necessarily null-terminated. * len2 is the length of name2. */static int _is_same_field(const char *name1, const char *name2,			  size_t len2, const char *prefix){	size_t prefix_len;	/* Exact match? */	if (!strncasecmp(name1, name2, len2) && strlen(name1) == len2)		return 1;	/* Match including prefix? */	prefix_len = strlen(prefix);	if (!strncasecmp(prefix, name1, prefix_len) &&	    !strncasecmp(name1 + prefix_len, name2, len2) &&	    strlen(name1) == prefix_len + len2)		return 1;	return 0;}static int _field_match(struct dm_report *rh, const char *field, size_t flen){	uint32_t f;	if (!flen)		return 0;	for (f = 0; rh->fields[f].report_fn; f++)		if (_is_same_field(rh->fields[f].id, field, flen,				   rh->field_prefix))			return _add_field(rh, f, 0) ? 1 : 0;	return 0;}static int _add_sort_key(struct dm_report *rh, uint32_t field_num,			 uint32_t flags){	struct field_properties *fp, *found = NULL;	list_iterate_items(fp, &rh->field_props) {		if (fp->field_num == field_num) {			found = fp;			break;		}	}	if (!found && !(found = _add_field(rh, field_num, FLD_HIDDEN)))		return_0;	if (found->flags & FLD_SORT_KEY) {		log_error("dm_report: Ignoring duplicate sort field: %s",			  rh->fields[field_num].id);		return 1;	}	found->flags |= FLD_SORT_KEY;	found->sort_posn = rh->keys_count++;	found->flags |= flags;	return 1;}static int _key_match(struct dm_report *rh, const char *key, size_t len){	uint32_t f;	uint32_t flags;	if (!len)		return 0;	if (*key == '+') {		key++;		len--;		flags = FLD_ASCENDING;	} else if (*key == '-') {		key++;		len--;		flags = FLD_DESCENDING;	} else		flags = FLD_ASCENDING;	if (!len) {		log_error("dm_report: Missing sort field name");		return 0;	}	for (f = 0; rh->fields[f].report_fn; f++)		if (_is_same_field(rh->fields[f].id, key, len,				   rh->field_prefix))			return _add_sort_key(rh, f, flags);	return 0;}static int _parse_options(struct dm_report *rh, const char *format){	const char *ws;		/* Word start */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -