compat.c 101 KB
Newer Older
1
2
/* Copyright (c) 2003-2004, Roger Dingledine
 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
Nick Mathewson's avatar
Nick Mathewson committed
3
 * Copyright (c) 2007-2016, The Tor Project, Inc. */
4
5
/* See LICENSE for licensing information */

6
7
8
/**
 * \file compat.c
 * \brief Wrappers to make calls more portable.  This code defines
9
 * functions such as tor_snprintf, get/set various data types,
10
11
12
13
14
 * renaming, setting socket options, switching user IDs.  It is basically
 * where the non-portable items are conditionally included depending on
 * the platform.
 **/

15
#define COMPAT_PRIVATE
Nick Mathewson's avatar
Nick Mathewson committed
16
#include "compat.h"
17

18
#ifdef _WIN32
19
#include <winsock2.h>
20
#include <windows.h>
21
#include <sys/locking.h>
22
#endif
23

24
25
26
#ifdef HAVE_UNAME
#include <sys/utsname.h>
#endif
27
28
29
30
31
32
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
33
34
35
36
37
38
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
#ifdef HAVE_SYS_UTIME_H
#include <sys/utime.h>
#endif
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_FCNTL_H
#include <sys/fcntl.h>
#endif
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#ifdef HAVE_GRP_H
#include <grp.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
60
61
62
#ifdef HAVE_CRT_EXTERNS_H
#include <crt_externs.h>
#endif
63
64
65
#ifdef HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
#endif
66
67
68
#ifdef HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
#endif
69

70
71
72
73
74
/* Now deprecated in Linux GLIBC */
#if defined(HAVE_SYS_SYSCTL_H) && !defined(_WIN32) && !defined(__linux__)
#include <sys/sysctl.h>
#endif

75
76
77
#ifdef _WIN32
#include <conio.h>
#include <wchar.h>
78
/* Some mingw headers lack these. :p */
Nick Mathewson's avatar
Nick Mathewson committed
79
#if defined(HAVE_DECL__GETWCH) && !HAVE_DECL__GETWCH
80
81
82
83
84
wint_t _getwch(void);
#endif
#ifndef WEOF
#define WEOF (wchar_t)(0xFFFF)
#endif
Nick Mathewson's avatar
Nick Mathewson committed
85
#if defined(HAVE_DECL_SECUREZEROMEMORY) && !HAVE_DECL_SECUREZEROMEMORY
Nick Mathewson's avatar
Nick Mathewson committed
86
87
static inline void
SecureZeroMemory(PVOID ptr, SIZE_T cnt)
88
89
90
91
92
{
  volatile char *vcptr = (volatile char*)ptr;
  while (cnt--)
    *vcptr++ = 0;
}
93
#endif
94
#elif defined(HAVE_READPASSPHRASE_H)
95
#include <readpassphrase.h>
96
#else
97
#include "tor_readpassphrase.h"
98
#endif
99

100
101
/* Includes for the process attaching prevention */
#if defined(HAVE_SYS_PRCTL_H) && defined(__linux__)
102
/* Only use the linux prctl;  the IRIX prctl is totally different */
103
104
105
106
107
108
#include <sys/prctl.h>
#elif defined(__APPLE__)
#include <sys/types.h>
#include <sys/ptrace.h>
#endif

109
110
111
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
112
113
114
115
116
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h> /* FreeBSD needs this to know what version it is */
#endif
#include <stdio.h>
#include <stdlib.h>
117
#include <assert.h>
118
119
120
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
121
122
123
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
124
125
126
#ifdef HAVE_SYS_SYSLIMITS_H
#include <sys/syslimits.h>
#endif
127
128
129
#ifdef HAVE_SYS_FILE_H
#include <sys/file.h>
#endif
130

Nick Mathewson's avatar
Nick Mathewson committed
131
#include "torlog.h"
132
#include "util.h"
133
#include "container.h"
134
#include "address.h"
Cristian Toader's avatar
Cristian Toader committed
135
#include "sandbox.h"
136

Roger Dingledine's avatar
Roger Dingledine committed
137
/* Inline the strl functions if the platform doesn't have them. */
138
139
140
141
142
143
144
#ifndef HAVE_STRLCPY
#include "strlcpy.c"
#endif
#ifndef HAVE_STRLCAT
#include "strlcat.c"
#endif

145
146
147
148
149
/* When set_max_file_descriptors() is called, update this with the max file
 * descriptor value so we can use it to check the limit when opening a new
 * socket. Default value is what Debian sets as the default hard limit. */
static int max_sockets = 1024;

150
151
152
153
154
/** As open(path, flags, mode), but return an fd with the close-on-exec mode
 * set. */
int
tor_open_cloexec(const char *path, int flags, unsigned mode)
{
155
  int fd;
156
  const char *p = sandbox_intern_string(path);
157
#ifdef O_CLOEXEC
teor's avatar
teor committed
158
  fd = open(p, flags|O_CLOEXEC, mode);
159
160
161
  if (fd >= 0)
    return fd;
  /* If we got an error, see if it is EINVAL. EINVAL might indicate that,
Roger Dingledine's avatar
Roger Dingledine committed
162
   * even though we were built on a system with O_CLOEXEC support, we
163
164
165
166
167
   * are running on one without. */
  if (errno != EINVAL)
    return -1;
#endif

teor's avatar
teor committed
168
169
  log_debug(LD_FS, "Opening %s with flags %x", p, flags);
  fd = open(p, flags, mode);
170
#ifdef FD_CLOEXEC
171
172
173
174
175
176
177
  if (fd >= 0) {
    if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
      log_warn(LD_FS,"Couldn't set FD_CLOEXEC: %s", strerror(errno));
      close(fd);
      return -1;
    }
  }
178
179
180
181
#endif
  return fd;
}

Roger Dingledine's avatar
Roger Dingledine committed
182
/** As fopen(path,mode), but ensures that the O_CLOEXEC bit is set on the
183
 * underlying file handle. */
184
185
186
187
188
FILE *
tor_fopen_cloexec(const char *path, const char *mode)
{
  FILE *result = fopen(path, mode);
#ifdef FD_CLOEXEC
189
190
191
192
193
194
195
  if (result != NULL) {
    if (fcntl(fileno(result), F_SETFD, FD_CLOEXEC) == -1) {
      log_warn(LD_FS,"Couldn't set FD_CLOEXEC: %s", strerror(errno));
      fclose(result);
      return NULL;
    }
  }
196
197
198
199
#endif
  return result;
}

200
201
202
203
/** As rename(), but work correctly with the sandbox. */
int
tor_rename(const char *path_old, const char *path_new)
{
204
  log_debug(LD_FS, "Renaming %s to %s", path_old, path_new);
205
206
207
208
  return rename(sandbox_intern_string(path_old),
                sandbox_intern_string(path_new));
}

209
#if defined(HAVE_SYS_MMAN_H) || defined(RUNNING_DOXYGEN)
210
/** Try to create a memory mapping for <b>filename</b> and return it.  On
211
212
 * failure, return NULL.  Sets errno properly, using ERANGE to mean
 * "empty file". */
213
tor_mmap_t *
214
tor_mmap_file(const char *filename)
215
216
217
{
  int fd; /* router file */
  char *string;
218
  int page_size, result;
219
  tor_mmap_t *res;
220
  size_t size, filesize;
221
  struct stat st;
222
223
224

  tor_assert(filename);

225
  fd = tor_open_cloexec(filename, O_RDONLY, 0);
226
  if (fd<0) {
227
    int save_errno = errno;
228
229
230
    int severity = (errno == ENOENT) ? LOG_INFO : LOG_WARN;
    log_fn(severity, LD_FS,"Could not open \"%s\" for mmap(): %s",filename,
           strerror(errno));
231
    errno = save_errno;
232
233
234
    return NULL;
  }

235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
  /* Get the size of the file */
  result = fstat(fd, &st);
  if (result != 0) {
    int save_errno = errno;
    log_warn(LD_FS,
             "Couldn't fstat opened descriptor for \"%s\" during mmap: %s",
             filename, strerror(errno));
    close(fd);
    errno = save_errno;
    return NULL;
  }
  size = filesize = (size_t)(st.st_size);
  /*
   * Should we check for weird crap like mmapping a named pipe here,
   * or just wait for if (!size) below to fail?
   */
251
252
  /* ensure page alignment */
  page_size = getpagesize();
253
  size += (size%page_size) ? page_size-(size%page_size) : 0;
254

255
  if (!size) {
256
257
    /* Zero-length file. If we call mmap on it, it will succeed but
     * return NULL, and bad things will happen. So just fail. */
258
    log_info(LD_FS,"File \"%s\" is empty. Ignoring.",filename);
259
    errno = ERANGE;
260
    close(fd);
261
262
263
    return NULL;
  }

264
  string = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
265
  close(fd);
266
  if (string == MAP_FAILED) {
267
    int save_errno = errno;
268
269
    log_warn(LD_FS,"Could not mmap file \"%s\": %s", filename,
             strerror(errno));
270
    errno = save_errno;
271
272
273
    return NULL;
  }

274
275
276
  res = tor_malloc_zero(sizeof(tor_mmap_t));
  res->data = string;
  res->size = filesize;
277
  res->mapping_size = size;
278

279
  return res;
280
}
281
282
283
/** Release storage held for a memory mapping; returns 0 on success,
 * or -1 on failure (and logs a warning). */
int
284
285
tor_munmap_file(tor_mmap_t *handle)
{
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
  int res;

  if (handle == NULL)
    return 0;

  res = munmap((char*)handle->data, handle->mapping_size);
  if (res == 0) {
    /* munmap() succeeded */
    tor_free(handle);
  } else {
    log_warn(LD_FS, "Failed to munmap() in tor_munmap_file(): %s",
             strerror(errno));
    res = -1;
  }

  return res;
302
}
303
#elif defined(_WIN32)
304
tor_mmap_t *
305
tor_mmap_file(const char *filename)
306
{
307
  TCHAR tfilename[MAX_PATH]= {0};
Nick Mathewson's avatar
Nick Mathewson committed
308
  tor_mmap_t *res = tor_malloc_zero(sizeof(tor_mmap_t));
309
  int empty = 0;
310
  HANDLE file_handle = INVALID_HANDLE_VALUE;
311
312
  DWORD size_low, size_high;
  uint64_t real_size;
313
  res->mmap_handle = NULL;
314
315
316
317
318
#ifdef UNICODE
  mbstowcs(tfilename,filename,MAX_PATH);
#else
  strlcpy(tfilename,filename,MAX_PATH);
#endif
319
  file_handle = CreateFile(tfilename,
320
                           GENERIC_READ, FILE_SHARE_READ,
321
322
323
324
                           NULL,
                           OPEN_EXISTING,
                           FILE_ATTRIBUTE_NORMAL,
                           0);
325

326
  if (file_handle == INVALID_HANDLE_VALUE)
327
    goto win_err;
328

329
  size_low = GetFileSize(file_handle, &size_high);
330

331
332
333
334
335
  if (size_low == INVALID_FILE_SIZE && GetLastError() != NO_ERROR) {
    log_warn(LD_FS,"Error getting size of \"%s\".",filename);
    goto win_err;
  }
  if (size_low == 0 && size_high == 0) {
336
    log_info(LD_FS,"File \"%s\" is empty. Ignoring.",filename);
337
    empty = 1;
338
339
    goto err;
  }
340
341
342
343
344
345
  real_size = (((uint64_t)size_high)<<32) | size_low;
  if (real_size > SIZE_MAX) {
    log_warn(LD_FS,"File \"%s\" is too big to map; not trying.",filename);
    goto err;
  }
  res->size = real_size;
346

347
  res->mmap_handle = CreateFileMapping(file_handle,
348
349
                                       NULL,
                                       PAGE_READONLY,
350
351
                                       size_high,
                                       size_low,
352
                                       NULL);
353
  if (res->mmap_handle == NULL)
354
    goto win_err;
355
356
357
358
  res->data = (char*) MapViewOfFile(res->mmap_handle,
                                    FILE_MAP_READ,
                                    0, 0, 0);
  if (!res->data)
359
    goto win_err;
360

361
  CloseHandle(file_handle);
362
  return res;
363
364
 win_err: {
    DWORD e = GetLastError();
365
    int severity = (e == ERROR_FILE_NOT_FOUND || e == ERROR_PATH_NOT_FOUND) ?
366
367
      LOG_INFO : LOG_WARN;
    char *msg = format_win32_error(e);
368
    log_fn(severity, LD_FS, "Couldn't mmap file \"%s\": %s", filename, msg);
369
    tor_free(msg);
370
371
372
373
    if (e == ERROR_FILE_NOT_FOUND || e == ERROR_PATH_NOT_FOUND)
      errno = ENOENT;
    else
      errno = EINVAL;
374
  }
375
 err:
376
377
  if (empty)
    errno = ERANGE;
378
379
  if (file_handle != INVALID_HANDLE_VALUE)
    CloseHandle(file_handle);
380
  tor_munmap_file(res);
381
382
  return NULL;
}
383
384
385

/* Unmap the file, and return 0 for success or -1 for failure */
int
386
tor_munmap_file(tor_mmap_t *handle)
387
{
388
389
390
  if (handle == NULL)
    return 0;

391
  if (handle->data) {
392
393
    /* This is an ugly cast, but without it, "data" in struct tor_mmap_t would
       have to be redefined as non-const. */
394
395
396
397
398
399
    BOOL ok = UnmapViewOfFile( (LPVOID) handle->data);
    if (!ok) {
      log_warn(LD_FS, "Failed to UnmapViewOfFile() in tor_munmap_file(): %d",
               (int)GetLastError());
    }
  }
400

401
  if (handle->mmap_handle != NULL)
Nick Mathewson's avatar
Nick Mathewson committed
402
    CloseHandle(handle->mmap_handle);
403
  tor_free(handle);
404
405

  return 0;
406
407
}
#else
408
tor_mmap_t *
409
tor_mmap_file(const char *filename)
410
{
411
  struct stat st;
412
  char *res = read_file_to_str(filename, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
413
  tor_mmap_t *handle;
414
415
  if (! res)
    return NULL;
416
  handle = tor_malloc_zero(sizeof(tor_mmap_t));
417
  handle->data = res;
418
  handle->size = st.st_size;
419
  return handle;
420
}
421
422
423
424
425
426

/** Unmap the file mapped with tor_mmap_file(), and return 0 for success
 * or -1 for failure.
 */

int
427
tor_munmap_file(tor_mmap_t *handle)
428
{
429
  char *d = NULL;
430
431
  if (handle == NULL)
    return 0;
432
433

  d = (char*)handle->data;
434
  tor_free(d);
435
  memwipe(handle, 0, sizeof(tor_mmap_t));
436
  tor_free(handle);
437
438
439

  /* Can't fail in this mmap()/munmap()-free case */
  return 0;
440
441
442
}
#endif

443
444
445
/** Replacement for snprintf.  Differs from platform snprintf in two
 * ways: First, always NUL-terminates its output.  Second, always
 * returns -1 if the result is truncated.  (Note that this return
446
447
 * behavior does <i>not</i> conform to C99; it just happens to be
 * easier to emulate "return -1" with conformant implementations than
448
449
 * it is to emulate "return number that would be written" with
 * non-conformant implementations.) */
450
451
int
tor_snprintf(char *str, size_t size, const char *format, ...)
452
453
454
455
456
457
458
459
460
{
  va_list ap;
  int r;
  va_start(ap,format);
  r = tor_vsnprintf(str,size,format,ap);
  va_end(ap);
  return r;
}

461
/** Replacement for vsnprintf; behavior differs as tor_snprintf differs from
462
463
 * snprintf.
 */
464
465
int
tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
466
467
{
  int r;
468
469
  if (size == 0)
    return -1; /* no place for the NUL */
470
  if (size > SIZE_T_CEILING)
471
    return -1;
472
#ifdef _WIN32
473
474
475
476
477
  r = _vsnprintf(str, size, format, args);
#else
  r = vsnprintf(str, size, format, args);
#endif
  str[size-1] = '\0';
478
  if (r < 0 || r >= (ssize_t)size)
479
480
481
482
    return -1;
  return r;
}

483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
/**
 * Portable asprintf implementation.  Does a printf() into a newly malloc'd
 * string.  Sets *<b>strp</b> to this string, and returns its length (not
 * including the terminating NUL character).
 *
 * You can treat this function as if its implementation were something like
   <pre>
     char buf[_INFINITY_];
     tor_snprintf(buf, sizeof(buf), fmt, args);
     *strp = tor_strdup(buf);
     return strlen(*strp):
   </pre>
 * Where _INFINITY_ is an imaginary constant so big that any string can fit
 * into it.
 */
int
tor_asprintf(char **strp, const char *fmt, ...)
{
  int r;
  va_list args;
  va_start(args, fmt);
  r = tor_vasprintf(strp, fmt, args);
  va_end(args);
  if (!*strp || r < 0) {
507
    /* LCOV_EXCL_START */
508
509
    log_err(LD_BUG, "Internal error in asprintf");
    tor_assert(0);
510
    /* LCOV_EXCL_STOP */
511
512
513
514
515
516
517
518
519
520
521
522
  }
  return r;
}

/**
 * Portable vasprintf implementation.  Does a printf() into a newly malloc'd
 * string.  Differs from regular vasprintf in the same ways that
 * tor_asprintf() differs from regular asprintf.
 */
int
tor_vasprintf(char **strp, const char *fmt, va_list args)
{
523
524
  /* use a temporary variable in case *strp is in args. */
  char *strp_tmp=NULL;
525
526
#ifdef HAVE_VASPRINTF
  /* If the platform gives us one, use it. */
527
  int r = vasprintf(&strp_tmp, fmt, args);
528
529
  if (r < 0)
    *strp = NULL;
530
531
  else
    *strp = strp_tmp;
532
  return r;
533
#elif defined(HAVE__VSCPRINTF)
534
535
536
  /* On Windows, _vsnprintf won't tell us the length of the string if it
   * overflows, so we need to use _vcsprintf to tell how much to allocate */
  int len, r;
537
538
539
540
  va_list tmp_args;
  va_copy(tmp_args, args);
  len = _vscprintf(fmt, tmp_args);
  va_end(tmp_args);
541
  if (len < 0) {
542
    *strp = NULL;
543
544
    return -1;
  }
545
546
  strp_tmp = tor_malloc((size_t)len + 1);
  r = _vsnprintf(strp_tmp, (size_t)len+1, fmt, args);
547
  if (r != len) {
548
549
    tor_free(strp_tmp);
    *strp = NULL;
550
551
    return -1;
  }
552
  *strp = strp_tmp;
553
554
555
556
557
558
  return len;
#else
  /* Everywhere else, we have a decent vsnprintf that tells us how many
   * characters we need.  We give it a try on a short buffer first, since
   * it might be nice to avoid the second vsnprintf call.
   */
559
560
561
  /* XXXX This code spent a number of years broken (see bug 30651). It is
   * possible that no Tor users actually run on systems without vasprintf() or
   * _vscprintf(). If so, we should consider removing this code. */
562
563
564
565
  char buf[128];
  int len, r;
  va_list tmp_args;
  va_copy(tmp_args, args);
566
567
568
  /* Use vsnprintf to retrieve needed length.  tor_vsnprintf() is not an
   * option here because it will simply return -1 if buf is not large enough
   * to hold the complete string.
569
570
   */
  len = vsnprintf(buf, sizeof(buf), fmt, tmp_args);
571
  va_end(tmp_args);
572
573
574
575
576
  buf[sizeof(buf) - 1] = '\0';
  if (len < 0) {
    *strp = NULL;
    return -1;
  }
577
578
579
580
  if (len < (int)sizeof(buf)) {
    *strp = tor_strdup(buf);
    return len;
  }
581
  strp_tmp = tor_malloc((size_t)len+1);
582
  /* use of tor_vsnprintf() will ensure string is null terminated */
583
  r = tor_vsnprintf(strp_tmp, (size_t)len+1, fmt, args);
584
  if (r != len) {
585
586
    tor_free(strp_tmp);
    *strp = NULL;
587
588
    return -1;
  }
589
  *strp = strp_tmp;
590
591
592
593
  return len;
#endif
}

Nick Mathewson's avatar
Nick Mathewson committed
594
/** Given <b>hlen</b> bytes at <b>haystack</b> and <b>nlen</b> bytes at
Roger Dingledine's avatar
Roger Dingledine committed
595
 * <b>needle</b>, return a pointer to the first occurrence of the needle
Nick Mathewson's avatar
Nick Mathewson committed
596
597
 * within the haystack, or NULL if there is no such occurrence.
 *
598
599
 * This function is <em>not</em> timing-safe.
 *
Robert Ransom's avatar
Robert Ransom committed
600
 * Requires that <b>nlen</b> be greater than zero.
Nick Mathewson's avatar
Nick Mathewson committed
601
602
 */
const void *
603
604
tor_memmem(const void *_haystack, size_t hlen,
           const void *_needle, size_t nlen)
Nick Mathewson's avatar
Nick Mathewson committed
605
606
607
{
#if defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2)
  tor_assert(nlen);
Nick Mathewson's avatar
Nick Mathewson committed
608
  return memmem(_haystack, hlen, _needle, nlen);
Nick Mathewson's avatar
Nick Mathewson committed
609
#else
610
611
  /* This isn't as fast as the GLIBC implementation, but it doesn't need to
   * be. */
612
  const char *p, *last_possible_start;
Nick Mathewson's avatar
Nick Mathewson committed
613
614
  const char *haystack = (const char*)_haystack;
  const char *needle = (const char*)_needle;
Nick Mathewson's avatar
Nick Mathewson committed
615
616
617
  char first;
  tor_assert(nlen);

618
619
620
  if (nlen > hlen)
    return NULL;

Nick Mathewson's avatar
Nick Mathewson committed
621
  p = haystack;
622
623
  /* Last position at which the needle could start. */
  last_possible_start = haystack + hlen - nlen;
Nick Mathewson's avatar
Nick Mathewson committed
624
  first = *(const char*)needle;
625
  while ((p = memchr(p, first, last_possible_start + 1 - p))) {
626
    if (fast_memeq(p, needle, nlen))
Nick Mathewson's avatar
Nick Mathewson committed
627
      return p;
628
629
630
631
632
633
634
    if (++p > last_possible_start) {
      /* This comparison shouldn't be necessary, since if p was previously
       * equal to last_possible_start, the next memchr call would be
       * "memchr(p, first, 0)", which will return NULL. But it clarifies the
       * logic. */
      return NULL;
    }
Nick Mathewson's avatar
Nick Mathewson committed
635
636
637
638
639
  }
  return NULL;
#endif
}

640
641
/**
 * Tables to implement ctypes-replacement TOR_IS*() functions.  Each table
642
643
644
 * has 256 bits to look up whether a character is in some set or not.  This
 * fails on non-ASCII platforms, but it is hard to find a platform whose
 * character set is not a superset of ASCII nowadays. */
645
646

/**@{*/
647
const uint32_t TOR_ISALPHA_TABLE[8] =
648
  { 0, 0, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
649
const uint32_t TOR_ISALNUM_TABLE[8] =
650
  { 0, 0x3ff0000, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
651
652
const uint32_t TOR_ISSPACE_TABLE[8] = { 0x3e00, 0x1, 0, 0, 0, 0, 0, 0 };
const uint32_t TOR_ISXDIGIT_TABLE[8] =
653
  { 0, 0x3ff0000, 0x7e, 0x7e, 0, 0, 0, 0 };
654
655
const uint32_t TOR_ISDIGIT_TABLE[8] = { 0, 0x3ff0000, 0, 0, 0, 0, 0, 0 };
const uint32_t TOR_ISPRINT_TABLE[8] =
656
  { 0, 0xffffffff, 0xffffffff, 0x7fffffff, 0, 0, 0, 0x0 };
657
658
const uint32_t TOR_ISUPPER_TABLE[8] = { 0, 0, 0x7fffffe, 0, 0, 0, 0, 0 };
const uint32_t TOR_ISLOWER_TABLE[8] = { 0, 0, 0, 0x7fffffe, 0, 0, 0, 0 };
659
660
661
662

/** Upper-casing and lowercasing tables to map characters to upper/lowercase
 * equivalents.  Used by tor_toupper() and tor_tolower(). */
/**@{*/
663
const uint8_t TOR_TOUPPER_TABLE[256] = {
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
  16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
  32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
  48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
  64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
  80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
  96,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
  80,81,82,83,84,85,86,87,88,89,90,123,124,125,126,127,
  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
  144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
  160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
  176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
  208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
  224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
  240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
};
681
const uint8_t TOR_TOLOWER_TABLE[256] = {
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
  16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
  32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
  48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
  64,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
  112,113,114,115,116,117,118,119,120,121,122,91,92,93,94,95,
  96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
  112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
  144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
  160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
  176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
  208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
  224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
  240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
};
699
/**@}*/
700

701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
/** Helper for tor_strtok_r_impl: Advances cp past all characters in
 * <b>sep</b>, and returns its new value. */
static char *
strtok_helper(char *cp, const char *sep)
{
  if (sep[1]) {
    while (*cp && strchr(sep, *cp))
      ++cp;
  } else {
    while (*cp && *cp == *sep)
      ++cp;
  }
  return cp;
}

716
/** Implementation of strtok_r for platforms whose coders haven't figured out
717
718
 * how to write one.  Hey, retrograde libc developers!  You can use this code
 * here for free! */
719
720
721
722
char *
tor_strtok_r_impl(char *str, const char *sep, char **lasts)
{
  char *cp, *start;
723
724
725
726
727
  tor_assert(*sep);
  if (str) {
    str = strtok_helper(str, sep);
    if (!*str)
      return NULL;
728
    start = cp = *lasts = str;
729
  } else if (!*lasts || !**lasts) {
730
    return NULL;
731
  } else {
732
    start = cp = *lasts;
733
  }
734
735
736
737
738
739
740
741
742
743
744
745

  if (sep[1]) {
    while (*cp && !strchr(sep, *cp))
      ++cp;
  } else {
    cp = strchr(cp, *sep);
  }

  if (!cp || !*cp) {
    *lasts = NULL;
  } else {
    *cp++ = '\0';
746
    *lasts = strtok_helper(cp, sep);
747
748
749
750
  }
  return start;
}

751
#ifdef _WIN32
752
753
754
755
/** Take a filename and return a pointer to its final element.  This
 * function is called on __FILE__ to fix a MSVC nit where __FILE__
 * contains the full path to the file.  This is bad, because it
 * confuses users to find the home directory of the person who
Nick Mathewson's avatar
Nick Mathewson committed
756
 * compiled the binary in their warning messages.
757
758
 */
const char *
759
tor_fix_source_file(const char *fname)
760
{
761
  const char *cp1, *cp2, *r;
762
763
764
  cp1 = strrchr(fname, '/');
  cp2 = strrchr(fname, '\\');
  if (cp1 && cp2) {
765
    r = (cp1<cp2)?(cp2+1):(cp1+1);
766
  } else if (cp1) {
767
    r = cp1+1;
768
  } else if (cp2) {
769
    r = cp2+1;
770
  } else {
771
    r = fname;
772
  }
773
  return r;
774
}
775
#endif
776

777
/**
778
 * Read a 16-bit value beginning at <b>cp</b>.  Equivalent to
779
780
781
 * *(uint16_t*)(cp), but will not cause segfaults on platforms that forbid
 * unaligned memory access.
 */
782
uint16_t
Nick Mathewson's avatar
Nick Mathewson committed
783
get_uint16(const void *cp)
784
785
786
787
788
789
{
  uint16_t v;
  memcpy(&v,cp,2);
  return v;
}
/**
790
 * Read a 32-bit value beginning at <b>cp</b>.  Equivalent to
791
792
793
 * *(uint32_t*)(cp), but will not cause segfaults on platforms that forbid
 * unaligned memory access.
 */
794
uint32_t
Nick Mathewson's avatar
Nick Mathewson committed
795
get_uint32(const void *cp)
796
797
798
799
800
{
  uint32_t v;
  memcpy(&v,cp,4);
  return v;
}
801
/**
Sebastian Hahn's avatar
Sebastian Hahn committed
802
803
 * Read a 64-bit value beginning at <b>cp</b>.  Equivalent to
 * *(uint64_t*)(cp), but will not cause segfaults on platforms that forbid
804
805
806
 * unaligned memory access.
 */
uint64_t
Nick Mathewson's avatar
Nick Mathewson committed
807
get_uint64(const void *cp)
808
809
810
811
812
813
{
  uint64_t v;
  memcpy(&v,cp,8);
  return v;
}

814
815
/**
 * Set a 16-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to
816
 * *(uint16_t*)(cp) = v, but will not cause segfaults on platforms that forbid
817
 * unaligned memory access. */
818
void
Nick Mathewson's avatar
Nick Mathewson committed
819
set_uint16(void *cp, uint16_t v)
820
821
822
823
824
{
  memcpy(cp,&v,2);
}
/**
 * Set a 32-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to
825
 * *(uint32_t*)(cp) = v, but will not cause segfaults on platforms that forbid
826
 * unaligned memory access. */
827
void
Nick Mathewson's avatar
Nick Mathewson committed
828
set_uint32(void *cp, uint32_t v)
829
830
831
{
  memcpy(cp,&v,4);
}
832
833
834
835
836
/**
 * Set a 64-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to
 * *(uint64_t*)(cp) = v, but will not cause segfaults on platforms that forbid
 * unaligned memory access. */
void
Nick Mathewson's avatar
Nick Mathewson committed
837
set_uint64(void *cp, uint64_t v)
838
839
840
{
  memcpy(cp,&v,8);
}
841
842

/**
Nick Mathewson's avatar
Nick Mathewson committed
843
 * Rename the file <b>from</b> to the file <b>to</b>.  On Unix, this is
Roger Dingledine's avatar
Roger Dingledine committed
844
845
 * the same as rename(2).  On windows, this removes <b>to</b> first if
 * it already exists.
846
847
 * Returns 0 on success.  Returns -1 and sets errno on failure.
 */
848
849
int
replace_file(const char *from, const char *to)
850
{
851
#ifndef _WIN32
852
  return tor_rename(from, to);
853
#else
854
  switch (file_status(to))
855
856
857
858
    {
    case FN_NOENT:
      break;
    case FN_FILE:
859
    case FN_EMPTY:
860
861
862
863
864
865
866
867
      if (unlink(to)) return -1;
      break;
    case FN_ERROR:
      return -1;
    case FN_DIR:
      errno = EISDIR;
      return -1;
    }
868
  return tor_rename(from,to);
869
870
871
#endif
}

872
873
874
875
876
877
878
879
880
/** Change <b>fname</b>'s modification time to now. */
int
touch_file(const char *fname)
{
  if (utime(fname, NULL)!=0)
    return -1;
  return 0;
}

881
/** Represents a lockfile on which we hold the lock. */
882
struct tor_lockfile_t {
883
  /** Name of the file */
884
  char *filename;
885
  /** File descriptor used to hold the file open */
886
887
888
  int fd;
};

889
890
891
892
893
894
895
896
897
/** Try to get a lock on the lockfile <b>filename</b>, creating it as
 * necessary.  If someone else has the lock and <b>blocking</b> is true,
 * wait until the lock is available.  Otherwise return immediately whether
 * we succeeded or not.
 *
 * Set *<b>locked_out</b> to true if somebody else had the lock, and to false
 * otherwise.
 *
 * Return a <b>tor_lockfile_t</b> on success, NULL on failure.
898
899
900
 *
 * (Implementation note: because we need to fall back to fcntl on some
 *  platforms, these locks are per-process, not per-thread.  If you want
901
902
903
904
 *  to do in-process locking, use tor_mutex_t like a normal person.
 *  On Windows, when <b>blocking</b> is true, the maximum time that
 *  is actually waited is 10 seconds, after which NULL is returned
 *  and <b>locked_out</b> is set to 1.)
905
 */
906
907
908
909
910
911
912
913
tor_lockfile_t *
tor_lockfile_lock(const char *filename, int blocking, int *locked_out)
{
  tor_lockfile_t *result;
  int fd;
  *locked_out = 0;

  log_info(LD_FS, "Locking \"%s\"", filename);
914
  fd = tor_open_cloexec(filename, O_RDWR|O_CREAT|O_TRUNC, 0600);
915
916
917
918
919
  if (fd < 0) {
    log_warn(LD_FS,"Couldn't open \"%s\" for locking: %s", filename,
             strerror(errno));
    return NULL;
  }
920

921
#ifdef _WIN32
922
  _lseek(fd, 0, SEEK_SET);
923
  if (_locking(fd, blocking ? _LK_LOCK : _LK_NBLCK, 1) < 0) {
924
    if (errno != EACCES && errno != EDEADLOCK)
925
926
927
928
929
930
      log_warn(LD_FS,"Couldn't lock \"%s\": %s", filename, strerror(errno));
    else
      *locked_out = 1;
    close(fd);
    return NULL;
  }
931
#elif defined(HAVE_FLOCK)
932
933
934
935
936
937
938
939
  if (flock(fd, LOCK_EX|(blocking ? 0 : LOCK_NB)) < 0) {
    if (errno != EWOULDBLOCK)
      log_warn(LD_FS,"Couldn't lock \"%s\": %s", filename, strerror(errno));
    else
      *locked_out = 1;
    close(fd);
    return NULL;
  }
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
#else
  {
    struct flock lock;
    memset(&lock, 0, sizeof(lock));
    lock.l_type = F_WRLCK;
    lock.l_whence = SEEK_SET;
    if (fcntl(fd, blocking ? F_SETLKW : F_SETLK, &lock) < 0) {
      if (errno != EACCES && errno != EAGAIN)
        log_warn(LD_FS, "Couldn't lock \"%s\": %s", filename, strerror(errno));
      else
        *locked_out = 1;
      close(fd);
      return NULL;
    }
  }
955
956
957
958
959
960
961
962
#endif

  result = tor_malloc(sizeof(tor_lockfile_t));
  result->filename = tor_strdup(filename);
  result->fd = fd;
  return result;
}

963
/** Release the lock held as <b>lockfile</b>. */
964
965
966
967
968
969
void
tor_lockfile_unlock(tor_lockfile_t *lockfile)
{
  tor_assert(lockfile);

  log_info(LD_FS, "Unlocking \"%s\"", lockfile->filename);
970
#ifdef _WIN32
971
  _lseek(lockfile->fd, 0, SEEK_SET);
972
  if (_locking(lockfile->fd, _LK_UNLCK, 1) < 0) {
973
974
975
    log_warn(LD_FS,"Error unlocking \"%s\": %s", lockfile->filename,
             strerror(errno));
  }
976
#elif defined(HAVE_FLOCK)
977
978
979
980
  if (flock(lockfile->fd, LOCK_UN) < 0) {
    log_warn(LD_FS, "Error unlocking \"%s\": %s", lockfile->filename,
             strerror(errno));
  }
981
982
#else
  /* Closing the lockfile is sufficient. */
983
984
985
986
987
988
989
990
#endif

  close(lockfile->fd);
  lockfile->fd = -1;
  tor_free(lockfile->filename);
  tor_free(lockfile);
}

991
992
/** @{ */
/** Some old versions of Unix didn't define constants for these values,
993
 * and instead expect you to say 0, 1, or 2. */
994
995
996
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
997
998
999
1000
#ifndef SEEK_CUR
#define SEEK_CUR 1
#endif
#ifndef SEEK_END
For faster browsing, not all history is shown. View entire blame