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

📄 db_load.c

📁 linux 下的源代码分析阅读器 red hat公司新版
💻 C
📖 第 1 页 / 共 2 页
字号:
		case '1':						\			if ((ret = dbp->set_flags(dbp, flag)) != 0) {	\				dbp->err(dbp, ret, "%s: set_flags: %s",	\				    G(progname), name);			\				goto err;				\			}						\			break;						\		case '0':						\			break;						\		default:						\			db_load_badnum(dbenv);					\			goto err;					\		}							\		continue;						\	}#define	NUMBER(name, value, keyword, func, t)				\	if (strcmp(name, keyword) == 0) {				\		if ((ret = __db_getlong(dbenv,				\		    NULL, value, 0, LONG_MAX, &val)) != 0 ||		\		    (ret = dbp->func(dbp, (t)val)) != 0)		\			goto nameerr;					\		continue;						\	}#define	STRING(name, value, keyword, func)				\	if (strcmp(name, keyword) == 0) {				\		if ((ret = dbp->func(dbp, value[0])) != 0)		\			goto nameerr;					\		continue;						\	}/* * The code to check a command-line or input header argument against a list * of configuration options.  It's #defined because it's used in two places * and the two places have gotten out of sync more than once. */#define	CONFIGURATION_LIST_COMPARE					\	NUMBER(name, value, "bt_minkey", set_bt_minkey, u_int32_t);	\	  FLAG(name, value, "chksum", DB_CHKSUM);			\	NUMBER(name, value, "db_lorder", set_lorder, int);		\	NUMBER(name, value, "db_pagesize", set_pagesize, u_int32_t);	\	  FLAG(name, value, "duplicates", DB_DUP);			\	  FLAG(name, value, "dupsort", DB_DUPSORT);			\	NUMBER(name, value, "extentsize", set_q_extentsize, u_int32_t);	\	NUMBER(name, value, "h_ffactor", set_h_ffactor, u_int32_t);	\	NUMBER(name, value, "h_nelem", set_h_nelem, u_int32_t);		\	NUMBER(name, value, "re_len", set_re_len, u_int32_t);		\	STRING(name, value, "re_pad", set_re_pad);			\	  FLAG(name, value, "recnum", DB_RECNUM);			\	  FLAG(name, value, "renumber", DB_RENUMBER)/* * configure -- *	Handle command-line configuration options. */intdb_load_configure(dbenv, dbp, clp, subdbp, keysp)	DB_ENV *dbenv;	DB *dbp;	char **clp, **subdbp;	int *keysp;{	long val;	int ret, savech;	char *name, *value;	for (; (name = *clp) != NULL; *--value = savech, ++clp) {		if ((value = strchr(name, '=')) == NULL) {			dbp->errx(dbp,		    "command-line configuration uses name=value format");			return (1);		}		savech = *value;		*value++ = '\0';		if (strcmp(name, "database") == 0 ||		    strcmp(name, "subdatabase") == 0) {			if (*subdbp != NULL)				free(*subdbp);			if ((*subdbp = strdup(value)) == NULL) {				dbp->err(dbp, ENOMEM, NULL);				return (1);			}			continue;		}		if (strcmp(name, "keys") == 0) {			if (strcmp(value, "1") == 0)				*keysp = 1;			else if (strcmp(value, "0") == 0)				*keysp = 0;			else {				db_load_badnum(dbenv);				return (1);			}			continue;		}		CONFIGURATION_LIST_COMPARE;		dbp->errx(dbp,		    "unknown command-line configuration keyword \"%s\"", name);		return (1);	}	return (0);nameerr:	dbp->err(dbp, ret, "%s: %s=%s", G(progname), name, value);err:	return (1);}/* * rheader -- *	Read the header message. */intdb_load_rheader(dbenv, dbp, dbtypep, subdbp, checkprintp, keysp)	DB_ENV *dbenv;	DB *dbp;	DBTYPE *dbtypep;	char **subdbp;	int *checkprintp, *keysp;{	size_t buflen, linelen, start;	long val;	int ch, first, hdr, ret;	char *buf, *name, *p, *value;	*dbtypep = DB_UNKNOWN;	*checkprintp = 0;	name = NULL;	/*	 * We start with a smallish buffer;  most headers are small.	 * We may need to realloc it for a large subdatabase name.	 */	buflen = 4096;	if (G(hdrbuf) == NULL) {		hdr = 0;		if ((buf = malloc(buflen)) == NULL)			goto memerr;		G(hdrbuf) = buf;		G(origline) = G(lineno);	} else {		hdr = 1;		buf = G(hdrbuf);		G(lineno) = G(origline);	}	start = 0;	for (first = 1;; first = 0) {		++G(lineno);		/* Read a line, which may be of arbitrary length, into buf. */		linelen = 0;		buf = &G(hdrbuf)[start];		if (hdr == 0) {			for (;;) {				if ((ch = getchar()) == EOF) {					if (!first || ferror(stdin))						goto badfmt;					G(endofile) = 1;					break;				}				/*				 * If the buffer is too small, double it.				 */				if (linelen + start == buflen) {					G(hdrbuf) =					    realloc(G(hdrbuf), buflen *= 2);					if (G(hdrbuf) == NULL)						goto memerr;					buf = &G(hdrbuf)[start];				}				if (ch == '\n')					break;				buf[linelen++] = ch;			}			if (G(endofile) == 1)				break;			buf[linelen++] = '\0';		} else			linelen = strlen(buf) + 1;		start += linelen;		if (name != NULL) {			free(name);			name = NULL;		}		/* If we don't see the expected information, it's an error. */		if ((name = strdup(buf)) == NULL)			goto memerr;		if ((p = strchr(name, '=')) == NULL)			goto badfmt;		*p++ = '\0';		value = p--;		if (name[0] == '\0')			goto badfmt;		/*		 * The only values that may be zero-length are database names.		 * In the original Berkeley DB code it was possible to create		 * zero-length database names, and the db_load code was then		 * changed to allow such databases to be be dumped and loaded.		 * [#8204]		 */		if (strcmp(name, "database") == 0 ||		    strcmp(name, "subdatabase") == 0) {			if ((ret = db_load_convprintable(dbenv, value, subdbp)) != 0) {				dbp->err(dbp, ret, "error reading db name");				goto err;			}			continue;		}		/* No other values may be zero-length. */		if (value[0] == '\0')			goto badfmt;		if (strcmp(name, "HEADER") == 0)			break;		if (strcmp(name, "VERSION") == 0) {			/*			 * Version 1 didn't have a "VERSION" header line.  We			 * only support versions 1, 2, and 3 of the dump format.			 */			G(version) = atoi(value);			if (G(version) > 3) {				dbp->errx(dbp,				    "line %lu: VERSION %d is unsupported",				    G(lineno), G(version));				goto err;			}			continue;		}		if (strcmp(name, "format") == 0) {			if (strcmp(value, "bytevalue") == 0) {				*checkprintp = 0;				continue;			}			if (strcmp(value, "print") == 0) {				*checkprintp = 1;				continue;			}			goto badfmt;		}		if (strcmp(name, "type") == 0) {			if (strcmp(value, "btree") == 0) {				*dbtypep = DB_BTREE;				continue;			}			if (strcmp(value, "hash") == 0) {				*dbtypep = DB_HASH;				continue;			}			if (strcmp(value, "recno") == 0) {				*dbtypep = DB_RECNO;				continue;			}			if (strcmp(value, "queue") == 0) {				*dbtypep = DB_QUEUE;				continue;			}			dbp->errx(dbp, "line %lu: unknown type", G(lineno));			goto err;		}		if (strcmp(name, "keys") == 0) {			if (strcmp(value, "1") == 0)				*keysp = 1;			else if (strcmp(value, "0") == 0)				*keysp = 0;			else {				db_load_badnum(dbenv);				goto err;			}			continue;		}		CONFIGURATION_LIST_COMPARE;		dbp->errx(dbp,		    "unknown input-file header configuration keyword \"%s\"",		    name);		goto err;	}	ret = 0;	if (0) {nameerr:	dbp->err(dbp, ret, "%s: %s=%s", G(progname), name, value);		ret = 1;	}	if (0) {badfmt:		dbp->errx(dbp, "line %lu: unexpected format", G(lineno));		ret = 1;	}	if (0) {memerr:		dbp->errx(dbp, "unable to allocate memory");err:		ret = 1;	}	if (name != NULL)		free(name);	return (ret);}/* * Macro to convert a pair of hex bytes to a decimal value. * * !!! * Note that this macro is side-effect safe.  This was done deliberately, * callers depend on it. */#define	DIGITIZE(store, v1, v2) {					\	char _v1, _v2;							\	_v1 = (v1);							\	_v2 = (v2);							\	if ((_v1) > 'f' || (_v2) > 'f')					\		return (db_load_badend(dbenv));					\	(store) =							\	((_v1) == '0' ? 0 :						\	((_v1) == '1' ? 1 :						\	((_v1) == '2' ? 2 :						\	((_v1) == '3' ? 3 :						\	((_v1) == '4' ? 4 :						\	((_v1) == '5' ? 5 :						\	((_v1) == '6' ? 6 :						\	((_v1) == '7' ? 7 :						\	((_v1) == '8' ? 8 :						\	((_v1) == '9' ? 9 :						\	((_v1) == 'a' ? 10 :						\	((_v1) == 'b' ? 11 :						\	((_v1) == 'c' ? 12 :						\	((_v1) == 'd' ? 13 :						\	((_v1) == 'e' ? 14 : 15))))))))))))))) << 4 |			\	((_v2) == '0' ? 0 :						\	((_v2) == '1' ? 1 :						\	((_v2) == '2' ? 2 :						\	((_v2) == '3' ? 3 :						\	((_v2) == '4' ? 4 :						\	((_v2) == '5' ? 5 :						\	((_v2) == '6' ? 6 :						\	((_v2) == '7' ? 7 :						\	((_v2) == '8' ? 8 :						\	((_v2) == '9' ? 9 :						\	((_v2) == 'a' ? 10 :						\	((_v2) == 'b' ? 11 :						\	((_v2) == 'c' ? 12 :						\	((_v2) == 'd' ? 13 :						\	((_v2) == 'e' ? 14 : 15)))))))))))))));				\}/* * convprintable -- *	Convert a printable-encoded string into a newly allocated string. * * In an ideal world, this would probably share code with dbt_rprint, but * that's set up to read character-by-character (to avoid large memory * allocations that aren't likely to be a problem here), and this has fewer * special cases to deal with. * * Note that despite the printable encoding, the char * interface to this * function (which is, not coincidentally, also used for database naming) * means that outstr cannot contain any nuls. */intdb_load_convprintable(dbenv, instr, outstrp)	DB_ENV *dbenv;	char *instr, **outstrp;{	char *outstr;	/*	 * Just malloc a string big enough for the whole input string;	 * the output string will be smaller (or of equal length).	 *	 * Note that we may be passed a zero-length string and need to	 * be able to duplicate it.	 */	if ((outstr = malloc(strlen(instr) + 1)) == NULL)		return (ENOMEM);	*outstrp = outstr;	for ( ; *instr != '\0'; instr++)		if (*instr == '\\') {			if (*++instr == '\\') {				*outstr++ = '\\';				continue;			}			DIGITIZE(*outstr++, *instr, *++instr);		} else			*outstr++ = *instr;	*outstr = '\0';	return (0);}/* * dbt_rprint -- *	Read a printable line into a DBT structure. */intdb_load_dbt_rprint(dbenv, dbtp)	DB_ENV *dbenv;	DBT *dbtp;{	u_int32_t len;	u_int8_t *p;	int c1, c2, escape, first;	char buf[32];	++G(lineno);	first = 1;	escape = 0;	for (p = dbtp->data, len = 0; (c1 = getchar()) != '\n';) {		if (c1 == EOF) {			if (len == 0) {				G(endofile) = G(endodata) = 1;				return (0);			}			return (db_load_badend(dbenv));		}		if (first) {			first = 0;			if (G(version) > 1) {				if (c1 != ' ') {					buf[0] = c1;					if (fgets(buf + 1,					    sizeof(buf) - 1, stdin) == NULL ||					    strcmp(buf, "DATA=END\n") != 0)						return (db_load_badend(dbenv));					G(endodata) = 1;					return (0);				}				continue;			}		}		if (escape) {			if (c1 != '\\') {				if ((c2 = getchar()) == EOF)					return (db_load_badend(dbenv));				DIGITIZE(c1, c1, c2);			}			escape = 0;		} else			if (c1 == '\\') {				escape = 1;				continue;			}		if (len >= dbtp->ulen - 10) {			dbtp->ulen *= 2;			if ((dbtp->data =			    realloc(dbtp->data, dbtp->ulen)) == NULL) {				dbenv->err(dbenv, ENOMEM, NULL);				return (1);			}			p = (u_int8_t *)dbtp->data + len;		}		++len;		*p++ = c1;	}	dbtp->size = len;	return (0);}/* * dbt_rdump -- *	Read a byte dump line into a DBT structure. */intdb_load_dbt_rdump(dbenv, dbtp)	DB_ENV *dbenv;	DBT *dbtp;{	u_int32_t len;	u_int8_t *p;	int c1, c2, first;	char buf[32];	++G(lineno);	first = 1;	for (p = dbtp->data, len = 0; (c1 = getchar()) != '\n';) {		if (c1 == EOF) {			if (len == 0) {				G(endofile) = G(endodata) = 1;				return (0);			}			return (db_load_badend(dbenv));		}		if (first) {			first = 0;			if (G(version) > 1) {				if (c1 != ' ') {					buf[0] = c1;					if (fgets(buf + 1,					    sizeof(buf) - 1, stdin) == NULL ||					    strcmp(buf, "DATA=END\n") != 0)						return (db_load_badend(dbenv));					G(endodata) = 1;					return (0);				}				continue;			}		}		if ((c2 = getchar()) == EOF)			return (db_load_badend(dbenv));		if (len >= dbtp->ulen - 10) {			dbtp->ulen *= 2;			if ((dbtp->data =			    realloc(dbtp->data, dbtp->ulen)) == NULL) {				dbenv->err(dbenv, ENOMEM, NULL);				return (1);			}			p = (u_int8_t *)dbtp->data + len;		}		++len;		DIGITIZE(*p++, c1, c2);	}	dbtp->size = len;	return (0);}/* * dbt_rrecno -- *	Read a record number dump line into a DBT structure. */intdb_load_dbt_rrecno(dbenv, dbtp, ishex)	DB_ENV *dbenv;	DBT *dbtp;	int ishex;{	char buf[32], *p, *q;	u_long recno;	++G(lineno);	if (fgets(buf, sizeof(buf), stdin) == NULL) {		G(endofile) = G(endodata) = 1;		return (0);	}	if (strcmp(buf, "DATA=END\n") == 0) {		G(endodata) = 1;		return (0);	}	if (buf[0] != ' ')		goto err;	/*	 * If we're expecting a hex key, do an in-place conversion	 * of hex to straight ASCII before calling __db_getulong().	 */	if (ishex) {		for (p = q = buf + 1; *q != '\0' && *q != '\n';) {			/*			 * 0-9 in hex are 0x30-0x39, so this is easy.			 * We should alternate between 3's and [0-9], and			 * if the [0-9] are something unexpected,			 * __db_getulong will fail, so we only need to catch			 * end-of-string conditions.			 */			if (*q++ != '3')				goto err;			if (*q == '\n' || *q == '\0')				goto err;			*p++ = *q++;		}		*p = '\0';	}	if (__db_getulong(dbenv, G(progname), buf + 1, 0, 0, &recno))		goto err;	*((db_recno_t *)dbtp->data) = recno;	dbtp->size = sizeof(db_recno_t);	return (0);err:	return (db_load_badend(dbenv));}intdb_load_dbt_to_recno(dbenv, dbt, recnop)	DB_ENV *dbenv;	DBT *dbt;	db_recno_t *recnop;{	char buf[32];				/* Large enough for 2^64. */	memcpy(buf, dbt->data, dbt->size);	buf[dbt->size] = '\0';	return (__db_getulong(dbenv, G(progname), buf, 0, 0, (u_long *)recnop));}/* * badnum -- *	Display the bad number message. */voiddb_load_badnum(dbenv)	DB_ENV *dbenv;{	dbenv->errx(dbenv,	    "boolean name=value pairs require a value of 0 or 1");}/* * badend -- *	Display the bad end to input message. */intdb_load_badend(dbenv)	DB_ENV *dbenv;{	dbenv->errx(dbenv, "unexpected end of input data or key/data pair");	return (1);}/* * usage -- *	Display the usage message. */intdb_load_usage(){	(void)fprintf(stderr, "usage: %s %s\n\t%s\n", progname,	    "[-nTV] [-c name=value] [-f file]",    "[-h home] [-P password] [-t btree | hash | recno | queue] db_file");	(void)fprintf(stderr, "usage: %s %s\n",	    progname, "-r lsn | fileid [-h home] [-P password] db_file");	return (EXIT_FAILURE);}intdb_load_version_check(){	int v_major, v_minor, v_patch;	/* Make sure we're loaded with the right version of the DB library. */	(void)db_version(&v_major, &v_minor, &v_patch);	if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) {		fprintf(stderr,	"%s: version %d.%d doesn't match library version %d.%d\n",		    progname, DB_VERSION_MAJOR, DB_VERSION_MINOR,		    v_major, v_minor);		return (EXIT_FAILURE);	}	return (0);}

⌨️ 快捷键说明

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