net-snmp 5.7
|
00001 #include <net-snmp/net-snmp-config.h> 00002 00003 #include <stdlib.h> 00004 #include <string.h> 00005 00006 #include <net-snmp/net-snmp-includes.h> 00007 #include <net-snmp/library/snmp_transport.h> 00008 00009 static char** 00010 create_word_array_helper(const char* cptr, size_t idx, char* tmp, size_t tmplen) 00011 { 00012 char* item; 00013 char** res; 00014 cptr = copy_nword(NETSNMP_REMOVE_CONST(char *, cptr), tmp, tmplen); 00015 item = strdup(tmp); 00016 if (cptr) 00017 res = create_word_array_helper(cptr, idx + 1, tmp, tmplen); 00018 else { 00019 res = (char**)malloc(sizeof(char*) * (idx + 2)); 00020 res[idx + 1] = NULL; 00021 } 00022 res[idx] = item; 00023 return res; 00024 } 00025 00026 static char** 00027 create_word_array(const char* cptr) 00028 { 00029 size_t tmplen = strlen(cptr); 00030 char* tmp = (char*)malloc(tmplen + 1); 00031 char** res = create_word_array_helper(cptr, 0, tmp, tmplen); 00032 free(tmp); 00033 return res; 00034 } 00035 00036 static void 00037 destroy_word_array(char** arr) 00038 { 00039 if (arr) { 00040 char** run = arr; 00041 while(*run) { 00042 free(*run); 00043 ++run; 00044 } 00045 free(arr); 00046 } 00047 } 00048 00049 struct netsnmp_lookup_domain { 00050 char* application; 00051 char** userDomain; 00052 char** domain; 00053 struct netsnmp_lookup_domain* next; 00054 }; 00055 00056 static struct netsnmp_lookup_domain* domains = NULL; 00057 00058 int 00059 netsnmp_register_default_domain(const char* application, const char* domain) 00060 { 00061 struct netsnmp_lookup_domain *run = domains, *prev = NULL; 00062 int res = 0; 00063 00064 while (run != NULL && strcmp(run->application, application) < 0) { 00065 prev = run; 00066 run = run->next; 00067 } 00068 if (run && strcmp(run->application, application) == 0) { 00069 if (run->domain != NULL) { 00070 destroy_word_array(run->domain); 00071 run->domain = NULL; 00072 res = 1; 00073 } 00074 } else { 00075 run = SNMP_MALLOC_STRUCT(netsnmp_lookup_domain); 00076 run->application = strdup(application); 00077 run->userDomain = NULL; 00078 if (prev) { 00079 run->next = prev->next; 00080 prev->next = run; 00081 } else { 00082 run->next = domains; 00083 domains = run; 00084 } 00085 } 00086 if (domain) { 00087 run->domain = create_word_array(domain); 00088 } else if (run->userDomain == NULL) { 00089 if (prev) 00090 prev->next = run->next; 00091 else 00092 domains = run->next; 00093 free(run->application); 00094 free(run); 00095 } 00096 return res; 00097 } 00098 00099 void 00100 netsnmp_clear_default_domain(void) 00101 { 00102 while (domains) { 00103 struct netsnmp_lookup_domain *tmp = domains; 00104 domains = domains->next; 00105 free(tmp->application); 00106 destroy_word_array(tmp->userDomain); 00107 destroy_word_array(tmp->domain); 00108 free(tmp); 00109 } 00110 } 00111 00112 static void 00113 netsnmp_register_user_domain(const char* token, char* cptr) 00114 { 00115 struct netsnmp_lookup_domain *run = domains, *prev = NULL; 00116 size_t len = strlen(cptr) + 1; 00117 char* application = (char*)malloc(len); 00118 char** domain; 00119 00120 { 00121 char* cp = copy_nword(cptr, application, len); 00122 domain = create_word_array(cp); 00123 } 00124 00125 while (run != NULL && strcmp(run->application, application) < 0) { 00126 prev = run; 00127 run = run->next; 00128 } 00129 if (run && strcmp(run->application, application) == 0) { 00130 if (run->userDomain != NULL) { 00131 config_perror("Default transport already registered for this " 00132 "application"); 00133 destroy_word_array(domain); 00134 free(application); 00135 return; 00136 } 00137 } else { 00138 run = SNMP_MALLOC_STRUCT(netsnmp_lookup_domain); 00139 run->application = strdup(application); 00140 run->domain = NULL; 00141 if (prev) { 00142 run->next = prev->next; 00143 prev->next = run; 00144 } else { 00145 run->next = domains; 00146 domains = run; 00147 } 00148 } 00149 run->userDomain = domain; 00150 free(application); 00151 } 00152 00153 static void 00154 netsnmp_clear_user_domain(void) 00155 { 00156 struct netsnmp_lookup_domain *run = domains, *prev = NULL; 00157 00158 while (run) { 00159 if (run->userDomain != NULL) { 00160 destroy_word_array(run->userDomain); 00161 run->userDomain = NULL; 00162 } 00163 if (run->domain == NULL) { 00164 struct netsnmp_lookup_domain *tmp = run; 00165 if (prev) 00166 run = prev->next = run->next; 00167 else 00168 run = domains = run->next; 00169 free(tmp->application); 00170 free(tmp); 00171 } else { 00172 prev = run; 00173 run = run->next; 00174 } 00175 } 00176 } 00177 00178 const char* const * 00179 netsnmp_lookup_default_domains(const char* application) 00180 { 00181 const char * const * res; 00182 00183 if (application == NULL) 00184 res = NULL; 00185 else { 00186 struct netsnmp_lookup_domain *run = domains; 00187 00188 while (run && strcmp(run->application, application) < 0) 00189 run = run->next; 00190 if (run && strcmp(run->application, application) == 0) 00191 if (run->userDomain) 00192 res = (const char * const *)run->userDomain; 00193 else 00194 res = (const char * const *)run->domain; 00195 else 00196 res = NULL; 00197 } 00198 DEBUGMSGTL(("defaults", 00199 "netsnmp_lookup_default_domain(\"%s\") ->", 00200 application ? application : "[NIL]")); 00201 if (res) { 00202 const char * const * r = res; 00203 while(*r) { 00204 DEBUGMSG(("defaults", " \"%s\"", *r)); 00205 ++r; 00206 } 00207 DEBUGMSG(("defaults", "\n")); 00208 } else 00209 DEBUGMSG(("defaults", " \"[NIL]\"\n")); 00210 return res; 00211 } 00212 00213 const char* 00214 netsnmp_lookup_default_domain(const char* application) 00215 { 00216 const char * const * res = netsnmp_lookup_default_domains(application); 00217 return (res ? *res : NULL); 00218 } 00219 00220 struct netsnmp_lookup_target { 00221 char* application; 00222 char* domain; 00223 char* userTarget; 00224 char* target; 00225 struct netsnmp_lookup_target* next; 00226 }; 00227 00228 static struct netsnmp_lookup_target* targets = NULL; 00229 00230 int 00231 netsnmp_register_default_target(const char* application, const char* domain, 00232 const char* target) 00233 { 00234 struct netsnmp_lookup_target *run = targets, *prev = NULL; 00235 int i = 0, res = 0; 00236 while (run && ((i = strcmp(run->application, application)) < 0 || 00237 (i == 0 && strcmp(run->domain, domain) < 0))) { 00238 prev = run; 00239 run = run->next; 00240 } 00241 if (run && i == 0 && strcmp(run->domain, domain) == 0) { 00242 if (run->target != NULL) { 00243 free(run->target); 00244 run->target = NULL; 00245 res = 1; 00246 } 00247 } else { 00248 run = SNMP_MALLOC_STRUCT(netsnmp_lookup_target); 00249 run->application = strdup(application); 00250 run->domain = strdup(domain); 00251 run->userTarget = NULL; 00252 if (prev) { 00253 run->next = prev->next; 00254 prev->next = run; 00255 } else { 00256 run->next = targets; 00257 targets = run; 00258 } 00259 } 00260 if (target) { 00261 run->target = strdup(target); 00262 } else if (run->userTarget == NULL) { 00263 if (prev) 00264 prev->next = run->next; 00265 else 00266 targets = run->next; 00267 free(run->domain); 00268 free(run->application); 00269 free(run); 00270 } 00271 return res; 00272 } 00273 00274 void 00275 netsnmp_clear_default_target(void) 00276 { 00277 while (targets) { 00278 struct netsnmp_lookup_target *tmp = targets; 00279 targets = targets->next; 00280 free(tmp->application); 00281 free(tmp->domain); 00282 free(tmp->userTarget); 00283 free(tmp->target); 00284 free(tmp); 00285 } 00286 } 00287 00288 static void 00289 netsnmp_register_user_target(const char* token, char* cptr) 00290 { 00291 struct netsnmp_lookup_target *run = targets, *prev = NULL; 00292 size_t len = strlen(cptr) + 1; 00293 char* application = (char*)malloc(len); 00294 char* domain = (char*)malloc(len); 00295 char* target = (char*)malloc(len); 00296 int i = 0; 00297 00298 { 00299 char* cp = copy_nword(cptr, application, len); 00300 cp = copy_nword(cp, domain, len); 00301 cp = copy_nword(cp, target, len); 00302 if (cp) 00303 config_pwarn("Trailing junk found"); 00304 } 00305 00306 while (run && ((i = strcmp(run->application, application)) < 0 || 00307 (i == 0 && strcmp(run->domain, domain) < 0))) { 00308 prev = run; 00309 run = run->next; 00310 } 00311 if (run && i == 0 && strcmp(run->domain, domain) == 0) { 00312 if (run->userTarget != NULL) { 00313 config_perror("Default target already registered for this " 00314 "application-domain combination"); 00315 goto done; 00316 } 00317 } else { 00318 run = SNMP_MALLOC_STRUCT(netsnmp_lookup_target); 00319 run->application = strdup(application); 00320 run->domain = strdup(domain); 00321 run->target = NULL; 00322 if (prev) { 00323 run->next = prev->next; 00324 prev->next = run; 00325 } else { 00326 run->next = targets; 00327 targets = run; 00328 } 00329 } 00330 run->userTarget = strdup(target); 00331 done: 00332 free(target); 00333 free(domain); 00334 free(application); 00335 } 00336 00337 static void 00338 netsnmp_clear_user_target(void) 00339 { 00340 struct netsnmp_lookup_target *run = targets, *prev = NULL; 00341 00342 while (run) { 00343 if (run->userTarget != NULL) { 00344 free(run->userTarget); 00345 run->userTarget = NULL; 00346 } 00347 if (run->target == NULL) { 00348 struct netsnmp_lookup_target *tmp = run; 00349 if (prev) 00350 run = prev->next = run->next; 00351 else 00352 run = targets = run->next; 00353 free(tmp->application); 00354 free(tmp->domain); 00355 free(tmp); 00356 } else { 00357 prev = run; 00358 run = run->next; 00359 } 00360 } 00361 } 00362 00363 const char* 00364 netsnmp_lookup_default_target(const char* application, const char* domain) 00365 { 00366 int i = 0; 00367 struct netsnmp_lookup_target *run = targets; 00368 const char *res; 00369 00370 if (application == NULL || domain == NULL) 00371 res = NULL; 00372 else { 00373 while (run && ((i = strcmp(run->application, application)) < 0 || 00374 (i == 0 && strcmp(run->domain, domain) < 0))) 00375 run = run->next; 00376 if (run && i == 0 && strcmp(run->domain, domain) == 0) 00377 if (run->userTarget != NULL) 00378 res = run->userTarget; 00379 else 00380 res = run->target; 00381 else 00382 res = NULL; 00383 } 00384 DEBUGMSGTL(("defaults", 00385 "netsnmp_lookup_default_target(\"%s\", \"%s\") -> \"%s\"\n", 00386 application ? application : "[NIL]", 00387 domain ? domain : "[NIL]", 00388 res ? res : "[NIL]")); 00389 return res; 00390 } 00391 00392 void 00393 netsnmp_register_service_handlers(void) 00394 { 00395 register_config_handler("snmp:", "defDomain", 00396 netsnmp_register_user_domain, 00397 netsnmp_clear_user_domain, 00398 "application domain"); 00399 register_config_handler("snmp:", "defTarget", 00400 netsnmp_register_user_target, 00401 netsnmp_clear_user_target, 00402 "application domain target"); 00403 }