/* * Locate the appropriate transport domain and call the create function for * it. */ netsnmp_transport * netsnmp_tdomain_transport_full(const char *application, const char *str, int local, const char *default_domain, const char *default_target) { netsnmp_tdomain *match = NULL; const char *addr = NULL; const char * const *spec = NULL; int any_found = 0; DEBUGMSGTL(("tdomain", "tdomain_transport_full(\"%s\", \"%s\", %d, \"%s\", \"%s\")\n", application, str ? str : "[NIL]", local, default_domain ? default_domain : "[NIL]", default_target ? default_target : "[NIL]")); /* First try - assume that there is a domain in str (domain:target) */ if (str != NULL) { char *cp; if ((cp = strchr(str, ':')) != NULL) { char* mystring = (char*)malloc(cp + 1 - str); memcpy(mystring, str, cp - str); mystring[cp - str] = '\0'; addr = cp + 1; match = find_tdomain(mystring); free(mystring); } } /* * Second try, if there is no domain in str (target), then try the * default domain */ if (match == NULL) { addr = str; if (addr && *addr == '/') { DEBUGMSGTL(("tdomain", "Address starts with '/', so assume \"unix\" " "domain\n")); match = find_tdomain("unix"); } else if (default_domain) { DEBUGMSGTL(("tdomain", "Use user specified default domain \"%s\"\n", default_domain)); match = find_tdomain(default_domain); } else { spec = netsnmp_lookup_default_domains(application); if (spec == NULL) { DEBUGMSGTL(("tdomain", "No default domain found, assume \"udp\"\n")); match = find_tdomain("udp"); } else { const char * const * r = spec; DEBUGMSGTL(("tdomain", "Use application default domains")); while(*r) { DEBUGMSG(("tdomain", " \"%s\"", *r)); ++r; } DEBUGMSG(("tdomain", "\n")); } } } for(;;) { if (match) { netsnmp_transport *t = NULL; const char* addr2; any_found = 1; /* * Ok, we know what domain to try, lets see what default data * should be used with it */ if (default_target != NULL) addr2 = default_target; else addr2 = netsnmp_lookup_default_target(application, match->prefix[0]); DEBUGMSGTL(("tdomain", "trying domain \"%s\" address \"%s\" " "default address \"%s\"\n", match->prefix[0], addr ? addr : "[NIL]", addr2 ? addr2 : "[NIL]")); if (match->f_create_from_tstring) t = match->f_create_from_tstring(addr, local); else t = match->f_create_from_tstring_new(addr, local, addr2); if (t) return t; } addr = str; if (spec && *spec) match = find_tdomain(*spec++); else break; } if (!any_found) snmp_log(LOG_ERR, "No support for any checked transport domain\n"); return NULL; }
/* * Locate the appropriate transport domain and call the create function for * it. */ netsnmp_transport * netsnmp_tdomain_transport_full(const char *application, const char *str, int local, const char *default_domain, const char *default_target) { netsnmp_tdomain *match = NULL; const char *addr = NULL; const char * const *spec = NULL; int any_found = 0; char buf[SNMP_MAXPATH]; char **lspec = 0; DEBUGMSGTL(("tdomain", "tdomain_transport_full(\"%s\", \"%s\", %d, \"%s\", \"%s\")\n", application, str ? str : "[NIL]", local, default_domain ? default_domain : "[NIL]", default_target ? default_target : "[NIL]")); /* see if we can load a host-name specific set of conf files */ if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_LOAD_HOST_FILES) && netsnmp_is_fqdn(str)) { static int have_added_handler = 0; char *newhost; struct config_line *config_handlers; struct config_files file_names; char *prev_hostname; /* register a "transport" specifier */ if (!have_added_handler) { have_added_handler = 1; netsnmp_ds_register_config(ASN_OCTET_STR, "snmp", "transport", NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_HOSTNAME); } /* we save on specific setting that we don't allow to change from one transport creation to the next; ie, we don't want the "transport" specifier to be a default. It should be a single invocation use only */ prev_hostname = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_HOSTNAME); if (prev_hostname) prev_hostname = strdup(prev_hostname); /* read in the hosts/STRING.conf files */ config_handlers = read_config_get_handlers("snmp"); snprintf(buf, sizeof(buf)-1, "hosts/%s", str); file_names.fileHeader = buf; file_names.start = config_handlers; file_names.next = NULL; DEBUGMSGTL(("tdomain", "checking for host specific config %s\n", buf)); read_config_files_of_type(EITHER_CONFIG, &file_names); if (NULL != (newhost = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_HOSTNAME))) { strlcpy(buf, newhost, sizeof(buf)); str = buf; } netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_HOSTNAME, prev_hostname); SNMP_FREE(prev_hostname); } /* First try - assume that there is a domain in str (domain:target) */ if (str != NULL) { const char *cp; if ((cp = strchr(str, ':')) != NULL) { char* mystring = (char*)malloc(cp + 1 - str); memcpy(mystring, str, cp - str); mystring[cp - str] = '\0'; addr = cp + 1; match = find_tdomain(mystring); free(mystring); } } /* * Second try, if there is no domain in str (target), then try the * default domain */ if (match == NULL) { addr = str; if (addr && *addr == '/') { DEBUGMSGTL(("tdomain", "Address starts with '/', so assume \"unix\" " "domain\n")); match = find_tdomain("unix"); } else if (default_domain) { DEBUGMSGTL(("tdomain", "Use user specified default domain \"%s\"\n", default_domain)); if (!strchr(default_domain, ',')) match = find_tdomain(default_domain); else { int commas = 0; const char *cp = default_domain; char *dup = strdup(default_domain); while (*++cp) if (*cp == ',') commas++; lspec = (char **) calloc(commas+2, sizeof(char *)); commas = 1; lspec[0] = strtok(dup, ","); while ((lspec[commas++] = strtok(NULL, ","))) ; spec = (const char * const *)lspec; } } else { spec = netsnmp_lookup_default_domains(application); if (spec == NULL) { DEBUGMSGTL(("tdomain", "No default domain found, assume \"udp\"\n")); match = find_tdomain("udp"); } else { const char * const * r = spec; DEBUGMSGTL(("tdomain", "Use application default domains")); while(*r) { DEBUGMSG(("tdomain", " \"%s\"", *r)); ++r; } DEBUGMSG(("tdomain", "\n")); } } } for(;;) { if (match) { netsnmp_transport *t = NULL; const char* addr2; any_found = 1; /* * Ok, we know what domain to try, lets see what default data * should be used with it */ if (default_target != NULL) addr2 = default_target; else addr2 = netsnmp_lookup_default_target(application, match->prefix[0]); DEBUGMSGTL(("tdomain", "trying domain \"%s\" address \"%s\" " "default address \"%s\"\n", match->prefix[0], addr ? addr : "[NIL]", addr2 ? addr2 : "[NIL]")); if (match->f_create_from_tstring) { NETSNMP_LOGONCE((LOG_WARNING, "transport domain %s uses deprecated f_create_from_tstring\n", match->prefix[0])); t = match->f_create_from_tstring(addr, local); } else t = match->f_create_from_tstring_new(addr, local, addr2); if (t) { if (lspec) { free(lspec[0]); free(lspec); } return t; } } addr = str; if (spec && *spec) match = find_tdomain(*spec++); else break; } if (!any_found) snmp_log(LOG_ERR, "No support for any checked transport domain\n"); if (lspec) { free(lspec[0]); free(lspec); } return NULL; }