1 /*
2  *Copyright(c)2004,Cisco URP imburses and Network Information Center in Beijing University of Posts and Telecommunications researches.
3  *
4  *All right reserved
5  *
6  *File Name: expObjectTable.c
7  *File Description: expObjectTable MIB operation.
8  *
9  *Current Version:1.0
10  *Author:JianShun Tong
11  *Date:2004.8.20
12  */
13 
14 
15 /*
16  * This file was generated by mib2c and is intended for use as
17  * a mib module for the ucd-snmp snmpd agent.
18  */
19 
20 
21 /*
22  * This should always be included first before anything else
23  */
24 #include <net-snmp/net-snmp-config.h>
25 #include <net-snmp/net-snmp-features.h>
26 #if HAVE_STDLIB_H
27 #include <stdlib.h>
28 #endif
29 #if HAVE_STRING_H
30 #include <string.h>
31 #else
32 #include <strings.h>
33 #endif
34 #ifdef HAVE_LIMITS_H
35 #include <limits.h>
36 #endif
37 
38 #ifndef NETSNMP_NO_WRITE_SUPPORT
39 netsnmp_feature_require(header_complex_find_entry);
40 #endif /* NETSNMP_NO_WRITE_SUPPORT */
41 
42 /*
43  * minimal include directives
44  */
45 #include <net-snmp/net-snmp-includes.h>
46 #include <net-snmp/agent/net-snmp-agent-includes.h>
47 
48 #include "header_complex.h"
49 #include "expExpressionTable.h"
50 #include "expObjectTable.h"
51 
52 
53 /*
54  * expObjectTable_variables_oid:
55  *   this is the top level oid that we want to register under.  This
56  *   is essentially a prefix, with the suffix appearing in the
57  *   variable below.
58  */
59 oid             TimeInstance[] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
60 
61 oid             expObjectTable_variables_oid[] =
62     { 1, 3, 6, 1, 2, 1, 90, 1, 2, 3 };
63 
64 /*
65  * variable2 expObjectTable_variables:
66  */
67 
68 struct variable2 expObjectTable_variables[] = {
69     /*
70      * magic number        , variable type , ro/rw , callback fn  , L, oidsuffix
71      */
72 #define	EXPOBJECTID  2
73     {EXPOBJECTID,         ASN_OBJECT_ID, NETSNMP_OLDAPI_RWRITE,
74      var_expObjectTable, 2, {1, 2}},
75 #define	EXPOBJECTIDWILDCARD 3
76     {EXPOBJECTIDWILDCARD, ASN_INTEGER,   NETSNMP_OLDAPI_RWRITE,
77      var_expObjectTable, 2, {1, 3}},
78 #define	EXPOBJECTSAMPLETYPE 4
79     {EXPOBJECTSAMPLETYPE, ASN_INTEGER,   NETSNMP_OLDAPI_RWRITE,
80      var_expObjectTable, 2, {1, 4}},
81 #define	EXPOBJECTDELTADISCONTINUITYID 5
82     {EXPOBJECTDELTADISCONTINUITYID,  ASN_OBJECT_ID, NETSNMP_OLDAPI_RWRITE,
83      var_expObjectTable, 2, {1, 5}},
84 #define	EXPOBJECTDISCONTINUITYIDWILDCARD 6
85     {EXPOBJECTDISCONTINUITYIDWILDCARD, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
86      var_expObjectTable, 2, {1, 6}},
87 #define	EXPOBJECTDISCONTINUITYIDTYPE 7
88     {EXPOBJECTDISCONTINUITYIDTYPE,     ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
89      var_expObjectTable, 2, {1, 7}},
90 #define	EXPOBJECTCONDITIONAL  8
91     {EXPOBJECTCONDITIONAL, ASN_OBJECT_ID, NETSNMP_OLDAPI_RWRITE,
92      var_expObjectTable, 2, {1, 8}},
93 #define	EXPOBJECTCONDITIONALWILDCARD  9
94     {EXPOBJECTCONDITIONALWILDCARD,     ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
95      var_expObjectTable, 2, {1, 9}},
96 #define	EXPOBJECTENTRYSTATUS  10
97     {EXPOBJECTENTRYSTATUS, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
98      var_expObjectTable, 2, {1, 10}}
99 };
100 
101 
102 struct header_complex_index *expObjectTableStorage = NULL;
103 
104 /*
105  * init_expObjectTable():
106  *   Initialization routine.  This is called when the agent starts up.
107  *   At a minimum, registration of your variables should take place here.
108  */
109 void
init_expObjectTable(void)110 init_expObjectTable(void)
111 {
112     DEBUGMSGTL(("expObjectTable", "initializing...  "));
113 
114 
115     /*
116      * register ourselves with the agent to handle our mib tree
117      */
118     REGISTER_MIB("expObjectTable",
119                  expObjectTable_variables, variable2,
120                  expObjectTable_variables_oid);
121 
122     /*
123      * register our config handler(s) to deal with registrations
124      */
125     snmpd_register_config_handler("expObjectTable", parse_expObjectTable,
126                                   NULL, NULL);
127 
128     snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
129                            store_expObjectTable, NULL);
130 
131     DEBUGMSGTL(("expObjectTable", "done.\n"));
132 }
133 
134 
135 struct expObjectTable_data *
create_expObjectTable_data(void)136 create_expObjectTable_data(void)
137 {
138     struct expObjectTable_data *StorageNew;
139 
140     StorageNew = SNMP_MALLOC_STRUCT(expObjectTable_data);
141 
142     /*
143      * fill in default row values here into StorageNew
144      */
145     /*
146      * fill in values for all tables (even if not
147      * appropriate), since its easier to do here than anywhere
148      * else
149      */
150 
151     StorageNew->expObjectIDWildcard = EXPOBJCETIDWILDCARD_FALSE;
152     StorageNew->expObjectSampleType = EXPOBJCETSAMPLETYPE_ABSOLUTEVALUE;
153     StorageNew->expObjectDeltaDiscontinuityID =
154         netsnmp_memdup(TimeInstance, sizeof(TimeInstance));
155     StorageNew->expObjectDeltaDiscontinuityIDLen =
156         sizeof(TimeInstance) / sizeof(oid);
157 
158 
159 
160 
161     StorageNew->expObjectDiscontinuityIDWildcard =
162         EXPOBJCETDISCONTINUITYIDWILDCARD_FALSE;
163     StorageNew->expObjectDiscontinuityIDType =
164         EXPOBJECTDISCONTINUITYIDTYPE_TIMETICKS;
165 
166     StorageNew->expObjectConditional = calloc(1, sizeof(oid) * 2);      /* 0.0 */
167     StorageNew->expObjectConditionalLen = 2;
168 
169     StorageNew->expObjectID = calloc(1, sizeof(oid) * 2);       /* 0.0 */
170     StorageNew->expObjectIDLen = 2;
171 
172     StorageNew->expObjectConditionalWildcard =
173         EXPOBJECTCONDITIONALWILDCARD_FALSE;
174     StorageNew->storageType = ST_NONVOLATILE;
175 
176     return StorageNew;
177 }
178 
179 int
expObjectTable_add(struct expObjectTable_data * thedata)180 expObjectTable_add(struct expObjectTable_data *thedata)
181 {
182     netsnmp_variable_list *vars = NULL;
183 
184 
185     DEBUGMSGTL(("expObjectTable", "adding data...  "));
186     /*
187      * add the index variables to the varbind list, which is
188      * used by header_complex to index the data
189      */
190 
191 
192     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->expExpressionOwner, thedata->expExpressionOwnerLen);     /* expExpressionOwner */
193     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->expExpressionName, thedata->expExpressionNameLen);       /* expExpressionName */
194     snmp_varlist_add_variable(&vars, NULL, 0, ASN_UNSIGNED, (char *) &thedata->expObjectIndex, sizeof(thedata->expObjectIndex));        /* expExpressionName */
195 
196 
197 
198 
199     header_complex_add_data(&expObjectTableStorage, vars, thedata);
200     DEBUGMSGTL(("expObjectTable", "registered an entry\n"));
201 
202 
203     DEBUGMSGTL(("expObjectTable", "done.\n"));
204     return SNMPERR_SUCCESS;
205 }
206 
207 
208 
209 /*
210  * parse_mteTriggerTable():
211  *   parses .conf file entries needed to configure the mib.
212  */
213 void
parse_expObjectTable(const char * token,char * line)214 parse_expObjectTable(const char *token, char *line)
215 {
216     size_t          tmpint;
217     struct expObjectTable_data *StorageTmp =
218         SNMP_MALLOC_STRUCT(expObjectTable_data);
219 
220     DEBUGMSGTL(("expObjectTable", "parsing config...  "));
221 
222     if (StorageTmp == NULL) {
223         config_perror("malloc failure");
224         return;
225     }
226 
227     line =
228         read_config_read_data(ASN_OCTET_STR, line,
229                               &StorageTmp->expExpressionOwner,
230                               &StorageTmp->expExpressionOwnerLen);
231     if (StorageTmp->expExpressionOwner == NULL) {
232         config_perror("invalid specification for expExpressionOwner");
233         return;
234     }
235 
236     line =
237         read_config_read_data(ASN_OCTET_STR, line,
238                               &StorageTmp->expExpressionName,
239                               &StorageTmp->expExpressionNameLen);
240     if (StorageTmp->expExpressionName == NULL) {
241         config_perror("invalid specification for expExpressionName");
242         return;
243     }
244 
245     line =
246         read_config_read_data(ASN_UNSIGNED, line,
247                               &StorageTmp->expObjectIndex, &tmpint);
248 
249     line =
250         read_config_read_data(ASN_OBJECT_ID, line,
251                               &StorageTmp->expObjectID,
252                               &StorageTmp->expObjectIDLen);
253     if (StorageTmp->expObjectID == NULL) {
254         config_perror("invalid specification for expObjectID");
255         return;
256     }
257 
258     line =
259         read_config_read_data(ASN_INTEGER, line,
260                               &StorageTmp->expObjectIDWildcard, &tmpint);
261 
262     line =
263         read_config_read_data(ASN_INTEGER, line,
264                               &StorageTmp->expObjectSampleType, &tmpint);
265 
266     line =
267         read_config_read_data(ASN_OBJECT_ID, line,
268                               &StorageTmp->expObjectDeltaDiscontinuityID,
269                               &StorageTmp->
270                               expObjectDeltaDiscontinuityIDLen);
271     if (StorageTmp->expObjectDeltaDiscontinuityID == NULL) {
272         config_perror
273             ("invalid specification for expObjectDeltaDiscontinuityID");
274         return;
275     }
276 
277     line =
278         read_config_read_data(ASN_INTEGER, line,
279                               &StorageTmp->
280                               expObjectDiscontinuityIDWildcard, &tmpint);
281 
282     line =
283         read_config_read_data(ASN_INTEGER, line,
284                               &StorageTmp->expObjectDiscontinuityIDType,
285                               &tmpint);
286 
287     line =
288         read_config_read_data(ASN_OBJECT_ID, line,
289                               &StorageTmp->expObjectConditional,
290                               &StorageTmp->expObjectConditionalLen);
291     if (StorageTmp->expObjectConditional == NULL) {
292         config_perror("invalid specification for expObjectConditional");
293         return;
294     }
295 
296     line =
297         read_config_read_data(ASN_INTEGER, line,
298                               &StorageTmp->expObjectConditionalWildcard,
299                               &tmpint);
300 
301     line =
302         read_config_read_data(ASN_INTEGER, line,
303                               &StorageTmp->expObjectEntryStatus, &tmpint);
304 
305     StorageTmp->storageType = ST_NONVOLATILE;
306     expObjectTable_add(StorageTmp);
307 
308     DEBUGMSGTL(("expObjectTable", "done.\n"));
309 
310 }
311 
312 
313 
314 /*
315  * store_expExpressionTable():
316  *   stores .conf file entries needed to configure the mib.
317  */
318 int
store_expObjectTable(int majorID,int minorID,void * serverarg,void * clientarg)319 store_expObjectTable(int majorID, int minorID, void *serverarg,
320                      void *clientarg)
321 {
322     char            line[SNMP_MAXBUF];
323     char           *cptr;
324     size_t          tmpint;
325     struct expObjectTable_data *StorageTmp;
326     struct header_complex_index *hcindex;
327 
328     DEBUGMSGTL(("expObjectTable", "storing data...  "));
329 
330     for (hcindex = expObjectTableStorage; hcindex != NULL;
331          hcindex = hcindex->next) {
332         StorageTmp = (struct expObjectTable_data *) hcindex->data;
333 
334 
335 
336         if (StorageTmp->storageType == ST_NONVOLATILE) {
337 
338             memset(line, 0, sizeof(line));
339             strcat(line, "expObjectTable ");
340             cptr = line + strlen(line);
341             /*
342              * expObjectTable
343              */
344 
345             cptr =
346                 read_config_store_data(ASN_OCTET_STR, cptr,
347                                        &StorageTmp->expExpressionOwner,
348                                        &StorageTmp->expExpressionOwnerLen);
349             cptr =
350                 read_config_store_data(ASN_OCTET_STR, cptr,
351                                        &StorageTmp->expExpressionName,
352                                        &StorageTmp->expExpressionNameLen);
353             cptr =
354                 read_config_store_data(ASN_UNSIGNED, cptr,
355                                        &StorageTmp->expObjectIndex,
356                                        &tmpint);
357             cptr =
358                 read_config_store_data(ASN_OBJECT_ID, cptr,
359                                        &StorageTmp->expObjectID,
360                                        &StorageTmp->expObjectIDLen);
361             cptr =
362                 read_config_store_data(ASN_INTEGER, cptr,
363                                        &StorageTmp->expObjectIDWildcard,
364                                        &tmpint);
365             cptr =
366                 read_config_store_data(ASN_INTEGER, cptr,
367                                        &StorageTmp->expObjectSampleType,
368                                        &tmpint);
369             cptr =
370                 read_config_store_data(ASN_OBJECT_ID, cptr,
371                                        &StorageTmp->
372                                        expObjectDeltaDiscontinuityID,
373                                        &StorageTmp->
374                                        expObjectDeltaDiscontinuityIDLen);
375             cptr =
376                 read_config_store_data(ASN_INTEGER, cptr,
377                                        &StorageTmp->
378                                        expObjectDiscontinuityIDWildcard,
379                                        &tmpint);
380             cptr =
381                 read_config_store_data(ASN_INTEGER, cptr,
382                                        &StorageTmp->
383                                        expObjectDiscontinuityIDType,
384                                        &tmpint);
385             cptr =
386                 read_config_store_data(ASN_OBJECT_ID, cptr,
387                                        &StorageTmp->expObjectConditional,
388                                        &StorageTmp->
389                                        expObjectConditionalLen);
390             cptr =
391                 read_config_store_data(ASN_INTEGER, cptr,
392                                        &StorageTmp->
393                                        expObjectConditionalWildcard,
394                                        &tmpint);
395             cptr =
396                 read_config_store_data(ASN_INTEGER, cptr,
397                                        &StorageTmp->expObjectEntryStatus,
398                                        &tmpint);
399             snmpd_store_config(line);
400         }
401     }
402     DEBUGMSGTL(("expObjectTable", "storage done\n"));
403     return 0;
404 }
405 
406 
407 /*
408  * var_expObjectTable():
409  *   Handle this table separately from the scalar value case.
410  *   The workings of this are basically the same as for var_expObjectTable above.
411  */
412 unsigned char  *
var_expObjectTable(struct variable * vp,oid * name,size_t * length,int exact,size_t * var_len,WriteMethod ** write_method)413 var_expObjectTable(struct variable *vp,
414                    oid * name,
415                    size_t *length,
416                    int exact, size_t *var_len, WriteMethod ** write_method)
417 {
418     struct expObjectTable_data *StorageTmp = NULL;
419 
420 
421     DEBUGMSGTL(("expObjectTable", "var_expObjectTable: Entering...  \n"));
422     /*
423      * this assumes you have registered all your data properly
424      */
425     if ((StorageTmp =
426          header_complex(expObjectTableStorage, vp, name, length, exact,
427                         var_len, write_method)) == NULL) {
428         if (vp->magic == EXPOBJECTENTRYSTATUS)
429             *write_method = write_expObjectEntryStatus;
430         return NULL;
431     }
432     /*
433      * this is where we do the value assignments for the mib results.
434      */
435     switch (vp->magic) {
436 
437     case EXPOBJECTID:
438         *write_method = write_expObjectID;
439         *var_len = StorageTmp->expObjectIDLen * sizeof(oid);
440         return (u_char *) StorageTmp->expObjectID;
441 
442     case EXPOBJECTIDWILDCARD:
443         *write_method = write_expObjectIDWildcard;
444         *var_len = sizeof(StorageTmp->expObjectIDWildcard);
445         return (u_char *) & StorageTmp->expObjectIDWildcard;
446 
447     case EXPOBJECTSAMPLETYPE:
448         *write_method = write_expObjectSampleType;
449         *var_len = sizeof(StorageTmp->expObjectSampleType);
450         return (u_char *) & StorageTmp->expObjectSampleType;
451 
452     case EXPOBJECTDELTADISCONTINUITYID:
453         *write_method = write_expObjectDeltaDiscontinuityID;
454         *var_len =
455             StorageTmp->expObjectDeltaDiscontinuityIDLen * sizeof(oid);
456         return (u_char *) StorageTmp->expObjectDeltaDiscontinuityID;
457 
458     case EXPOBJECTDISCONTINUITYIDWILDCARD:
459         *write_method = write_expObjectDiscontinuityIDWildcard;
460         *var_len = sizeof(StorageTmp->expObjectDiscontinuityIDWildcard);
461         return (u_char *) & StorageTmp->expObjectDiscontinuityIDWildcard;
462 
463     case EXPOBJECTDISCONTINUITYIDTYPE:
464         *write_method = write_expObjectDiscontinuityIDWildcard;
465         *var_len = sizeof(StorageTmp->expObjectDiscontinuityIDType);
466         return (u_char *) & StorageTmp->expObjectDiscontinuityIDType;
467 
468     case EXPOBJECTCONDITIONAL:
469         *write_method = write_expObjectConditional;
470         *var_len = StorageTmp->expObjectConditionalLen * sizeof(oid);
471         return (u_char *) StorageTmp->expObjectConditional;
472 
473     case EXPOBJECTCONDITIONALWILDCARD:
474         *write_method = write_expObjectConditionalWildcard;
475         *var_len = sizeof(StorageTmp->expObjectConditionalWildcard);
476         return (u_char *) & StorageTmp->expObjectConditionalWildcard;
477 
478     case EXPOBJECTENTRYSTATUS:
479         *write_method = write_expObjectEntryStatus;
480         *var_len = sizeof(StorageTmp->expObjectEntryStatus);
481         return (u_char *) & StorageTmp->expObjectEntryStatus;
482 
483 
484     default:
485         ERROR_MSG("");
486     }
487     return NULL;
488 }
489 
490 int
write_expObjectID(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)491 write_expObjectID(int action,
492                   u_char * var_val,
493                   u_char var_val_type,
494                   size_t var_val_len,
495                   u_char * statP, oid * name, size_t name_len)
496 {
497     static oid     *tmpvar;
498     struct expObjectTable_data *StorageTmp = NULL;
499     static size_t   tmplen;
500     size_t          newlen =
501         name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) +
502                     3 - 1);
503 
504 
505     DEBUGMSGTL(("expObjectTable",
506                 "write_expObjectID entering action=%d...  \n", action));
507     if ((StorageTmp =
508          header_complex(expObjectTableStorage, NULL,
509                         &name[sizeof(expObjectTable_variables_oid) /
510                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
511                         NULL)) == NULL)
512         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
513 
514 
515     switch (action) {
516     case RESERVE1:
517         if (var_val_type != ASN_OBJECT_ID) {
518             snmp_log(LOG_ERR, "write to expObjectID not ASN_OBJECT_ID\n");
519             return SNMP_ERR_WRONGTYPE;
520         }
521         if (StorageTmp->storageType != ST_NONVOLATILE)
522             return SNMP_ERR_NOTWRITABLE;
523         break;
524 
525 
526     case RESERVE2:
527         /*
528          * memory reseveration, final preparation...
529          */
530         break;
531 
532 
533     case FREE:
534         /*
535          * Release any resources that have been allocated
536          */
537         break;
538 
539 
540     case ACTION:
541         /*
542          * The variable has been stored in objid for
543          * you to use, and you have just been asked to do something with
544          * it.  Note that anything done here must be reversable in the UNDO case
545          */
546         tmpvar = StorageTmp->expObjectID;
547         tmplen = StorageTmp->expObjectIDLen;
548         StorageTmp->expObjectID = netsnmp_memdup(var_val, var_val_len);
549         StorageTmp->expObjectIDLen = var_val_len / sizeof(oid);
550         break;
551 
552 
553     case UNDO:
554         /*
555          * Back out any changes made in the ACTION case
556          */
557         SNMP_FREE(StorageTmp->expObjectID);
558         StorageTmp->expObjectID = tmpvar;
559         StorageTmp->expObjectIDLen = tmplen;
560         break;
561 
562 
563     case COMMIT:
564         /*
565          * Things are working well, so it's now safe to make the change
566          * permanently.  Make sure that anything done here can't fail!
567          */
568 
569         /*
570          * XXX: if the valueID has actually changed, shouldn't we dump any
571          * previous values, as these are from a different object?
572          */
573         SNMP_FREE(tmpvar);
574         snmp_store_needed(NULL);
575         break;
576     }
577     return SNMP_ERR_NOERROR;
578 }
579 
580 int
write_expObjectIDWildcard(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)581 write_expObjectIDWildcard(int action,
582                           u_char * var_val,
583                           u_char var_val_type,
584                           size_t var_val_len,
585                           u_char * statP, oid * name, size_t name_len)
586 {
587     static int      tmpvar;
588     struct expObjectTable_data *StorageTmp = NULL;
589     size_t          newlen =
590         name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) +
591                     3 - 1);
592 
593 
594     DEBUGMSGTL(("expObjectTable",
595                 "write_expObjectIDWildcard entering action=%d...  \n",
596                 action));
597     if ((StorageTmp =
598          header_complex(expObjectTableStorage, NULL,
599                         &name[sizeof(expObjectTable_variables_oid) /
600                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
601                         NULL)) == NULL)
602         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
603 
604 
605     switch (action) {
606     case RESERVE1:
607         if (var_val_type != ASN_INTEGER) {
608             snmp_log(LOG_ERR,
609                      "write to expObjectIDWildcard not ASN_INTEGER\n");
610             return SNMP_ERR_WRONGTYPE;
611         }
612         if (StorageTmp->storageType != ST_NONVOLATILE)
613             return SNMP_ERR_NOTWRITABLE;
614         break;
615 
616 
617     case RESERVE2:
618         /*
619          * memory reseveration, final preparation...
620          */
621         break;
622 
623 
624     case FREE:
625         /*
626          * Release any resources that have been allocated
627          */
628         break;
629 
630 
631     case ACTION:
632         /*
633          * The variable has been stored in long_ret for
634          * you to use, and you have just been asked to do something with
635          * it.  Note that anything done here must be reversable in the UNDO case
636          */
637         tmpvar = StorageTmp->expObjectIDWildcard;
638         StorageTmp->expObjectIDWildcard = *((long *) var_val);
639         break;
640 
641 
642     case UNDO:
643         /*
644          * Back out any changes made in the ACTION case
645          */
646         StorageTmp->expObjectIDWildcard = tmpvar;
647         break;
648 
649 
650     case COMMIT:
651         /*
652          * Things are working well, so it's now safe to make the change
653          * permanently.  Make sure that anything done here can't fail!
654          */
655         snmp_store_needed(NULL);
656         break;
657     }
658     return SNMP_ERR_NOERROR;
659 }
660 
661 
662 int
write_expObjectSampleType(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)663 write_expObjectSampleType(int action,
664                           u_char * var_val,
665                           u_char var_val_type,
666                           size_t var_val_len,
667                           u_char * statP, oid * name, size_t name_len)
668 {
669     static int      tmpvar;
670     struct expObjectTable_data *StorageTmp = NULL;
671     size_t          newlen =
672         name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) +
673                     3 - 1);
674 
675 
676     DEBUGMSGTL(("expObjectTable",
677                 "write_expObjectSampleType entering action=%d...  \n",
678                 action));
679     if ((StorageTmp =
680          header_complex(expObjectTableStorage, NULL,
681                         &name[sizeof(expObjectTable_variables_oid) /
682                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
683                         NULL)) == NULL)
684         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
685 
686 
687     switch (action) {
688     case RESERVE1:
689         if (var_val_type != ASN_INTEGER) {
690             snmp_log(LOG_ERR,
691                      "write to expObjectSampleTypenot ASN_INTEGER\n");
692             return SNMP_ERR_WRONGTYPE;
693         }
694         if (StorageTmp->storageType != ST_NONVOLATILE)
695             return SNMP_ERR_NOTWRITABLE;
696         break;
697 
698 
699     case RESERVE2:
700         /*
701          * memory reseveration, final preparation...
702          */
703         break;
704 
705 
706     case FREE:
707         /*
708          * Release any resources that have been allocated
709          */
710         break;
711 
712 
713     case ACTION:
714         /*
715          * The variable has been stored in long_ret for
716          * you to use, and you have just been asked to do something with
717          * it.  Note that anything done here must be reversable in the UNDO case
718          */
719         tmpvar = StorageTmp->expObjectSampleType;
720         StorageTmp->expObjectSampleType = *((long *) var_val);
721         break;
722 
723 
724     case UNDO:
725         /*
726          * Back out any changes made in the ACTION case
727          */
728         StorageTmp->expObjectSampleType = tmpvar;
729         break;
730 
731 
732     case COMMIT:
733         /*
734          * Things are working well, so it's now safe to make the change
735          * permanently.  Make sure that anything done here can't fail!
736          */
737         snmp_store_needed(NULL);
738         break;
739     }
740     return SNMP_ERR_NOERROR;
741 }
742 
743 
744 
745 int
write_expObjectDeltaDiscontinuityID(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)746 write_expObjectDeltaDiscontinuityID(int action,
747                                     u_char * var_val,
748                                     u_char var_val_type,
749                                     size_t var_val_len,
750                                     u_char * statP, oid * name,
751                                     size_t name_len)
752 {
753     static oid     *tmpvar;
754     struct expObjectTable_data *StorageTmp = NULL;
755     static size_t   tmplen;
756     size_t          newlen =
757         name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) +
758                     3 - 1);
759 
760 
761     DEBUGMSGTL(("expObjectTable",
762                 "write_expObjectDeltaDiscontinuityID entering action=%d...  \n",
763                 action));
764     if ((StorageTmp =
765          header_complex(expObjectTableStorage, NULL,
766                         &name[sizeof(expObjectTable_variables_oid) /
767                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
768                         NULL)) == NULL)
769         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
770 
771 
772     switch (action) {
773     case RESERVE1:
774         if (var_val_type != ASN_OBJECT_ID) {
775             snmp_log(LOG_ERR,
776                      "write to expObjectDeltaDiscontinuityID not ASN_OBJECT_ID\n");
777             return SNMP_ERR_WRONGTYPE;
778         }
779         if (StorageTmp->storageType != ST_NONVOLATILE)
780             return SNMP_ERR_NOTWRITABLE;
781         break;
782 
783 
784     case RESERVE2:
785         /*
786          * memory reseveration, final preparation...
787          */
788         break;
789 
790 
791     case FREE:
792         /*
793          * Release any resources that have been allocated
794          */
795         break;
796 
797 
798     case ACTION:
799         /*
800          * The variable has been stored in objid for
801          * you to use, and you have just been asked to do something with
802          * it.  Note that anything done here must be reversable in the UNDO case
803          */
804         tmpvar = StorageTmp->expObjectDeltaDiscontinuityID;
805         tmplen = StorageTmp->expObjectDeltaDiscontinuityIDLen;
806         StorageTmp->expObjectDeltaDiscontinuityID =
807             netsnmp_memdup(var_val, var_val_len);
808         StorageTmp->expObjectDeltaDiscontinuityIDLen =
809             var_val_len / sizeof(oid);
810         break;
811 
812 
813     case UNDO:
814         /*
815          * Back out any changes made in the ACTION case
816          */
817         SNMP_FREE(StorageTmp->expObjectDeltaDiscontinuityID);
818         StorageTmp->expObjectDeltaDiscontinuityID = tmpvar;
819         StorageTmp->expObjectDeltaDiscontinuityIDLen = tmplen;
820         break;
821 
822 
823     case COMMIT:
824         /*
825          * Things are working well, so it's now safe to make the change
826          * permanently.  Make sure that anything done here can't fail!
827          */
828 
829         /*
830          * XXX: if the valueID has actually changed, shouldn't we dump any
831          * previous values, as these are from a different object?
832          */
833         SNMP_FREE(tmpvar);
834         snmp_store_needed(NULL);
835         break;
836     }
837     return SNMP_ERR_NOERROR;
838 }
839 
840 
841 
842 int
write_expObjectDiscontinuityIDWildcard(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)843 write_expObjectDiscontinuityIDWildcard(int action,
844                                        u_char * var_val,
845                                        u_char var_val_type,
846                                        size_t var_val_len,
847                                        u_char * statP,
848                                        oid * name, size_t name_len)
849 {
850     static int      tmpvar;
851     struct expObjectTable_data *StorageTmp = NULL;
852     size_t          newlen =
853         name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) +
854                     3 - 1);
855 
856 
857     DEBUGMSGTL(("expObjectTable",
858                 "write_expObjectDiscontinuityIDWildcard entering action=%d...  \n",
859                 action));
860     if ((StorageTmp =
861          header_complex(expObjectTableStorage, NULL,
862                         &name[sizeof(expObjectTable_variables_oid) /
863                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
864                         NULL)) == NULL)
865         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
866 
867 
868     switch (action) {
869     case RESERVE1:
870         if (var_val_type != ASN_INTEGER) {
871             snmp_log(LOG_ERR,
872                      "write to expObjectDiscontinuityIDWildcard not ASN_INTEGER\n");
873             return SNMP_ERR_WRONGTYPE;
874         }
875         if (StorageTmp->storageType != ST_NONVOLATILE)
876             return SNMP_ERR_NOTWRITABLE;
877         break;
878 
879 
880     case RESERVE2:
881         /*
882          * memory reseveration, final preparation...
883          */
884         break;
885 
886 
887     case FREE:
888         /*
889          * Release any resources that have been allocated
890          */
891         break;
892 
893 
894     case ACTION:
895         /*
896          * The variable has been stored in long_ret for
897          * you to use, and you have just been asked to do something with
898          * it.  Note that anything done here must be reversable in the UNDO case
899          */
900         tmpvar = StorageTmp->expObjectDiscontinuityIDWildcard;
901         StorageTmp->expObjectDiscontinuityIDWildcard = *((long *) var_val);
902         break;
903 
904 
905     case UNDO:
906         /*
907          * Back out any changes made in the ACTION case
908          */
909         StorageTmp->expObjectDiscontinuityIDWildcard = tmpvar;
910         break;
911 
912 
913     case COMMIT:
914         /*
915          * Things are working well, so it's now safe to make the change
916          * permanently.  Make sure that anything done here can't fail!
917          */
918         snmp_store_needed(NULL);
919         break;
920     }
921     return SNMP_ERR_NOERROR;
922 }
923 
924 
925 
926 int
write_expObjectDiscontinuityIDType(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)927 write_expObjectDiscontinuityIDType(int action,
928                                    u_char * var_val,
929                                    u_char var_val_type,
930                                    size_t var_val_len,
931                                    u_char * statP,
932                                    oid * name, size_t name_len)
933 {
934     static int      tmpvar;
935     struct expObjectTable_data *StorageTmp = NULL;
936     size_t          newlen =
937         name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) +
938                     3 - 1);
939 
940 
941     DEBUGMSGTL(("expObjectTable",
942                 "write_expObjectDiscontinuityIDWildcard entering action=%d...  \n",
943                 action));
944     if ((StorageTmp =
945          header_complex(expObjectTableStorage, NULL,
946                         &name[sizeof(expObjectTable_variables_oid) /
947                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
948                         NULL)) == NULL)
949         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
950 
951 
952     switch (action) {
953     case RESERVE1:
954         if (var_val_type != ASN_INTEGER) {
955             snmp_log(LOG_ERR,
956                      "write to expObjectDiscontinuityIDType not ASN_INTEGER\n");
957             return SNMP_ERR_WRONGTYPE;
958         }
959         if (StorageTmp->storageType != ST_NONVOLATILE)
960             return SNMP_ERR_NOTWRITABLE;
961         break;
962 
963 
964     case RESERVE2:
965         /*
966          * memory reseveration, final preparation...
967          */
968         break;
969 
970 
971     case FREE:
972         /*
973          * Release any resources that have been allocated
974          */
975         break;
976 
977 
978     case ACTION:
979         /*
980          * The variable has been stored in long_ret for
981          * you to use, and you have just been asked to do something with
982          * it.  Note that anything done here must be reversable in the UNDO case
983          */
984         tmpvar = StorageTmp->expObjectDiscontinuityIDType;
985         StorageTmp->expObjectDiscontinuityIDType = *((long *) var_val);
986         break;
987 
988 
989     case UNDO:
990         /*
991          * Back out any changes made in the ACTION case
992          */
993         StorageTmp->expObjectDiscontinuityIDType = tmpvar;
994         break;
995 
996 
997     case COMMIT:
998         /*
999          * Things are working well, so it's now safe to make the change
1000          * permanently.  Make sure that anything done here can't fail!
1001          */
1002         snmp_store_needed(NULL);
1003         break;
1004     }
1005     return SNMP_ERR_NOERROR;
1006 }
1007 
1008 
1009 
1010 int
write_expObjectConditional(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)1011 write_expObjectConditional(int action,
1012                            u_char * var_val,
1013                            u_char var_val_type,
1014                            size_t var_val_len,
1015                            u_char * statP, oid * name, size_t name_len)
1016 {
1017     static oid     *tmpvar;
1018     struct expObjectTable_data *StorageTmp = NULL;
1019     static size_t   tmplen;
1020     size_t          newlen =
1021         name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) +
1022                     3 - 1);
1023 
1024 
1025     DEBUGMSGTL(("expObjectTable",
1026                 "write_expObjectConditional entering action=%d...  \n",
1027                 action));
1028     if ((StorageTmp =
1029          header_complex(expObjectTableStorage, NULL,
1030                         &name[sizeof(expObjectTable_variables_oid) /
1031                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
1032                         NULL)) == NULL)
1033         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
1034 
1035 
1036     switch (action) {
1037     case RESERVE1:
1038         if (var_val_type != ASN_OBJECT_ID) {
1039             snmp_log(LOG_ERR,
1040                      "write to expObjectConditional not ASN_OBJECT_ID\n");
1041             return SNMP_ERR_WRONGTYPE;
1042         }
1043         if (StorageTmp->storageType != ST_NONVOLATILE)
1044             return SNMP_ERR_NOTWRITABLE;
1045         break;
1046 
1047 
1048     case RESERVE2:
1049         /*
1050          * memory reseveration, final preparation...
1051          */
1052         break;
1053 
1054 
1055     case FREE:
1056         /*
1057          * Release any resources that have been allocated
1058          */
1059         break;
1060 
1061 
1062     case ACTION:
1063         /*
1064          * The variable has been stored in objid for
1065          * you to use, and you have just been asked to do something with
1066          * it.  Note that anything done here must be reversable in the UNDO case
1067          */
1068         tmpvar = StorageTmp->expObjectConditional;
1069         tmplen = StorageTmp->expObjectConditionalLen;
1070         StorageTmp->expObjectConditional = netsnmp_memdup(var_val, var_val_len);
1071         StorageTmp->expObjectConditionalLen = var_val_len / sizeof(oid);
1072         break;
1073 
1074 
1075     case UNDO:
1076         /*
1077          * Back out any changes made in the ACTION case
1078          */
1079         SNMP_FREE(StorageTmp->expObjectConditional);
1080         StorageTmp->expObjectConditional = tmpvar;
1081         StorageTmp->expObjectConditionalLen = tmplen;
1082         break;
1083 
1084 
1085     case COMMIT:
1086         /*
1087          * Things are working well, so it's now safe to make the change
1088          * permanently.  Make sure that anything done here can't fail!
1089          */
1090 
1091         /*
1092          * XXX: if the valueID has actually changed, shouldn't we dump any
1093          * previous values, as these are from a different object?
1094          */
1095         SNMP_FREE(tmpvar);
1096         snmp_store_needed(NULL);
1097         break;
1098     }
1099     return SNMP_ERR_NOERROR;
1100 }
1101 
1102 
1103 
1104 
1105 int
write_expObjectConditionalWildcard(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)1106 write_expObjectConditionalWildcard(int action,
1107                                    u_char * var_val,
1108                                    u_char var_val_type,
1109                                    size_t var_val_len,
1110                                    u_char * statP,
1111                                    oid * name, size_t name_len)
1112 {
1113     static int      tmpvar;
1114     struct expObjectTable_data *StorageTmp = NULL;
1115     size_t          newlen =
1116         name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) +
1117                     3 - 1);
1118 
1119 
1120     DEBUGMSGTL(("expObjectTable",
1121                 "write_expObjectConditionalWildcard entering action=%d...  \n",
1122                 action));
1123     if ((StorageTmp =
1124          header_complex(expObjectTableStorage, NULL,
1125                         &name[sizeof(expObjectTable_variables_oid) /
1126                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
1127                         NULL)) == NULL)
1128         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
1129 
1130 
1131     switch (action) {
1132     case RESERVE1:
1133         if (var_val_type != ASN_INTEGER) {
1134             snmp_log(LOG_ERR,
1135                      "write to expObjectConditionalWildcard not ASN_INTEGER\n");
1136             return SNMP_ERR_WRONGTYPE;
1137         }
1138         if (StorageTmp->storageType != ST_NONVOLATILE)
1139             return SNMP_ERR_NOTWRITABLE;
1140         break;
1141 
1142 
1143     case RESERVE2:
1144         /*
1145          * memory reseveration, final preparation...
1146          */
1147         break;
1148 
1149 
1150     case FREE:
1151         /*
1152          * Release any resources that have been allocated
1153          */
1154         break;
1155 
1156 
1157     case ACTION:
1158         /*
1159          * The variable has been stored in long_ret for
1160          * you to use, and you have just been asked to do something with
1161          * it.  Note that anything done here must be reversable in the UNDO case
1162          */
1163         tmpvar = StorageTmp->expObjectConditionalWildcard;
1164         StorageTmp->expObjectConditionalWildcard = *((long *) var_val);
1165         break;
1166 
1167 
1168     case UNDO:
1169         /*
1170          * Back out any changes made in the ACTION case
1171          */
1172         StorageTmp->expObjectConditionalWildcard = tmpvar;
1173         break;
1174 
1175 
1176     case COMMIT:
1177         /*
1178          * Things are working well, so it's now safe to make the change
1179          * permanently.  Make sure that anything done here can't fail!
1180          */
1181         snmp_store_needed(NULL);
1182         break;
1183     }
1184     return SNMP_ERR_NOERROR;
1185 }
1186 
1187 
1188 
1189 
1190 int
write_expObjectEntryStatus(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)1191 write_expObjectEntryStatus(int action,
1192                            u_char * var_val,
1193                            u_char var_val_type,
1194                            size_t var_val_len,
1195                            u_char * statP, oid * name, size_t name_len)
1196 {
1197     struct expObjectTable_data *StorageTmp = NULL;
1198     static struct expObjectTable_data *StorageNew, *StorageDel;
1199     size_t          newlen =
1200         name_len - (sizeof(expObjectTable_variables_oid) / sizeof(oid) +
1201                     3 - 1);
1202     static int      old_value;
1203     int             set_value;
1204     static netsnmp_variable_list *vars, *vp;
1205     struct header_complex_index *hciptr;
1206 
1207     StorageTmp =
1208         header_complex(expObjectTableStorage, NULL,
1209                        &name[sizeof(expObjectTable_variables_oid) /
1210                              sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL);
1211 
1212 
1213 
1214 
1215     if (var_val_type != ASN_INTEGER || var_val == NULL) {
1216         snmp_log(LOG_ERR,
1217                  "write to expObjectEntryStatus not ASN_INTEGER\n");
1218         return SNMP_ERR_WRONGTYPE;
1219     }
1220     set_value = *((long *) var_val);
1221 
1222 
1223     /*
1224      * check legal range, and notReady is reserved for us, not a user
1225      */
1226     if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY)
1227         return SNMP_ERR_INCONSISTENTVALUE;
1228 
1229 
1230     switch (action) {
1231     case RESERVE1:
1232         /*
1233          * stage one: test validity
1234          */
1235         if (StorageTmp == NULL) {
1236             /*
1237              * create the row now?
1238              */
1239 
1240 
1241             /*
1242              * ditch illegal values now
1243              */
1244             if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE)
1245                 return SNMP_ERR_INCONSISTENTVALUE;
1246 
1247 
1248             /*
1249              * destroying a non-existent row is actually legal
1250              */
1251             if (set_value == RS_DESTROY) {
1252                 return SNMP_ERR_NOERROR;
1253             }
1254 
1255 
1256             /*
1257              * illegal creation values
1258              */
1259             if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) {
1260                 return SNMP_ERR_INCONSISTENTVALUE;
1261             }
1262         } else {
1263             /*
1264              * row exists.  Check for a valid state change
1265              */
1266             if (set_value == RS_CREATEANDGO
1267                 || set_value == RS_CREATEANDWAIT) {
1268                 /*
1269                  * can't create a row that exists
1270                  */
1271                 return SNMP_ERR_INCONSISTENTVALUE;
1272             }
1273 
1274             if (StorageTmp->expObjectEntryStatus == RS_ACTIVE &&
1275                 set_value != RS_DESTROY) {
1276                 /*
1277                  * "Once made active an entry may not be modified except to
1278                  * delete it."  XXX: doesn't this in fact apply to ALL
1279                  * columns of the table and not just this one?
1280                  */
1281                 return SNMP_ERR_INCONSISTENTVALUE;
1282             }
1283             if (StorageTmp->storageType != ST_NONVOLATILE)
1284                 return SNMP_ERR_NOTWRITABLE;
1285         }
1286         break;
1287 
1288 
1289 
1290 
1291     case RESERVE2:
1292         /*
1293          * memory reseveration, final preparation...
1294          */
1295         if (StorageTmp == NULL) {
1296             /*
1297              * creation
1298              */
1299             vars = NULL;
1300 
1301 
1302             snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0);  /* expExpressionOwner */
1303             snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0);  /* expExpressionName */
1304             snmp_varlist_add_variable(&vars, NULL, 0, ASN_UNSIGNED, NULL, 0);   /* expObjectIndex */
1305 
1306 
1307 
1308             if (header_complex_parse_oid
1309                 (&
1310                  (name
1311                   [sizeof(expObjectTable_variables_oid) / sizeof(oid) +
1312                    2]), newlen, vars) != SNMPERR_SUCCESS) {
1313                 /*
1314                  * XXX: free, zero vars
1315                  */
1316                 return SNMP_ERR_INCONSISTENTNAME;
1317             }
1318             vp = vars;
1319 
1320 
1321             StorageNew = create_expObjectTable_data();
1322 
1323             StorageNew->expExpressionOwner = malloc(vp->val_len + 1);
1324             memcpy(StorageNew->expExpressionOwner, vp->val.string,
1325                    vp->val_len);
1326             StorageNew->expExpressionOwner[vp->val_len] = '\0';
1327             StorageNew->expExpressionOwnerLen = vp->val_len;
1328 
1329             vp = vp->next_variable;
1330             StorageNew->expExpressionName = malloc(vp->val_len + 1);
1331             memcpy(StorageNew->expExpressionName, vp->val.string,
1332                    vp->val_len);
1333 
1334             StorageNew->expExpressionName[vp->val_len] = '\0';
1335             StorageNew->expExpressionNameLen = vp->val_len;
1336 
1337             vp = vp->next_variable;
1338             StorageNew->expObjectIndex = *vp->val.integer;
1339 
1340             StorageNew->expObjectEntryStatus = set_value;
1341 
1342         }
1343 
1344 
1345         break;
1346 
1347 
1348 
1349 
1350     case FREE:
1351         /*
1352          * XXX: free, zero vars
1353          */
1354         /*
1355          * Release any resources that have been allocated
1356          */
1357         break;
1358 
1359 
1360 
1361 
1362     case ACTION:
1363         /*
1364          * The variable has been stored in set_value for you to
1365          * use, and you have just been asked to do something with
1366          * it.  Note that anything done here must be reversable in
1367          * the UNDO case
1368          */
1369 
1370 
1371         if (StorageTmp == NULL && set_value != RS_DESTROY) {
1372             /*
1373              * row creation, so add it
1374              */
1375             if (StorageNew != NULL)
1376                 expObjectTable_add(StorageNew);
1377             /*
1378              * XXX: ack, and if it is NULL?
1379              */
1380         } else if (StorageTmp != NULL && set_value != RS_DESTROY) {
1381             /*
1382              * set the flag?
1383              */
1384             old_value = StorageTmp->expObjectEntryStatus;
1385             StorageTmp->expObjectEntryStatus = *((long *) var_val);
1386         } else {
1387             /*
1388              * destroy...  extract it for now
1389              */
1390             hciptr =
1391                 header_complex_find_entry(expObjectTableStorage,
1392                                           StorageTmp);
1393             StorageDel =
1394                 header_complex_extract_entry(&expObjectTableStorage,
1395                                              hciptr);
1396         }
1397         break;
1398 
1399 
1400 
1401 
1402     case UNDO:
1403         /*
1404          * Back out any changes made in the ACTION case
1405          */
1406         if (StorageTmp == NULL) {
1407             /*
1408              * row creation, so remove it again
1409              */
1410             hciptr =
1411                 header_complex_find_entry(expObjectTableStorage,
1412                                           StorageTmp);
1413             StorageDel =
1414                 header_complex_extract_entry(&expObjectTableStorage,
1415                                              hciptr);
1416             /*
1417              * XXX: free it
1418              */
1419         } else if (StorageDel != NULL) {
1420             /*
1421              * row deletion, so add it again
1422              */
1423             expObjectTable_add(StorageDel);
1424         } else {
1425             StorageTmp->expObjectEntryStatus = old_value;
1426         }
1427         break;
1428 
1429 
1430 
1431 
1432     case COMMIT:
1433         /*
1434          * Things are working well, so it's now safe to make the change
1435          * permanently.  Make sure that anything done here can't fail!
1436          */
1437         if (StorageDel != NULL) {
1438             StorageDel = 0;
1439             /*
1440              * XXX: free it, its dead
1441              */
1442         } else {
1443             if (StorageTmp
1444                 && StorageTmp->expObjectEntryStatus == RS_CREATEANDGO) {
1445                 StorageTmp->expObjectEntryStatus = RS_ACTIVE;
1446             } else if (StorageTmp &&
1447                        StorageTmp->expObjectEntryStatus ==
1448                        RS_CREATEANDWAIT) {
1449                 StorageTmp->expObjectEntryStatus = RS_NOTINSERVICE;
1450             }
1451         }
1452         snmp_store_needed(NULL);
1453         break;
1454     }
1455     return SNMP_ERR_NOERROR;
1456 }
1457