Logo
Home page Net-SNMP

Archive Search:

Require all words?

Site Search:
Google
Main Page | Modules | Data Structures | File List | Data Fields | Related Pages | Examples

instance.c

00001 /* Portions of this file are subject to the following copyright(s).  See
00002  * the Net-SNMP's COPYING file for more details and other copyrights
00003  * that may apply:
00004  */
00005 /*
00006  * Portions of this file are copyrighted by:
00007  * Copyright © 2003 Sun Microsystems, Inc. All rights reserved.
00008  * Use is subject to license terms specified in the COPYING file
00009  * distributed with the Net-SNMP package.
00010  */
00011 #include <net-snmp/net-snmp-config.h>
00012 
00013 #include <stdlib.h>
00014 #if HAVE_STRING_H
00015 #include <string.h>
00016 #else
00017 #include <strings.h>
00018 #endif
00019 
00020 #include <net-snmp/net-snmp-includes.h>
00021 #include <net-snmp/agent/net-snmp-agent-includes.h>
00022 
00023 #include <net-snmp/agent/instance.h>
00024 #include <net-snmp/agent/serialize.h>
00025 #include <net-snmp/agent/read_only.h>
00026 
00027 typedef struct netsnmp_num_file_instance_s {
00028     char *file_name;
00029     FILE *filep;
00030     int   type;
00031     int   flags;
00032 } netsnmp_num_file_instance;
00033 
00048 netsnmp_mib_handler *
00049 netsnmp_get_instance_handler(void)
00050 {
00051     return netsnmp_create_handler("instance",
00052                                   netsnmp_instance_helper_handler);
00053 }
00054 
00073 int
00074 netsnmp_register_instance(netsnmp_handler_registration *reginfo)
00075 {
00076     netsnmp_inject_handler(reginfo, netsnmp_get_instance_handler());
00077     return netsnmp_register_serialize(reginfo);
00078 }
00079 
00098 int
00099 netsnmp_register_read_only_instance(netsnmp_handler_registration *reginfo)
00100 {
00101     netsnmp_inject_handler(reginfo, netsnmp_get_instance_handler());
00102     netsnmp_inject_handler(reginfo, netsnmp_get_read_only_handler());
00103     return netsnmp_register_serialize(reginfo);
00104 }
00105 
00106 static
00107 netsnmp_handler_registration *
00108 get_reg(const char *name,
00109         const char *ourname,
00110         oid * reg_oid, size_t reg_oid_len,
00111         void *it,
00112         int modes,
00113         Netsnmp_Node_Handler * scalarh, Netsnmp_Node_Handler * subhandler,
00114         const char *contextName)
00115 {
00116     netsnmp_handler_registration *myreg;
00117     netsnmp_mib_handler *myhandler;
00118 
00119     if (subhandler) {
00120         myreg =
00121             netsnmp_create_handler_registration(name,
00122                                                 subhandler,
00123                                                 reg_oid, reg_oid_len,
00124                                                 modes);
00125         myhandler = netsnmp_create_handler(ourname, scalarh);
00126         myhandler->myvoid = (void *) it;
00127         netsnmp_inject_handler(myreg, myhandler);
00128     } else {
00129         myreg =
00130             netsnmp_create_handler_registration(name,
00131                                                 scalarh,
00132                                                 reg_oid, reg_oid_len,
00133                                                 modes);
00134         myreg->handler->myvoid = (void *) it;
00135     }
00136     if (contextName)
00137         myreg->contextName = strdup(contextName);
00138     return myreg;
00139 }
00140 
00141 int
00142 netsnmp_register_read_only_ulong_instance(const char *name,
00143                                           oid * reg_oid,
00144                                           size_t reg_oid_len, u_long * it,
00145                                           Netsnmp_Node_Handler *
00146                                           subhandler)
00147 {
00148     netsnmp_handler_registration *myreg;
00149 
00150     myreg = get_reg(name, "ulong_handler", reg_oid, reg_oid_len, it,
00151                     HANDLER_CAN_RONLY, netsnmp_instance_ulong_handler,
00152                     subhandler, NULL);
00153     return netsnmp_register_read_only_instance(myreg);
00154 }
00155 
00156 int
00157 netsnmp_register_ulong_instance(const char *name,
00158                                 oid * reg_oid, size_t reg_oid_len,
00159                                 u_long * it,
00160                                 Netsnmp_Node_Handler * subhandler)
00161 {
00162     netsnmp_handler_registration *myreg;
00163 
00164     myreg = get_reg(name, "ulong_handler", reg_oid, reg_oid_len, it,
00165                     HANDLER_CAN_RWRITE, netsnmp_instance_ulong_handler,
00166                     subhandler, NULL);
00167     return netsnmp_register_instance(myreg);
00168 }
00169 
00170 int
00171 netsnmp_register_read_only_counter32_instance(const char *name,
00172                                               oid * reg_oid,
00173                                               size_t reg_oid_len,
00174                                               u_long * it,
00175                                               Netsnmp_Node_Handler *
00176                                               subhandler)
00177 {
00178     netsnmp_handler_registration *myreg;
00179 
00180     myreg = get_reg(name, "counter32_handler", reg_oid, reg_oid_len, it,
00181                     HANDLER_CAN_RONLY, netsnmp_instance_counter32_handler,
00182                     subhandler, NULL);
00183     return netsnmp_register_read_only_instance(myreg);
00184 }
00185 
00186 int
00187 netsnmp_register_read_only_long_instance(const char *name,
00188                                          oid * reg_oid, size_t reg_oid_len,
00189                                          long *it,
00190                                          Netsnmp_Node_Handler * subhandler)
00191 {
00192     netsnmp_handler_registration *myreg;
00193 
00194     myreg = get_reg(name, "long_handler", reg_oid, reg_oid_len, it,
00195                     HANDLER_CAN_RONLY, netsnmp_instance_long_handler,
00196                     subhandler, NULL);
00197     return netsnmp_register_read_only_instance(myreg);
00198 }
00199 
00200 int
00201 netsnmp_register_long_instance(const char *name,
00202                                oid * reg_oid, size_t reg_oid_len,
00203                                long *it, Netsnmp_Node_Handler * subhandler)
00204 {
00205     netsnmp_handler_registration *myreg;
00206 
00207     myreg = get_reg(name, "long_handler", reg_oid, reg_oid_len, it,
00208                     HANDLER_CAN_RWRITE, netsnmp_instance_long_handler,
00209                     subhandler, NULL);
00210     return netsnmp_register_instance(myreg);
00211 }
00212 
00213 int
00214 netsnmp_register_read_only_int_instance(const char *name,
00215                                 oid * reg_oid, size_t reg_oid_len,
00216                                 int *it, Netsnmp_Node_Handler * subhandler)
00217 {
00218     netsnmp_handler_registration *myreg;
00219 
00220     myreg = get_reg(name, "int_handler", reg_oid, reg_oid_len, it,
00221                     HANDLER_CAN_RONLY, netsnmp_instance_int_handler,
00222                     subhandler, NULL);
00223     return netsnmp_register_read_only_instance(myreg);
00224 }
00225 
00226   /*
00227    * Compatibility with earlier (inconsistently named) routine
00228    */
00229 int
00230 register_read_only_int_instance(const char *name,
00231                                 oid * reg_oid, size_t reg_oid_len,
00232                                 int *it, Netsnmp_Node_Handler * subhandler)
00233 {
00234   return netsnmp_register_read_only_int_instance(name,
00235                                 reg_oid, reg_oid_len,
00236                                 it, subhandler);
00237 }
00238 
00239 /*
00240  * Context registrations
00241  */
00242 
00243 int
00244 netsnmp_register_read_only_ulong_instance_context(const char *name,
00245                                                   oid * reg_oid,
00246                                                   size_t reg_oid_len,
00247                                                   u_long * it,
00248                                                   Netsnmp_Node_Handler *
00249                                                   subhandler,
00250                                                   const char *contextName)
00251 {
00252     netsnmp_handler_registration *myreg;
00253 
00254     myreg = get_reg(name, "ulong_handler", reg_oid, reg_oid_len, it,
00255                     HANDLER_CAN_RONLY, netsnmp_instance_ulong_handler,
00256                     subhandler, contextName);
00257     return netsnmp_register_read_only_instance(myreg);
00258 }
00259 
00260 int
00261 netsnmp_register_ulong_instance_context(const char *name,
00262                                         oid * reg_oid, size_t reg_oid_len,
00263                                         u_long * it,
00264                                         Netsnmp_Node_Handler * subhandler,
00265                                         const char *contextName)
00266 {
00267     netsnmp_handler_registration *myreg;
00268 
00269     myreg = get_reg(name, "ulong_handler", reg_oid, reg_oid_len, it,
00270                     HANDLER_CAN_RWRITE, netsnmp_instance_ulong_handler,
00271                     subhandler, contextName);
00272     return netsnmp_register_instance(myreg);
00273 }
00274 
00275 int
00276 netsnmp_register_read_only_counter32_instance_context(const char *name,
00277                                                       oid * reg_oid,
00278                                                       size_t reg_oid_len,
00279                                                       u_long * it,
00280                                                       Netsnmp_Node_Handler *
00281                                                       subhandler,
00282                                                       const char *contextName)
00283 {
00284     netsnmp_handler_registration *myreg;
00285 
00286     myreg = get_reg(name, "counter32_handler", reg_oid, reg_oid_len, it,
00287                     HANDLER_CAN_RONLY, netsnmp_instance_counter32_handler,
00288                     subhandler, contextName);
00289     return netsnmp_register_read_only_instance(myreg);
00290 }
00291 
00292 int
00293 netsnmp_register_read_only_long_instance_context(const char *name,
00294                                                  oid * reg_oid,
00295                                                  size_t reg_oid_len,
00296                                                  long *it,
00297                                                  Netsnmp_Node_Handler
00298                                                  *subhandler,
00299                                                  const char *contextName)
00300 {
00301     netsnmp_handler_registration *myreg;
00302 
00303     myreg = get_reg(name, "long_handler", reg_oid, reg_oid_len, it,
00304                     HANDLER_CAN_RONLY, netsnmp_instance_long_handler,
00305                     subhandler, contextName);
00306     return netsnmp_register_read_only_instance(myreg);
00307 }
00308 
00309 int
00310 netsnmp_register_long_instance_context(const char *name,
00311                                        oid * reg_oid, size_t reg_oid_len,
00312                                        long *it,
00313                                        Netsnmp_Node_Handler * subhandler,
00314                                        const char *contextName)
00315 {
00316     netsnmp_handler_registration *myreg;
00317 
00318     myreg = get_reg(name, "long_handler", reg_oid, reg_oid_len, it,
00319                     HANDLER_CAN_RWRITE, netsnmp_instance_long_handler,
00320                     subhandler, contextName);
00321     return netsnmp_register_instance(myreg);
00322 }
00323 
00324 int
00325 netsnmp_register_int_instance_context(const char *name,
00326                                       oid * reg_oid,
00327                                       size_t reg_oid_len,
00328                                       int *it,
00329                                       Netsnmp_Node_Handler * subhandler,
00330                                       const char *contextName)
00331 {
00332     netsnmp_handler_registration *myreg;
00333 
00334     myreg = get_reg(name, "int_handler", reg_oid, reg_oid_len, it,
00335                     HANDLER_CAN_RWRITE, netsnmp_instance_int_handler,
00336                     subhandler, contextName);
00337     return netsnmp_register_read_only_instance(myreg);
00338 }
00339 
00340 int
00341 netsnmp_register_read_only_int_instance_context(const char *name,
00342                                                 oid * reg_oid,
00343                                                 size_t reg_oid_len,
00344                                                 int *it,
00345                                                 Netsnmp_Node_Handler * subhandler,
00346                                                 const char *contextName)
00347 {
00348     netsnmp_handler_registration *myreg;
00349 
00350     myreg = get_reg(name, "int_handler", reg_oid, reg_oid_len, it,
00351                     HANDLER_CAN_RONLY, netsnmp_instance_int_handler,
00352                     subhandler, contextName);
00353     return netsnmp_register_read_only_instance(myreg);
00354 }
00355 
00356 /*
00357  * Compatibility with earlier (inconsistently named) routine
00358  */
00359 int
00360 register_read_only_int_instance_context(const char *name,
00361                                         oid * reg_oid, size_t reg_oid_len,
00362                                         int *it,
00363                                         Netsnmp_Node_Handler * subhandler,
00364                                         const char *contextName)
00365 {
00366     return netsnmp_register_read_only_int_instance_context(name,
00367                                                            reg_oid, reg_oid_len,
00368                                                            it, subhandler,
00369                                                            contextName);
00370 }
00371 
00372 int
00373 netsnmp_register_num_file_instance(const char *name,
00374                                    oid * reg_oid, size_t reg_oid_len,
00375                                    char *file_name, int asn_type, int mode,
00376                                    Netsnmp_Node_Handler * subhandler,
00377                                    const char *contextName)
00378 {
00379     netsnmp_handler_registration *myreg;
00380     netsnmp_num_file_instance *nfi;
00381 
00382     if ((NULL == name) || (NULL == reg_oid) || (NULL == file_name)) {
00383         snmp_log(LOG_ERR, "bad parameter to netsnmp_register_num_file_instance\n");
00384         return MIB_REGISTRATION_FAILED;
00385     }
00386 
00387     nfi = SNMP_MALLOC_TYPEDEF(netsnmp_num_file_instance);
00388     if ((NULL == nfi) ||
00389         (NULL == (nfi->file_name = strdup(file_name)))) {
00390         snmp_log(LOG_ERR, "could not not allocate memory\n");
00391         return MIB_REGISTRATION_FAILED;
00392     }
00393 
00394     myreg = get_reg(name, "file_num_handler", reg_oid, reg_oid_len, nfi,
00395                     mode, netsnmp_instance_num_file_handler,
00396                     subhandler, contextName);
00397     if (NULL == myreg)
00398         return MIB_REGISTRATION_FAILED;
00399 
00400     nfi->type = asn_type;
00401 
00402     if (HANDLER_CAN_RONLY == mode)
00403         return netsnmp_register_read_only_instance(myreg);
00404 
00405     return netsnmp_register_instance(myreg);
00406 }
00407 
00426 int
00427 netsnmp_register_int_instance(const char *name,
00428                               oid * reg_oid, size_t reg_oid_len,
00429                               int *it, Netsnmp_Node_Handler * subhandler)
00430 {
00431     netsnmp_handler_registration *myreg;
00432 
00433     myreg = get_reg(name, "int_handler", reg_oid, reg_oid_len, it,
00434                     HANDLER_CAN_RWRITE, netsnmp_instance_int_handler,
00435                     subhandler, NULL);
00436     return netsnmp_register_instance(myreg);
00437 }
00438 
00439 int
00440 netsnmp_instance_ulong_handler(netsnmp_mib_handler *handler,
00441                                netsnmp_handler_registration *reginfo,
00442                                netsnmp_agent_request_info *reqinfo,
00443                                netsnmp_request_info *requests)
00444 {
00445 
00446     u_long         *it = (u_long *) handler->myvoid;
00447     u_long         *it_save;
00448 
00449     DEBUGMSGTL(("netsnmp_instance_ulong_handler", "Got request:  %d\n",
00450                 reqinfo->mode));
00451 
00452     switch (reqinfo->mode) {
00453         /*
00454          * data requests 
00455          */
00456     case MODE_GET:
00457         snmp_set_var_typed_value(requests->requestvb, ASN_UNSIGNED,
00458                                  (u_char *) it, sizeof(*it));
00459         break;
00460 
00461         /*
00462          * SET requests.  Should only get here if registered RWRITE 
00463          */
00464     case MODE_SET_RESERVE1:
00465         if (requests->requestvb->type != ASN_UNSIGNED)
00466             netsnmp_set_request_error(reqinfo, requests,
00467                                       SNMP_ERR_WRONGTYPE);
00468         break;
00469 
00470     case MODE_SET_RESERVE2:
00471         /*
00472          * store old info for undo later 
00473          */
00474         memdup((u_char **) & it_save, (u_char *) it, sizeof(u_long));
00475         if (it_save == NULL) {
00476             netsnmp_set_request_error(reqinfo, requests,
00477                                       SNMP_ERR_RESOURCEUNAVAILABLE);
00478             return SNMP_ERR_NOERROR;
00479         }
00480         netsnmp_request_add_list_data(requests,
00481                                       netsnmp_create_data_list
00482                                       (INSTANCE_HANDLER_NAME, it_save,
00483                                        free));
00484         break;
00485 
00486     case MODE_SET_ACTION:
00487         /*
00488          * update current 
00489          */
00490         DEBUGMSGTL(("testhandler", "updated u_long %ul -> %ul\n", *it,
00491                     *(requests->requestvb->val.integer)));
00492         *it = *(requests->requestvb->val.integer);
00493         break;
00494 
00495     case MODE_SET_UNDO:
00496         *it =
00497             *((u_long *) netsnmp_request_get_list_data(requests,
00498                                                        INSTANCE_HANDLER_NAME));
00499         break;
00500 
00501     case MODE_SET_COMMIT:
00502     case MODE_SET_FREE:
00503         /*
00504          * nothing to do 
00505          */
00506         break;
00507     }
00508 
00509     if (handler->next && handler->next->access_method)
00510         return netsnmp_call_next_handler(handler, reginfo, reqinfo,
00511                                          requests);
00512 
00513     return SNMP_ERR_NOERROR;
00514 }
00515 
00516 int
00517 netsnmp_instance_counter32_handler(netsnmp_mib_handler *handler,
00518                                    netsnmp_handler_registration *reginfo,
00519                                    netsnmp_agent_request_info *reqinfo,
00520                                    netsnmp_request_info *requests)
00521 {
00522 
00523     u_long         *it = (u_long *) handler->myvoid;
00524 
00525     DEBUGMSGTL(("netsnmp_instance_counter32_handler",
00526                 "Got request:  %d\n", reqinfo->mode));
00527 
00528     switch (reqinfo->mode) {
00529         /*
00530          * data requests 
00531          */
00532     case MODE_GET:
00533         snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER,
00534                                  (u_char *) it, sizeof(*it));
00535         break;
00536 
00537         /*
00538          * SET requests.  Should only get here if registered RWRITE 
00539          */
00540     default:
00541         snmp_log(LOG_ERR,
00542                  "netsnmp_instance_counter32_handler: illegal mode\n");
00543         netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
00544         return SNMP_ERR_NOERROR;
00545     }
00546     if (handler->next && handler->next->access_method)
00547         return netsnmp_call_next_handler(handler, reginfo, reqinfo,
00548                                          requests);
00549     return SNMP_ERR_NOERROR;
00550 }
00551 
00552 int
00553 netsnmp_instance_long_handler(netsnmp_mib_handler *handler,
00554                               netsnmp_handler_registration *reginfo,
00555                               netsnmp_agent_request_info *reqinfo,
00556                               netsnmp_request_info *requests)
00557 {
00558 
00559     long           *it = (u_long *) handler->myvoid;
00560     long           *it_save;
00561 
00562     DEBUGMSGTL(("netsnmp_instance_long_handler", "Got request:  %d\n",
00563                 reqinfo->mode));
00564 
00565     switch (reqinfo->mode) {
00566         /*
00567          * data requests 
00568          */
00569     case MODE_GET:
00570         snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
00571                                  (u_char *) it, sizeof(*it));
00572         break;
00573 
00574         /*
00575          * SET requests.  Should only get here if registered RWRITE 
00576          */
00577     case MODE_SET_RESERVE1:
00578         if (requests->requestvb->type != ASN_INTEGER)
00579             netsnmp_set_request_error(reqinfo, requests,
00580                                       SNMP_ERR_WRONGTYPE);
00581         break;
00582 
00583     case MODE_SET_RESERVE2:
00584         /*
00585          * store old info for undo later 
00586          */
00587         memdup((u_char **) & it_save, (u_char *) it, sizeof(u_long));
00588         if (it_save == NULL) {
00589             netsnmp_set_request_error(reqinfo, requests,
00590                                       SNMP_ERR_RESOURCEUNAVAILABLE);
00591             return SNMP_ERR_NOERROR;
00592         }
00593         netsnmp_request_add_list_data(requests,
00594                                       netsnmp_create_data_list
00595                                       (INSTANCE_HANDLER_NAME, it_save,
00596                                        free));
00597         break;
00598 
00599     case MODE_SET_ACTION:
00600         /*
00601          * update current 
00602          */
00603         DEBUGMSGTL(("testhandler", "updated u_long %ul -> %ul\n", *it,
00604                     *(requests->requestvb->val.integer)));
00605         *it = *(requests->requestvb->val.integer);
00606         break;
00607 
00608     case MODE_SET_UNDO:
00609         *it =
00610             *((u_long *) netsnmp_request_get_list_data(requests,
00611                                                        INSTANCE_HANDLER_NAME));
00612         break;
00613 
00614     case MODE_SET_COMMIT:
00615     case MODE_SET_FREE:
00616         /*
00617          * nothing to do 
00618          */
00619         break;
00620     }
00621     if (handler->next && handler->next->access_method)
00622         return netsnmp_call_next_handler(handler, reginfo, reqinfo,
00623                                          requests);
00624     return SNMP_ERR_NOERROR;
00625 }
00626 
00627 int
00628 netsnmp_instance_int_handler(netsnmp_mib_handler *handler,
00629                              netsnmp_handler_registration *reginfo,
00630                              netsnmp_agent_request_info *reqinfo,
00631                              netsnmp_request_info *requests)
00632 {
00633 
00634     int *it = (int *) handler->myvoid;
00635     int *it_save;
00636     long tmp_it;
00637     
00638     DEBUGMSGTL(("netsnmp_instance_int_handler", "Got request:  %d\n",
00639                 reqinfo->mode));
00640 
00641     switch (reqinfo->mode) {
00642         /*
00643          * data requests 
00644          */
00645     case MODE_GET:
00646         /*
00647          * Use a long here, otherwise on 64 bit use of an int would fail
00648          */
00649         tmp_it = *it;
00650         snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
00651                                  (u_char *) &tmp_it, sizeof(tmp_it));
00652         break;
00653 
00654         /*
00655          * SET requests.  Should only get here if registered RWRITE 
00656          */
00657     case MODE_SET_RESERVE1:
00658         if (requests->requestvb->type != ASN_INTEGER)
00659             netsnmp_set_request_error(reqinfo, requests,
00660                                       SNMP_ERR_WRONGTYPE);
00661         break;
00662 
00663     case MODE_SET_RESERVE2:
00664         /*
00665          * store old info for undo later 
00666          */
00667         memdup((u_char **) & it_save, (u_char *) it, sizeof(u_long));
00668         if (it_save == NULL) {
00669             netsnmp_set_request_error(reqinfo, requests,
00670                                       SNMP_ERR_RESOURCEUNAVAILABLE);
00671             return SNMP_ERR_NOERROR;
00672         }
00673         netsnmp_request_add_list_data(requests,
00674                                       netsnmp_create_data_list
00675                                       (INSTANCE_HANDLER_NAME, it_save,
00676                                        free));
00677         break;
00678 
00679     case MODE_SET_ACTION:
00680         /*
00681          * update current 
00682          */
00683         DEBUGMSGTL(("testhandler", "updated int %d -> %l\n", *it,
00684                     *(requests->requestvb->val.integer)));
00685         *it = (int) *(requests->requestvb->val.integer);
00686         break;
00687 
00688     case MODE_SET_UNDO:
00689         *it =
00690             *((u_int *) netsnmp_request_get_list_data(requests,
00691                                                       INSTANCE_HANDLER_NAME));
00692         break;
00693 
00694     case MODE_SET_COMMIT:
00695     case MODE_SET_FREE:
00696         /*
00697          * nothing to do 
00698          */
00699         break;
00700     }
00701     if (handler->next && handler->next->access_method)
00702         return netsnmp_call_next_handler(handler, reginfo, reqinfo,
00703                                          requests);
00704     return SNMP_ERR_NOERROR;
00705 }
00706 
00707 int
00708 netsnmp_instance_num_file_handler(netsnmp_mib_handler *handler,
00709                                   netsnmp_handler_registration *reginfo,
00710                                   netsnmp_agent_request_info *reqinfo,
00711                                   netsnmp_request_info *requests)
00712 {
00713     netsnmp_num_file_instance *nfi;
00714     u_long it, *it_save;
00715     int rc;
00716 
00717     netsnmp_assert(NULL != handler);
00718     nfi = (netsnmp_num_file_instance *)handler->myvoid;
00719     netsnmp_assert(NULL != nfi);
00720     netsnmp_assert(NULL != nfi->file_name);
00721 
00722     DEBUGMSGTL(("netsnmp_instance_int_handler", "Got request:  %d\n",
00723                 reqinfo->mode));
00724 
00725     switch (reqinfo->mode) {
00726         /*
00727          * data requests 
00728          */
00729     case MODE_GET:
00730         /*
00731          * Use a long here, otherwise on 64 bit use of an int would fail
00732          */
00733         netsnmp_assert(NULL == nfi->filep);
00734         nfi->filep = fopen(nfi->file_name, "r");
00735         if (NULL == nfi->filep) {
00736             netsnmp_set_request_error(reqinfo, requests,
00737                                       SNMP_NOSUCHINSTANCE);
00738             return SNMP_ERR_NOERROR;
00739         }
00740         rc = fscanf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu",
00741                     &it);
00742         fclose(nfi->filep);
00743         nfi->filep = NULL;
00744         if (rc != 1) {
00745             netsnmp_set_request_error(reqinfo, requests,
00746                                       SNMP_NOSUCHINSTANCE);
00747             return SNMP_ERR_NOERROR;
00748         }
00749         snmp_set_var_typed_value(requests->requestvb, nfi->type,
00750                                  (u_char *) &it, sizeof(it));
00751         break;
00752 
00753         /*
00754          * SET requests.  Should only get here if registered RWRITE 
00755          */
00756     case MODE_SET_RESERVE1:
00757         netsnmp_assert(NULL == nfi->filep);
00758         if (requests->requestvb->type != nfi->type)
00759             netsnmp_set_request_error(reqinfo, requests,
00760                                       SNMP_ERR_WRONGTYPE);
00761         break;
00762 
00763     case MODE_SET_RESERVE2:
00764         netsnmp_assert(NULL == nfi->filep);
00765         nfi->filep = fopen(nfi->file_name, "w+");
00766         if (NULL == nfi->filep) {
00767             netsnmp_set_request_error(reqinfo, requests,
00768                                       SNMP_ERR_NOTWRITABLE);
00769             return SNMP_ERR_NOERROR;
00770         }
00771         /*
00772          * store old info for undo later 
00773          */
00774         if (fscanf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu",
00775                    &it) != 1) {
00776             netsnmp_set_request_error(reqinfo, requests,
00777                                       SNMP_ERR_RESOURCEUNAVAILABLE);
00778             return SNMP_ERR_NOERROR;
00779         }
00780 
00781         memdup((u_char **) & it_save, (u_char *)&it, sizeof(u_long));
00782         if (it_save == NULL) {
00783             netsnmp_set_request_error(reqinfo, requests,
00784                                       SNMP_ERR_RESOURCEUNAVAILABLE);
00785             return SNMP_ERR_NOERROR;
00786         }
00787         netsnmp_request_add_list_data(requests,
00788                                       netsnmp_create_data_list
00789                                       (INSTANCE_HANDLER_NAME, it_save,
00790                                        free));
00791         break;
00792 
00793     case MODE_SET_ACTION:
00794         /*
00795          * update current 
00796          */
00797         DEBUGMSGTL(("helper:instance", "updated %s -> %l\n", nfi->file_name,
00798                     *(requests->requestvb->val.integer)));
00799         it = *(requests->requestvb->val.integer);
00800         rewind(nfi->filep); /* rewind to make sure we are at the beginning */
00801         rc = fprintf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu",
00802                      it);
00803         if (rc < 0) {
00804             netsnmp_set_request_error(reqinfo, requests,
00805                                       SNMP_ERR_GENERR);
00806             return SNMP_ERR_NOERROR;
00807         }
00808         break;
00809 
00810     case MODE_SET_UNDO:
00811         it =
00812             *((u_int *) netsnmp_request_get_list_data(requests,
00813                                                       INSTANCE_HANDLER_NAME));
00814         rc = fprintf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu",
00815                      it);
00816         if (rc < 0)
00817             netsnmp_set_request_error(reqinfo, requests,
00818                                       SNMP_ERR_UNDOFAILED);
00821     case MODE_SET_COMMIT:
00822     case MODE_SET_FREE:
00823         if (NULL != nfi->filep) {
00824             fclose(nfi->filep);
00825             nfi->filep = NULL;
00826         }
00827         break;
00828     }
00829 
00830     if (handler->next && handler->next->access_method)
00831         return netsnmp_call_next_handler(handler, reginfo, reqinfo,
00832                                          requests);
00833     return SNMP_ERR_NOERROR;
00834 }
00835 
00836 int
00837 netsnmp_instance_helper_handler(netsnmp_mib_handler *handler,
00838                                 netsnmp_handler_registration *reginfo,
00839                                 netsnmp_agent_request_info *reqinfo,
00840                                 netsnmp_request_info *requests)
00841 {
00842 
00843     netsnmp_variable_list *var = requests->requestvb;
00844 
00845     int             ret, cmp;
00846 
00847     DEBUGMSGTL(("helper:instance", "Got request:\n"));
00848     cmp = snmp_oid_compare(requests->requestvb->name,
00849                            requests->requestvb->name_length,
00850                            reginfo->rootoid, reginfo->rootoid_len);
00851 
00852     DEBUGMSGTL(("helper:instance", "  oid:", cmp));
00853     DEBUGMSGOID(("helper:instance", var->name, var->name_length));
00854     DEBUGMSG(("helper:instance", "\n"));
00855 
00856     switch (reqinfo->mode) {
00857     case MODE_GET:
00858         if (cmp != 0) {
00859             netsnmp_set_request_error(reqinfo, requests,
00860                                       SNMP_NOSUCHINSTANCE);
00861             return SNMP_ERR_NOERROR;
00862         } else {
00863             return netsnmp_call_next_handler(handler, reginfo, reqinfo,
00864                                              requests);
00865         }
00866         break;
00867 
00868     case MODE_SET_RESERVE1:
00869     case MODE_SET_RESERVE2:
00870     case MODE_SET_ACTION:
00871     case MODE_SET_COMMIT:
00872     case MODE_SET_UNDO:
00873     case MODE_SET_FREE:
00874         if (cmp != 0) {
00875             netsnmp_set_request_error(reqinfo, requests,
00876                                       SNMP_ERR_NOCREATION);
00877             return SNMP_ERR_NOERROR;
00878         } else {
00879             return netsnmp_call_next_handler(handler, reginfo, reqinfo,
00880                                              requests);
00881         }
00882         break;
00883 
00884     case MODE_GETNEXT:
00885         if (cmp < 0 || (cmp == 0 && requests->inclusive)) {
00886             reqinfo->mode = MODE_GET;
00887             snmp_set_var_objid(requests->requestvb, reginfo->rootoid,
00888                                reginfo->rootoid_len);
00889             ret =
00890                 netsnmp_call_next_handler(handler, reginfo, reqinfo,
00891                                           requests);
00892             reqinfo->mode = MODE_GETNEXT;
00893             if (!requests->delegated &&
00894                 (requests->requestvb->type == ASN_NULL ||
00895                  requests->requestvb->type == SNMP_NOSUCHINSTANCE ||
00896                  requests->requestvb->type == SNMP_NOSUCHOBJECT)) {
00897                 requests->requestvb->type = ASN_PRIV_RETRY;
00898             }
00899             return ret;
00900         } else {
00901             return SNMP_ERR_NOERROR;
00902         }
00903         break;
00904     }
00905     /*
00906      * got here only if illegal mode found 
00907      */
00908     return SNMP_ERR_GENERR;
00909 }
00910 
00911 /*
00912  * @} 
00913  */

Generated on Fri Dec 30 13:47:45 2005 for net-snmp by  doxygen 1.3.9.1

Valid CSS!


Last modified: Thursday, 01-Mar-2007 16:20:14 PST
For questions regarding web content and site functionality, please write to the net-snmp-users mail list.