diff options
Diffstat (limited to 'src/openvpn/status.c')
-rw-r--r-- | src/openvpn/status.c | 401 |
1 files changed, 221 insertions, 180 deletions
diff --git a/src/openvpn/status.c b/src/openvpn/status.c index b7ff484..e47f35c 100644 --- a/src/openvpn/status.c +++ b/src/openvpn/status.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -42,251 +42,292 @@ */ static const char * -print_status_mode (unsigned int flags) +print_status_mode(unsigned int flags) { - switch (flags) + switch (flags) { - case STATUS_OUTPUT_WRITE: - return "WRITE"; - case STATUS_OUTPUT_READ: - return "READ"; - case STATUS_OUTPUT_READ|STATUS_OUTPUT_WRITE: - return "READ/WRITE"; - default: - return "UNDEF"; + case STATUS_OUTPUT_WRITE: + return "WRITE"; + + case STATUS_OUTPUT_READ: + return "READ"; + + case STATUS_OUTPUT_READ|STATUS_OUTPUT_WRITE: + return "READ/WRITE"; + + default: + return "UNDEF"; } } struct status_output * -status_open (const char *filename, - const int refresh_freq, - const int msglevel, - const struct virtual_output *vout, - const unsigned int flags) +status_open(const char *filename, + const int refresh_freq, + const int msglevel, + const struct virtual_output *vout, + const unsigned int flags) { - struct status_output *so = NULL; - if (filename || msglevel >= 0 || vout) + struct status_output *so = NULL; + if (filename || msglevel >= 0 || vout) { - ALLOC_OBJ_CLEAR (so, struct status_output); - so->flags = flags; - so->msglevel = msglevel; - so->vout = vout; - so->fd = -1; - buf_reset (&so->read_buf); - event_timeout_clear (&so->et); - if (filename) + ALLOC_OBJ_CLEAR(so, struct status_output); + so->flags = flags; + so->msglevel = msglevel; + so->vout = vout; + so->fd = -1; + buf_reset(&so->read_buf); + event_timeout_clear(&so->et); + if (filename) { - switch (so->flags) + switch (so->flags) + { + case STATUS_OUTPUT_WRITE: + so->fd = platform_open(filename, + O_CREAT | O_TRUNC | O_WRONLY, + S_IRUSR | S_IWUSR); + break; + + case STATUS_OUTPUT_READ: + so->fd = platform_open(filename, + O_RDONLY, + S_IRUSR | S_IWUSR); + break; + + case STATUS_OUTPUT_READ|STATUS_OUTPUT_WRITE: + so->fd = platform_open(filename, + O_CREAT | O_RDWR, + S_IRUSR | S_IWUSR); + break; + + default: + ASSERT(0); + } + if (so->fd >= 0) + { + so->filename = string_alloc(filename, NULL); + set_cloexec(so->fd); + + /* allocate read buffer */ + if (so->flags & STATUS_OUTPUT_READ) + { + so->read_buf = alloc_buf(512); + } + } + else { - case STATUS_OUTPUT_WRITE: - so->fd = platform_open (filename, - O_CREAT | O_TRUNC | O_WRONLY, - S_IRUSR | S_IWUSR); - break; - case STATUS_OUTPUT_READ: - so->fd = platform_open (filename, - O_RDONLY, - S_IRUSR | S_IWUSR); - break; - case STATUS_OUTPUT_READ|STATUS_OUTPUT_WRITE: - so->fd = platform_open (filename, - O_CREAT | O_RDWR, - S_IRUSR | S_IWUSR); - break; - default: - ASSERT (0); + msg(M_WARN, "Note: cannot open %s for %s", filename, print_status_mode(so->flags)); + so->errors = true; } - if (so->fd >= 0) - { - so->filename = string_alloc (filename, NULL); - set_cloexec (so->fd); - - /* allocate read buffer */ - if (so->flags & STATUS_OUTPUT_READ) - so->read_buf = alloc_buf (512); - } - else - { - msg (M_WARN, "Note: cannot open %s for %s", filename, print_status_mode (so->flags)); - so->errors = true; - } - } - else - so->flags = STATUS_OUTPUT_WRITE; - - if ((so->flags & STATUS_OUTPUT_WRITE) && refresh_freq > 0) - { - event_timeout_init (&so->et, refresh_freq, 0); - } + } + else + { + so->flags = STATUS_OUTPUT_WRITE; + } + + if ((so->flags & STATUS_OUTPUT_WRITE) && refresh_freq > 0) + { + event_timeout_init(&so->et, refresh_freq, 0); + } } - return so; + return so; } bool -status_trigger (struct status_output *so) +status_trigger(struct status_output *so) { - if (so) + if (so) { - struct timeval null; - CLEAR (null); - return event_timeout_trigger (&so->et, &null, ETT_DEFAULT); + struct timeval null; + CLEAR(null); + return event_timeout_trigger(&so->et, &null, ETT_DEFAULT); + } + else + { + return false; } - else - return false; } bool -status_trigger_tv (struct status_output *so, struct timeval *tv) +status_trigger_tv(struct status_output *so, struct timeval *tv) { - if (so) - return event_timeout_trigger (&so->et, tv, ETT_DEFAULT); - else - return false; + if (so) + { + return event_timeout_trigger(&so->et, tv, ETT_DEFAULT); + } + else + { + return false; + } } void -status_reset (struct status_output *so) +status_reset(struct status_output *so) { - if (so && so->fd >= 0) - lseek (so->fd, (off_t)0, SEEK_SET); + if (so && so->fd >= 0) + { + lseek(so->fd, (off_t)0, SEEK_SET); + } } void -status_flush (struct status_output *so) +status_flush(struct status_output *so) { - if (so && so->fd >= 0 && (so->flags & STATUS_OUTPUT_WRITE)) + if (so && so->fd >= 0 && (so->flags & STATUS_OUTPUT_WRITE)) { #if defined(HAVE_FTRUNCATE) - { - const off_t off = lseek (so->fd, (off_t)0, SEEK_CUR); - if (ftruncate (so->fd, off) != 0) { - msg (M_WARN, "Failed to truncate status file: %s", strerror(errno)); - } - } + { + const off_t off = lseek(so->fd, (off_t)0, SEEK_CUR); + if (ftruncate(so->fd, off) != 0) + { + msg(M_WARN, "Failed to truncate status file: %s", strerror(errno)); + } + } #elif defined(HAVE_CHSIZE) - { - const long off = (long) lseek (so->fd, (off_t)0, SEEK_CUR); - chsize (so->fd, off); - } -#else + { + const long off = (long) lseek(so->fd, (off_t)0, SEEK_CUR); + chsize(so->fd, off); + } +#else /* if defined(HAVE_FTRUNCATE) */ #warning both ftruncate and chsize functions appear to be missing from this OS #endif - /* clear read buffer */ - if (buf_defined (&so->read_buf)) - { - ASSERT (buf_init (&so->read_buf, 0)); - } + /* clear read buffer */ + if (buf_defined(&so->read_buf)) + { + ASSERT(buf_init(&so->read_buf, 0)); + } } } /* return false if error occurred */ bool -status_close (struct status_output *so) +status_close(struct status_output *so) { - bool ret = true; - if (so) + bool ret = true; + if (so) { - if (so->errors) - ret = false; - if (so->fd >= 0) - { - if (close (so->fd) < 0) - ret = false; - } - if (so->filename) - free (so->filename); - if (buf_defined (&so->read_buf)) - free_buf (&so->read_buf); - free (so); + if (so->errors) + { + ret = false; + } + if (so->fd >= 0) + { + if (close(so->fd) < 0) + { + ret = false; + } + } + if (so->filename) + { + free(so->filename); + } + if (buf_defined(&so->read_buf)) + { + free_buf(&so->read_buf); + } + free(so); + } + else + { + ret = false; } - else - ret = false; - return ret; + return ret; } #define STATUS_PRINTF_MAXLEN 512 void -status_printf (struct status_output *so, const char *format, ...) +status_printf(struct status_output *so, const char *format, ...) { - if (so && (so->flags & STATUS_OUTPUT_WRITE)) + if (so && (so->flags & STATUS_OUTPUT_WRITE)) { - char buf[STATUS_PRINTF_MAXLEN+2]; /* leave extra bytes for CR, LF */ - va_list arglist; - int stat; - - va_start (arglist, format); - stat = vsnprintf (buf, STATUS_PRINTF_MAXLEN, format, arglist); - va_end (arglist); - buf[STATUS_PRINTF_MAXLEN - 1] = 0; - - if (stat < 0 || stat >= STATUS_PRINTF_MAXLEN) - so->errors = true; - - if (so->msglevel >= 0 && !so->errors) - msg (so->msglevel, "%s", buf); - - if (so->fd >= 0 && !so->errors) - { - int len; - strcat (buf, "\n"); - len = strlen (buf); - if (len > 0) - { - if (write (so->fd, buf, len) != len) - so->errors = true; - } - } - - if (so->vout && !so->errors) - { - chomp (buf); - (*so->vout->func) (so->vout->arg, so->vout->flags_default, buf); - } + char buf[STATUS_PRINTF_MAXLEN+2]; /* leave extra bytes for CR, LF */ + va_list arglist; + int stat; + + va_start(arglist, format); + stat = vsnprintf(buf, STATUS_PRINTF_MAXLEN, format, arglist); + va_end(arglist); + buf[STATUS_PRINTF_MAXLEN - 1] = 0; + + if (stat < 0 || stat >= STATUS_PRINTF_MAXLEN) + { + so->errors = true; + } + + if (so->msglevel >= 0 && !so->errors) + { + msg(so->msglevel, "%s", buf); + } + + if (so->fd >= 0 && !so->errors) + { + int len; + strcat(buf, "\n"); + len = strlen(buf); + if (len > 0) + { + if (write(so->fd, buf, len) != len) + { + so->errors = true; + } + } + } + + if (so->vout && !so->errors) + { + chomp(buf); + (*so->vout->func)(so->vout->arg, so->vout->flags_default, buf); + } } } bool -status_read (struct status_output *so, struct buffer *buf) +status_read(struct status_output *so, struct buffer *buf) { - bool ret = false; + bool ret = false; - if (so && so->fd >= 0 && (so->flags & STATUS_OUTPUT_READ)) + if (so && so->fd >= 0 && (so->flags & STATUS_OUTPUT_READ)) { - ASSERT (buf_defined (&so->read_buf)); - ASSERT (buf_defined (buf)); - while (true) - { - const int c = buf_read_u8 (&so->read_buf); + ASSERT(buf_defined(&so->read_buf)); + ASSERT(buf_defined(buf)); + while (true) + { + const int c = buf_read_u8(&so->read_buf); - /* read more of file into buffer */ - if (c == -1) - { - int len; + /* read more of file into buffer */ + if (c == -1) + { + int len; - ASSERT (buf_init (&so->read_buf, 0)); - len = read (so->fd, BPTR (&so->read_buf), BCAP (&so->read_buf)); - if (len <= 0) - break; + ASSERT(buf_init(&so->read_buf, 0)); + len = read(so->fd, BPTR(&so->read_buf), BCAP(&so->read_buf)); + if (len <= 0) + { + break; + } - ASSERT (buf_inc_len (&so->read_buf, len)); - continue; - } + ASSERT(buf_inc_len(&so->read_buf, len)); + continue; + } - ret = true; + ret = true; - if (c == '\r') - continue; + if (c == '\r') + { + continue; + } - if (c == '\n') - break; + if (c == '\n') + { + break; + } - buf_write_u8 (buf, c); - } + buf_write_u8(buf, c); + } - buf_null_terminate (buf); + buf_null_terminate(buf); } - return ret; + return ret; } |