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

📄 udb.c

📁 < linux网络编程工具>>配套源码
💻 C
📖 第 1 页 / 共 3 页
字号:
							a->q_user,
							hp->po_name,
							hp->po_host);
					break;
				}
				info.data = pobuf;
				snprintf(pobuf, sizeof pobuf, "%s@%s",
					hp->po_name, hp->po_host);
				info.size = strlen(info.data);
#  else /* HES_GETMAILHOST */
				break;
#  endif /* HES_GETMAILHOST */
			}
			if (tTd(28, 80))
				dprintf("udbexpand: match %.*s: %.*s\n",
					(int) key.size, (char *) key.data,
					(int) info.size, (char *) info.data);
			a->q_flags &= ~QSELFREF;

			if (bitset(EF_VRFYONLY, e->e_flags))
			{
				a->q_state = QS_VERIFIED;
				return EX_OK;
			}

			breakout = TRUE;
			if (info.size >= usersize)
				user = xalloc(info.size + 1);
			memmove(user, info.data, info.size);
			user[info.size] = '\0';

			message("hesioded to %s", user);
			if (LogLevel > 10)
				sm_syslog(LOG_INFO, e->e_id,
					  "hesiod %.100s => %s",
					  e->e_to,
					  shortenstring(user, MAXSHORTSTR));
			naddrs = sendtolist(user, a, sendq, aliaslevel + 1, e);

			if (naddrs > 0 && !bitset(QSELFREF, a->q_flags))
			{
				if (tTd(28, 5))
				{
					dprintf("udbexpand: QS_EXPANDED ");
					printaddr(a, FALSE);
				}
				a->q_state = QS_EXPANDED;
			}

			/*
			**  If this address has a -request address, reflect
			**  it into the envelope.
			*/

			(void) strlcpy(keybuf, a->q_user, sizeof keybuf);
			(void) strlcat(keybuf, ":mailsender", sizeof keybuf);
			keylen = strlen(keybuf);
			key.data = keybuf;
			key.size = keylen;
			i = hes_udb_get(&key, &info);
			if (i != 0 || info.size <= 0)
				break;
			a->q_owner = xalloc(info.size + 1);
			memmove(a->q_owner, info.data, info.size);
			a->q_owner[info.size] = '\0';
			break;
# endif /* HESIOD */

		  case UDB_REMOTE:
			/* not yet implemented */
			break;

		  case UDB_FORWARD:
			if (bitset(EF_VRFYONLY, e->e_flags))
			{
				a->q_state = QS_VERIFIED;
				return EX_OK;
			}
			i = strlen(up->udb_fwdhost) + strlen(a->q_user) + 1;
			if (i >= usersize)
			{
				usersize = i + 1;
				user = xalloc(usersize);
			}
			(void) snprintf(user, usersize, "%s@%s",
					a->q_user, up->udb_fwdhost);
			message("expanded to %s", user);
			a->q_flags &= ~QSELFREF;
			naddrs = sendtolist(user, a, sendq, aliaslevel + 1, e);
			if (naddrs > 0 && !bitset(QSELFREF, a->q_flags))
			{
				if (tTd(28, 5))
				{
					dprintf("udbexpand: QS_EXPANDED ");
					printaddr(a, FALSE);
				}
				a->q_state = QS_EXPANDED;
			}
			breakout = TRUE;
			break;

		  case UDB_EOLIST:
			breakout = TRUE;
			break;

		  default:
			/* unknown entry type */
			break;
		}
		if (user != userbuf)
			free(user);
	}
	return EX_OK;
}
/*
**  UDBSENDER -- return canonical external name of sender, given local name
**
**	Parameters:
**		sender -- the name of the sender on the local machine.
**
**	Returns:
**		The external name for this sender, if derivable from the
**			database.
**		NULL -- if nothing is changed from the database.
**
**	Side Effects:
**		none.
*/

char *
udbsender(sender)
	char *sender;
{
	return udbmatch(sender, "mailname");
}
/*
**  UDBMATCH -- match user in field, return result of lookup.
**
**	Parameters:
**		user -- the name of the user.
**		field -- the field to lookup.
**
**	Returns:
**		The external name for this sender, if derivable from the
**			database.
**		NULL -- if nothing is changed from the database.
**
**	Side Effects:
**		none.
*/

static char *
udbmatch(user, field)
	char *user;
	char *field;
{
	register char *p;
	register struct udbent *up;
	int i;
	int keylen;
	DBT key, info;
	char keybuf[MAXKEY];

	if (tTd(28, 1))
		dprintf("udbmatch(%s, %s)\n", user, field);

	if (!UdbInitialized)
	{
		if (_udbx_init(CurEnv) == EX_TEMPFAIL)
			return NULL;
	}

	/* short circuit if no spec */
	if (UdbSpec == NULL || UdbSpec[0] == '\0')
		return NULL;

	/* short circuit name begins with '\\' since it can't possibly match */
	if (user[0] == '\\')
		return NULL;

	/* long names can never match and are a pain to deal with */
	i = strlen(field);
	if (i < sizeof "maildrop")
		i = sizeof "maildrop";
	if ((strlen(user) + i) > sizeof keybuf - 4)
		return NULL;

	/* names beginning with colons indicate metadata */
	if (user[0] == ':')
		return NULL;

	/* build database key */
	(void) snprintf(keybuf, sizeof keybuf, "%s:%s", user, field);
	keylen = strlen(keybuf);

	for (up = UdbEnts; up->udb_type != UDB_EOLIST; up++)
	{
		/*
		**  Select action based on entry type.
		*/

		switch (up->udb_type)
		{
# ifdef NEWDB
		  case UDB_DBFETCH:
			memset(&key, '\0', sizeof key);
			memset(&info, '\0', sizeof info);
			key.data = keybuf;
			key.size = keylen;
#  if DB_VERSION_MAJOR < 2
			i = (*up->udb_dbp->get)(up->udb_dbp, &key, &info, 0);
#  else /* DB_VERSION_MAJOR < 2 */
			i = errno = (*up->udb_dbp->get)(up->udb_dbp, NULL,
							&key, &info, 0);
#  endif /* DB_VERSION_MAJOR < 2 */
			if (i != 0 || info.size <= 0)
			{
				if (tTd(28, 2))
					dprintf("udbmatch: no match on %s (%d) via db\n",
						keybuf, keylen);
				continue;
			}

			p = xalloc(info.size + 1);
			memmove(p, info.data, info.size);
			p[info.size] = '\0';
			if (tTd(28, 1))
				dprintf("udbmatch ==> %s\n", p);
			return p;
# endif /* NEWDB */

# ifdef HESIOD
		  case UDB_HESIOD:
			key.data = keybuf;
			key.size = keylen;
			i = hes_udb_get(&key, &info);
			if (i != 0 || info.size <= 0)
			{
				if (tTd(28, 2))
					dprintf("udbmatch: no match on %s (%d) via hesiod\n",
						keybuf, keylen);
				continue;
			}

			p = xalloc(info.size + 1);
			memmove(p, info.data, info.size);
			p[info.size] = '\0';
			if (tTd(28, 1))
				dprintf("udbmatch ==> %s\n", p);
			return p;
# endif /* HESIOD */
		}
	}

	if (strcmp(field, "mailname") != 0)
		return NULL;

	/*
	**  Nothing yet.  Search again for a default case.  But only
	**  use it if we also have a forward (:maildrop) pointer already
	**  in the database.
	*/

	/* build database key */
	(void) strlcpy(keybuf, user, sizeof keybuf);
	(void) strlcat(keybuf, ":maildrop", sizeof keybuf);
	keylen = strlen(keybuf);

	for (up = UdbEnts; up->udb_type != UDB_EOLIST; up++)
	{
		switch (up->udb_type)
		{
# ifdef NEWDB
		  case UDB_DBFETCH:
			/* get the default case for this database */
			if (up->udb_default == NULL)
			{
				memset(&key, '\0', sizeof key);
				memset(&info, '\0', sizeof info);
				key.data = ":default:mailname";
				key.size = strlen(key.data);
#  if DB_VERSION_MAJOR < 2
				i = (*up->udb_dbp->get)(up->udb_dbp,
							&key, &info, 0);
#  else /* DB_VERSION_MAJOR < 2 */
				i = errno = (*up->udb_dbp->get)(up->udb_dbp,
								NULL, &key,
								&info, 0);
#  endif /* DB_VERSION_MAJOR < 2 */
				if (i != 0 || info.size <= 0)
				{
					/* no default case */
					up->udb_default = "";
					continue;
				}

				/* save the default case */
				up->udb_default = xalloc(info.size + 1);
				memmove(up->udb_default, info.data, info.size);
				up->udb_default[info.size] = '\0';
			}
			else if (up->udb_default[0] == '\0')
				continue;

			/* we have a default case -- verify user:maildrop */
			memset(&key, '\0', sizeof key);
			memset(&info, '\0', sizeof info);
			key.data = keybuf;
			key.size = keylen;
#  if DB_VERSION_MAJOR < 2
			i = (*up->udb_dbp->get)(up->udb_dbp, &key, &info, 0);
#  else /* DB_VERSION_MAJOR < 2 */
			i = errno = (*up->udb_dbp->get)(up->udb_dbp, NULL,
							&key, &info, 0);
#  endif /* DB_VERSION_MAJOR < 2 */
			if (i != 0 || info.size <= 0)
			{
				/* nope -- no aliasing for this user */
				continue;
			}

			/* they exist -- build the actual address */
			i = strlen(user) + strlen(up->udb_default) + 2;
			p = xalloc(i);
			(void) snprintf(p, i, "%s@%s", user, up->udb_default);
			if (tTd(28, 1))
				dprintf("udbmatch ==> %s\n", p);
			return p;
# endif /* NEWDB */

# ifdef HESIOD
		  case UDB_HESIOD:
			/* get the default case for this database */
			if (up->udb_default == NULL)
			{
				key.data = ":default:mailname";
				key.size = strlen(key.data);
				i = hes_udb_get(&key, &info);

				if (i != 0 || info.size <= 0)
				{
					/* no default case */
					up->udb_default = "";
					continue;
				}

				/* save the default case */
				up->udb_default = xalloc(info.size + 1);
				memmove(up->udb_default, info.data, info.size);
				up->udb_default[info.size] = '\0';
			}
			else if (up->udb_default[0] == '\0')
				continue;

			/* we have a default case -- verify user:maildrop */
			key.data = keybuf;
			key.size = keylen;
			i = hes_udb_get(&key, &info);
			if (i != 0 || info.size <= 0)
			{
				/* nope -- no aliasing for this user */
				continue;
			}

			/* they exist -- build the actual address */
			i = strlen(user) + strlen(up->udb_default) + 2;
			p = xalloc(i);
			(void) snprintf(p, i, "%s@%s", user, up->udb_default);
			if (tTd(28, 1))
				dprintf("udbmatch ==> %s\n", p);
			return p;
			break;
# endif /* HESIOD */
		}
	}

	/* still nothing....  too bad */
	return NULL;
}
/*
**  UDB_MAP_LOOKUP -- look up arbitrary entry in user database map
**
**	Parameters:
**		map -- the map being queried.
**		name -- the name to look up.
**		av -- arguments to the map lookup.
**		statp -- to get any error status.
**
**	Returns:
**		NULL if name not found in map.
**		The rewritten name otherwise.
*/

/* ARGSUSED3 */
char *
udb_map_lookup(map, name, av, statp)
	MAP *map;
	char *name;
	char **av;
	int *statp;
{
	char *val;
	char *key;
	char keybuf[MAXNAME + 1];

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

	if (bitset(MF_NOFOLDCASE, map->map_mflags))
	{
		key = name;
	}
	else
	{
		int keysize = strlen(name);

		if (keysize > sizeof keybuf - 1)
			keysize = sizeof keybuf - 1;
		memmove(keybuf, name, keysize);
		keybuf[keysize] = '\0';
		makelower(keybuf);
		key = keybuf;
	}
	val = udbmatch(key, map->map_file);
	if (val == NULL)
		return NULL;
	if (bitset(MF_MATCHONLY, map->map_mflags))
		return map_rewrite(map, name, strlen(name), NULL);
	else
		return map_rewrite(map, val, strlen(val), av);
}
/*
**  _UDBX_INIT -- parse the UDB specification, opening any valid entries.
**
**	Parameters:
**		e -- the current envelope.
**

⌨️ 快捷键说明

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