net-snmp 5.7
snmp_service.c
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 }