/* * Copyright (c) 2003-2005 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. */ #include "sm/generic.h" SM_RCSID("@(#)$Id: lookupdomain.c,v 1.17 2007/01/22 17:24:21 ca Exp $") #include "sm/assert.h" #include "sm/error.h" #include "sm/memops.h" #include "sm/heap.h" #include "sm/rdstr.h" #include "map.h" #include "sm/map.h" #include "sm/maps.h" #include "sm/mapc.h" /* ** Add flags (also for lookup_ip): ** lookup also .domain ** lookup only Tag: ** others? */ /* ** SM_MAP_LOOKUP_DOMAIN -- Lookup domain and subdomains (and . if requested) ** ** Parameters: ** map -- map ** domain -- input string (domain) ** tag -- tag including delimiter (NULL for no tag) ** flags -- flags to control lookup ** rhs -- rhs of matching entry ** ** Returns: ** usual sm_error code */ sm_ret_T sm_map_lookup_domain(sm_map_P map, sm_rdstr_P domain, sm_str_P tag, uint32_t flags, sm_str_P rhs) { sm_ret_T ret; sm_mapc_P mapc; sm_str_P str; size_t j, len_domain; bool found; if (NULL == map) return sm_error_perm(SM_EM_MAP, SM_E_NOMAP); SM_IS_MAP(map); mapc = map->sm_map_class; SM_IS_MAPC(mapc); if (NULL == mapc->sm_mapc_lookupf) return sm_error_perm(SM_EM_MAP, SM_E_NOTIMPL); if (!SMMAP_LT_M_CAPS(map, SMMAP_FL_HAS_DOMAIN)) return sm_error_perm(SM_EM_MAP, ENOENT); /* XXX */ len_domain = SM_RDSTR_GETLEN(domain); if (0 == len_domain) return sm_error_perm(SM_EM_MAP, SM_E_NOTFOUND); /* XXX */ if (tag != NULL) len_domain += sm_str_getlen(tag); str = sm_str_new(NULL, len_domain , len_domain + 2); if (NULL == str) return sm_error_perm(SM_EM_MAP, ENOMEM); ret = sm_error_perm(SM_EM_MAP, SM_E_NOTFOUND); /* XXX */ j = 0; found = false; len_domain = SM_RDSTR_GETLEN(domain) - 1; while (j <= len_domain) { sm_str_clr(str); if (tag != NULL) { ret = sm_str_cat(str, tag); if (sm_is_err(ret)) break; } ret = sm_str_catpart(str, (sm_rdstr_P) domain, j, len_domain); if (sm_is_err(ret)) break; ret = mapc->sm_mapc_lookupf(map, SMMAP_FL_LWR_KEY, str, rhs); if (SM_MAP_DATA2BIG == ret) goto done; if (SM_SUCCESS == ret) { found = true; break; } #if 0 if (SMMAP_IS_LFL(flags, SMMAP_LFL_DOTSUBDOM)) #endif ++j; /* search for next '.'; domains don't have escaped dots */ while (j < len_domain && SM_RDSTR_RD_ELEM(domain, j) != '.') ++j; #if 0 if (!SMMAP_IS_LFL(flags, SMMAP_LFL_DOTSUBDOM)) ++j; #endif } if (!found && SMMAP_IS_LFL(flags, SMMAP_LFL_TAG) && j > len_domain && tag != NULL) { /* lookup default: just tag */ ret = mapc->sm_mapc_lookupf(map, SMMAP_FL_NONE, tag, rhs); if (SM_MAP_DATA2BIG == ret) goto done; if (SM_SUCCESS == ret) found = true; } if (!found && SMMAP_IS_LFL(flags, SMMAP_LFL_DOT) && j > len_domain) { /* lookup . */ sm_str_clr(str); ret = sm_str_scat(str, "."); if (!sm_is_err(ret)) { ret = mapc->sm_mapc_lookupf(map, SMMAP_FL_NONE, str, rhs); if (SM_SUCCESS == ret) found = true; } } done: sm_str_free(str); /* ** Who "owns" the data? ** need some flags that tell us what to do? see BDB. */ return ret; }