snmpTargetAddrEntry.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:58k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  * snmpTargetAddrEntry MIB
  3.  * 
  4.  * This file was generated by mib2c and is intended for use as a mib module
  5.  * for the ucd-snmp snmpd agent. Edited by Michael Baer
  6.  * 
  7.  * last changed 2/2/99.
  8.  */
  9. #include <net-snmp/net-snmp-config.h>
  10. #if HAVE_STRING_H
  11. #include <string.h>
  12. #else
  13. #include <strings.h>
  14. #endif
  15. #include <stdlib.h>
  16. #include <ctype.h>
  17. #if HAVE_WINSOCK_H
  18. #include <winsock.h>
  19. #endif
  20. #include <net-snmp/net-snmp-includes.h>
  21. #include <net-snmp/agent/net-snmp-agent-includes.h>
  22. #include "snmpTargetAddrEntry.h"
  23. #include "util_funcs.h"
  24. #define snmpTargetAddrOIDLen 11 /*This is base+column, 
  25.                                  * i.e. everything but index */
  26. oid             snmpTargetAddrOID[snmpTargetAddrOIDLen] =
  27.     { 1, 3, 6, 1, 6, 3, 12, 1, 2, 1, 0 };
  28. static unsigned long snmpTargetSpinLock = 0;
  29. static struct targetAddrTable_struct *aAddrTable = 0;
  30. /*
  31.  * Utility routines 
  32.  */
  33. struct targetAddrTable_struct *
  34. get_addrTable(void)
  35. {
  36.     return aAddrTable;
  37. }
  38. struct targetAddrTable_struct *
  39. get_addrForName(char *name)
  40. {
  41.     struct targetAddrTable_struct *ptr;
  42.     for (ptr = aAddrTable; ptr != NULL; ptr = ptr->next) {
  43.         if (ptr->name && strcmp(ptr->name, name) == 0)
  44.             return ptr;
  45.     }
  46.     return NULL;
  47. }
  48. /*
  49.  * TargetAddrTable_create creates and returns a pointer
  50.  * to a targetAddrTable_struct with default values set 
  51.  */
  52. struct targetAddrTable_struct
  53.                *
  54. snmpTargetAddrTable_create(void)
  55. {
  56.     struct targetAddrTable_struct *newEntry;
  57.     newEntry = (struct targetAddrTable_struct *)
  58.         malloc(sizeof(struct targetAddrTable_struct));
  59.     if (newEntry) {
  60.         newEntry->name = 0;
  61.         newEntry->tDomainLen = 0;
  62.         newEntry->tAddress = 0;
  63.         newEntry->timeout = 1500;
  64.         newEntry->retryCount = 3;
  65.         newEntry->tagList = strdup("");
  66.         newEntry->params = 0;
  67.         newEntry->storageType = SNMP_STORAGE_NONVOLATILE;
  68.         newEntry->rowStatus = SNMP_ROW_NONEXISTENT;
  69.         newEntry->sess = (netsnmp_session *) NULL;
  70.         newEntry->next = 0;
  71.     }
  72.     return newEntry;
  73. }                               /* snmpTargetAddrTable_create */
  74. /*
  75.  * TargetAddrTable_dispose frees the space allocated to a
  76.  * targetAddrTable_struct 
  77.  */
  78. void
  79. snmpTargetAddrTable_dispose(struct targetAddrTable_struct *reaped)
  80. {
  81.     SNMP_FREE(reaped->name);
  82.     SNMP_FREE(reaped->tAddress);
  83.     SNMP_FREE(reaped->tagList);
  84.     SNMP_FREE(reaped->params);
  85.     SNMP_FREE(reaped);
  86. }                               /* snmpTargetAddrTable_dispose  */
  87. /*
  88.  * snmpTargetAddrTable_addToList adds a targetAddrTable_struct 
  89.  * to a list passed in. The list is assumed to be in a sorted order,
  90.  * low to high and this procedure inserts a new struct in the proper 
  91.  * location. Sorting uses OID values based on name. A new equal value 
  92.  * overwrites a current one. 
  93.  */
  94. void
  95. snmpTargetAddrTable_addToList(struct targetAddrTable_struct *newEntry,
  96.                               struct targetAddrTable_struct **listPtr)
  97. {
  98.     static struct targetAddrTable_struct *curr_struct, *prev_struct;
  99.     int             i;
  100.     size_t          newOIDLen = 0, currOIDLen = 0;
  101.     oid             newOID[128], currOID[128];
  102.     /*
  103.      * if the list is empty, add the new entry to the top 
  104.      */
  105.     if ((prev_struct = curr_struct = *listPtr) == 0) {
  106.         *listPtr = newEntry;
  107.         return;
  108.     } else {
  109.         /*
  110.          * get the 'OID' value of the new entry 
  111.          */
  112.         newOIDLen = strlen(newEntry->name);
  113.         for (i = 0; i < (int) newOIDLen; i++) {
  114.             newOID[i] = newEntry->name[i];
  115.         }
  116.         /*
  117.          * search through the list for an equal or greater OID value 
  118.          */
  119.         while (curr_struct != 0) {
  120.             currOIDLen = strlen(curr_struct->name);
  121.             for (i = 0; i < (int) currOIDLen; i++) {
  122.                 currOID[i] = curr_struct->name[i];
  123.             }
  124.             i = snmp_oid_compare(newOID, newOIDLen, currOID, currOIDLen);
  125.             if (i == 0) {       /* Exact match, overwrite with new struct */
  126.                 newEntry->next = curr_struct->next;
  127.                 /*
  128.                  * if curr_struct is the top of the list 
  129.                  */
  130.                 if (*listPtr == curr_struct)
  131.                     *listPtr = newEntry;
  132.                 else
  133.                     prev_struct->next = newEntry;
  134.                 snmpTargetAddrTable_dispose(curr_struct);
  135.                 return;
  136.             } else if (i < 0) { /* Found a greater OID, insert struct in front of it. */
  137.                 newEntry->next = curr_struct;
  138.                 /*
  139.                  * if curr_struct is the top of the list 
  140.                  */
  141.                 if (*listPtr == curr_struct)
  142.                     *listPtr = newEntry;
  143.                 else
  144.                     prev_struct->next = newEntry;
  145.                 return;
  146.             }
  147.             prev_struct = curr_struct;
  148.             curr_struct = curr_struct->next;
  149.         }
  150.     }
  151.     /*
  152.      * if we're here, no larger OID was ever found, insert on end of list 
  153.      */
  154.     prev_struct->next = newEntry;
  155. }                               /* snmpTargeAddrTable_addToList  */
  156. void
  157. snmpTargetAddrTable_add(struct targetAddrTable_struct *newEntry)
  158. {
  159.     snmpTargetAddrTable_addToList(newEntry, &aAddrTable);
  160. }
  161. /*
  162.  * snmpTargetAddrTable_remFromList removes a targetAddrTable_struct 
  163.  * from the list passed in 
  164.  */
  165. void
  166. snmpTargetAddrTable_remFromList(struct targetAddrTable_struct *oldEntry,
  167.                                 struct targetAddrTable_struct **listPtr)
  168. {
  169.     struct targetAddrTable_struct *tptr;
  170.     if ((tptr = *listPtr) == 0)
  171.         return;
  172.     else if (tptr == oldEntry) {
  173.         *listPtr = (*listPtr)->next;
  174.         snmpTargetAddrTable_dispose(tptr);
  175.         return;
  176.     } else {
  177.         while (tptr->next != 0) {
  178.             if (tptr->next == oldEntry) {
  179.                 tptr->next = tptr->next->next;
  180.                 snmpTargetAddrTable_dispose(oldEntry);
  181.                 return;
  182.             }
  183.             tptr = tptr->next;
  184.         }
  185.     }
  186. }                               /* snmpTargetAddrTable_remFromList  */
  187. /*
  188.  * lookup OID in the link list of Addr Table Entries 
  189.  */
  190. struct targetAddrTable_struct *
  191. search_snmpTargetAddrTable(oid * baseName,
  192.                            size_t baseNameLen,
  193.                            oid * name, size_t * length, int exact)
  194. {
  195.     static struct targetAddrTable_struct *temp_struct;
  196.     int             i;
  197.     size_t          myOIDLen = 0;
  198.     oid             newNum[128];
  199.     /*
  200.      * lookup entry in addrTable linked list, Get Current MIB ID 
  201.      */
  202.     memcpy(newNum, baseName, baseNameLen * sizeof(oid));
  203.     for (temp_struct = aAddrTable; temp_struct != 0;
  204.          temp_struct = temp_struct->next) {
  205.         for (i = 0; i < (int) strlen(temp_struct->name); i++) {
  206.             newNum[baseNameLen + i] = temp_struct->name[i];
  207.         }
  208.         myOIDLen = baseNameLen + strlen(temp_struct->name);
  209.         i = snmp_oid_compare(name, *length, newNum, myOIDLen);
  210.         /*
  211.          * Assumes that the linked list sorted by OID, low to high 
  212.          */
  213.         if ((i == 0 && exact != 0) || (i < 0 && exact == 0)) {
  214.             if (exact == 0) {
  215.                 memcpy(name, newNum, myOIDLen * sizeof(oid));
  216.                 *length = myOIDLen;
  217.             }
  218.             return temp_struct;
  219.         }
  220.     }
  221.     return (0);
  222. }                               /* search_snmpTargetAddrTable  */
  223. /*
  224.  * snmpTargetAddr_rowStatusCheck is boolean funciton that  checks 
  225.  * the status of a row's values in order to determine whether
  226.  * the row should be notReady or notInService  
  227.  */
  228. int
  229. snmpTargetAddr_rowStatusCheck(struct targetAddrTable_struct *entry)
  230. {
  231.     if ((entry->tDomainLen == 0) || (entry->tAddress == 0) ||
  232.         (entry->params == 0))
  233.         return 0;
  234.     else
  235.         return 1;
  236. }                               /* snmtpTargetAddrTable_rowStatusCheck */
  237. /*
  238.  * Init routines 
  239.  */
  240. /*
  241.  * this variable defines function callbacks and type return information 
  242.  * for the snmpTargetAddrEntry mib 
  243.  */
  244. struct variable2 snmpTargetAddrEntry_variables[] = {
  245.     {SNMPTARGETADDRTDOMAIN, ASN_OBJECT_ID, RWRITE,
  246.      var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRTDOMAINCOLUMN}},
  247.     {SNMPTARGETADDRTADDRESS, ASN_OCTET_STR, RWRITE,
  248.      var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRTADDRESSCOLUMN}},
  249.     {SNMPTARGETADDRTIMEOUT, ASN_INTEGER, RWRITE,
  250.      var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRTIMEOUTCOLUMN}},
  251.     {SNMPTARGETADDRRETRYCOUNT, ASN_INTEGER, RWRITE,
  252.      var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRRETRYCOUNTCOLUMN}},
  253.     {SNMPTARGETADDRTAGLIST, ASN_OCTET_STR, RWRITE,
  254.      var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRTAGLISTCOLUMN}},
  255.     {SNMPTARGETADDRPARAMS, ASN_OCTET_STR, RWRITE,
  256.      var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRPARAMSCOLUMN}},
  257.     {SNMPTARGETADDRSTORAGETYPE, ASN_INTEGER, RWRITE,
  258.      var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRSTORAGETYPECOLUMN}},
  259.     {SNMPTARGETADDRROWSTATUS, ASN_INTEGER, RWRITE,
  260.      var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRROWSTATUSCOLUMN}},
  261. };
  262. struct variable2 snmpTargetSpinLock_var[] = {
  263.     {SNMPTARGETSPINLOCK, ASN_INTEGER, RWRITE, var_targetSpinLock, 1, {1}}
  264. };
  265. static oid      snmpTargetSpinLock_oid[] = { 1, 3, 6, 1, 6, 3, 12, 1 };
  266. /*
  267.  * now load this mib into the agents mib table 
  268.  */
  269. oid             snmpTargetAddrEntry_variables_oid[] =
  270.     { 1, 3, 6, 1, 6, 3, 12, 1, 2, 1 };
  271. void
  272. init_snmpTargetAddrEntry(void)
  273. {
  274.     aAddrTable = 0;
  275.     DEBUGMSGTL(("snmpTargetAddrEntry", "initn"));
  276.     REGISTER_MIB("target/snmpTargetAddrEntry",
  277.                  snmpTargetAddrEntry_variables, variable2,
  278.                  snmpTargetAddrEntry_variables_oid);
  279.     REGISTER_MIB("target/snmpTargetSpinLock", snmpTargetSpinLock_var,
  280.                  variable2, snmpTargetSpinLock_oid);
  281.     snmpd_register_config_handler("targetAddr",
  282.                                   snmpd_parse_config_targetAddr, 0, NULL);
  283.     /*
  284.      * we need to be called back later 
  285.      */
  286.     snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
  287.                            store_snmpTargetAddrEntry, NULL);
  288. }                               /* init_snmpTargetAddrEntry */
  289. int
  290. snmpTargetAddr_addName(struct targetAddrTable_struct *entry, char *cptr)
  291. {
  292.     size_t          len;
  293.     if (cptr == 0) {
  294.         DEBUGMSGTL(("snmpTargetAddrEntry",
  295.                     "ERROR snmpTargetAddrEntry: no name in config stringn"));
  296.         return (0);
  297.     } else {
  298.         len = strlen(cptr);
  299.         /*
  300.          * spec check for string 1-32 
  301.          */
  302.         if (len < 1 || len > 32) {
  303.             DEBUGMSGTL(("snmpTargetAddrEntry",
  304.                         "ERROR snmpTargetAddrEntry: name out of range in config stringn"));
  305.             return (0);
  306.         }
  307.         entry->name = (char *) malloc(len + 1);
  308.         strncpy(entry->name, cptr, len);
  309.         entry->name[len] = '';
  310.     }
  311.     return (1);
  312. }                               /* addName */
  313. int
  314. snmpTargetAddr_addTDomain(struct targetAddrTable_struct *entry, char *cptr)
  315. {
  316.     size_t          len = 128;
  317.     if (cptr == 0) {
  318.         DEBUGMSGTL(("snmpTargetAddrEntry",
  319.                     "ERROR snmpTargetAddrEntry: no tDomain in config stringn"));
  320.         return (0);
  321.     }
  322.     if (!read_objid(cptr, entry->tDomain, &len)) {
  323.         DEBUGMSGTL(("snmpTargetAddrEntry",
  324.                     "ERROR snmpTargetAddrEntry: tDomain unreadable in config stringn"));
  325.         return (0);
  326.     }
  327.     /*
  328.      * spec check for oid 1-128 
  329.      */
  330.     if (len < 1 || len > 128) {
  331.         DEBUGMSGTL(("snmpTargetAddrEntry",
  332.                     "ERROR snmpTargetAddrEntry: tDomain out of range in config stringn"));
  333.         return (0);
  334.     }
  335.     entry->tDomainLen = len;
  336.     return (1);
  337. }                               /* snmpTargetAddr_addTDomain */
  338. int
  339. snmpTargetAddr_addTAddress(struct targetAddrTable_struct *entry,
  340.                            char *cptr, size_t len)
  341. {
  342.     if (cptr == 0) {
  343.         DEBUGMSGTL(("snmpTargetAddrEntry",
  344.                     "ERROR snmpTargetAddrEntry: no tAddress in config stringn"));
  345.         return (0);
  346.     } else {
  347.         /*
  348.          * spec check for string 1-32 
  349.          */
  350.         /*
  351.          * if (len < 1 || len > 32)  {
  352.          * DEBUGMSGTL(("snmpTargetAddrEntry","ERROR snmpTargetAddrEntry: name out of range in config stringn"));
  353.          * return(0);
  354.          * } 
  355.          */
  356.         SNMP_FREE(entry->tAddress);
  357.         entry->tAddress = (u_char *) malloc(len);
  358.         entry->tAddressLen = len;
  359.         memcpy(entry->tAddress, cptr, len);
  360.     }
  361.     return (1);
  362. }                               /* snmpTargetAddr_addTAddress */
  363. int
  364. snmpTargetAddr_addTimeout(struct targetAddrTable_struct *entry, char *cptr)
  365. {
  366.     if (cptr == 0) {
  367.         DEBUGMSGTL(("snmpTargetAddrEntry",
  368.                     "ERROR snmpTargetParamsEntry: no Timeout in config stringn"));
  369.         return (0);
  370.     } else if (!(isdigit(*cptr))) {
  371.         DEBUGMSGTL(("snmpTargetAddrEntry",
  372.                     "ERROR snmpTargeParamsEntry: Timeout is not a digit in config stringn"));
  373.         return (0);
  374.     }
  375.     /*
  376.      * check Timeout >= 0 
  377.      */
  378.     else if ((entry->timeout = (int) strtol(cptr, (char **) NULL, 0)) < 0) {
  379.         DEBUGMSGTL(("snmpTargetAddrEntry",
  380.                     "ERROR snmpTargeParamsEntry: Timeout out of range in config stringn"));
  381.         return (0);
  382.     }
  383.     return (1);
  384. }                               /* snmpTargetAddr_addTimeout  */
  385. int
  386. snmpTargetAddr_addRetryCount(struct targetAddrTable_struct *entry,
  387.                              char *cptr)
  388. {
  389.     if (cptr == 0) {
  390.         DEBUGMSGTL(("snmpTargetAddrEntry",
  391.                     "ERROR snmpTargetParamsEntry: no Retry Count in config stringn"));
  392.         return (0);
  393.     } else if (!(isdigit(*cptr))) {
  394.         DEBUGMSGTL(("snmpTargetAddrEntry",
  395.                     "ERROR snmpTargeParamsEntry: Retry Count is not a digit in config stringn"));
  396.         return (0);
  397.     }
  398.     /*
  399.      * spec check 0..255 
  400.      */
  401.     else {
  402.         entry->retryCount = (int) strtol(cptr, (char **) NULL, 0);
  403.         if ((entry->retryCount < 0) || (entry->retryCount > 255)) {
  404.             DEBUGMSGTL(("snmpTargetAddrEntry",
  405.                         "ERROR snmpTargeParamsEntry: Retry Count is out of range in config stringn"));
  406.             return (0);
  407.         }
  408.     }
  409.     return (1);
  410. }                               /* snmpTargetAddr_addRetryCount  */
  411. int
  412. snmpTargetAddr_addTagList(struct targetAddrTable_struct *entry, char *cptr)
  413. {
  414.     size_t          len;
  415.     if (cptr == 0) {
  416.         DEBUGMSGTL(("snmpTargetAddrEntry",
  417.                     "ERROR snmpTargetAddrEntry: no tag list in config stringn"));
  418.         return (0);
  419.     } else {
  420.         len = strlen(cptr);
  421.         /*
  422.          * spec check for string 0-255 
  423.          */
  424.         if (len < 0 || len > 255) {
  425.             DEBUGMSGTL(("snmpTargetAddrEntry",
  426.                         "ERROR snmpTargetAddrEntry: tag list out of range in config stringn"));
  427.             return (0);
  428.         }
  429.         SNMP_FREE(entry->tagList);
  430.         entry->tagList = (char *) malloc(len + 1);
  431.         strncpy(entry->tagList, cptr, len);
  432.         entry->tagList[len] = '';
  433.     }
  434.     return (1);
  435. }                               /* snmpTargetAddr_addTagList */
  436. int
  437. snmpTargetAddr_addParams(struct targetAddrTable_struct *entry, char *cptr)
  438. {
  439.     size_t          len;
  440.     if (cptr == 0) {
  441.         DEBUGMSGTL(("snmpTargetAddrEntry",
  442.                     "ERROR snmpTargetAddrEntry: no params in config stringn"));
  443.         return (0);
  444.     } else {
  445.         len = strlen(cptr);
  446.         /*
  447.          * spec check for string 1-32 
  448.          */
  449.         if (len < 1 || len > 32) {
  450.             DEBUGMSGTL(("snmpTargetAddrEntry",
  451.                         "ERROR snmpTargetAddrEntry: params out of range in config stringn"));
  452.             return (0);
  453.         }
  454.         entry->params = (char *) malloc(len + 1);
  455.         strncpy(entry->params, cptr, len);
  456.         entry->params[len] = '';
  457.     }
  458.     return (1);
  459. }                               /* snmpTargetAddr_addParams */
  460. int
  461. snmpTargetAddr_addStorageType(struct targetAddrTable_struct *entry,
  462.                               char *cptr)
  463. {
  464.     char            buff[1024];
  465.     if (cptr == 0) {
  466.         DEBUGMSGTL(("snmpTargetAddrEntry",
  467.                     "ERROR snmpTargetAddrEntry: no storage type in config stringn"));
  468.         return (0);
  469.     } else if (!(isdigit(*cptr))) {
  470.         DEBUGMSGTL(("snmpTargetAddrEntry",
  471.                     "ERROR snmpTargetAddrEntry: storage type is not a digit in config stringn"));
  472.         return (0);
  473.     }
  474.     /*
  475.      * check that storage type is a possible value 
  476.      */
  477.     else if (((entry->storageType = (int) strtol(cptr, (char **) NULL, 0))
  478.               != SNMP_STORAGE_OTHER) &&
  479.              (entry->storageType != SNMP_STORAGE_VOLATILE) &&
  480.              (entry->storageType != SNMP_STORAGE_NONVOLATILE) &&
  481.              (entry->storageType != SNMP_STORAGE_PERMANENT) &&
  482.              (entry->storageType != SNMP_STORAGE_READONLY)) {
  483.         snprintf(buff, sizeof(buff),
  484.                 "ERROR snmpTargetAddrEntry: storage type not a valid value of other(%d), volatile(%d), nonvolatile(%d), permanent(%d), or readonly(%d) in config string.n",
  485.                 SNMP_STORAGE_OTHER, SNMP_STORAGE_VOLATILE,
  486.                 SNMP_STORAGE_NONVOLATILE, SNMP_STORAGE_PERMANENT,
  487.                 SNMP_STORAGE_READONLY);
  488.         buff[ sizeof(buff)-1 ] = 0;
  489.         DEBUGMSGTL(("snmpTargetAddrEntry", buff));
  490.         return (0);
  491.     }
  492.     return (1);
  493. }                               /* snmpTargetAddr_addStorageType */
  494. int
  495. snmpTargetAddr_addRowStatus(struct targetAddrTable_struct *entry,
  496.                             char *cptr)
  497. {
  498.     char            buff[1024];
  499.     if (cptr == 0) {
  500.         DEBUGMSGTL(("snmpTargetAddrEntry",
  501.                     "ERROR snmpTargetAddrEntry: no Row Status in config stringn"));
  502.         return (0);
  503.     } else if (!(isdigit(*cptr))) {
  504.         DEBUGMSGTL(("snmpTargetAddrEntry",
  505.                     "ERROR snmpTargetAddrEntry: Row Status is not a digit in config stringn"));
  506.         return (0);
  507.     }
  508.     /*
  509.      * check that row status is a valid value 
  510.      */
  511.     else if (((entry->rowStatus = (int) strtol(cptr, (char **) NULL, 0))
  512.               != SNMP_ROW_ACTIVE) &&
  513.              (entry->rowStatus != SNMP_ROW_NOTINSERVICE) &&
  514.              (entry->rowStatus != SNMP_ROW_NOTREADY)) {
  515.         snprintf(buff, sizeof(buff),
  516.                 "ERROR snmpTargetAddrEntry: Row Status is not a valid value of active(%d), notinservice(%d), or notready(%d) in config string.n",
  517.                 SNMP_ROW_ACTIVE, SNMP_ROW_NOTINSERVICE, SNMP_ROW_NOTREADY);
  518.         buff[ sizeof(buff)-1 ] = 0;
  519.         DEBUGMSGTL(("snmpTargetAddrEntry", buff));
  520.         return (0);
  521.     }
  522.     return (1);
  523. }                               /* snmpTargetAddr_addRowStatus  */
  524. void
  525. snmpd_parse_config_targetAddr(const char *token, char *char_ptr)
  526. {
  527.     char           *cptr = char_ptr, buff[1024];
  528.     struct targetAddrTable_struct *newEntry;
  529.     int             i;
  530.     newEntry = snmpTargetAddrTable_create();
  531.     cptr = copy_nword(cptr, buff, sizeof(buff));
  532.     if (snmpTargetAddr_addName(newEntry, buff) == 0) {
  533.         snmpTargetAddrTable_dispose(newEntry);
  534.         return;
  535.     }
  536.     cptr = copy_nword(cptr, buff, sizeof(buff));
  537.     if (snmpTargetAddr_addTDomain(newEntry, buff) == 0) {
  538.         snmpTargetAddrTable_dispose(newEntry);
  539.         return;
  540.     }
  541.     cptr =
  542.         read_config_read_octet_string(cptr,
  543.                                       (u_char **) & newEntry->tAddress,
  544.                                       &newEntry->tAddressLen);
  545.     if (!cptr || !(newEntry->tAddress)) {
  546.         DEBUGMSGTL(("snmpTargetAddrEntry",
  547.                     "ERROR snmpTargetAddrEntry: no TAddress in config stringn"));
  548.         snmpTargetAddrTable_dispose(newEntry);
  549.         return;
  550.     }
  551.     cptr = copy_nword(cptr, buff, sizeof(buff));
  552.     if (snmpTargetAddr_addTimeout(newEntry, buff) == 0) {
  553.         snmpTargetAddrTable_dispose(newEntry);
  554.         return;
  555.     }
  556.     cptr = copy_nword(cptr, buff, sizeof(buff));
  557.     if (snmpTargetAddr_addRetryCount(newEntry, buff) == 0) {
  558.         snmpTargetAddrTable_dispose(newEntry);
  559.         return;
  560.     }
  561.     cptr = copy_nword(cptr, buff, sizeof(buff));
  562.     if (snmpTargetAddr_addTagList(newEntry, buff) == 0) {
  563.         snmpTargetAddrTable_dispose(newEntry);
  564.         return;
  565.     }
  566.     cptr = copy_nword(cptr, buff, sizeof(buff));
  567.     if (snmpTargetAddr_addParams(newEntry, buff) == 0) {
  568.         snmpTargetAddrTable_dispose(newEntry);
  569.         return;
  570.     }
  571.     cptr = copy_nword(cptr, buff, sizeof(buff));
  572.     if (snmpTargetAddr_addStorageType(newEntry, buff) == 0) {
  573.         snmpTargetAddrTable_dispose(newEntry);
  574.         return;
  575.     }
  576.     cptr = copy_nword(cptr, buff, sizeof(buff));
  577.     if (snmpTargetAddr_addRowStatus(newEntry, buff) == 0) {
  578.         snmpTargetAddrTable_dispose(newEntry);
  579.         return;
  580.     }
  581.     snprintf(buff, sizeof(buff), "snmp_parse_config_targetAddr, read: %sn",
  582.             newEntry->name);
  583.     buff[ sizeof(buff)-1 ] = 0;
  584.     for (i = 0; i < newEntry->tDomainLen; i++) {
  585.         snprintf(&buff[strlen(buff)], sizeof(buff)-strlen(buff)-1,
  586.                  ".%d", (int) newEntry->tDomain[i]);
  587.         buff[ sizeof(buff)-1 ] = 0;
  588.     }
  589.     snprintf(&buff[strlen(buff)], sizeof(buff)-strlen(buff)-1,
  590.             " %s %d %d %s %s %d %dn",
  591.             newEntry->tAddress, newEntry->timeout, newEntry->retryCount,
  592.             newEntry->tagList, newEntry->params, newEntry->storageType,
  593.             newEntry->rowStatus);
  594.     buff[ sizeof(buff)-1 ] = 0;
  595.     DEBUGMSGTL(("snmpTargetAddrEntry", buff));
  596.     snmpTargetAddrTable_addToList(newEntry, &aAddrTable);
  597. }                               /* snmpd_parse_config_target */
  598. /*
  599.  * Shutdown routines 
  600.  */
  601. /*
  602.  * store_snmpTargetAddrEntry handles the persistent storage proccess 
  603.  * for this MIB table. It writes out all the non-volatile rows 
  604.  * to permanent storage on a shutdown  
  605.  */
  606. int
  607. store_snmpTargetAddrEntry(int majorID, int minorID, void *serverarg,
  608.                           void *clientarg)
  609. {
  610.     struct targetAddrTable_struct *curr_struct;
  611.     char            line[1024];
  612.     int             i;
  613.     if ((curr_struct = aAddrTable) != 0) {
  614.         while (curr_struct != 0) {
  615.             if ((curr_struct->storageType == SNMP_STORAGE_NONVOLATILE ||
  616.                  curr_struct->storageType == SNMP_STORAGE_PERMANENT)
  617.                 &&
  618.                 (curr_struct->rowStatus == SNMP_ROW_ACTIVE ||
  619.                  curr_struct->rowStatus == SNMP_ROW_NOTINSERVICE)) {
  620.                 snprintf(line, sizeof(line),
  621.                         "targetAddr %s ", curr_struct->name);
  622.                 line[ sizeof(line)-1 ] = 0;
  623.                 for (i = 0; i < curr_struct->tDomainLen; i++) {
  624.                     snprintf(&line[strlen(line)],
  625.                             sizeof(line)-strlen(line)-1, ".%i",
  626.                             (int) curr_struct->tDomain[i]);
  627.                     line[ sizeof(line)-1 ] = 0;
  628.                 }
  629.                 if ( strlen(line)+2 < sizeof(line) ) {
  630.                     line[ strlen(line)+1 ] = 0;
  631.                     line[ strlen(line)   ] = ' ';
  632.                 }
  633.                 read_config_save_octet_string(&line[strlen(line)],
  634.                                               curr_struct->tAddress,
  635.                                               curr_struct->tAddressLen);
  636.                 snprintf(&line[strlen(line)], sizeof(line)-strlen(line)-1,
  637.                         " %i %i "%s" %s %i %i",
  638.                         curr_struct->timeout,
  639.                         curr_struct->retryCount, curr_struct->tagList,
  640.                         curr_struct->params, curr_struct->storageType,
  641.                         curr_struct->rowStatus);
  642.                 line[ sizeof(line)-1 ] = 0;
  643.                 /*
  644.                  * store to file 
  645.                  */
  646.                 snmpd_store_config(line);
  647.             }
  648.             curr_struct = curr_struct->next;
  649.         }
  650.     }
  651.     return SNMPERR_SUCCESS;
  652. }                               /*  store_snmpTargetAddrEntry  */
  653. /*
  654.  * MIB table access routines 
  655.  */
  656. u_char         *
  657. var_snmpTargetAddrEntry(struct variable * vp,
  658.                         oid * name,
  659.                         size_t * length,
  660.                         int exact,
  661.                         size_t * var_len, WriteMethod ** write_method)
  662. {
  663.     /*
  664.      * variables we may use later 
  665.      */
  666.     static long     long_ret;
  667.     static char     string[1500];
  668.     static oid      objid[128];
  669.     struct targetAddrTable_struct *temp_struct;
  670.     int             i = 0;
  671.     /*
  672.      * Set up write_method first, in case we return NULL before getting to the
  673.      * switch (vp->magic) below.  In some of these cases, we still want to call
  674.      * the appropriate write_method, if only to have it return the appropriate
  675.      * error.  
  676.      */
  677.     switch (vp->magic) {
  678.     case SNMPTARGETADDRTDOMAIN:
  679.         *write_method = write_snmpTargetAddrTDomain;
  680.         break;
  681.     case SNMPTARGETADDRTADDRESS:
  682.         *write_method = write_snmpTargetAddrTAddress;
  683.         break;
  684.     case SNMPTARGETADDRRETRYCOUNT:
  685.         *write_method = write_snmpTargetAddrRetryCount;
  686.         break;
  687.     case SNMPTARGETADDRTIMEOUT:
  688.         *write_method = write_snmpTargetAddrTimeout;
  689.         break;
  690.     case SNMPTARGETADDRTAGLIST:
  691.         *write_method = write_snmpTargetAddrTagList;
  692.         break;
  693.     case SNMPTARGETADDRPARAMS:
  694.         *write_method = write_snmpTargetAddrParams;
  695.         break;
  696.     case SNMPTARGETADDRSTORAGETYPE:
  697.         *write_method = write_snmpTargetAddrStorageType;
  698.         break;
  699.     case SNMPTARGETADDRROWSTATUS:
  700.         *write_method = write_snmpTargetAddrRowStatus;
  701.         break;
  702.     default:
  703.         *write_method = NULL;
  704.     }
  705.     *var_len = sizeof(long_ret);        /* assume an integer and change later if not */
  706.     /*
  707.      * look for OID in current table 
  708.      */
  709.     if ((temp_struct = search_snmpTargetAddrTable(vp->name, vp->namelen,
  710.                                                   name, length,
  711.                                                   exact)) == 0) {
  712.         return (0);
  713.     }
  714.     /*
  715.      * We found what we were looking for, either the next OID or the exact OID 
  716.      */
  717.     /*
  718.      * this is where we do the value assignments for the mib results. 
  719.      */
  720.     switch (vp->magic) {
  721.     case SNMPTARGETADDRTDOMAIN:
  722.         if (temp_struct->tDomainLen <= 0) {
  723.             return (0);
  724.         } else {
  725.             for (i = 0; i < temp_struct->tDomainLen; i++) {
  726.                 objid[i] = temp_struct->tDomain[i];
  727.             }
  728.             *var_len = temp_struct->tDomainLen * sizeof(oid);
  729.         }
  730.         return (unsigned char *) objid;
  731.     case SNMPTARGETADDRTADDRESS:
  732.         if (temp_struct->tAddress == 0)
  733.             return (0);
  734.         *var_len = temp_struct->tAddressLen;
  735.         return (unsigned char *) temp_struct->tAddress;
  736.     case SNMPTARGETADDRTIMEOUT:
  737.         long_ret = temp_struct->timeout;
  738.         return (unsigned char *) &long_ret;
  739.     case SNMPTARGETADDRRETRYCOUNT:
  740.         long_ret = temp_struct->retryCount;
  741.         return (unsigned char *) &long_ret;
  742.     case SNMPTARGETADDRTAGLIST:
  743.         if (temp_struct->tagList != NULL) {
  744.             strcpy(string, temp_struct->tagList);
  745.             *var_len = strlen(string);
  746.             return (unsigned char *) string;
  747.         } else {
  748.             return NULL;
  749.         }
  750.     case SNMPTARGETADDRPARAMS:
  751.         if (temp_struct->params == 0)
  752.             return (0);
  753.         strcpy(string, temp_struct->params);
  754.         *var_len = strlen(string);
  755.         return (unsigned char *) string;
  756.     case SNMPTARGETADDRSTORAGETYPE:
  757.         long_ret = temp_struct->storageType;
  758.         return (unsigned char *) &long_ret;
  759.     case SNMPTARGETADDRROWSTATUS:
  760.         long_ret = temp_struct->rowStatus;
  761.         return (unsigned char *) &long_ret;
  762.     default:
  763.         DEBUGMSGTL(("snmpd",
  764.                     "unknown sub-id %d in var_snmpTargetAddrEntryn",
  765.                     vp->magic));
  766.     }
  767.     return 0;
  768. }                               /* var_snmpTargetAddrEntry */
  769. int
  770. write_snmpTargetAddrTDomain(int action,
  771.                             u_char * var_val,
  772.                             u_char var_val_type,
  773.                             size_t var_val_len,
  774.                             u_char * statP, oid * name, size_t name_len)
  775. {
  776.     struct targetAddrTable_struct *target = NULL;
  777.     static oid      old_oid[MAX_OID_LEN];
  778.     static size_t   old_oid_len;
  779.     if (action == RESERVE1) {
  780.         if (var_val_type != ASN_OBJECT_ID) {
  781.             DEBUGMSGTL(("snmpTargetAddrEntry",
  782.                         "write to snmpTargetAddrTDomain not ASN_OBJECT_IDn"));
  783.             return SNMP_ERR_WRONGTYPE;
  784.         }
  785.         if ((var_val_len > (MAX_OID_LEN * sizeof(oid))) ||
  786.             (var_val_len % sizeof(oid) != 0)) {
  787.             DEBUGMSGTL(("snmpTargetAddrEntry",
  788.                         "write to snmpTargetAddrTDomain: bad lengthn"));
  789.             return SNMP_ERR_WRONGLENGTH;
  790.         }
  791.     } else if (action == RESERVE2) {
  792.         snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
  793.             SNMPTARGETADDRTDOMAINCOLUMN;
  794.         if ((target =
  795.              search_snmpTargetAddrTable(snmpTargetAddrOID,
  796.                                         snmpTargetAddrOIDLen, name,
  797.                                         &name_len, 1)) == 0) {
  798.             DEBUGMSGTL(("snmpTargetAddrEntry",
  799.                         "write to snmpTargetAddrTDomain: BAD OID!n"));
  800.             return SNMP_ERR_INCONSISTENTNAME;
  801.         } else {
  802.             if (target->storageType == SNMP_STORAGE_READONLY) {
  803.                 DEBUGMSGTL(("snmpTargetAddrEntry",
  804.                             "write to snmpTargetAddrTDomain: row is read onlyn"));
  805.                 return SNMP_ERR_NOTWRITABLE;
  806.             }
  807.             if (target->rowStatus == SNMP_ROW_ACTIVE) {
  808.                 DEBUGMSGTL(("snmpTargetAddrEntry",
  809.                             "write to snmpTargetAddrTDomain: not allowed in active row.n"));
  810.                 return SNMP_ERR_INCONSISTENTVALUE;
  811.             }
  812.             /*
  813.              * Finally, we're golden, save current value.  
  814.              */
  815.             memcpy(old_oid, target->tDomain,
  816.                    target->tDomainLen * sizeof(oid));
  817.             old_oid_len = target->tDomainLen;
  818.             memcpy((u_char *) target->tDomain, var_val, var_val_len);
  819.             target->tDomainLen = var_val_len / sizeof(oid);
  820.             /*
  821.              * If row is new, check if its status can be updated.  
  822.              */
  823.             if ((target->rowStatus == SNMP_ROW_NOTREADY) &&
  824.                 (snmpTargetAddr_rowStatusCheck(target) != 0)) {
  825.                 target->rowStatus = SNMP_ROW_NOTINSERVICE;
  826.             }
  827.         }
  828.     } else if (action == FREE || action == UNDO) {
  829.         /*
  830.          * Try to undo the SET here (abnormal usage of FREE clause)  
  831.          */
  832.         snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
  833.             SNMPTARGETADDRTDOMAINCOLUMN;
  834.         if ((target =
  835.              search_snmpTargetAddrTable(snmpTargetAddrOID,
  836.                                         snmpTargetAddrOIDLen, name,
  837.                                         &name_len, 1)) != NULL) {
  838.             if (target->storageType != SNMP_STORAGE_READONLY
  839.                 && target->rowStatus != SNMP_ROW_ACTIVE) {
  840.                 memcpy((u_char *) target->tDomain, (u_char *) old_oid,
  841.                        (old_oid_len * sizeof(oid)));
  842.                 target->tDomainLen = old_oid_len;
  843.                 if (target->rowStatus == SNMP_ROW_NOTINSERVICE &&
  844.                     snmpTargetAddr_rowStatusCheck(target) == 0) {
  845.                     target->rowStatus = SNMP_ROW_NOTREADY;
  846.                 }
  847.             }
  848.         }
  849.     }
  850.     return SNMP_ERR_NOERROR;
  851. }                               /* write_snmpTargetAddrTDomain */
  852. int
  853. write_snmpTargetAddrTAddress(int action,
  854.                              u_char * var_val,
  855.                              u_char var_val_type,
  856.                              size_t var_val_len,
  857.                              u_char * statP, oid * name, size_t name_len)
  858. {
  859.     struct targetAddrTable_struct *target = NULL;
  860.     static char    *old_addr = NULL;
  861.     static size_t   old_len = 0;
  862.     if (action == RESERVE1) {
  863.         if (var_val_type != ASN_OCTET_STR) {
  864.             DEBUGMSGTL(("snmpTargetAddrEntry",
  865.                         "write to snmpTargetAddrTAddress not ASN_OCTET_STRn"));
  866.             return SNMP_ERR_WRONGTYPE;
  867.         } else if (var_val_len < 1 || var_val_len > 255) {
  868.             return SNMP_ERR_WRONGLENGTH;
  869.         }
  870.     } else if (action == RESERVE2) {
  871.         snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
  872.             SNMPTARGETADDRTADDRESSCOLUMN;
  873.         if ((target =
  874.              search_snmpTargetAddrTable(snmpTargetAddrOID,
  875.                                         snmpTargetAddrOIDLen, name,
  876.                                         &name_len, 1)) == 0) {
  877.             DEBUGMSGTL(("snmpTargetAddrEntry",
  878.                         "write to snmpTargetAddrTAddress: BAD OID!n"));
  879.             return SNMP_ERR_INCONSISTENTNAME;
  880.         } else {
  881.             if (target->storageType == SNMP_STORAGE_READONLY) {
  882.                 DEBUGMSGTL(("snmpTargetAddrEntry",
  883.                             "write to snmpTargetAddrTAddress: row is read onlyn"));
  884.                 return SNMP_ERR_NOTWRITABLE;
  885.             }
  886.             if (target->rowStatus == SNMP_ROW_ACTIVE) {
  887.                 DEBUGMSGTL(("snmpTargetAddrEntry",
  888.                             "write to snmpTargetAddrTAddress: not allowed in active row.n"));
  889.                 return SNMP_ERR_INCONSISTENTVALUE;
  890.             }
  891.             old_addr = target->tAddress;
  892.             old_len = target->tAddressLen;
  893.             target->tAddress = (u_char *) malloc(var_val_len);
  894.             if (target->tAddress == NULL) {
  895.                 return SNMP_ERR_RESOURCEUNAVAILABLE;
  896.             }
  897.             memcpy(target->tAddress, var_val, var_val_len);
  898.             target->tAddressLen = var_val_len;
  899.             /*
  900.              * If row is new, check if its status can be updated.  
  901.              */
  902.             if ((target->rowStatus == SNMP_ROW_NOTREADY) &&
  903.                 (snmpTargetAddr_rowStatusCheck(target) != 0)) {
  904.                 target->rowStatus = SNMP_ROW_NOTINSERVICE;
  905.             }
  906.         }
  907.     } else if (action == COMMIT) {
  908.         SNMP_FREE(old_addr);
  909.         old_addr = NULL;
  910.     } else if (action == FREE || action == UNDO) {
  911.         /*
  912.          * Try to undo the SET here (abnormal usage of FREE clause)  
  913.          */
  914.         snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
  915.             SNMPTARGETADDRTADDRESSCOLUMN;
  916.         if ((target =
  917.              search_snmpTargetAddrTable(snmpTargetAddrOID,
  918.                                         snmpTargetAddrOIDLen, name,
  919.                                         &name_len, 1)) != NULL) {
  920.             if (target->storageType != SNMP_STORAGE_READONLY
  921.                 && target->rowStatus != SNMP_ROW_ACTIVE) {
  922.                 SNMP_FREE(target->tAddress);
  923.                 target->tAddress = old_addr;
  924.                 target->tAddressLen = old_len;
  925.                 if (target->rowStatus == SNMP_ROW_NOTINSERVICE &&
  926.                     snmpTargetAddr_rowStatusCheck(target) == 0) {
  927.                     target->rowStatus = SNMP_ROW_NOTREADY;
  928.                 }
  929.             }
  930.         }
  931.     }
  932.     return SNMP_ERR_NOERROR;
  933. }                               /* write_snmpTargetAddrTAddress */
  934. int
  935. write_snmpTargetAddrTimeout(int action,
  936.                             u_char * var_val,
  937.                             u_char var_val_type,
  938.                             size_t var_val_len,
  939.                             u_char * statP, oid * name, size_t name_len)
  940. {
  941.     /*
  942.      * variables we may use later 
  943.      */
  944.     static long     long_ret;
  945.     size_t          size;
  946.     struct targetAddrTable_struct *temp_struct;
  947.     if (action == RESERVE1) {
  948.         if (var_val_type != ASN_INTEGER) {
  949.             DEBUGMSGTL(("snmpTargetAddrEntry",
  950.                         "write to snmpTargetAddrTimeout not ASN_INTEGERn"));
  951.             return SNMP_ERR_WRONGTYPE;
  952.         }
  953.         if (var_val_len > (size = sizeof(long_ret))) {
  954.             DEBUGMSGTL(("snmpTargetAddrEntry",
  955.                         "write to snmpTargetAddrTimeout: bad lengthn"));
  956.             return SNMP_ERR_WRONGLENGTH;
  957.         }
  958.         long_ret = *((long *) var_val);
  959.     } else if (action == RESERVE2) {
  960.         /*
  961.          * spec check range, no spec check 
  962.          */
  963.         /*
  964.          * Find row in linked list and check pertinent status... 
  965.          */
  966.         snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
  967.             SNMPTARGETADDRTIMEOUTCOLUMN;
  968.         if ((temp_struct =
  969.              search_snmpTargetAddrTable(snmpTargetAddrOID,
  970.                                         snmpTargetAddrOIDLen, name, &name_len,
  971.                                         1)) == 0) {
  972.             DEBUGMSGTL(("snmpTargetAddrEntry",
  973.                         "write to snmpTargetAddrTimeout : BAD OIDn"));
  974.             return SNMP_ERR_NOSUCHNAME;
  975.         }
  976.         /*
  977.          * row exists, check if it is changeable 
  978.          */
  979.         if (temp_struct->storageType == SNMP_STORAGE_READONLY) {
  980.             DEBUGMSGTL(("snmpTargetAddrEntry",
  981.                         "write to snmpTargetAddrTimeout : row is read onlyn"));
  982.             return SNMP_ERR_NOTWRITABLE;
  983.         }
  984.     } else if  (action == COMMIT) {
  985.         /*
  986.          * Finally, we're golden, should we save value? 
  987.          */
  988.         snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
  989.             SNMPTARGETADDRTIMEOUTCOLUMN;
  990.         if ((temp_struct =
  991.              search_snmpTargetAddrTable(snmpTargetAddrOID,
  992.                                         snmpTargetAddrOIDLen, name, &name_len,
  993.                                         1)) != 0) {
  994.             temp_struct->timeout = long_ret;
  995.         }
  996.     }
  997.     return SNMP_ERR_NOERROR;
  998. }                               /* write_snmpTargetAddrTimeout */
  999. int
  1000. write_snmpTargetAddrRetryCount(int action,
  1001.                                u_char * var_val,
  1002.                                u_char var_val_type,
  1003.                                size_t var_val_len,
  1004.                                u_char * statP, oid * name, size_t name_len)
  1005. {
  1006.     static long     long_ret;
  1007.     struct targetAddrTable_struct *target;
  1008.     if (action == RESERVE1) {
  1009.         if (var_val_type != ASN_INTEGER) {
  1010.             DEBUGMSGTL(("snmpTargetAddrEntry",
  1011.                         "write to snmpTargetAddrRetryCount not ASN_INTEGERn"));
  1012.             return SNMP_ERR_WRONGTYPE;
  1013.         }
  1014.         if (var_val_len != sizeof(long)) {
  1015.             DEBUGMSGTL(("snmpTargetAddrEntry",
  1016.                         "write to snmpTargetAddrRetryCount: bad lengthn"));
  1017.             return SNMP_ERR_WRONGLENGTH;
  1018.         }
  1019.         long_ret = *((long *) var_val);
  1020.         if (long_ret < 0 || long_ret > 255) {
  1021.             return SNMP_ERR_WRONGVALUE;
  1022.         }
  1023.     } else if (action == RESERVE2) {
  1024.         snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
  1025.             SNMPTARGETADDRRETRYCOUNTCOLUMN;
  1026.         if ((target = search_snmpTargetAddrTable(snmpTargetAddrOID,
  1027.                                                  snmpTargetAddrOIDLen,
  1028.                                                  name, &name_len,
  1029.                                                  1)) == NULL) {
  1030.             DEBUGMSGTL(("snmpTargetAddrEntry",
  1031.                         "write to snmpTargetAddrTimeout: BAD OIDn"));
  1032.             return SNMP_ERR_INCONSISTENTNAME;
  1033.         } else {
  1034.             if (target->storageType == SNMP_STORAGE_READONLY) {
  1035.                 DEBUGMSGTL(("snmpTargetAddrEntry",
  1036.                             "write to snmpTargetAddrRetryCount: row is read onlyn"));
  1037.                 return SNMP_ERR_NOTWRITABLE;
  1038.             }
  1039.         }
  1040.     } else if (action == COMMIT) {
  1041.         snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
  1042.             SNMPTARGETADDRRETRYCOUNTCOLUMN;
  1043.         if ((target = search_snmpTargetAddrTable(snmpTargetAddrOID,
  1044.                                                  snmpTargetAddrOIDLen,
  1045.                                                  name, &name_len,
  1046.                                                  1)) != NULL) {
  1047.             target->retryCount = long_ret;
  1048.         }
  1049.     }
  1050.     return SNMP_ERR_NOERROR;
  1051. }                               /* write_snmpTargetAddrRetryCount */
  1052. static int
  1053. is_delim(const char c)
  1054. {
  1055.     return (c == 0x020 || c == 0x09 || c == 0x0d || c == 0x0b);
  1056. }
  1057. int
  1058. snmpTagListValid(const char *tagList, const size_t tagListLen)
  1059. {
  1060.     size_t          i = 0;
  1061.     int             inTag = 0;
  1062.     for (i = 0; i < tagListLen; i++) {
  1063.         if (is_delim(tagList[i]) && !inTag) {
  1064.             /*
  1065.              * Either a leading delimiter or two consecutive delimiters.  
  1066.              */
  1067.             return 0;
  1068.         } else if (is_delim(tagList[i]) && inTag) {
  1069.             inTag = 0;
  1070.         } else if (!is_delim(tagList[i]) && !inTag) {
  1071.             inTag = 1;
  1072.         }
  1073.     }
  1074.     if (!inTag) {
  1075.         /*
  1076.          * Trailing delimiter.  
  1077.          */
  1078.         return 0;
  1079.     }
  1080.     return 1;
  1081. }
  1082. int
  1083. write_snmpTargetAddrTagList(int action,
  1084.                             u_char * var_val,
  1085.                             u_char var_val_type,
  1086.                             size_t var_val_len,
  1087.                             u_char * statP, oid * name, size_t name_len)
  1088. {
  1089.     struct targetAddrTable_struct *target = NULL;
  1090.     static char    *old_tlist;
  1091.     if (action == RESERVE1) {
  1092.         if (var_val_type != ASN_OCTET_STR) {
  1093.             DEBUGMSGTL(("snmpTargetAddrEntry",
  1094.                         "write to snmpTargetAddrTagList not ASN_OCTET_STRn"));
  1095.             return SNMP_ERR_WRONGTYPE;
  1096.         }
  1097.         if (var_val_len > 255) {
  1098.             DEBUGMSGTL(("snmpTargetAddrEntry",
  1099.                         "write to snmpTargetAddrTagList: bad lengthn"));
  1100.             return SNMP_ERR_WRONGLENGTH;
  1101.         }
  1102.         if (!snmpTagListValid(var_val, var_val_len)) {
  1103.             return SNMP_ERR_WRONGVALUE;
  1104.         }
  1105.     } else if (action == RESERVE2) {
  1106.         snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
  1107.             SNMPTARGETADDRTAGLISTCOLUMN;
  1108.         if ((target =
  1109.              search_snmpTargetAddrTable(snmpTargetAddrOID,
  1110.                                         snmpTargetAddrOIDLen, name,
  1111.                                         &name_len, 1)) == NULL) {
  1112.             DEBUGMSGTL(("snmpTargetAddrEntry",
  1113.                         "write to snmpTargetAddrTagList: BAD OID!n"));
  1114.             return SNMP_ERR_INCONSISTENTNAME;
  1115.         } else {
  1116.             if (target->storageType == SNMP_STORAGE_READONLY) {
  1117.                 DEBUGMSGTL(("snmpTargetAddrEntry",
  1118.                             "write to snmpTargetAddrTagList: row is read onlyn"));
  1119.                 return SNMP_ERR_NOTWRITABLE;
  1120.             }
  1121.             old_tlist = target->tagList;
  1122.             target->tagList = (char *) malloc(var_val_len + 1);
  1123.             if (target->tagList == NULL) {
  1124.                 return SNMP_ERR_RESOURCEUNAVAILABLE;
  1125.             }
  1126.             memcpy(target->tagList, var_val, var_val_len);
  1127.             target->tagList[var_val_len] = '';
  1128.         }
  1129.     } else if (action == COMMIT) {
  1130.         SNMP_FREE(old_tlist);
  1131.         old_tlist = NULL;
  1132.     } else if (action == FREE || action == UNDO) {
  1133.         snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
  1134.             SNMPTARGETADDRTAGLISTCOLUMN;
  1135.         if ((target =
  1136.              search_snmpTargetAddrTable(snmpTargetAddrOID,
  1137.                                         snmpTargetAddrOIDLen, name,
  1138.                                         &name_len, 1)) != NULL) {
  1139.             if (target->storageType != SNMP_STORAGE_READONLY) {
  1140.                 SNMP_FREE(target->tagList);
  1141.                 target->tagList = old_tlist;
  1142.             }
  1143.         }
  1144.     }
  1145.     return SNMP_ERR_NOERROR;
  1146. }                               /* write_snmpTargetAddrTagList */
  1147. int
  1148. write_snmpTargetAddrParams(int action,
  1149.                            u_char * var_val,
  1150.                            u_char var_val_type,
  1151.                            size_t var_val_len,
  1152.                            u_char * statP, oid * name, size_t name_len)
  1153. {
  1154.     struct targetAddrTable_struct *target = NULL;
  1155.     static char    *old_params = NULL;
  1156.     if (action == RESERVE1) {
  1157.         if (var_val_type != ASN_OCTET_STR) {
  1158.             DEBUGMSGTL(("snmpTargetAddrEntry",
  1159.                         "write to snmpTargetAddrParams not ASN_OCTET_STRn"));
  1160.             return SNMP_ERR_WRONGTYPE;
  1161.         } else if (var_val_len < 1 || var_val_len > 32) {
  1162.             return SNMP_ERR_WRONGLENGTH;
  1163.         }
  1164.     } else if (action == RESERVE2) {
  1165.         snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
  1166.             SNMPTARGETADDRPARAMSCOLUMN;
  1167.         if ((target =
  1168.              search_snmpTargetAddrTable(snmpTargetAddrOID,
  1169.                                         snmpTargetAddrOIDLen, name,
  1170.                                         &name_len, 1)) == 0) {
  1171.             DEBUGMSGTL(("snmpTargetAddrEntry",
  1172.                         "write to snmpTargetAddrParams: BAD OID!n"));
  1173.             return SNMP_ERR_INCONSISTENTNAME;
  1174.         } else {
  1175.             if (target->storageType == SNMP_STORAGE_READONLY) {
  1176.                 DEBUGMSGTL(("snmpTargetAddrEntry",
  1177.                             "write to snmpTargetAddrParams: row is read onlyn"));
  1178.                 return SNMP_ERR_NOTWRITABLE;
  1179.             }
  1180.             if (target->rowStatus == SNMP_ROW_ACTIVE) {
  1181.                 DEBUGMSGTL(("snmpTargetAddrEntry",
  1182.                             "write to snmpTargetAddrParams: not allowed in active row.n"));
  1183.                 return SNMP_ERR_INCONSISTENTVALUE;
  1184.             }
  1185.             old_params = target->params;
  1186.             target->params = (u_char *) malloc(var_val_len + 1);
  1187.             if (target->params == NULL) {
  1188.                 return SNMP_ERR_RESOURCEUNAVAILABLE;
  1189.             }
  1190.             memcpy(target->params, var_val, var_val_len);
  1191.             target->params[var_val_len] = '';
  1192.             /*
  1193.              * If row is new, check if its status can be updated.  
  1194.              */
  1195.             if ((target->rowStatus == SNMP_ROW_NOTREADY) &&
  1196.                 (snmpTargetAddr_rowStatusCheck(target) != 0)) {
  1197.                 target->rowStatus = SNMP_ROW_NOTINSERVICE;
  1198.             }
  1199.         }
  1200.     } else if (action == COMMIT) {
  1201.         SNMP_FREE(old_params);
  1202.         old_params = NULL;
  1203.     } else if (action == FREE || action == UNDO) {
  1204.         /*
  1205.          * Try to undo the SET here (abnormal usage of FREE clause)  
  1206.          */
  1207.         snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
  1208.             SNMPTARGETADDRPARAMSCOLUMN;
  1209.         if ((target =
  1210.              search_snmpTargetAddrTable(snmpTargetAddrOID,
  1211.                                         snmpTargetAddrOIDLen, name,
  1212.                                         &name_len, 1)) != NULL) {
  1213.             if (target->storageType != SNMP_STORAGE_READONLY
  1214.                 && target->rowStatus != SNMP_ROW_ACTIVE) {
  1215.                 SNMP_FREE(target->params);
  1216.                 target->params = old_params;
  1217.                 if (target->rowStatus == SNMP_ROW_NOTINSERVICE &&
  1218.                     snmpTargetAddr_rowStatusCheck(target) == 0) {
  1219.                     target->rowStatus = SNMP_ROW_NOTREADY;
  1220.                 }
  1221.             }
  1222.         }
  1223.     }
  1224.     return SNMP_ERR_NOERROR;
  1225. }                               /* write_snmpTargetAddrParams */
  1226. int
  1227. write_snmpTargetAddrStorageType(int action,
  1228.                                 u_char * var_val,
  1229.                                 u_char var_val_type,
  1230.                                 size_t var_val_len,
  1231.                                 u_char * statP,
  1232.                                 oid * name, size_t name_len)
  1233. {
  1234.     long            long_ret = *((long *) var_val);
  1235.     struct targetAddrTable_struct *target;
  1236.     if (action == RESERVE1) {
  1237.         if (var_val_type != ASN_INTEGER) {
  1238.             DEBUGMSGTL(("snmpTargetAddrEntry",
  1239.                         "write to snmpTargetAddrStorageType not ASN_INTEGERn"));
  1240.             return SNMP_ERR_WRONGTYPE;
  1241.         }
  1242.         if (var_val_len != sizeof(long)) {
  1243.             DEBUGMSGTL(("snmpTargetAddrEntry",
  1244.                         "write to snmpTargetAddrStorageType: bad lengthn"));
  1245.             return SNMP_ERR_WRONGLENGTH;
  1246.         }
  1247.         if (long_ret != SNMP_STORAGE_OTHER &&
  1248.             long_ret != SNMP_STORAGE_VOLATILE &&
  1249.             long_ret != SNMP_STORAGE_NONVOLATILE) {
  1250.             DEBUGMSGTL(("snmpTargetAddrEntry",
  1251.                         "write to snmpTargetAddrStorageType: attempted storage type not a valid"));
  1252.             DEBUGMSG(("snmpTargetAddrEntry",
  1253.                       " value of other(%d), volatile(%d), or nonvolatile(%d)n",
  1254.                       SNMP_STORAGE_OTHER, SNMP_STORAGE_VOLATILE,
  1255.                       SNMP_STORAGE_NONVOLATILE));
  1256.             return SNMP_ERR_WRONGVALUE;
  1257.         }
  1258.     } else if (action == RESERVE2) {
  1259.         snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
  1260.             SNMPTARGETADDRSTORAGETYPECOLUMN;
  1261.         if ((target = search_snmpTargetAddrTable(snmpTargetAddrOID,
  1262.                                                  snmpTargetAddrOIDLen,
  1263.                                                  name, &name_len,
  1264.                                                  1)) == NULL) {
  1265.             DEBUGMSGTL(("snmpTargetAddrEntry",
  1266.                         "write to snmpTargetAddrStorageType: BAD OIDn"));
  1267.             return SNMP_ERR_INCONSISTENTNAME;
  1268.         } else {
  1269.             if (target->storageType == SNMP_STORAGE_PERMANENT ||
  1270.                 target->storageType == SNMP_STORAGE_READONLY) {
  1271.                 DEBUGMSGTL(("snmpTargetAddrEntry",
  1272.                             "write to snmpTargetAddrStorageType: row has unchangeable storage status: %dn",
  1273.                             target->storageType));
  1274.                 return SNMP_ERR_WRONGVALUE;
  1275.             }
  1276.         }
  1277.     } else if (action == COMMIT) {
  1278.         snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
  1279.             SNMPTARGETADDRSTORAGETYPECOLUMN;
  1280.         if ((target = search_snmpTargetAddrTable(snmpTargetAddrOID,
  1281.                                                  snmpTargetAddrOIDLen,
  1282.                                                  name, &name_len,
  1283.                                                  1)) != NULL) {
  1284.             target->storageType = long_ret;
  1285.         }
  1286.     }
  1287.     return SNMP_ERR_NOERROR;
  1288. }                               /* write_snmpTargetAddrStorageType */
  1289. /*
  1290.  * snmpTargeAddr_createNewRow is called from write_snmpTargetAddrRowStatus
  1291.  * when a new row is required. It creates a new row with 
  1292.  * the index of the passed in 'name' (i.e. full index OID) and
  1293.  * adds it to the linked list. 'name' should be the full OID of the new index. 
  1294.  * It passes back 0 if unsuccessfull.
  1295.  */
  1296. int
  1297. snmpTargetAddr_createNewRow(oid * name, size_t name_len)
  1298. {
  1299.     size_t          newNameLen;
  1300.     int             i;
  1301.     struct targetAddrTable_struct *temp_struct;
  1302.     /*
  1303.      * setup a new snmpTargetAddrTable structure and add it to the list 
  1304.      */
  1305.     newNameLen = name_len - snmpTargetAddrOIDLen;
  1306.     if (newNameLen > 0) {
  1307.         temp_struct = snmpTargetAddrTable_create();
  1308.         temp_struct->name = (char *) malloc(newNameLen + 1);
  1309.         if (temp_struct->name == NULL) {
  1310.             return 0;
  1311.         }
  1312.         for (i = 0; i < (int) newNameLen; i++) {
  1313.             temp_struct->name[i] = (char) name[i + snmpTargetAddrOIDLen];
  1314.         }
  1315.         temp_struct->name[newNameLen] = '';
  1316.         temp_struct->rowStatus = SNMP_ROW_NOTREADY;
  1317.         snmpTargetAddrTable_addToList(temp_struct, &aAddrTable);
  1318.         return 1;
  1319.     }
  1320.     return 0;
  1321. }                               /* snmpTargetAddr_createNewRow */
  1322. /*
  1323.  * Assign a value to the Row Status variable 
  1324.  */
  1325. int
  1326. write_snmpTargetAddrRowStatus(int action,
  1327.                               u_char * var_val,
  1328.                               u_char var_val_type,
  1329.                               size_t var_val_len,
  1330.                               u_char * statP, oid * name, size_t name_len)
  1331. {
  1332.     static long     value;
  1333.     struct targetAddrTable_struct *target = NULL;
  1334.     if (action == RESERVE1) {
  1335.         value = *((long *) var_val);
  1336.         if (var_val_type != ASN_INTEGER) {
  1337.             DEBUGMSGTL(("snmpTargetAddrEntry",
  1338.                         "write to snmpTargetAddrRowStatus not ASN_INTEGERn"));
  1339.             return SNMP_ERR_WRONGTYPE;
  1340.         }
  1341.         if (var_val_len != sizeof(int)) {
  1342.             DEBUGMSGTL(("snmpTargetAddrEntry",
  1343.                         "write to snmpTargetAddrRowStatus: bad lengthn"));
  1344.             return SNMP_ERR_WRONGLENGTH;
  1345.         }
  1346.         if (value == RS_NOTREADY || value < 1 || value > 6) {
  1347.             return SNMP_ERR_WRONGVALUE;
  1348.         }
  1349.         /*
  1350.          * Check index value is reasonable.  
  1351.          */
  1352.         if (name_len < snmpTargetAddrOIDLen + 1 ||
  1353.             name_len > snmpTargetAddrOIDLen + 32) {
  1354.             DEBUGMSGTL(("snmpTargetAddrEntry", "bad index length %dn",
  1355.                         name_len - snmpTargetAddrOIDLen));
  1356.             return SNMP_ERR_NOCREATION;
  1357.         }
  1358.         /*
  1359.          * Search for struct in linked list.  
  1360.          */
  1361.         snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
  1362.             SNMPTARGETADDRROWSTATUSCOLUMN;
  1363.         target =
  1364.             search_snmpTargetAddrTable(snmpTargetAddrOID,
  1365.                                        snmpTargetAddrOIDLen, name,
  1366.                                        &name_len, 1);
  1367.         if (target != NULL) {
  1368.             if (value == RS_CREATEANDGO || value == RS_CREATEANDWAIT) {
  1369.                 value = RS_NOTREADY;
  1370.                 return SNMP_ERR_INCONSISTENTVALUE;
  1371.             }
  1372.             if (target->storageType == SNMP_STORAGE_READONLY) {
  1373.                 DEBUGMSGTL(("snmpTargetAddrEntry", "row is read onlyn"));
  1374.                 return SNMP_ERR_NOTWRITABLE;
  1375.             }
  1376.             if (target->storageType == SNMP_STORAGE_PERMANENT) {
  1377.                 if (value == RS_DESTROY) {
  1378.                     DEBUGMSGTL(("snmpTargetAddrEntry",
  1379.                                 "unable to destroy permanent rown"));
  1380.                     return SNMP_ERR_INCONSISTENTVALUE;
  1381.                 }
  1382.             }
  1383.         } else {
  1384.             if (value == RS_ACTIVE || value == RS_NOTINSERVICE) {
  1385.                 return SNMP_ERR_INCONSISTENTVALUE;
  1386.             }
  1387.             if (value == RS_CREATEANDGO || value == RS_CREATEANDWAIT) {
  1388.                 if (snmpTargetAddr_createNewRow(name, name_len) == 0) {
  1389.                     DEBUGMSGTL(("snmpTargetAddrEntry",
  1390.                                 "couldn't malloc() new rown"));
  1391.                     return SNMP_ERR_RESOURCEUNAVAILABLE;
  1392.                 }
  1393.             }
  1394.         }
  1395.     } else if (action == ACTION) {
  1396.         snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
  1397.             SNMPTARGETADDRROWSTATUSCOLUMN;
  1398.         target =
  1399.             search_snmpTargetAddrTable(snmpTargetAddrOID,
  1400.                                        snmpTargetAddrOIDLen, name,
  1401.                                        &name_len, 1);
  1402.         if (target != NULL) {
  1403.             if (value == RS_CREATEANDGO) {
  1404.                 /*
  1405.                  * Check whether all the required objects have been set.  
  1406.                  */
  1407.                 if (snmpTargetAddr_rowStatusCheck(target)) {
  1408.                     target->rowStatus = RS_ACTIVE;
  1409.                 } else {
  1410.                     target->rowStatus = RS_NOTREADY;
  1411.                 }
  1412.             } else if (value == RS_CREATEANDWAIT) {
  1413.                 /*
  1414.                  * Check whether all the required objects have been set.  
  1415.                  */
  1416.                 if (snmpTargetAddr_rowStatusCheck(target)) {
  1417.                     target->rowStatus = RS_NOTINSERVICE;
  1418.                 } else {
  1419.                     target->rowStatus = RS_NOTREADY;
  1420.                 }
  1421.             } else if (value == RS_ACTIVE) {
  1422.                 if (target->rowStatus == RS_NOTINSERVICE) {
  1423.                     target->rowStatus = RS_ACTIVE;
  1424.                 } else if (target->rowStatus == RS_NOTREADY) {
  1425.                     return SNMP_ERR_INCONSISTENTVALUE;
  1426.                 }
  1427.             } else if (value == RS_NOTINSERVICE) {
  1428.                 if (target->rowStatus == RS_ACTIVE) {
  1429.                     target->rowStatus = RS_NOTINSERVICE;
  1430.                 } else if (target->rowStatus == RS_NOTREADY) {
  1431.                     return SNMP_ERR_INCONSISTENTVALUE;
  1432.                 }
  1433.             }
  1434.         }
  1435.     } else if (action == COMMIT) {
  1436.         snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
  1437.             SNMPTARGETADDRROWSTATUSCOLUMN;
  1438.         target =
  1439.             search_snmpTargetAddrTable(snmpTargetAddrOID,
  1440.                                        snmpTargetAddrOIDLen, name,
  1441.                                        &name_len, 1);
  1442.         if (target != NULL) {
  1443.             if (value == RS_DESTROY) {
  1444.                 snmpTargetAddrTable_remFromList(target, &aAddrTable);
  1445.             }
  1446.             if (value == RS_NOTINSERVICE) {
  1447.                 if (target->sess != NULL) {
  1448.                     snmp_close(target->sess);
  1449.                     target->sess = NULL;
  1450.                 }
  1451.             }
  1452.         }
  1453.     } else if (action == UNDO || action == FREE) {
  1454.         snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
  1455.             SNMPTARGETADDRROWSTATUSCOLUMN;
  1456.         target =
  1457.             search_snmpTargetAddrTable(snmpTargetAddrOID,
  1458.                                        snmpTargetAddrOIDLen, name,
  1459.                                        &name_len, 1);
  1460.         if (value == RS_CREATEANDGO || value == RS_CREATEANDWAIT) {
  1461.             if (target != NULL) {
  1462.                 snmpTargetAddrTable_remFromList(target, &aAddrTable);
  1463.             }
  1464.         }
  1465.     }
  1466.     return SNMP_ERR_NOERROR;
  1467. }                               /* write_snmpTargetAddrRowStatus */
  1468. int
  1469. write_targetSpinLock(int action,
  1470.                      u_char * var_val,
  1471.                      u_char var_val_type,
  1472.                      size_t var_val_len,
  1473.                      u_char * statP, oid * name, size_t name_len)
  1474. {
  1475.     if (action == RESERVE1) {
  1476.         if (var_val_type != ASN_INTEGER) {
  1477.             return SNMP_ERR_WRONGTYPE;
  1478.         }
  1479.         if (var_val_len != sizeof(unsigned long)) {
  1480.             return SNMP_ERR_WRONGLENGTH;
  1481.         }
  1482.         if (*((unsigned long *) var_val) != snmpTargetSpinLock) {
  1483.             return SNMP_ERR_INCONSISTENTVALUE;
  1484.         }
  1485.     } else if (action == COMMIT) {
  1486.         if (snmpTargetSpinLock == 2147483647) {
  1487.             snmpTargetSpinLock = 0;
  1488.         } else {
  1489.             snmpTargetSpinLock++;
  1490.         }
  1491.     }
  1492.     return SNMP_ERR_NOERROR;
  1493. }
  1494. u_char         *
  1495. var_targetSpinLock(struct variable * vp,
  1496.                    oid * name,
  1497.                    size_t * length,
  1498.                    int exact,
  1499.                    size_t * var_len, WriteMethod ** write_method)
  1500. {
  1501.     if (header_generic(vp, name, length, exact, var_len, write_method) ==
  1502.         MATCH_FAILED) {
  1503.         *write_method = write_targetSpinLock;
  1504.         return NULL;
  1505.     }
  1506.     if (vp->magic == SNMPTARGETSPINLOCK) {
  1507.         *write_method = write_targetSpinLock;
  1508.         *var_len = sizeof(unsigned long);
  1509.         return (u_char *) & (snmpTargetSpinLock);
  1510.     }
  1511.     return NULL;
  1512. }