Code

Fix translations when extra-opts aren't enabled
[nagiosplug.git] / plugins / check_ups.c
index 4632bdc013d0abf54b99fd36d4e8f2be6d084e43..ce57ef3d00f8aafc415397c21183b12a1f7c8c04 100644 (file)
-/******************************************************************************
-*
-* CHECK_UPS.C
-*
-* Program: UPS monitor plugin for Nagios
+/*****************************************************************************
+* 
+* Nagios check_ups plugin
+* 
 * License: GPL
-* Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)
-*
-* Last Modified: $Date$
-*
-* Command line: CHECK_UPS <host_address> [-u ups] [-p port] [-v variable] \
-*                         [-wv warn_value] [-cv crit_value] [-to to_sec]
-*
+* Copyright (c) 2000 Tom Shields
+*               2004 Alain Richard <alain.richard@equation.fr>
+*               2004 Arnaud Quette <arnaud.quette@mgeups.com>
+* Copyright (c) 2002-2007 Nagios Plugins Development Team
+* 
 * Description:
-*
-
-* This plugin attempts to determine the status of an UPS
-* (Uninterruptible Power Supply) on a remote host (or the local host)
-* that is being monitored with Russel Kroll's "Smarty UPS Tools"
-* package. If the UPS is online or calibrating, the plugin will
-* return an OK state. If the battery is on it will return a WARNING
-* state.  If the UPS is off or has a low battery the plugin will
-* return a CRITICAL state.  You may also specify a variable to check
-* (such as temperature, utility voltage, battery load, etc.)  as well
-* as warning and critical thresholds for the value of that variable.
-* If the remote host has multiple UPS that are being monitored you
-* will have to use the [ups] option to specify which UPS to check.
-*
-* Notes:
-*
-* This plugin requires that the UPSD daemon distributed with Russel
-* Kroll's "Smart UPS Tools" be installed on the remote host.  If you
-* don't have the package installed on your system, you can download
-* it from http://www.exploits.org/~rkroll/smartupstools
-*
-* License Information:
-*
-* This program is free software; you can redistribute it and/or modify
+* 
+* This file contains Network UPS Tools plugin for Nagios
+* 
+* This plugin tests the UPS service on the specified host. Network UPS Tools
+* from www.networkupstools.org must be running for this plugin to work.
+* 
+* 
+* This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
+* the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
-*
+* 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
-*
+* 
 * You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-******************************************************************************/
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+* 
+* 
+*****************************************************************************/
+
+const char *progname = "check_ups";
+const char *copyright = "2000-2007";
+const char *email = "nagiosplug-devel@lists.sourceforge.net";
 
-#include "config.h"
 #include "common.h"
 #include "netutils.h"
 #include "utils.h"
 
-#define PROGNAME "check_ups"
-
-#define CHECK_NONE     0
-
-#define PORT   3305
-
-#define UPS_NONE       0                                                       /* no supported options */
-#define UPS_UTILITY    1                                               /* supports utility line voltage */
-#define UPS_BATTPCT    2                                               /* supports percent battery remaining */
-#define UPS_STATUS     4                                               /* supports UPS status */
-#define UPS_TEMP       8                                                       /* supports UPS temperature */
-#define UPS_LOADPCT    16                                      /* supports load percent */
-
-#define UPSSTATUS_NONE         0
-#define UPSSTATUS_OFF          1
-#define UPSSTATUS_OL           2
-#define UPSSTATUS_OB           4
-#define UPSSTATUS_LB           8
-#define UPSSTATUS_CAL          16
-#define UPSSTATUS_UNKOWN       32
+enum {
+       PORT = 3493
+};
+
+#define CHECK_NONE      0
+
+#define UPS_NONE     0   /* no supported options */
+#define UPS_UTILITY  1   /* supports utility line voltage */
+#define UPS_BATTPCT  2   /* supports percent battery remaining */
+#define UPS_STATUS   4   /* supports UPS status */
+#define UPS_TEMP     8   /* supports UPS temperature */
+#define UPS_LOADPCT    16   /* supports load percent */
+
+#define UPSSTATUS_NONE       0
+#define UPSSTATUS_OFF        1
+#define UPSSTATUS_OL         2
+#define UPSSTATUS_OB         4
+#define UPSSTATUS_LB         8
+#define UPSSTATUS_CAL       16
+#define UPSSTATUS_RB        32  /*Replace Battery */
+#define UPSSTATUS_BYPASS    64
+#define UPSSTATUS_OVER     128
+#define UPSSTATUS_TRIM     256
+#define UPSSTATUS_BOOST    512
+#define UPSSTATUS_CHRG    1024
+#define UPSSTATUS_DISCHRG 2048
+#define UPSSTATUS_UNKOWN  4096
+
+enum { NOSUCHVAR = ERROR-1 };
 
 int server_port = PORT;
-char *server_address = NULL;
+char *server_address;
 char *ups_name = NULL;
-double warning_value = 0.0L;
-double critical_value = 0.0L;
-int check_warning_value = FALSE;
-int check_critical_value = FALSE;
+double warning_value = 0.0;
+double critical_value = 0.0;
+int check_warn = FALSE;
+int check_crit = FALSE;
 int check_variable = UPS_NONE;
 int supported_options = UPS_NONE;
 int status = UPSSTATUS_NONE;
 
-double ups_utility_voltage = 0.0L;
-double ups_battery_percent = 0.0L;
-double ups_load_percent = 0.0L;
-double ups_temperature = 0.0L;
-char ups_status[MAX_INPUT_BUFFER] = "N/A";
+double ups_utility_voltage = 0.0;
+double ups_battery_percent = 0.0;
+double ups_load_percent = 0.0;
+double ups_temperature = 0.0;
+char *ups_status;
+int temp_output_c = 0;
 
 int determine_status (void);
-int determine_supported_vars (void);
-int get_ups_variable (const char *, char *, int);
+int get_ups_variable (const char *, char *, size_t);
 
 int process_arguments (int, char **);
-int call_getopt (int, char **);
 int validate_arguments (void);
 void print_help (void);
 void print_usage (void);
@@ -107,14 +99,27 @@ void print_usage (void);
 int
 main (int argc, char **argv)
 {
-       int result = STATE_OK;
-       char output_message[MAX_INPUT_BUFFER];
+       int result = STATE_UNKNOWN;
+       char *message;
+       char *data;
+       char *tunits;
        char temp_buffer[MAX_INPUT_BUFFER];
+       double ups_utility_deviation = 0.0;
+       int res;
+
+       setlocale (LC_ALL, "");
+       bindtextdomain (PACKAGE, LOCALEDIR);
+       textdomain (PACKAGE);
 
-       double ups_utility_deviation = 0.0L;
+       ups_status = strdup ("N/A");
+       data = strdup ("");
+       message = strdup ("");
 
-       if (process_arguments (argc, argv) != OK)
-               usage ("Invalid command arguments supplied\n");
+       /* Parse extra opts if any */
+       argv=np_extra_opts (&argc, argv, progname);
+
+       if (process_arguments (argc, argv) == ERROR)
+               usage4 (_("Could not parse arguments"));
 
        /* initialize alarm signal handling */
        signal (SIGALRM, socket_timeout_alarm_handler);
@@ -122,55 +127,77 @@ main (int argc, char **argv)
        /* set socket timeout */
        alarm (socket_timeout);
 
-       /* determine what variables the UPS supports */
-       if (determine_supported_vars () != OK)
-               return STATE_CRITICAL;
-
        /* get the ups status if possible */
+       if (determine_status () != OK)
+               return STATE_CRITICAL;
        if (supported_options & UPS_STATUS) {
 
-               if (determine_status () != OK)
-                       return STATE_CRITICAL;
-               ups_status[0] = 0;
+               ups_status = strdup ("");
                result = STATE_OK;
 
                if (status & UPSSTATUS_OFF) {
-                       strcpy (ups_status, "Off");
+                       asprintf (&ups_status, "Off");
                        result = STATE_CRITICAL;
                }
                else if ((status & (UPSSTATUS_OB | UPSSTATUS_LB)) ==
                                                 (UPSSTATUS_OB | UPSSTATUS_LB)) {
-                       strcpy (ups_status, "On Battery, Low Battery");
+                       asprintf (&ups_status, _("On Battery, Low Battery"));
                        result = STATE_CRITICAL;
                }
                else {
                        if (status & UPSSTATUS_OL) {
-                               strcat (ups_status, "Online");
+                               asprintf (&ups_status, "%s%s", ups_status, _("Online"));
                        }
                        if (status & UPSSTATUS_OB) {
-                               strcat (ups_status, "On Battery");
+                               asprintf (&ups_status, "%s%s", ups_status, _("On Battery"));
                                result = STATE_WARNING;
                        }
                        if (status & UPSSTATUS_LB) {
-                               strcat (ups_status, ", Low Battery");
+                               asprintf (&ups_status, "%s%s", ups_status, _(", Low Battery"));
                                result = STATE_WARNING;
                        }
                        if (status & UPSSTATUS_CAL) {
-                               strcat (ups_status, ", Calibrating");
+                               asprintf (&ups_status, "%s%s", ups_status, _(", Calibrating"));
+                       }
+                       if (status & UPSSTATUS_RB) {
+                               asprintf (&ups_status, "%s%s", ups_status, _(", Replace Battery"));
+                               result = STATE_WARNING;
+                       }
+                       if (status & UPSSTATUS_BYPASS) {
+                               asprintf (&ups_status, "%s%s", ups_status, _(", On Bypass"));
+                       }
+                       if (status & UPSSTATUS_OVER) {
+                               asprintf (&ups_status, "%s%s", ups_status, _(", Overload"));
+                       }
+                       if (status & UPSSTATUS_TRIM) {
+                               asprintf (&ups_status, "%s%s", ups_status, _(", Trimming"));
+                       }
+                       if (status & UPSSTATUS_BOOST) {
+                               asprintf (&ups_status, "%s%s", ups_status, _(", Boosting"));
+                       }
+                       if (status & UPSSTATUS_CHRG) {
+                               asprintf (&ups_status, "%s%s", ups_status, _(", Charging"));
+                       }
+                       if (status & UPSSTATUS_DISCHRG) {
+                               asprintf (&ups_status, "%s%s", ups_status, _(", Discharging"));
                        }
                        if (status & UPSSTATUS_UNKOWN) {
-                               strcat (ups_status, ", Unknown");
+                               asprintf (&ups_status, "%s%s", ups_status, _(", Unknown"));
                        }
                }
+               asprintf (&message, "%sStatus=%s ", message, ups_status);
        }
 
        /* get the ups utility voltage if possible */
-       if (supported_options & UPS_UTILITY) {
-
-               if (get_ups_variable ("UTILITY", temp_buffer, sizeof (temp_buffer)) != OK)
-                       return STATE_CRITICAL;
+       res=get_ups_variable ("input.voltage", temp_buffer, sizeof (temp_buffer));
+       if (res == NOSUCHVAR) supported_options &= ~UPS_UTILITY;
+       else if (res != OK)
+               return STATE_CRITICAL;
+       else {
+               supported_options |= UPS_UTILITY;
 
                ups_utility_voltage = atof (temp_buffer);
+               asprintf (&message, "%sUtility=%3.1fV ", message, ups_utility_voltage);
 
                if (ups_utility_voltage > 120.0)
                        ups_utility_deviation = 120.0 - ups_utility_voltage;
@@ -178,104 +205,129 @@ main (int argc, char **argv)
                        ups_utility_deviation = ups_utility_voltage - 120.0;
 
                if (check_variable == UPS_UTILITY) {
-                       if (check_critical_value == TRUE
-                                       && ups_utility_deviation >= critical_value) result = STATE_CRITICAL;
-                       else if (check_warning_value == TRUE
-                                                        && ups_utility_deviation >= warning_value
-                                                        && result < STATE_WARNING) result = STATE_WARNING;
+                       if (check_crit==TRUE && ups_utility_deviation>=critical_value) {
+                               result = STATE_CRITICAL;
+                       }
+                       else if (check_warn==TRUE && ups_utility_deviation>=warning_value) {
+                               result = max_state (result, STATE_WARNING);
+                       }
+                       asprintf (&data, "%s",
+                                 perfdata ("voltage", (long)(1000*ups_utility_voltage), "mV",
+                                           check_warn, (long)(1000*warning_value),
+                                           check_crit, (long)(1000*critical_value),
+                                           TRUE, 0, FALSE, 0));
+               } else {
+                       asprintf (&data, "%s",
+                                 perfdata ("voltage", (long)(1000*ups_utility_voltage), "mV",
+                                           FALSE, 0, FALSE, 0, TRUE, 0, FALSE, 0));
                }
        }
 
        /* get the ups battery percent if possible */
-       if (supported_options & UPS_BATTPCT) {
-
-               if (get_ups_variable ("BATTPCT", temp_buffer, sizeof (temp_buffer)) != OK)
-                       return STATE_CRITICAL;
-
+       res=get_ups_variable ("battery.charge", temp_buffer, sizeof (temp_buffer));
+       if (res == NOSUCHVAR) supported_options &= ~UPS_BATTPCT;
+       else if ( res != OK)
+               return STATE_CRITICAL;
+       else {
+               supported_options |= UPS_BATTPCT;
                ups_battery_percent = atof (temp_buffer);
+               asprintf (&message, "%sBatt=%3.1f%% ", message, ups_battery_percent);
 
                if (check_variable == UPS_BATTPCT) {
-                       if (check_critical_value == TRUE
-                                       && ups_battery_percent <= critical_value) result = STATE_CRITICAL;
-                       else if (check_warning_value == TRUE
-                                                        && ups_battery_percent <= warning_value
-                                                        && result < STATE_WARNING) result = STATE_WARNING;
+                       if (check_crit==TRUE && ups_battery_percent <= critical_value) {
+                               result = STATE_CRITICAL;
+                       }
+                       else if (check_warn==TRUE && ups_battery_percent<=warning_value) {
+                               result = max_state (result, STATE_WARNING);
+                       }
+                       asprintf (&data, "%s %s", data,
+                                 perfdata ("battery", (long)ups_battery_percent, "%",
+                                           check_warn, (long)(1000*warning_value),
+                                           check_crit, (long)(1000*critical_value),
+                                           TRUE, 0, TRUE, 100));
+               } else {
+                       asprintf (&data, "%s %s", data,
+                                 perfdata ("battery", (long)ups_battery_percent, "%",
+                                           FALSE, 0, FALSE, 0, TRUE, 0, TRUE, 100));
                }
        }
 
        /* get the ups load percent if possible */
-       if (supported_options & UPS_LOADPCT) {
-
-               if (get_ups_variable ("LOADPCT", temp_buffer, sizeof (temp_buffer)) != OK)
-                       return STATE_CRITICAL;
-
+       res=get_ups_variable ("ups.load", temp_buffer, sizeof (temp_buffer));
+       if ( res == NOSUCHVAR ) supported_options &= ~UPS_LOADPCT;
+       else if ( res != OK)
+               return STATE_CRITICAL;
+       else {
+               supported_options |= UPS_LOADPCT;
                ups_load_percent = atof (temp_buffer);
+               asprintf (&message, "%sLoad=%3.1f%% ", message, ups_load_percent);
 
                if (check_variable == UPS_LOADPCT) {
-                       if (check_critical_value == TRUE && ups_load_percent >= critical_value)
+                       if (check_crit==TRUE && ups_load_percent>=critical_value) {
                                result = STATE_CRITICAL;
-                       else if (check_warning_value == TRUE
-                                                        && ups_load_percent >= warning_value && result < STATE_WARNING)
-                               result = STATE_WARNING;
+                       }
+                       else if (check_warn==TRUE && ups_load_percent>=warning_value) {
+                               result = max_state (result, STATE_WARNING);
+                       }
+                       asprintf (&data, "%s %s", data,
+                                 perfdata ("load", (long)ups_load_percent, "%",
+                                           check_warn, (long)(1000*warning_value),
+                                           check_crit, (long)(1000*critical_value),
+                                           TRUE, 0, TRUE, 100));
+               } else {
+                       asprintf (&data, "%s %s", data,
+                                 perfdata ("load", (long)ups_load_percent, "%",
+                                           FALSE, 0, FALSE, 0, TRUE, 0, TRUE, 100));
                }
        }
 
        /* get the ups temperature if possible */
-       if (supported_options & UPS_TEMP) {
-
-               if (get_ups_variable ("UPSTEMP", temp_buffer, sizeof (temp_buffer)) != OK)
-                       return STATE_CRITICAL;
-
-               ups_temperature = (atof (temp_buffer) * 1.8) + 32;
+       res=get_ups_variable ("ups.temperature", temp_buffer, sizeof (temp_buffer));
+       if ( res == NOSUCHVAR ) supported_options &= ~UPS_TEMP;
+       else if ( res != OK)
+               return STATE_CRITICAL;
+       else {
+               supported_options |= UPS_TEMP;
+               if (temp_output_c) {
+                 tunits="degC";
+                 ups_temperature = atof (temp_buffer);
+                 asprintf (&message, "%sTemp=%3.1fC", message, ups_temperature);
+               }
+               else {
+                 tunits="degF";
+                 ups_temperature = (atof (temp_buffer) * 1.8) + 32;
+                 asprintf (&message, "%sTemp=%3.1fF", message, ups_temperature);
+               }
 
                if (check_variable == UPS_TEMP) {
-                       if (check_critical_value == TRUE && ups_temperature >= critical_value)
+                       if (check_crit==TRUE && ups_temperature>=critical_value) {
                                result = STATE_CRITICAL;
-                       else if (check_warning_value == TRUE && ups_temperature >= warning_value
-                                                        && result < STATE_WARNING)
-                               result = STATE_WARNING;
+                       }
+                       else if (check_warn == TRUE && ups_temperature>=warning_value) {
+                               result = max_state (result, STATE_WARNING);
+                       }
+                       asprintf (&data, "%s %s", data,
+                                 perfdata ("temp", (long)ups_temperature, tunits,
+                                           check_warn, (long)(1000*warning_value),
+                                           check_crit, (long)(1000*critical_value),
+                                           TRUE, 0, FALSE, 0));
+               } else {
+                       asprintf (&data, "%s %s", data,
+                                 perfdata ("temp", (long)ups_temperature, tunits,
+                                           FALSE, 0, FALSE, 0, TRUE, 0, FALSE, 0));
                }
        }
 
        /* if the UPS does not support any options we are looking for, report an error */
-       if (supported_options == UPS_NONE)
+       if (supported_options == UPS_NONE) {
                result = STATE_CRITICAL;
+               asprintf (&message, _("UPS does not support any available options\n"));
+       }
 
        /* reset timeout */
        alarm (0);
 
-
-       sprintf (output_message, "UPS %s - ",
-                                        (result == STATE_OK) ? "ok" : "problem");
-
-       if (supported_options & UPS_STATUS) {
-               sprintf (temp_buffer, "Status=%s ", ups_status);
-               strcat (output_message, temp_buffer);
-       }
-       if (supported_options & UPS_UTILITY) {
-               sprintf (temp_buffer, "Utility=%3.1fV ", ups_utility_voltage);
-               strcat (output_message, temp_buffer);
-       }
-       if (supported_options & UPS_BATTPCT) {
-               sprintf (temp_buffer, "Batt=%3.1f%% ", ups_battery_percent);
-               strcat (output_message, temp_buffer);
-       }
-       if (supported_options & UPS_LOADPCT) {
-               sprintf (temp_buffer, "Load=%3.1f%% ", ups_load_percent);
-               strcat (output_message, temp_buffer);
-       }
-       if (supported_options & UPS_TEMP) {
-               sprintf (temp_buffer, "Temp=%3.1fF", ups_temperature);
-               strcat (output_message, temp_buffer);
-       }
-       if (supported_options == UPS_NONE) {
-               sprintf (temp_buffer,
-                                                "UPS does not appear to support any available options\n");
-               strcat (output_message, temp_buffer);
-       }
-
-       printf ("%s\n", output_message);
-
+       printf ("UPS %s - %s|%s\n", state_text(result), message, data);
        return result;
 }
 
@@ -288,14 +340,16 @@ determine_status (void)
        char recv_buffer[MAX_INPUT_BUFFER];
        char temp_buffer[MAX_INPUT_BUFFER];
        char *ptr;
+       int res;
 
-       if (get_ups_variable ("STATUS", recv_buffer, sizeof (recv_buffer)) !=
-                       STATE_OK) {
-               printf ("Invalid response received from hostn");
+       res=get_ups_variable ("ups.status", recv_buffer, sizeof (recv_buffer));
+       if (res == NOSUCHVAR) return OK;
+       if (res != STATE_OK) {
+               printf ("%s\n", _("Invalid response received from host"));
                return ERROR;
        }
 
-       recv_buffer[strlen (recv_buffer) - 1] = 0;
+       supported_options |= UPS_STATUS;
 
        strcpy (temp_buffer, recv_buffer);
        for (ptr = (char *) strtok (temp_buffer, " "); ptr != NULL;
@@ -310,6 +364,20 @@ determine_status (void)
                        status |= UPSSTATUS_LB;
                else if (!strcmp (ptr, "CAL"))
                        status |= UPSSTATUS_CAL;
+               else if (!strcmp (ptr, "RB"))
+                       status |= UPSSTATUS_RB;
+               else if (!strcmp (ptr, "BYPASS"))
+                       status |= UPSSTATUS_BYPASS;
+               else if (!strcmp (ptr, "OVER"))
+                       status |= UPSSTATUS_OVER;
+               else if (!strcmp (ptr, "TRIM"))
+                       status |= UPSSTATUS_TRIM;
+               else if (!strcmp (ptr, "BOOST"))
+                       status |= UPSSTATUS_BOOST;
+               else if (!strcmp (ptr, "CHRG"))
+                       status |= UPSSTATUS_CHRG;
+               else if (!strcmp (ptr, "DISCHRG"))
+                       status |= UPSSTATUS_DISCHRG;
                else
                        status |= UPSSTATUS_UNKOWN;
        }
@@ -318,112 +386,70 @@ determine_status (void)
 }
 
 
-/* determines what options are supported by the UPS */
-int
-determine_supported_vars (void)
-{
-       char send_buffer[MAX_INPUT_BUFFER];
-       char recv_buffer[MAX_INPUT_BUFFER];
-       char temp_buffer[MAX_INPUT_BUFFER];
-       char *ptr;
-
-
-       /* get the list of variables that this UPS supports */
-       if (ups_name)
-               sprintf (send_buffer, "LISTVARS %s\r\n", ups_name);
-       else
-               sprintf (send_buffer, "LISTVARS\r\n");
-       if (process_tcp_request
-                       (server_address, server_port, send_buffer, recv_buffer,
-                        sizeof (recv_buffer)) != STATE_OK) {
-               printf ("Invalid response received from host\n");
-               return ERROR;
-       }
-
-       recv_buffer[strlen (recv_buffer) - 1] = 0;
-
-       if (ups_name)
-               ptr = recv_buffer + 5 + strlen (ups_name) + 2;
-       else
-               ptr = recv_buffer + 5;
-
-       strcpy (temp_buffer, recv_buffer);
-
-       for (ptr = (char *) strtok (temp_buffer, " "); ptr != NULL;
-                        ptr = (char *) strtok (NULL, " ")) {
-               if (!strcmp (ptr, "UTILITY"))
-                       supported_options |= UPS_UTILITY;
-               else if (!strcmp (ptr, "BATTPCT"))
-                       supported_options |= UPS_BATTPCT;
-               else if (!strcmp (ptr, "LOADPCT"))
-                       supported_options |= UPS_LOADPCT;
-               else if (!strcmp (ptr, "STATUS"))
-                       supported_options |= UPS_STATUS;
-               else if (!strcmp (ptr, "UPSTEMP"))
-                       supported_options |= UPS_TEMP;
-       }
-
-       return OK;
-}
-
-
 /* gets a variable value for a specific UPS  */
 int
-get_ups_variable (const char *varname, char *buf, int buflen)
+get_ups_variable (const char *varname, char *buf, size_t buflen)
 {
        /*  char command[MAX_INPUT_BUFFER]; */
        char temp_buffer[MAX_INPUT_BUFFER];
        char send_buffer[MAX_INPUT_BUFFER];
        char *ptr;
+       char *logout = "OK Goodbye\n";
+       int logout_len = strlen(logout);
+       int len;
+
+       *buf=0;
 
        /* create the command string to send to the UPS daemon */
-       if (ups_name)
-               sprintf (send_buffer, "REQ %s@%s\n", varname, ups_name);
-       else
-               sprintf (send_buffer, "REQ %s\n", varname);
+       /* Add LOGOUT to avoid read failure logs */
+       sprintf (send_buffer, "GET VAR %s %s\nLOGOUT\n", ups_name, varname);
 
        /* send the command to the daemon and get a response back */
        if (process_tcp_request
                        (server_address, server_port, send_buffer, temp_buffer,
                         sizeof (temp_buffer)) != STATE_OK) {
-               printf ("Invalid response received from host\n");
+               printf ("%s\n", _("Invalid response received from host"));
                return ERROR;
        }
 
-       if (ups_name)
-               ptr = temp_buffer + strlen (varname) + 5 + strlen (ups_name) + 1;
-       else
-               ptr = temp_buffer + strlen (varname) + 5;
-
-       if (!strcmp (ptr, "NOT-SUPPORTED")) {
-               printf ("Error: Variable '%s' is not supported\n", varname);
+       ptr = temp_buffer;
+       len = strlen(ptr);
+       if (len > logout_len && strcmp (ptr + len - logout_len, logout) == 0) len -= logout_len;
+       if (len > 0 && ptr[len-1] == '\n') ptr[len-1]=0;
+       if (strcmp (ptr, "ERR UNKNOWN-UPS") == 0) {
+               printf (_("CRITICAL - no such UPS '%s' on that host\n"), ups_name);
                return ERROR;
        }
 
-       if (!strcmp (ptr, "DATA-STALE")) {
-               printf ("Error: UPS data is stale\n");
+       if (strcmp (ptr, "ERR VAR-NOT-SUPPORTED") == 0) {
+               /*printf ("Error: Variable '%s' is not supported\n", varname);*/
+               return NOSUCHVAR;
+       }
+
+       if (strcmp (ptr, "ERR DATA-STALE") == 0) {
+               printf ("%s\n", _("CRITICAL - UPS data is stale"));
                return ERROR;
        }
 
-       if (!strcmp (ptr, "UNKNOWN-UPS")) {
-               if (ups_name)
-                       printf ("Error: UPS '%s' is unknown\n", ups_name);
-               else
-                       printf ("Error: UPS is unknown\n");
+       if (strncmp (ptr, "ERR", 3) == 0) {
+               printf (_("Unknown error: %s\n"), ptr);
                return ERROR;
        }
 
-       strncpy (buf, ptr, buflen - 1);
-       buf[buflen - 1] = 0;
+       ptr = temp_buffer + strlen (varname) + strlen (ups_name) + 6;
+       len = strlen(ptr);
+       if (len < 2 || ptr[0] != '"' || ptr[len-1] != '"') {
+               printf ("%s\n", _("Error: unable to parse variable"));
+               return ERROR;
+       }
+       strncpy (buf, ptr+1, len - 2);
+       buf[len - 2] = 0;
 
        return OK;
 }
 
 
-
-
-
-/* Command line: CHECK_UPS <host_address> [-u ups] [-p port] [-v variable] 
+/* Command line: CHECK_UPS -H <host_address> -u ups [-p port] [-v variable]
                           [-wv warn_value] [-cv crit_value] [-to to_sec] */
 
 
@@ -433,102 +459,54 @@ process_arguments (int argc, char **argv)
 {
        int c;
 
-       if (argc < 2)
-               return ERROR;
-
-       for (c = 1; c < argc; c++) {
-               if (strcmp ("-to", argv[c]) == 0)
-                       strcpy (argv[c], "-t");
-               else if (strcmp ("-wt", argv[c]) == 0)
-                       strcpy (argv[c], "-w");
-               else if (strcmp ("-ct", argv[c]) == 0)
-                       strcpy (argv[c], "-c");
-       }
-
-       c = 0;
-       while ((c += (call_getopt (argc - c, &argv[c]))) < argc) {
-
-               if (is_option (argv[c]))
-                       continue;
-
-               if (server_address == NULL) {
-                       if (is_host (argv[c])) {
-                               server_address = argv[c];
-                       }
-                       else {
-                               usage ("Invalid host name");
-                       }
-               }
-       }
-
-       if (server_address == NULL)
-               server_address = strscpy (NULL, "127.0.0.1");
-
-       return validate_arguments ();
-}
-
-
-
-
-
-
-int
-call_getopt (int argc, char **argv)
-{
-       int c, i = 0;
-
-#ifdef HAVE_GETOPT_H
-       int option_index = 0;
-       static struct option long_options[] = {
+       int option = 0;
+       static struct option longopts[] = {
                {"hostname", required_argument, 0, 'H'},
                {"ups", required_argument, 0, 'u'},
                {"port", required_argument, 0, 'p'},
                {"critical", required_argument, 0, 'c'},
                {"warning", required_argument, 0, 'w'},
                {"timeout", required_argument, 0, 't'},
+               {"temperature", no_argument, 0, 'T'},
                {"variable", required_argument, 0, 'v'},
                {"version", no_argument, 0, 'V'},
                {"help", no_argument, 0, 'h'},
                {0, 0, 0, 0}
        };
-#endif
 
-       while (1) {
-#ifdef HAVE_GETOPT_H
-               c =
-                       getopt_long (argc, argv, "+hVH:u:p:v:c:w:t:", long_options,
-                                                                        &option_index);
-#else
-               c = getopt (argc, argv, "+?hVH:u:p:v:c:w:t:");
-#endif
+       if (argc < 2)
+               return ERROR;
 
-               i++;
+       for (c = 1; c < argc; c++) {
+               if (strcmp ("-to", argv[c]) == 0)
+                       strcpy (argv[c], "-t");
+               else if (strcmp ("-wt", argv[c]) == 0)
+                       strcpy (argv[c], "-w");
+               else if (strcmp ("-ct", argv[c]) == 0)
+                       strcpy (argv[c], "-c");
+       }
 
-               if (c == -1 || c == EOF || c == 1)
-                       break;
+       while (1) {
+               c = getopt_long (argc, argv, "hVTH:u:p:v:c:w:t:", longopts,
+                                                                        &option);
 
-               switch (c) {
-               case 'H':
-               case 'u':
-               case 'p':
-               case 'v':
-               case 'c':
-               case 'w':
-               case 't':
-                       i++;
-               }
+               if (c == -1 || c == EOF)
+                       break;
 
                switch (c) {
                case '?':                                                                       /* help */
-                       usage ("Invalid argument\n");
+                       usage5 ();
                case 'H':                                                                       /* hostname */
                        if (is_host (optarg)) {
                                server_address = optarg;
                        }
                        else {
-                               usage ("Invalid host name\n");
+                               usage2 (_("Invalid hostname/address"), optarg);
                        }
                        break;
+               case 'T': /* FIXME: to be improved (ie "-T C" for Celsius or "-T F" for Farenheit) */
+                       temp_output_c = 1;
+                       break;
                case 'u':                                                                       /* ups name */
                        ups_name = optarg;
                        break;
@@ -537,25 +515,25 @@ call_getopt (int argc, char **argv)
                                server_port = atoi (optarg);
                        }
                        else {
-                               usage ("Server port must be a positive integer\n");
+                               usage2 (_("Port must be a positive integer"), optarg);
                        }
                        break;
                case 'c':                                                                       /* critical time threshold */
                        if (is_intnonneg (optarg)) {
                                critical_value = atoi (optarg);
-                               check_critical_value = TRUE;
+                               check_crit = TRUE;
                        }
                        else {
-                               usage ("Critical time must be a nonnegative integer\n");
+                               usage2 (_("Critical time must be a positive integer"), optarg);
                        }
                        break;
                case 'w':                                                                       /* warning time threshold */
                        if (is_intnonneg (optarg)) {
                                warning_value = atoi (optarg);
-                               check_warning_value = TRUE;
+                               check_warn = TRUE;
                        }
                        else {
-                               usage ("Warning time must be a nonnegative integer\n");
+                               usage2 (_("Warning time must be a positive integer"), optarg);
                        }
                        break;
                case 'v':                                                                       /* variable */
@@ -568,82 +546,121 @@ call_getopt (int argc, char **argv)
                        else if (!strcmp (optarg, "LOADPCT"))
                                check_variable = UPS_LOADPCT;
                        else
-                               usage ("Unrecognized UPS variable\n");
+                               usage2 (_("Unrecognized UPS variable"), optarg);
                        break;
                case 't':                                                                       /* timeout */
                        if (is_intnonneg (optarg)) {
                                socket_timeout = atoi (optarg);
                        }
                        else {
-                               usage ("Time interval must be a nonnegative integer\n");
+                               usage4 (_("Timeout interval must be a positive integer"));
                        }
                        break;
                case 'V':                                                                       /* version */
-                       print_revision (PROGNAME, "$Revision$");
+                       print_revision (progname, NP_VERSION);
                        exit (STATE_OK);
                case 'h':                                                                       /* help */
                        print_help ();
                        exit (STATE_OK);
                }
        }
-       return i;
-}
 
 
+       if (server_address == NULL && argc > optind) {
+               if (is_host (argv[optind]))
+                       server_address = argv[optind++];
+               else
+                       usage2 (_("Invalid hostname/address"), optarg);
+       }
+
+       if (server_address == NULL)
+               server_address = strdup("127.0.0.1");
 
+       return validate_arguments();
+}
 
 
 int
 validate_arguments (void)
 {
+       if (! ups_name) {
+               printf ("%s\n", _("Error : no UPS indicated"));
+               return ERROR;
+       }
        return OK;
 }
 
 
-
-
-
 void
 print_help (void)
 {
-       print_revision (PROGNAME, "$Revision$");
-       printf
-               ("Copyright (c) 2000 Tom Shields/Karl DeBisschop\n\n"
-                "This plugin tests the UPS service on the specified host.\n\n");
-       print_usage ();
-       printf
-               ("\nOptions:\n"
-                " -H, --hostname=STRING or IPADDRESS\n"
-                "   Check server on the indicated host\n"
-                " -p, --port=INTEGER\n"
-                "   Make connection on the indicated port (default: %d)\n"
-                " -u, --ups=STRING\n"
-                "   Name of UPS\n"
-                " -w, --warning=INTEGER\n"
-                "   Seconds necessary to result in a warning status\n"
-                " -c, --critical=INTEGER\n"
-                "   Seconds necessary to result in a critical status\n"
-                " -t, --timeout=INTEGER\n"
-                "   Seconds before connection attempt times out (default: %d)\n"
-                " -v, --verbose\n"
-                "   Print extra information (command-line use only)\n"
-                " -h, --help\n"
-                "   Print detailed help screen\n"
-                " -V, --version\n"
-                "   Print version information\n\n", PORT, DEFAULT_SOCKET_TIMEOUT);
-       support ();
-}
+       char *myport;
+       asprintf (&myport, "%d", PORT);
+
+       print_revision (progname, NP_VERSION);
+
+       printf ("Copyright (c) 2000 Tom Shields\n");
+       printf ("Copyright (c) 2004 Alain Richard <alain.richard@equation.fr>\n");
+       printf ("Copyright (c) 2004 Arnaud Quette <arnaud.quette@mgeups.com>\n");
+       printf (COPYRIGHT, copyright, email);
 
+       printf ("%s\n", _("This plugin tests the UPS service on the specified host. Network UPS Tools"));
+  printf ("%s\n", _("from www.networkupstools.org must be running for this plugin to work."));
 
+  printf ("\n\n");
 
+       print_usage ();
+
+       printf (UT_HELP_VRSN);
+       printf (UT_EXTRA_OPTS);
+
+       printf (UT_HOST_PORT, 'p', myport);
+
+       printf (" %s\n", "-u, --ups=STRING");
+  printf ("    %s\n", _("Name of UPS"));
+  printf (" %s\n", "-T, --temperature");
+  printf ("    %s\n", _("Output of temperatures in Celsius"));
+  printf (" %s\n", "-v, --variable=STRING");
+  printf ("    %s %s\n", _("Valid values for STRING are"), "LINE, TEMP, BATTPCT or LOADPCT");
+
+       printf (UT_WARN_CRIT);
+
+       printf (UT_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
+
+/* TODO: -v clashing with -v/-variable. Commenting out help text since verbose
+         is unused up to now */
+/*     printf (UT_VERBOSE); */
+
+  printf ("\n");
+       printf ("%s\n", _("This plugin attempts to determine the status of a UPS (Uninterruptible Power"));
+  printf ("%s\n", _("Supply) on a local or remote host. If the UPS is online or calibrating, the"));
+  printf ("%s\n", _("plugin will return an OK state. If the battery is on it will return a WARNING"));
+  printf ("%s\n", _("state. If the UPS is off or has a low battery the plugin will return a CRITICAL"));
+  printf ("%s\n", _("state."));
+
+  printf ("\n");
+  printf ("%s\n", _("Notes:"));
+  printf (" %s\n", _("You may also specify a variable to check (such as temperature, utility voltage,"));
+  printf (" %s\n", _("battery load, etc.) as well as warning and critical thresholds for the value"));
+  printf (" %s\n", _("of that variable.  If the remote host has multiple UPS that are being monitored"));
+  printf (" %s\n", _("you will have to use the --ups option to specify which UPS to check."));
+  printf ("\n");
+  printf (" %s\n", _("This plugin requires that the UPSD daemon distributed with Russell Kroll's"));
+  printf (" %s\n", _("Network UPS Tools be installed on the remote host. If you do not have the"));
+  printf (" %s\n", _("package installed on your system, you can download it from"));
+  printf (" %s\n", _("http://www.networkupstools.org"));
+#ifdef NP_EXTRA_OPTS
+  printf ("\n");
+  printf (UT_EXTRA_OPTS_NOTES);
+#endif
+
+       printf (UT_SUPPORT);
+}
 
 
 void
 print_usage (void)
 {
-       printf
-               ("Usage: %s -H host [-e expect] [-p port] [-w warn] [-c crit]\n"
-                "            [-t timeout] [-v]\n"
-                "       %s --help\n"
-                "       %s --version\n", PROGNAME, PROGNAME, PROGNAME);
+  printf (_("Usage:"));
+       printf ("%s -H host -u ups [-p port] [-v variable] [-w warn_value] [-c crit_value] [-to to_sec] [-T]\n", progname);
 }