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

📄 dbz.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
	} else		(void) fclose(f);	/* and let dbminit do the work */	return(dbminit(name));}/* - dbminit - open a database, creating it (using defaults) if necessary * * We try to leave errno set plausibly, to the extent that underlying * functions permit this, since many people consult it if dbminit() fails. */int 				/* 0 success, -1 failure */dbminit(name)char *name;{	register int i;	register size_t s;	register char *dirfname;	register char *pagfname;	if (pagf != NULL) {		DEBUG(("dbminit: dbminit already called once\n"));		errno = 0;		return(-1);	}	/* open the .dir file */	dirfname = enstring(name, dir);	if (dirfname == NULL)		return(-1);	dirf = fopen(dirfname, "r+");	if (dirf == NULL) {		dirf = fopen(dirfname, "r");		dirronly = 1;	} else		dirronly = 0;	free(dirfname);	if (dirf == NULL) {		DEBUG(("dbminit: can't open .dir file\n"));		return(-1);	}	/* open the .pag file */	pagfname = enstring(name, pag);	if (pagfname == NULL) {		(void) fclose(dirf);		return(-1);	}	pagf = fopen(pagfname, "r+b");	if (pagf == NULL) {		pagf = fopen(pagfname, "rb");		if (pagf == NULL) {			DEBUG(("dbminit: .pag open failed\n"));			(void) fclose(dirf);			free(pagfname);			return(-1);		}		pagronly = 1;	} else if (dirronly)		pagronly = 1;	else		pagronly = 0;#ifdef NOBUFFER	/*	 * B News does not do adequate locking on its database accesses.	 * Why it doesn't get into trouble using dbm is a mystery.  In any	 * case, doing unbuffered i/o does not cure the problem, but does	 * enormously reduce its incidence.	 */	(void) setbuf(pagf, (char *)NULL);#else#ifdef _IOFBF	(void) setvbuf(pagf, (char *)pagbuf, _IOFBF, sizeof(pagbuf));#endif#endif	pagpos = -1;	/* don't free pagfname, need it below */	/* open the base file */	basef = fopen(name, "r");	if (basef == NULL) {		DEBUG(("dbminit: basefile open failed\n"));		basefname = enstring(name, "");		if (basefname == NULL) {			(void) fclose(pagf);			(void) fclose(dirf);			free(pagfname);			pagf = NULL;			return(-1);		}	} else		basefname = NULL;#ifdef _IOFBF	if (basef != NULL)		(void) setvbuf(basef, basebuf, _IOFBF, sizeof(basebuf));#endif	/* pick up configuration */	if (getconf(dirf, pagf, &conf) < 0) {		DEBUG(("dbminit: getconf failure\n"));		(void) fclose(basef);		(void) fclose(pagf);		(void) fclose(dirf);		free(pagfname);		pagf = NULL;		errno = EDOM;	/* kind of a kludge, but very portable */		return(-1);	}	tagbits = conf.tagmask << conf.tagshift;	taghere = conf.tagenb << conf.tagshift;	tagboth = tagbits | taghere;	mybytemap(mybmap);	bytesame = 1;	for (i = 0; i < SOF; i++)		if (mybmap[i] != conf.bytemap[i])			bytesame = 0;	/* get first table into core, if it looks desirable and feasible */	s = (size_t)conf.tsize * SOF;	if (incore && (off_t)(s/SOF) == conf.tsize) {		bufpagf = fopen(pagfname, (pagronly) ? "rb" : "r+b");		if (bufpagf != NULL)			corepag = getcore(bufpagf);	} else {		bufpagf = NULL;		corepag = NULL;	}	free(pagfname);	/* misc. setup */	crcinit();	written = 0;	prevp = FRESH;	DEBUG(("dbminit: succeeded\n"));	return(0);}/* - enstring - concatenate two strings into a malloced area */static char *			/* NULL if malloc fails */enstring(s1, s2)char *s1;char *s2;{	register char *p;	p = malloc((size_t)strlen(s1) + (size_t)strlen(s2) + 1);	if (p != NULL) {		(void) strcpy(p, s1);		(void) strcat(p, s2);	} else {		DEBUG(("enstring(%s, %s) out of memory\n", s1, s2));	}	return(p);}/* - dbmclose - close a database */intdbmclose(){	register int ret = 0;	if (pagf == NULL) {		DEBUG(("dbmclose: not opened!\n"));		return(-1);	}	if (fclose(pagf) == EOF) {		DEBUG(("dbmclose: fclose(pagf) failed\n"));		ret = -1;	}	pagf = basef;		/* ensure valid pointer; dbzsync checks it */	if (dbzsync() < 0)		ret = -1;	if (bufpagf != NULL && fclose(bufpagf) == EOF) {		DEBUG(("dbmclose: fclose(bufpagf) failed\n"));		ret = -1;	}	if (corepag != NULL)		free((char *)corepag);	corepag = NULL;	if (fclose(basef) == EOF) {		DEBUG(("dbmclose: fclose(basef) failed\n"));		ret = -1;	}	if (basefname != NULL)		free(basefname);	basef = NULL;	pagf = NULL;	if (fclose(dirf) == EOF) {		DEBUG(("dbmclose: fclose(dirf) failed\n"));		ret = -1;	}	DEBUG(("dbmclose: %s\n", (ret == 0) ? "succeeded" : "failed"));	return(ret);}/* - dbzsync - push all in-core data out to disk */intdbzsync(){	register int ret = 0;	if (pagf == NULL) {		DEBUG(("dbzsync: not opened!\n"));		return(-1);	}	if (!written)		return(0);	if (corepag != NULL) {		if (putcore(corepag, bufpagf) < 0) {			DEBUG(("dbzsync: putcore failed\n"));			ret = -1;		}	}	if (!conf.olddbz)		if (putconf(dirf, &conf) < 0)			ret = -1;	DEBUG(("dbzsync: %s\n", (ret == 0) ? "succeeded" : "failed"));	return(ret);}/* - dbzcancel - cancel writing of in-core data * Mostly for use from child processes. * Note that we don't need to futz around with stdio buffers, because we * always fflush them immediately anyway and so they never have stale data. */intdbzcancel(){	if (pagf == NULL) {		DEBUG(("dbzcancel: not opened!\n"));		return(-1);	}	written = 0;	return(0);}/* - dbzfetch - fetch() with case mapping built in */datumdbzfetch(key)datum key;{	char buffer[DBZMAXKEY + 1];	datum mappedkey;	register size_t keysize;	DEBUG(("dbzfetch: (%s)\n", key.dptr));	/* Key is supposed to be less than DBZMAXKEY */	keysize = key.dsize;	if (keysize >= DBZMAXKEY) {		keysize = DBZMAXKEY;		DEBUG(("keysize is %d - truncated to %d\n", key.dsize, DBZMAXKEY));	}	mappedkey.dptr = mapcase(buffer, key.dptr, keysize);	buffer[keysize] = '\0';	/* just a debug aid */	mappedkey.dsize = keysize;	return(fetch(mappedkey));}/* - fetch - get an entry from the database * * Disgusting fine point, in the name of backward compatibility:  if the * last character of "key" is a NUL, that character is (effectively) not * part of the comparison against the stored keys. */datum				/* dptr NULL, dsize 0 means failure */fetch(key)datum key;{	char buffer[DBZMAXKEY + 1];	static off_t key_ptr;		/* return value points here */	datum output;	register size_t keysize;	register size_t cmplen;	register char *sepp;	DEBUG(("fetch: (%s)\n", key.dptr));	output.dptr = NULL;	output.dsize = 0;	prevp = FRESH;	/* Key is supposed to be less than DBZMAXKEY */	keysize = key.dsize;	if (keysize >= DBZMAXKEY) {		keysize = DBZMAXKEY;		DEBUG(("keysize is %d - truncated to %d\n", key.dsize, DBZMAXKEY));	}	if (pagf == NULL) {		DEBUG(("fetch: database not open!\n"));		return(output);	} else if (basef == NULL) {	/* basef didn't exist yet */		basef = latebase();		if (basef == NULL)			return(output);	}	cmplen = keysize;	sepp = &conf.fieldsep;	if (key.dptr[keysize-1] == '\0') {		cmplen--;		sepp = &buffer[keysize-1];	}	start(&srch, &key, FRESH);	while ((key_ptr = search(&srch)) != NOTFOUND) {		DEBUG(("got 0x%lx\n", key_ptr));		/* fetch the key */		if (fseek(basef, key_ptr, SEEK_SET) != 0) {			DEBUG(("fetch: seek failed\n"));			return(output);		}		if (fread(buffer, 1, keysize, basef) != keysize) {			DEBUG(("fetch: read failed\n"));			return(output);		}		/* try it */		buffer[keysize] = '\0';		/* terminated for DEBUG */		(void) mapcase(buffer, buffer, keysize);		DEBUG(("fetch: buffer (%s) looking for (%s) size = %d\n", 						buffer, key.dptr, keysize));		if (memcmp(key.dptr, buffer, cmplen) == 0 &&				(*sepp == conf.fieldsep || *sepp == '\0')) {			/* we found it */			output.dptr = (char *)&key_ptr;			output.dsize = SOF;			DEBUG(("fetch: successful\n"));			return(output);		}	}	/* we didn't find it */	DEBUG(("fetch: failed\n"));	prevp = &srch;			/* remember where we stopped */	return(output);}/* - latebase - try to open a base file that wasn't there at the start */static FILE *latebase(){	register FILE *it;	if (basefname == NULL) {		DEBUG(("latebase: name foulup\n"));		return(NULL);	}	it = fopen(basefname, "r");	if (it == NULL) {		DEBUG(("latebase: still can't open base\n"));	} else {		DEBUG(("latebase: late open succeeded\n"));		free(basefname);		basefname = NULL;#ifdef _IOFBF		(void) setvbuf(it, basebuf, _IOFBF, sizeof(basebuf));#endif	}	return(it);}/* - dbzstore - store() with case mapping built in */intdbzstore(key, data)datum key;datum data;{	char buffer[DBZMAXKEY + 1];	datum mappedkey;	register size_t keysize;	DEBUG(("dbzstore: (%s)\n", key.dptr));	/* Key is supposed to be less than DBZMAXKEY */	keysize = key.dsize;	if (keysize >= DBZMAXKEY) {		DEBUG(("dbzstore: key size too big (%d)\n", key.dsize));		return(-1);	}	mappedkey.dptr = mapcase(buffer, key.dptr, keysize);	buffer[keysize] = '\0';	/* just a debug aid */	mappedkey.dsize = keysize;	return(store(mappedkey, data));}/* - store - add an entry to the database */int				/* 0 success, -1 failure */store(key, data)datum key;datum data;{	off_t value;	if (pagf == NULL) {		DEBUG(("store: database not open!\n"));		return(-1);	} else if (basef == NULL) {	/* basef didn't exist yet */		basef = latebase();		if (basef == NULL)			return(-1);	}	if (pagronly) {		DEBUG(("store: database open read-only\n"));		return(-1);	}	if (data.dsize != SOF) {		DEBUG(("store: value size wrong (%d)\n", data.dsize));		return(-1);	}	if (key.dsize >= DBZMAXKEY) {		DEBUG(("store: key size too big (%d)\n", key.dsize));		return(-1);	}	/* copy the value in to ensure alignment */	(void) memcpy((char *)&value, data.dptr, SOF);	DEBUG(("store: (%s, %ld)\n", key.dptr, (long)value));	if (!okayvalue(value)) {		DEBUG(("store: reserved bit or overflow in 0x%lx\n", value));		return(-1);	}	/* find the place, exploiting previous search if possible */	start(&srch, &key, prevp);	while (search(&srch) != NOTFOUND)		continue;	prevp = FRESH;	conf.used[0]++;	DEBUG(("store: used count %ld\n", conf.used[0]));	written = 1;	return(set(&srch, value));}/* - dbzincore - control attempts to keep .pag file in core */int				/* old setting */dbzincore(value)int value;{	register int old = incore;	incore = value;	return(old);}/* - getconf - get configuration from .dir file */static int			/* 0 success, -1 failure */getconf(df, pf, cp)register FILE *df;		/* NULL means just give me the default */register FILE *pf;		/* NULL means don't care about .pag */register struct dbzconfig *cp;{	register int c;	register int i;	int err = 0;	c = (df != NULL) ? getc(df) : EOF;	if (c == EOF) {		/* empty file, no configuration known */		cp->olddbz = 0;		if (df != NULL && pf != NULL && getc(pf) != EOF)			cp->olddbz = 1;		cp->tsize = DEFSIZE;		cp->fieldsep = '\t';		for (i = 0; i < NUSEDS; i++)			cp->used[i] = 0;		cp->valuesize = SOF;		mybytemap(cp->bytemap);		cp->casemap = DEFCASE;		cp->tagenb = TAGENB;		cp->tagmask = TAGMASK;		cp->tagshift = TAGSHIFT;		DEBUG(("getconf: defaults (%ld, %c, (0x%lx/0x%lx<<%d))\n",			cp->tsize, cp->casemap, cp->tagenb, 			cp->tagmask, cp->tagshift));		return(0);	}	(void) ungetc(c, df);	/* first line, the vital stuff */	if (getc(df) != 'd' || getc(df) != 'b' || getc(df) != 'z')		err = -1;	if (getno(df, &err) != dbzversion)		err = -1;	cp->tsize = getno(df, &err);	cp->fieldsep = getno(df, &err);	while ((c = getc(df)) == ' ')		continue;	cp->casemap = c;	cp->tagenb = getno(df, &err);	cp->tagmask = getno(df, &err);	cp->tagshift = getno(df, &err);	cp->valuesize = getno(df, &err);	if (cp->valuesize != SOF) {		DEBUG(("getconf: wrong off_t size (%d)\n", cp->valuesize));		err = -1;		cp->valuesize = SOF;	/* to protect the loops below */	}	for (i = 0; i < cp->valuesize; i++)		cp->bytemap[i] = getno(df, &err);	if (getc(df) != '\n')		err = -1;	DEBUG(("size %ld, sep %d, cmap %c, tags 0x%lx/0x%lx<<%d, ", cp->tsize,			cp->fieldsep, cp->casemap, cp->tagenb, cp->tagmask,			cp->tagshift));	DEBUG(("bytemap (%d)", cp->valuesize));	for (i = 0; i < cp->valuesize; i++) {		DEBUG((" %d", cp->bytemap[i]));	}	DEBUG(("\n"));	/* second line, the usages */	for (i = 0; i < NUSEDS; i++)		cp->used[i] = getno(df, &err);	if (getc(df) != '\n')		err = -1;	DEBUG(("used %ld %ld %ld...\n", cp->used[0], cp->used[1], cp->used[2]));	if (err < 0) {		DEBUG(("getconf error\n"));		return(-1);	}	return(0);}/* - getno - get a long */static longgetno(f, ep)FILE *f;int *ep;{	register char *p;#	define	MAXN	50	char getbuf[MAXN];	register int c;	while ((c = getc(f)) == ' ')		continue;	if (c == EOF || c == '\n') {		DEBUG(("getno: missing number\n"));		*ep = -1;		return(0);	}	p = getbuf;	*p++ = c;	while ((c = getc(f)) != EOF && c != '\n' && c != ' ')		if (p < &getbuf[MAXN-1])			*p++ = c;	if (c == EOF) {		DEBUG(("getno: EOF\n"));		*ep = -1;	} else		(void) ungetc(c, f);	*p = '\0';	if (strspn(getbuf, "-1234567890") != strlen(getbuf)) {		DEBUG(("getno: `%s' non-numeric\n", getbuf));

⌨️ 快捷键说明

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