Back to index

nagios-plugins  1.4.16
Defines | Functions | Variables
utils_cmd.c File Reference
#include "common.h"
#include "utils_cmd.h"
#include "utils_base.h"
#include <fcntl.h>

Go to the source code of this file.

Defines

#define NAGIOSPLUG_API_C   1
#define WEXITSTATUS(stat_val)   ((unsigned)(stat_val) >> 8)
 macros
#define WIFEXITED(stat_val)   (((stat_val) & 255) == 0)
#define maxfd   256

Functions

static int _cmd_open (char *const *, int *, int *)
 prototypes
static int _cmd_close (int fd)
static int _cmd_fetch_output (int fd, output *op, int flags)
int cmd_run (const char *cmdstring, output *out, output *err, int flags)
 prototypes
int cmd_run_array (char *const *argv, output *out, output *err, int flags)
int cmd_file_read (char *filename, output *out, int flags)

Variables

char ** environ
 includes
static pid_t * _cmd_pids = NULL

Define Documentation

#define maxfd   256

Definition at line 87 of file utils_cmd.c.

#define NAGIOSPLUG_API_C   1

Definition at line 39 of file utils_cmd.c.

#define WEXITSTATUS (   stat_val)    ((unsigned)(stat_val) >> 8)

macros

Definition at line 56 of file utils_cmd.c.

#define WIFEXITED (   stat_val)    (((stat_val) & 255) == 0)

Definition at line 60 of file utils_cmd.c.


Function Documentation

static int _cmd_close ( int  fd) [static]

Definition at line 189 of file utils_cmd.c.

{
       int status;
       pid_t pid;

       /* make sure the provided fd was opened */
       if (fd < 0 || fd > maxfd || !_cmd_pids || (pid = _cmd_pids[fd]) == 0)
              return -1;

       _cmd_pids[fd] = 0;
       if (close (fd) == -1)
              return -1;

       /* EINTR is ok (sort of), everything else is bad */
       while (waitpid (pid, &status, 0) < 0)
              if (errno != EINTR)
                     return -1;

       /* return child's termination status */
       return (WIFEXITED (status)) ? WEXITSTATUS (status) : -1;
}

Here is the caller graph for this function:

static int _cmd_fetch_output ( int  fd,
output op,
int  flags 
) [static]

Definition at line 213 of file utils_cmd.c.

{
       size_t len = 0, i = 0, lineno = 0;
       size_t rsf = 6, ary_size = 0;      /* rsf = right shift factor, dec'ed uncond once */
       char *buf = NULL;
       int ret;
       char tmpbuf[4096];

       op->buf = NULL;
       op->buflen = 0;
       while ((ret = read (fd, tmpbuf, sizeof (tmpbuf))) > 0) {
              len = (size_t) ret;
              op->buf = realloc (op->buf, op->buflen + len + 1);
              memcpy (op->buf + op->buflen, tmpbuf, len);
              op->buflen += len;
              i++;
       }

       if (ret < 0) {
              printf ("read() returned %d: %s\n", ret, strerror (errno));
              return ret;
       }

       /* some plugins may want to keep output unbroken, and some commands
        * will yield no output, so return here for those */
       if (flags & CMD_NO_ARRAYS || !op->buf || !op->buflen)
              return op->buflen;

       /* and some may want both */
       if (flags & CMD_NO_ASSOC) {
              buf = malloc (op->buflen);
              memcpy (buf, op->buf, op->buflen);
       }
       else
              buf = op->buf;

       op->line = NULL;
       op->lens = NULL;
       i = 0;
       while (i < op->buflen) {
              /* make sure we have enough memory */
              if (lineno >= ary_size) {
                     /* ary_size must never be zero */
                     do {
                            ary_size = op->buflen >> --rsf;
                     } while (!ary_size);

                     op->line = realloc (op->line, ary_size * sizeof (char *));
                     op->lens = realloc (op->lens, ary_size * sizeof (size_t));
              }

              /* set the pointer to the string */
              op->line[lineno] = &buf[i];

              /* hop to next newline or end of buffer */
              while (buf[i] != '\n' && i < op->buflen)
                     i++;
              buf[i] = '\0';

              /* calculate the string length using pointer difference */
              op->lens[lineno] = (size_t) & buf[i] - (size_t) op->line[lineno];

              lineno++;
              i++;
       }

       return lineno;
}

Here is the caller graph for this function:

static int _cmd_open ( char *const argv,
int *  pfd,
int *  pfderr 
) [static]

prototypes

Definition at line 92 of file utils_cmd.c.

{
#ifndef maxfd
       if (!maxfd && (maxfd = sysconf (_SC_OPEN_MAX)) < 0) {
              /* possibly log or emit a warning here, since there's no
               * guarantee that our guess at maxfd will be adequate */
              maxfd = 256;
       }
#endif

       if (!_cmd_pids)
              _cmd_pids = calloc (maxfd, sizeof (pid_t));
}

Here is the caller graph for this function:

int cmd_file_read ( char *  filename,
output out,
int  flags 
)

Definition at line 381 of file utils_cmd.c.

{
       int fd;
       if(out)
              memset (out, 0, sizeof(output));

       if ((fd = open(filename, O_RDONLY)) == -1) {
              die( STATE_UNKNOWN, _("Error opening %s: %s"), filename, strerror(errno) );
       }
       
       if(out)
              out->lines = _cmd_fetch_output (fd, out, flags);

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int cmd_run ( const char *  cmdstring,
output out,
output err,
int  flags 
)

prototypes

Definition at line 284 of file utils_cmd.c.

{
       int fd, pfd_out[2], pfd_err[2];
       int i = 0, argc;
       size_t cmdlen;
       char **argv = NULL;
       char *cmd = NULL;
       char *str = NULL;

       if (cmdstring == NULL)
              return -1;

       /* initialize the structs */
       if (out)
              memset (out, 0, sizeof (output));
       if (err)
              memset (err, 0, sizeof (output));

       /* make copy of command string so strtok() doesn't silently modify it */
       /* (the calling program may want to access it later) */
       cmdlen = strlen (cmdstring);
       if ((cmd = malloc (cmdlen + 1)) == NULL)
              return -1;
       memcpy (cmd, cmdstring, cmdlen);
       cmd[cmdlen] = '\0';

       /* This is not a shell, so we don't handle "???" */
       if (strstr (cmdstring, "\"")) return -1;

       /* allow single quotes, but only if non-whitesapce doesn't occur on both sides */
       if (strstr (cmdstring, " ' ") || strstr (cmdstring, "'''"))
              return -1;

       /* each arg must be whitespace-separated, so args can be a maximum
        * of (len / 2) + 1. We add 1 extra to the mix for NULL termination */
       argc = (cmdlen >> 1) + 2;
       argv = calloc (sizeof (char *), argc);

       if (argv == NULL) {
              printf ("%s\n", _("Could not malloc argv array in popen()"));
              return -1;
       }

       /* get command arguments (stupidly, but fairly quickly) */
       while (cmd) {
              str = cmd;
              str += strspn (str, " \t\r\n");    /* trim any leading whitespace */

              if (strstr (str, "'") == str) {    /* handle SIMPLE quoted strings */
                     str++;
                     if (!strstr (str, "'"))
                            return -1;                                              /* balanced? */
                     cmd = 1 + strstr (str, "'");
                     str[strcspn (str, "'")] = 0;
              }
              else {
                     if (strpbrk (str, " \t\r\n")) {
                            cmd = 1 + strpbrk (str, " \t\r\n");
                            str[strcspn (str, " \t\r\n")] = 0;
                     }
                     else {
                            cmd = NULL;
                     }
              }

              if (cmd && strlen (cmd) == strspn (cmd, " \t\r\n"))
                     cmd = NULL;

              argv[i++] = str;
       }

       return cmd_run_array (argv, out, err, flags);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int cmd_run_array ( char *const argv,
output out,
output err,
int  flags 
)

Definition at line 359 of file utils_cmd.c.

{
       int fd, pfd_out[2], pfd_err[2];

       /* initialize the structs */
       if (out)
              memset (out, 0, sizeof (output));
       if (err)
              memset (err, 0, sizeof (output));

       if ((fd = _cmd_open (argv, pfd_out, pfd_err)) == -1)
              die (STATE_UNKNOWN, _("Could not open pipe: %s\n"), argv[0]);

       if (out)
              out->lines = _cmd_fetch_output (pfd_out[0], out, flags);
       if (err)
              err->lines = _cmd_fetch_output (pfd_err[0], err, flags);

       return _cmd_close (fd);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

pid_t* _cmd_pids = NULL [static]

Definition at line 76 of file utils_cmd.c.

char** environ

includes