#include "buffer.h"
#include "misc.h"
+#include "base64.h"
#include "tun.h"
#include "error.h"
- #include "thread.h"
#include "otime.h"
#include "plugin.h"
#include "options.h"
{
static unsigned int counter;
struct buffer fname = alloc_buf_gc (256, gc);
+ int fd;
+ const char *retfname = NULL;
+ unsigned int attempts = 0;
- ++counter;
-
- {
- uint8_t rndbytes[16];
- const char *rndstr;
-
- prng_bytes (rndbytes, sizeof (rndbytes));
- rndstr = format_hex_ex (rndbytes, sizeof (rndbytes), 40, 0, NULL, gc);
- buf_printf (&fname, PACKAGE "_%s_%s.tmp", prefix, rndstr);
- }
+ do
+ {
+ uint8_t rndbytes[16];
+ const char *rndstr;
+
+ ++attempts;
- mutex_lock_static (L_CREATE_TEMP);
+ ++counter;
- mutex_unlock_static (L_CREATE_TEMP);
+
+ prng_bytes (rndbytes, sizeof rndbytes);
+ rndstr = format_hex_ex (rndbytes, sizeof rndbytes, 40, 0, NULL, gc);
+ buf_printf (&fname, PACKAGE "_%s_%s.tmp", prefix, rndstr);
+
+ retfname = gen_path (directory, BSTR (&fname), gc);
+ if (!retfname)
+ {
+ msg (M_FATAL, "Failed to create temporary filename and path");
+ return NULL;
+ }
+
+ /* Atomically create the file. Errors out if the file already
+ exists. */
+ fd = open (retfname, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
+ if (fd != -1)
+ {
+ close (fd);
+ return retfname;
+ }
+ else if (fd == -1 && errno != EEXIST)
+ {
+ /* Something else went wrong, no need to retry. */
+ struct gc_arena gcerr = gc_new ();
+ msg (M_FATAL, "Could not create temporary file '%s': %s",
+ retfname, strerror_ts (errno, &gcerr));
+ gc_free (&gcerr);
+ return NULL;
+ }
+ }
+ while (attempts < 6);
- return gen_path (directory, BSTR (&fname), gc);
+ msg (M_FATAL, "Failed to create temporary file after %i attempts", attempts);
+ return NULL;
}
/*
/*
* Status file version 1
*/
- status_printf (so, PACKAGE_NAME " CLIENT LIST");
+ status_printf (so, "OpenVPN CLIENT LIST");
status_printf (so, "Updated,%s", time_string (0, 0, false, &gc_top));
status_printf (so, "Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since");
- hash_iterator_init (m->hash, &hi, true);
+ hash_iterator_init (m->hash, &hi);
while ((he = hash_iterator_next (&hi)))
{
struct gc_arena gc = gc_new ();
#endif
/*
- * Don't compile the struct buffer_list code unless something needs it
+ * Compile the struct buffer_list code
*/
-#if defined(ENABLE_MANAGEMENT) || defined(ENABLE_PF)
#define ENABLE_BUFFER_LIST
-#endif
- /*
- * Do we have pthread capability?
- */
- #ifdef USE_PTHREAD
- #if defined(USE_CRYPTO) && defined(USE_SSL) && P2MP
- #include <pthread.h>
- #else
- #undef USE_PTHREAD
- #endif
- #endif
-
- /*
- * Pthread support is currently experimental (and quite unfinished).
- */
- #if 1 /* JYFIXME -- if defined, disable pthread */
- #undef USE_PTHREAD
- #endif
-
/*
* Should we include OCC (options consistency check) code?
*/