@@ -177,7 +177,7 @@ static const char *mibname;
177177static const char * mibvers ;
178178
179179#define DRIVER_NAME "Generic SNMP UPS driver"
180- #define DRIVER_VERSION "1.36 "
180+ #define DRIVER_VERSION "1.37 "
181181
182182/* driver description structure */
183183upsdrv_info_t upsdrv_info = {
@@ -2123,7 +2123,9 @@ bool_t load_mib2nut(const char *mib)
21232123 return FALSE;
21242124}
21252125
2126- /* find the OID value matching that INFO_* value */
2126+ /* find the OID value matching that INFO_* value
2127+ * Return -1 and errno==EINVAL for unsupported inputs.
2128+ */
21272129long su_find_valinfo (info_lkp_t * oid2info , const char * value )
21282130{
21292131 info_lkp_t * info_lkp ;
@@ -2135,14 +2137,19 @@ long su_find_valinfo(info_lkp_t *oid2info, const char* value)
21352137 upsdebugx (1 , "%s: found %s (value: %s)" ,
21362138 __func__ , info_lkp -> info_value , value );
21372139
2140+ errno = 0 ;
21382141 return info_lkp -> oid_value ;
21392142 }
21402143 }
2144+
21412145 upsdebugx (1 , "%s: no matching INFO_* value for this OID value (%s)" , __func__ , value );
2146+ errno = EINVAL ;
21422147 return -1 ;
21432148}
21442149
2145- /* String reformatting function */
2150+ /* String reformatting function.
2151+ * Return NULL and errno==EINVAL for unsupported inputs.
2152+ */
21462153const char * su_find_strval (info_lkp_t * oid2info , void * value )
21472154{
21482155#if WITH_SNMP_LKP_FUN
@@ -2151,19 +2158,27 @@ const char *su_find_strval(info_lkp_t *oid2info, void *value)
21512158 const char * retvalue ;
21522159
21532160 upsdebugx (2 , "%s: using generic lookup function (string reformatting)" , __func__ );
2161+ errno = 0 ;
21542162 retvalue = oid2info -> fun_vp2s (value );
2155- upsdebugx (2 , "%s: got value '%s'" , __func__ , retvalue );
2163+ upsdebugx (2 , "%s: got value '%s'%s" ,
2164+ __func__ , retvalue ,
2165+ (errno == EINVAL ? ", invalid input" : "" )
2166+ );
21562167 return retvalue ;
21572168 }
21582169 upsdebugx (1 , "%s: no result value for this OID string value (%s)" , __func__ , (char * )value );
21592170#else
21602171 NUT_UNUSED_VARIABLE (oid2info );
21612172 upsdebugx (1 , "%s: no mapping function for this OID string value (%s)" , __func__ , (char * )value );
21622173#endif /* WITH_SNMP_LKP_FUN */
2174+
2175+ errno = EINVAL ;
21632176 return NULL ;
21642177}
21652178
2166- /* find the INFO_* value matching that OID numeric (long) value */
2179+ /* Find the INFO_* value matching that OID numeric (long) value.
2180+ * Return NULL and errno==EINVAL for unsupported inputs.
2181+ */
21672182const char * su_find_infoval (info_lkp_t * oid2info , void * raw_value )
21682183{
21692184 info_lkp_t * info_lkp ;
@@ -2175,8 +2190,12 @@ const char *su_find_infoval(info_lkp_t *oid2info, void *raw_value)
21752190 const char * retvalue ;
21762191
21772192 upsdebugx (2 , "%s: using generic lookup function" , __func__ );
2193+ errno = 0 ;
21782194 retvalue = oid2info -> fun_vp2s (raw_value );
2179- upsdebugx (2 , "%s: got value '%s'" , __func__ , retvalue );
2195+ upsdebugx (2 , "%s: got value '%s'%s" ,
2196+ __func__ , retvalue ,
2197+ (errno == EINVAL ? ", invalid input" : "" )
2198+ );
21802199 return retvalue ;
21812200 }
21822201#endif /* WITH_SNMP_LKP_FUN */
@@ -2189,10 +2208,13 @@ const char *su_find_infoval(info_lkp_t *oid2info, void *raw_value)
21892208 upsdebugx (1 , "%s: found %s (value: %ld)" ,
21902209 __func__ , info_lkp -> info_value , value );
21912210
2211+ errno = 0 ;
21922212 return info_lkp -> info_value ;
21932213 }
21942214 }
2215+
21952216 upsdebugx (1 , "%s: no matching INFO_* value for this OID value (%ld)" , __func__ , value );
2217+ errno = EINVAL ;
21962218 return NULL ;
21972219}
21982220
@@ -2838,6 +2860,7 @@ bool_t daisychain_init(void)
28382860 {
28392861#if WITH_SNMP_LKP_FUN
28402862 devices_count = -1 ;
2863+ errno = 0 ;
28412864 /* First test if we have a generic lookup function
28422865 * FIXME: Check if the field type is a string?
28432866 */
@@ -2849,11 +2872,14 @@ bool_t daisychain_init(void)
28492872 upsdebugx (2 , "%s: using generic string-to-long lookup function" , __func__ );
28502873 if (TRUE == nut_snmp_get_str (su_info_p -> OID , buf , sizeof (buf ), su_info_p -> oid2info )) {
28512874 devices_count = su_info_p -> oid2info -> nuf_s2l (buf );
2852- upsdebugx (2 , "%s: got value '%ld'" , __func__ , devices_count );
2875+ upsdebugx (2 , "%s: got value '%ld'%s" ,
2876+ __func__ , devices_count ,
2877+ (errno == EINVAL ? ", invalid input" : "" )
2878+ );
28532879 }
28542880 }
28552881
2856- if (devices_count == -1 ) {
2882+ if (devices_count == -1 || errno == EINVAL ) {
28572883#endif /* WITH_SNMP_LKP_FUN */
28582884
28592885 if (nut_snmp_get_int (su_info_p -> OID , & devices_count ) == TRUE) {
@@ -3659,10 +3685,13 @@ bool_t su_ups_get(snmp_info_t *su_info_p)
36593685 * @varname: name of variable or command to set the OID from
36603686 * @val: value for settings, NULL for commands
36613687
3662- * Returns
3663- * STAT_SET_HANDLED if OK,
3664- * STAT_SET_INVALID or STAT_SET_UNKNOWN if the command / setting is not supported
3665- * STAT_SET_FAILED otherwise
3688+ * Returns respectively (for instcmd or setvar activity):
3689+ * STAT_INSTCMD_HANDLED or STAT_SET_HANDLED if OK,
3690+ * STAT_*_CONVERSION_FAILED if the value was invalid
3691+ * (not a number when expected one,
3692+ * not a key in mapping table when used)
3693+ * STAT_*_INVALID or STAT_*_UNKNOWN if the command / setting is not supported
3694+ * STAT_*_FAILED otherwise
36663695 */
36673696static int su_setOID (int mode , const char * varname , const char * val )
36683697{
@@ -3755,7 +3784,7 @@ static int su_setOID(int mode, const char *varname, const char *val)
37553784 upsdebugx (2 , "daisychain %s for device.0 are not yet supported!" ,
37563785 (mode == SU_MODE_INSTCMD )?"command" :"setting" );
37573786 free (tmp_varname );
3758- return STAT_SET_INVALID ;
3787+ return ( mode == SU_MODE_INSTCMD ? STAT_INSTCMD_INVALID : STAT_SET_INVALID ) ;
37593788 }
37603789
37613790 /* Check if it is outlet / outlet.group, or standard variable */
@@ -3822,7 +3851,7 @@ static int su_setOID(int mode, const char *varname, const char *val)
38223851 /* out of bound item number */
38233852 upsdebugx (2 , "%s: item is out of bound (%i / %i)" ,
38243853 __func__ , item_number , total_items );
3825- return STAT_SET_INVALID ;
3854+ return ( mode == SU_MODE_INSTCMD ? STAT_INSTCMD_INVALID : STAT_SET_INVALID ) ;
38263855 }
38273856 /* find back the item template */
38283857 item_varname = (char * )xmalloc (SU_INFOSIZE );
@@ -3891,8 +3920,9 @@ static int su_setOID(int mode, const char *varname, const char *val)
38913920 tmp_info_p -> OID , "%i" , item_number );
38923921 }
38933922 }
3894- /* else, don't return STAT_SET_INVALID for mode==SU_MODE_SETVAR since we
3895- * can be setting a server side variable! */
3923+ /* else, don't return STAT_SET_INVALID for mode==SU_MODE_SETVAR
3924+ * since we can be setting a server side variable - but
3925+ * note this consideration does not apply to instcmd's! */
38963926 else {
38973927 if (mode == SU_MODE_INSTCMD ) {
38983928 free_info (su_info_p );
@@ -3917,15 +3947,15 @@ static int su_setOID(int mode, const char *varname, const char *val)
39173947 if (tmp_varname != NULL )
39183948 free (tmp_varname );
39193949
3920- return STAT_SET_UNKNOWN ;
3950+ return ( mode == SU_MODE_INSTCMD ? STAT_INSTCMD_UNKNOWN : STAT_SET_UNKNOWN ) ;
39213951 }
39223952
39233953 /* set value into the device, using the provided one, or the default one otherwise */
39243954 if (mode == SU_MODE_INSTCMD ) {
39253955 /* Sanity check: commands should either have a value or a default */
39263956 if ( (val == NULL ) && (su_info_p -> dfl == NULL ) ) {
39273957 upsdebugx (1 , "%s: cannot execute command '%s': a provided or default value is needed!" , __func__ , varname );
3928- return STAT_SET_INVALID ;
3958+ return STAT_INSTCMD_INVALID ;
39293959 }
39303960 upslog_INSTCMD_POWERSTATE_CHECKED (varname , val );
39313961 }
@@ -3937,19 +3967,24 @@ static int su_setOID(int mode, const char *varname, const char *val)
39373967 if (mode == SU_MODE_INSTCMD ) {
39383968 if ( !str_to_long (val ? val : su_info_p -> dfl , & value , 10 ) ) {
39393969 upsdebugx (1 , "%s: cannot execute command '%s': value is not a number!" , __func__ , varname );
3940- return STAT_SET_INVALID ;
3970+ return STAT_INSTCMD_CONVERSION_FAILED ;
39413971 }
39423972 }
39433973 else {
39443974 /* non string data may imply a value lookup */
39453975 if (su_info_p -> oid2info ) {
39463976 value = su_find_valinfo (su_info_p -> oid2info , val ? val : su_info_p -> dfl );
3977+ if (value == -1 && errno == EINVAL ) {
3978+ upsdebugx (1 , "%s: cannot set '%s': value %s is not supported by lookup mapping!" ,
3979+ __func__ , varname , NUT_STRARG (val ? val : su_info_p -> dfl ));
3980+ return STAT_SET_CONVERSION_FAILED ;
3981+ }
39473982 }
39483983 else {
39493984 /* Convert value and apply multiplier */
39503985 if ( !str_to_long (val , & value , 10 ) ) {
39513986 upsdebugx (1 , "%s: cannot set '%s': value is not a number!" , __func__ , varname );
3952- return STAT_SET_INVALID ;
3987+ return STAT_SET_CONVERSION_FAILED ;
39533988 }
39543989 value = (long )((double )value / su_info_p -> info_len );
39553990 }
@@ -3965,23 +4000,26 @@ static int su_setOID(int mode, const char *varname, const char *val)
39654000
39664001 /* Process result */
39674002 if (status == FALSE) {
3968- if (mode == SU_MODE_INSTCMD )
4003+ if (mode == SU_MODE_INSTCMD ) {
39694004 upsdebugx (1 , "%s: cannot execute command '%s'" , __func__ , varname );
3970- else
4005+ retval = STAT_INSTCMD_FAILED ;
4006+ }
4007+ else {
39714008 upsdebugx (1 , "%s: cannot set value %s on OID %s" , __func__ , val , su_info_p -> OID );
3972-
3973- retval = STAT_SET_FAILED ;
4009+ retval = STAT_SET_FAILED ;
4010+ }
39744011 }
39754012 else {
3976- retval = STAT_SET_HANDLED ;
3977- if (mode == SU_MODE_INSTCMD )
4013+ if (mode == SU_MODE_INSTCMD ) {
39784014 upsdebugx (1 , "%s: successfully sent command %s" , __func__ , varname );
3979- else {
4015+ retval = STAT_INSTCMD_HANDLED ;
4016+ } else {
39804017 upsdebugx (1 , "%s: successfully set %s to \"%s\"" , __func__ , varname , val );
39814018
39824019 /* update info array: call dstate_setinfo, since flags and aux are
39834020 * already published, and this saves us some processing */
39844021 dstate_setinfo (varname , "%s" , val );
4022+ retval = STAT_SET_HANDLED ;
39854023 }
39864024 }
39874025
@@ -4003,12 +4041,7 @@ int su_setvar(const char *varname, const char *val)
40034041
40044042 ret = su_setOID (SU_MODE_SETVAR , varname , val );
40054043
4006- if (ret == STAT_SET_FAILED )
4007- upslog_SET_FAILED (varname , val );
4008- else if (ret == STAT_SET_UNKNOWN )
4009- upslog_SET_UNKNOWN (varname , val );
4010- else if (ret == STAT_SET_INVALID )
4011- upslog_SET_INVALID (varname , val );
4044+ upslog_SET_RESULT (ret , varname , extradata );
40124045
40134046 return ret ;
40144047}
@@ -4047,12 +4080,7 @@ int su_instcmd(const char *cmdname, const char *extradata)
40474080
40484081 ret = su_setOID (SU_MODE_INSTCMD , cmdname , extradata );
40494082
4050- if (ret == STAT_INSTCMD_FAILED )
4051- upslog_INSTCMD_FAILED (cmdname , extradata );
4052- else if (ret == STAT_INSTCMD_UNKNOWN )
4053- upslog_INSTCMD_UNKNOWN (cmdname , extradata );
4054- else if (ret == STAT_INSTCMD_INVALID )
4055- upslog_INSTCMD_INVALID (cmdname , extradata );
4083+ upslog_INSTCMD_RESULT (ret , cmdname , extradata );
40564084
40574085 return ret ;
40584086}
0 commit comments