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

📄 map.c

📁 < linux网络编程工具>>配套源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) &&
	    !aliaswait(map, ".db", TRUE))
		return FALSE;
	return TRUE;
}


/*
**  DB_MAP_LOOKUP -- look up a datum in a BTREE- or HASH-type map
*/

char *
db_map_lookup(map, name, av, statp)
	MAP *map;
	char *name;
	char **av;
	int *statp;
{
	DBT key, val;
	register DB *db = (DB *) map->map_db2;
	int i;
	int st;
	int save_errno;
	int fd;
	struct stat stbuf;
	char keybuf[MAXNAME + 1];
	char buf[MAXNAME + 1];

	memset(&key, '\0', sizeof key);
	memset(&val, '\0', sizeof val);

	if (tTd(38, 20))
		dprintf("db_map_lookup(%s, %s)\n",
			map->map_mname, name);

	i = strlen(map->map_file);
	if (i > MAXNAME)
		i = MAXNAME;
	(void) strlcpy(buf, map->map_file, i + 1);
	if (i > 3 && strcmp(&buf[i - 3], ".db") == 0)
		buf[i - 3] = '\0';

	key.size = strlen(name);
	if (key.size > sizeof keybuf - 1)
		key.size = sizeof keybuf - 1;
	key.data = keybuf;
	memmove(keybuf, name, key.size);
	keybuf[key.size] = '\0';
	if (!bitset(MF_NOFOLDCASE, map->map_mflags))
		makelower(keybuf);
  lockdb:
# if DB_VERSION_MAJOR < 2
	fd = db->fd(db);
# else /* DB_VERSION_MAJOR < 2 */
	fd = -1;
	errno = db->fd(db, &fd);
# endif /* DB_VERSION_MAJOR < 2 */
	if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
		(void) lockfile(fd, buf, ".db", LOCK_SH);
	if (fd < 0 || fstat(fd, &stbuf) < 0 || stbuf.st_mtime > map->map_mtime)
	{
		/* Reopen the database to sync the cache */
		int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR
								 : O_RDONLY;

		if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
			(void) lockfile(fd, buf, ".db", LOCK_UN);
		map->map_class->map_close(map);
		map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
		if (map->map_class->map_open(map, omode))
		{
			map->map_mflags |= MF_OPEN;
			map->map_pid = getpid();
			if ((omode && O_ACCMODE) == O_RDWR)
				map->map_mflags |= MF_WRITABLE;
			db = (DB *) map->map_db2;
			goto lockdb;
		}
		else
		{
			if (!bitset(MF_OPTIONAL, map->map_mflags))
			{
				extern MAPCLASS BogusMapClass;

				*statp = EX_TEMPFAIL;
				map->map_class = &BogusMapClass;
				map->map_mflags |= MF_OPEN;
				map->map_pid = getpid();
				syserr("Cannot reopen DB database %s",
					map->map_file);
			}
			return NULL;
		}
	}

	st = 1;
	if (bitset(MF_TRY0NULL, map->map_mflags))
	{
# if DB_VERSION_MAJOR < 2
		st = db->get(db, &key, &val, 0);
# else /* DB_VERSION_MAJOR < 2 */
		errno = db->get(db, NULL, &key, &val, 0);
		switch (errno)
		{
		  case DB_NOTFOUND:
		  case DB_KEYEMPTY:
			st = 1;
			break;

		  case 0:
			st = 0;
			break;

		  default:
			st = -1;
			break;
		}
# endif /* DB_VERSION_MAJOR < 2 */
		if (st == 0)
			map->map_mflags &= ~MF_TRY1NULL;
	}
	if (st != 0 && bitset(MF_TRY1NULL, map->map_mflags))
	{
		key.size++;
# if DB_VERSION_MAJOR < 2
		st = db->get(db, &key, &val, 0);
# else /* DB_VERSION_MAJOR < 2 */
		errno = db->get(db, NULL, &key, &val, 0);
		switch (errno)
		{
		  case DB_NOTFOUND:
		  case DB_KEYEMPTY:
			st = 1;
			break;

		  case 0:
			st = 0;
			break;

		  default:
			st = -1;
			break;
		}
# endif /* DB_VERSION_MAJOR < 2 */
		if (st == 0)
			map->map_mflags &= ~MF_TRY0NULL;
	}
	save_errno = errno;
	if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
		(void) lockfile(fd, buf, ".db", LOCK_UN);
	if (st != 0)
	{
		errno = save_errno;
		if (st < 0)
			syserr("db_map_lookup: get (%s)", name);
		return NULL;
	}
	if (bitset(MF_MATCHONLY, map->map_mflags))
		return map_rewrite(map, name, strlen(name), NULL);
	else
		return map_rewrite(map, val.data, val.size, av);
}


/*
**  DB_MAP_STORE -- store a datum in the NEWDB database
*/

void
db_map_store(map, lhs, rhs)
	register MAP *map;
	char *lhs;
	char *rhs;
{
	int status;
	DBT key;
	DBT data;
	register DB *db = map->map_db2;
	char keybuf[MAXNAME + 1];

	memset(&key, '\0', sizeof key);
	memset(&data, '\0', sizeof data);

	if (tTd(38, 12))
		dprintf("db_map_store(%s, %s, %s)\n",
			map->map_mname, lhs, rhs);

	key.size = strlen(lhs);
	key.data = lhs;
	if (!bitset(MF_NOFOLDCASE, map->map_mflags))
	{
		if (key.size > sizeof keybuf - 1)
			key.size = sizeof keybuf - 1;
		memmove(keybuf, key.data, key.size);
		keybuf[key.size] = '\0';
		makelower(keybuf);
		key.data = keybuf;
	}

	data.size = strlen(rhs);
	data.data = rhs;

	if (bitset(MF_INCLNULL, map->map_mflags))
	{
		key.size++;
		data.size++;
	}

# if DB_VERSION_MAJOR < 2
	status = db->put(db, &key, &data, R_NOOVERWRITE);
# else /* DB_VERSION_MAJOR < 2 */
	errno = db->put(db, NULL, &key, &data, DB_NOOVERWRITE);
	switch (errno)
	{
	  case DB_KEYEXIST:
		status = 1;
		break;

	  case 0:
		status = 0;
		break;

	  default:
		status = -1;
		break;
	}
# endif /* DB_VERSION_MAJOR < 2 */
	if (status > 0)
	{
		if (!bitset(MF_APPEND, map->map_mflags))
			message("050 Warning: duplicate alias name %s", lhs);
		else
		{
			static char *buf = NULL;
			static int bufsiz = 0;
			DBT old;

			memset(&old, '\0', sizeof old);

			old.data = db_map_lookup(map, key.data,
						 (char **)NULL, &status);
			if (old.data != NULL)
			{
				old.size = strlen(old.data);
				if (data.size + old.size + 2 > (size_t)bufsiz)
				{
					if (buf != NULL)
						(void) free(buf);
					bufsiz = data.size + old.size + 2;
					buf = xalloc(bufsiz);
				}
				snprintf(buf, bufsiz, "%s,%s",
					(char *) data.data, (char *) old.data);
				data.size = data.size + old.size + 1;
				data.data = buf;
				if (tTd(38, 9))
					dprintf("db_map_store append=%s\n",
						(char *) data.data);
			}
		}
# if DB_VERSION_MAJOR < 2
		status = db->put(db, &key, &data, 0);
# else /* DB_VERSION_MAJOR < 2 */
		status = errno = db->put(db, NULL, &key, &data, 0);
# endif /* DB_VERSION_MAJOR < 2 */
	}
	if (status != 0)
		syserr("readaliases: db put (%s)", lhs);
}


/*
**  DB_MAP_CLOSE -- add distinguished entries and close the database
*/

void
db_map_close(map)
	MAP *map;
{
	register DB *db = map->map_db2;

	if (tTd(38, 9))
		dprintf("db_map_close(%s, %s, %lx)\n",
			map->map_mname, map->map_file, map->map_mflags);

	if (bitset(MF_WRITABLE, map->map_mflags))
	{
		/* write out the distinguished alias */
		db_map_store(map, "@", "@");
	}

	(void) db->sync(db, 0);

# if !LOCK_ON_OPEN
	if (map->map_lockfd >= 0)
		(void) close(map->map_lockfd);
# endif /* !LOCK_ON_OPEN */

# if DB_VERSION_MAJOR < 2
	if (db->close(db) != 0)
# else /* DB_VERSION_MAJOR < 2 */
	/*
	**  Berkeley DB can use internal shared memory
	**  locking for its memory pool.  Closing a map
	**  opened by another process will interfere
	**  with the shared memory and locks of the parent
	**  process leaving things in a bad state.
	*/

	/*
	**  If this map was not opened by the current
	**  process, do not close the map but recover
	**  the file descriptor.
	*/
	if (map->map_pid != getpid())
	{
		int fd = -1;

		errno = db->fd(db, &fd);
		if (fd >= 0)
			(void) close(fd);
		return;
	}

	if ((errno = db->close(db, 0)) != 0)
# endif /* DB_VERSION_MAJOR < 2 */
		syserr("db_map_close(%s, %s, %lx): db close failure",
			map->map_mname, map->map_file, map->map_mflags);
}
#endif /* NEWDB */
/*
**  NIS Modules
*/

#ifdef NIS

# ifndef YPERR_BUSY
#  define YPERR_BUSY	16
# endif /* ! YPERR_BUSY */

/*
**  NIS_MAP_OPEN -- open DBM map
*/

bool
nis_map_open(map, mode)
	MAP *map;
	int mode;
{
	int yperr;
	register char *p;
	auto char *vp;
	auto int vsize;

	if (tTd(38, 2))
		dprintf("nis_map_open(%s, %s, %d)\n",
			map->map_mname, map->map_file, mode);

	mode &= O_ACCMODE;
	if (mode != O_RDONLY)
	{
		/* issue a pseudo-error message */
# ifdef ENOSYS
		errno = ENOSYS;
# else /* ENOSYS */
#  ifdef EFTYPE
		errno = EFTYPE;
#  else /* EFTYPE */
		errno = ENXIO;
#  endif /* EFTYPE */
# endif /* ENOSYS */
		return FALSE;
	}

	p = strchr(map->map_file, '@');
	if (p != NULL)
	{
		*p++ = '\0';
		if (*p != '\0')
			map->map_domain = p;
	}

	if (*map->map_file == '\0')
		map->map_file = "mail.aliases";

	if (map->map_domain == NULL)
	{
		yperr = yp_get_default_domain(&map->map_domain);
		if (yperr != 0)
		{
			if (!bitset(MF_OPTIONAL, map->map_mflags))
				syserr("421 4.3.5 NIS map %s specified, but NIS not running",
				       map->map_file);
			return FALSE;
		}
	}

	/* check to see if this map actually exists */
	vp = NULL;
	yperr = yp_match(map->map_domain, map->map_file, "@", 1,
			&vp, &vsize);
	if (tTd(38, 10))
		dprintf("nis_map_open: yp_match(@, %s, %s) => %s\n",
			map->map_domain, map->map_file, yperr_string(yperr));
	if (vp != NULL)
		free(vp);

	if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY)
	{
		/*
		**  We ought to be calling aliaswait() here if this is an
		**  alias file, but powerful HP-UX NIS servers  apparently
		**  don't insert the @:@ token into the alias map when it
		**  is rebuilt, so aliaswait() just hangs.  I hate HP-UX.
		*/

# if 0
		if (!bitset(MF_ALIAS, map->map_mflags) ||
		    aliaswait(map, NULL, TRUE))
# endif /* 0 */
			return TRUE;
	}

	if (!bitset(MF_OPTIONAL, map->map_mflags))
	{
		syserr("421 4.0.0 Cannot bind to map %s in domain %s: %s",
			map->map_file, map->map_domain, yperr_string(yperr));
	}

	return FALSE;
}


/*
**  NIS_MAP_LOOKUP -- look up a datum in a NIS map
*/

/* ARGSUSED3 */
char *
nis_map_lookup(map, name, av, statp)
	MAP *map;
	char *name;
	char **av;
	int *statp;
{
	char *vp;
	auto int vsize;
	int buflen;
	int yperr;
	char keybuf[MAXNAME + 1];

	if (tTd(38, 20))
		dprintf("nis_map_lookup(%s, %s)\n",
			map->map_mname, name);

	buflen = strlen(name);
	if (buflen > sizeof keybuf - 1)
		buflen = sizeof keybuf - 1;
	memmove(keybuf, name, buflen);
	keybuf[buflen] = '\0';
	if (!bitset(MF_NOFOLDCASE, map->map_mflags))
		makelower(keybuf);
	yperr = YPERR_KEY;
	vp = NULL;
	if (bitset(MF_TRY0NULL, map->map_mflags))
	{
		yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen,
			     &vp, &vsize);
		if (yperr == 0)
			map->map_mflags &= ~MF_TRY1NULL;
	}
	if (yperr == YPERR_KEY && bitset(MF_TRY1NULL, map->map_mflags))
	{
		if (vp != NULL)
		{
			free(vp);
			vp = NULL;
		}
		buflen++;
		yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen,
			     &vp, &vsize);
		if (yperr == 0)
			map->map_mflags &= ~MF_TRY0NULL;
	}
	if (yperr != 0)
	{
		if (yperr != YPERR_KEY && yperr != YPERR_BUSY)
			map->map_mflags &= ~(MF_VALID|MF_OPEN);
		if (vp != NULL)
			free(vp);
		return NULL;
	}
	if (bitset(MF_MATCHONLY, map->map_mflags))
		return map_rewrite(map, name, strlen(name), NULL);
	else
	{
		char *ret;

		ret = map_rewrite(map, vp, vsize, av);
		if (vp != NULL)
			free(vp);
		return ret;
	}
}


/*
**  NIS_GETCANONNAME -- look up canonical name in NIS
*/

static bool
nis_getcanonname(name, hbsize, statp)
	char *name;
	int hbsize;
	int *statp;
{
	char *vp;
	auto int vsize;
	int keylen;
	int yperr;
	static bool try0null = TRUE;
	static bool try1null = TRUE;
	static char *yp_domain = NULL;
	char host_record[MAXLINE];
	char cbuf[MAXNAME];
	char nbuf[MAXNAME + 1];

	if (tTd(38, 20))
		dprintf("nis_getcanonname(%s)\n", name);

	if (strlcpy(nbuf, name, sizeof nbuf) >= sizeof nbuf)
	{
		*statp = EX_UNAVAILABLE;
		return FALSE;
	}
	shorten_hostname(nbuf);
	keylen = strlen(nbuf);

	if (yp_domain == NULL)
		(void) yp_get_default_domain(&yp_domain);
	makelower(nbuf);
	yperr = YPERR_KEY;
	vp = NULL;
	if (try0null)
	{
		yperr = yp_match(yp_domain, "hosts.byname", nbuf, keylen,
			     &vp, &vsize);
		if (yperr == 0)
			try1null = FALSE;
	}
	if (yperr == YPERR_KEY && try1null)
	{
		if (vp != NULL)
		{
			free(vp);
			vp = NULL;
		}
		keylen++;
		yperr = yp_match(yp_domain, "hosts.byname", nbuf, keylen,
			     &vp, &vsize);
		if (yperr == 0)
			try0null = FALSE;
	}
	if (yperr != 0)
	{
		if (yperr == YPERR_KEY)
			*statp = EX_NOHOST;
		else if (yperr == YPERR_BUSY)
			*statp = EX_TEMPFAIL;
		else
			*statp = EX_UNAVAILABLE;
		if (vp != NULL)
			free(vp);
		return FALSE;
	}

⌨️ 快捷键说明

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