compat.c 102 KB
Newer Older
1
2
/* Copyright (c) 2003-2004, Roger Dingledine
 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3
 * Copyright (c) 2007-2017, 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
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
30
31
32
#ifdef HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif
33
34
35
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
36
37
38
39
40
41
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
#ifdef HAVE_SYS_UTIME_H
#include <sys/utime.h>
#endif
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#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
63
64
65
#ifdef HAVE_CRT_EXTERNS_H
#include <crt_externs.h>
#endif
66
67
68
#ifdef HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
#endif
69
70
71
#ifdef HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
#endif
72
73
74
75

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

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

107
108
109
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
110
111
112
113
114
#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>
115
#include <assert.h>
116
117
118
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
119
120
121
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
122
123
124
#ifdef HAVE_SYS_SYSLIMITS_H
#include <sys/syslimits.h>
#endif
125
126
127
#ifdef HAVE_SYS_FILE_H
#include <sys/file.h>
#endif
128

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

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

143
144
145
146
147
/* 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;

148
149
150
151
152
/** 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)
{
153
  int fd;
154
  const char *p = sandbox_intern_string(path);
155
#ifdef O_CLOEXEC
teor's avatar
teor committed
156
  fd = open(p, flags|O_CLOEXEC, mode);
157
158
159
  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
160
   * even though we were built on a system with O_CLOEXEC support, we
161
162
163
   * are running on one without. */
  if (errno != EINVAL)
    return -1;
164
#endif /* defined(O_CLOEXEC) */
165

teor's avatar
teor committed
166
167
  log_debug(LD_FS, "Opening %s with flags %x", p, flags);
  fd = open(p, flags, mode);
168
#ifdef FD_CLOEXEC
169
170
171
172
173
174
175
  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;
    }
  }
176
#endif /* defined(FD_CLOEXEC) */
177
178
179
  return fd;
}

Roger Dingledine's avatar
Roger Dingledine committed
180
/** As fopen(path,mode), but ensures that the O_CLOEXEC bit is set on the
181
 * underlying file handle. */
182
183
184
185
186
FILE *
tor_fopen_cloexec(const char *path, const char *mode)
{
  FILE *result = fopen(path, mode);
#ifdef FD_CLOEXEC
187
188
189
190
191
192
193
  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;
    }
  }
194
#endif /* defined(FD_CLOEXEC) */
195
196
197
  return result;
}

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

207
208
209
210
211
212
213
214
/* Some MinGW builds have sys/mman.h, but not the corresponding symbols.
 * Other configs rename the symbols using macros (including getpagesize).
 * So check for sys/mman.h and unistd.h, and a getpagesize declaration. */
#if (defined(HAVE_SYS_MMAN_H) && defined(HAVE_UNISTD_H) && \
     defined(HAVE_DECL_GETPAGESIZE))
#define COMPAT_HAS_MMAN_AND_PAGESIZE
#endif

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

  tor_assert(filename);

232
  fd = tor_open_cloexec(filename, O_RDONLY, 0);
233
  if (fd<0) {
234
    int save_errno = errno;
235
236
237
    int severity = (errno == ENOENT) ? LOG_INFO : LOG_WARN;
    log_fn(severity, LD_FS,"Could not open \"%s\" for mmap(): %s",filename,
           strerror(errno));
238
    errno = save_errno;
239
240
241
    return NULL;
  }

242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
  /* 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?
   */
258
259
  /* ensure page alignment */
  page_size = getpagesize();
260
  size += (size%page_size) ? page_size-(size%page_size) : 0;
261

262
  if (st.st_size > SSIZE_T_CEILING || (off_t)size < st.st_size) {
263
264
265
266
267
    log_warn(LD_FS, "File \"%s\" is too large. Ignoring.",filename);
    errno = EFBIG;
    close(fd);
    return NULL;
  }
268
  if (!size) {
269
270
    /* Zero-length file. If we call mmap on it, it will succeed but
     * return NULL, and bad things will happen. So just fail. */
271
    log_info(LD_FS,"File \"%s\" is empty. Ignoring.",filename);
272
    errno = ERANGE;
273
    close(fd);
274
275
276
    return NULL;
  }

277
  string = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
278
  close(fd);
279
  if (string == MAP_FAILED) {
280
    int save_errno = errno;
281
282
    log_warn(LD_FS,"Could not mmap file \"%s\": %s", filename,
             strerror(errno));
283
    errno = save_errno;
284
285
286
    return NULL;
  }

287
288
289
  res = tor_malloc_zero(sizeof(tor_mmap_t));
  res->data = string;
  res->size = filesize;
290
  res->mapping_size = size;
291

292
  return res;
293
}
294
295
296
/** Release storage held for a memory mapping; returns 0 on success,
 * or -1 on failure (and logs a warning). */
int
297
298
tor_munmap_file(tor_mmap_t *handle)
{
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
  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;
315
}
316
#elif defined(_WIN32)
317
tor_mmap_t *
318
tor_mmap_file(const char *filename)
319
{
320
  TCHAR tfilename[MAX_PATH]= {0};
Nick Mathewson's avatar
Nick Mathewson committed
321
  tor_mmap_t *res = tor_malloc_zero(sizeof(tor_mmap_t));
322
  int empty = 0;
323
  HANDLE file_handle = INVALID_HANDLE_VALUE;
324
325
  DWORD size_low, size_high;
  uint64_t real_size;
326
  res->mmap_handle = NULL;
327
328
329
330
331
#ifdef UNICODE
  mbstowcs(tfilename,filename,MAX_PATH);
#else
  strlcpy(tfilename,filename,MAX_PATH);
#endif
332
  file_handle = CreateFile(tfilename,
333
                           GENERIC_READ, FILE_SHARE_READ,
334
335
336
337
                           NULL,
                           OPEN_EXISTING,
                           FILE_ATTRIBUTE_NORMAL,
                           0);
338

339
  if (file_handle == INVALID_HANDLE_VALUE)
340
    goto win_err;
341

342
  size_low = GetFileSize(file_handle, &size_high);
343

344
345
346
347
348
  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) {
349
    log_info(LD_FS,"File \"%s\" is empty. Ignoring.",filename);
350
    empty = 1;
351
352
    goto err;
  }
353
354
355
356
357
358
  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;
359

360
  res->mmap_handle = CreateFileMapping(file_handle,
361
362
                                       NULL,
                                       PAGE_READONLY,
363
364
                                       size_high,
                                       size_low,
365
                                       NULL);
366
  if (res->mmap_handle == NULL)
367
    goto win_err;
368
369
370
371
  res->data = (char*) MapViewOfFile(res->mmap_handle,
                                    FILE_MAP_READ,
                                    0, 0, 0);
  if (!res->data)
372
    goto win_err;
373

374
  CloseHandle(file_handle);
375
  return res;
376
377
 win_err: {
    DWORD e = GetLastError();
378
    int severity = (e == ERROR_FILE_NOT_FOUND || e == ERROR_PATH_NOT_FOUND) ?
379
380
      LOG_INFO : LOG_WARN;
    char *msg = format_win32_error(e);
381
    log_fn(severity, LD_FS, "Couldn't mmap file \"%s\": %s", filename, msg);
382
    tor_free(msg);
383
384
385
386
    if (e == ERROR_FILE_NOT_FOUND || e == ERROR_PATH_NOT_FOUND)
      errno = ENOENT;
    else
      errno = EINVAL;
387
  }
388
 err:
389
390
  if (empty)
    errno = ERANGE;
391
392
  if (file_handle != INVALID_HANDLE_VALUE)
    CloseHandle(file_handle);
393
  tor_munmap_file(res);
394
395
  return NULL;
}
396
397
398

/* Unmap the file, and return 0 for success or -1 for failure */
int
399
tor_munmap_file(tor_mmap_t *handle)
400
{
401
402
403
  if (handle == NULL)
    return 0;

404
  if (handle->data) {
405
406
    /* This is an ugly cast, but without it, "data" in struct tor_mmap_t would
       have to be redefined as non-const. */
407
408
409
410
411
412
    BOOL ok = UnmapViewOfFile( (LPVOID) handle->data);
    if (!ok) {
      log_warn(LD_FS, "Failed to UnmapViewOfFile() in tor_munmap_file(): %d",
               (int)GetLastError());
    }
  }
413

414
  if (handle->mmap_handle != NULL)
Nick Mathewson's avatar
Nick Mathewson committed
415
    CloseHandle(handle->mmap_handle);
416
  tor_free(handle);
417
418

  return 0;
419
420
}
#else
421
tor_mmap_t *
422
tor_mmap_file(const char *filename)
423
{
424
  struct stat st;
425
  char *res = read_file_to_str(filename, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
426
  tor_mmap_t *handle;
427
428
  if (! res)
    return NULL;
429
  handle = tor_malloc_zero(sizeof(tor_mmap_t));
430
  handle->data = res;
431
  handle->size = st.st_size;
432
  return handle;
433
}
434
435
436
437
438
439

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

int
440
tor_munmap_file(tor_mmap_t *handle)
441
{
442
  char *d = NULL;
443
444
  if (handle == NULL)
    return 0;
445
446

  d = (char*)handle->data;
447
  tor_free(d);
448
  memwipe(handle, 0, sizeof(tor_mmap_t));
449
  tor_free(handle);
450
451
452

  /* Can't fail in this mmap()/munmap()-free case */
  return 0;
453
}
454
#endif /* defined(COMPAT_HAS_MMAN_AND_PAGESIZE) || ... || ... */
455

456
457
458
/** 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
459
460
 * behavior does <i>not</i> conform to C99; it just happens to be
 * easier to emulate "return -1" with conformant implementations than
461
462
 * it is to emulate "return number that would be written" with
 * non-conformant implementations.) */
463
464
int
tor_snprintf(char *str, size_t size, const char *format, ...)
465
466
467
468
469
470
471
472
473
{
  va_list ap;
  int r;
  va_start(ap,format);
  r = tor_vsnprintf(str,size,format,ap);
  va_end(ap);
  return r;
}

474
/** Replacement for vsnprintf; behavior differs as tor_snprintf differs from
475
476
 * snprintf.
 */
477
478
int
tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
479
480
{
  int r;
481
482
  if (size == 0)
    return -1; /* no place for the NUL */
483
  if (size > SIZE_T_CEILING)
484
    return -1;
485
#ifdef _WIN32
486
487
488
489
490
  r = _vsnprintf(str, size, format, args);
#else
  r = vsnprintf(str, size, format, args);
#endif
  str[size-1] = '\0';
491
  if (r < 0 || r >= (ssize_t)size)
492
493
494
495
    return -1;
  return r;
}

496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
/**
 * 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) {
520
    /* LCOV_EXCL_START */
521
522
    log_err(LD_BUG, "Internal error in asprintf");
    tor_assert(0);
523
    /* LCOV_EXCL_STOP */
524
525
526
527
528
529
530
531
532
533
534
535
  }
  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)
{
536
537
  /* use a temporary variable in case *strp is in args. */
  char *strp_tmp=NULL;
538
539
#ifdef HAVE_VASPRINTF
  /* If the platform gives us one, use it. */
540
  int r = vasprintf(&strp_tmp, fmt, args);
541
542
  if (r < 0)
    *strp = NULL;
543
544
  else
    *strp = strp_tmp;
545
  return r;
546
#elif defined(HAVE__VSCPRINTF)
547
548
549
  /* 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;
550
551
552
553
  va_list tmp_args;
  va_copy(tmp_args, args);
  len = _vscprintf(fmt, tmp_args);
  va_end(tmp_args);
554
  if (len < 0) {
555
    *strp = NULL;
556
557
    return -1;
  }
558
559
  strp_tmp = tor_malloc(len + 1);
  r = _vsnprintf(strp_tmp, len+1, fmt, args);
560
  if (r != len) {
561
562
    tor_free(strp_tmp);
    *strp = NULL;
563
564
    return -1;
  }
565
  *strp = strp_tmp;
566
567
568
569
570
571
572
573
574
575
  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.
   */
  char buf[128];
  int len, r;
  va_list tmp_args;
  va_copy(tmp_args, args);
576
577
578
  /* vsnprintf() was properly checked but tor_vsnprintf() available so
   * why not use it? */
  len = tor_vsnprintf(buf, sizeof(buf), fmt, tmp_args);
579
580
581
582
583
  va_end(tmp_args);
  if (len < (int)sizeof(buf)) {
    *strp = tor_strdup(buf);
    return len;
  }
584
  strp_tmp = tor_malloc(len+1);
585
586
  /* use of tor_vsnprintf() will ensure string is null terminated */
  r = tor_vsnprintf(strp_tmp, len+1, fmt, args);
587
  if (r != len) {
588
589
    tor_free(strp_tmp);
    *strp = NULL;
590
591
    return -1;
  }
592
  *strp = strp_tmp;
593
  return len;
594
#endif /* defined(HAVE_VASPRINTF) || ... */
595
596
}

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

621
622
623
  if (nlen > hlen)
    return NULL;

Nick Mathewson's avatar
Nick Mathewson committed
624
  p = haystack;
625
626
  /* Last position at which the needle could start. */
  last_possible_start = haystack + hlen - nlen;
Nick Mathewson's avatar
Nick Mathewson committed
627
  first = *(const char*)needle;
628
  while ((p = memchr(p, first, last_possible_start + 1 - p))) {
629
    if (fast_memeq(p, needle, nlen))
Nick Mathewson's avatar
Nick Mathewson committed
630
      return p;
631
632
633
634
635
636
637
    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
638
639
  }
  return NULL;
640
#endif /* defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2) */
Nick Mathewson's avatar
Nick Mathewson committed
641
642
}

643
644
/**
 * Tables to implement ctypes-replacement TOR_IS*() functions.  Each table
645
646
647
 * 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. */
648
649

/**@{*/
650
const uint32_t TOR_ISALPHA_TABLE[8] =
651
  { 0, 0, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
652
const uint32_t TOR_ISALNUM_TABLE[8] =
653
  { 0, 0x3ff0000, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
654
655
const uint32_t TOR_ISSPACE_TABLE[8] = { 0x3e00, 0x1, 0, 0, 0, 0, 0, 0 };
const uint32_t TOR_ISXDIGIT_TABLE[8] =
656
  { 0, 0x3ff0000, 0x7e, 0x7e, 0, 0, 0, 0 };
657
658
const uint32_t TOR_ISDIGIT_TABLE[8] = { 0, 0x3ff0000, 0, 0, 0, 0, 0, 0 };
const uint32_t TOR_ISPRINT_TABLE[8] =
659
  { 0, 0xffffffff, 0xffffffff, 0x7fffffff, 0, 0, 0, 0x0 };
660
661
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 };
662
663
664
665

/** Upper-casing and lowercasing tables to map characters to upper/lowercase
 * equivalents.  Used by tor_toupper() and tor_tolower(). */
/**@{*/
666
const uint8_t TOR_TOUPPER_TABLE[256] = {
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
  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,
};
684
const uint8_t TOR_TOLOWER_TABLE[256] = {
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
  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,
};
702
/**@}*/
703

704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
/** 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;
}

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

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

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

754
#ifdef _WIN32
755
756
757
758
/** 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
759
 * compiled the binary in their warning messages.
760
761
 */
const char *
762
tor_fix_source_file(const char *fname)
763
{
764
  const char *cp1, *cp2, *r;
765
766
767
  cp1 = strrchr(fname, '/');
  cp2 = strrchr(fname, '\\');
  if (cp1 && cp2) {
768
    r = (cp1<cp2)?(cp2+1):(cp1+1);
769
  } else if (cp1) {
770
    r = cp1+1;
771
  } else if (cp2) {
772
    r = cp2+1;
773
  } else {
774
    r = fname;
775
  }
776
  return r;
777
}
778
#endif /* defined(_WIN32) */
779

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

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

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

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

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

892
893
894
895
896
897
898
899
900
/** 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.
901
902
903
 *
 * (Implementation note: because we need to fall back to fcntl on some
 *  platforms, these locks are per-process, not per-thread.  If you want
904
905
906
907
 *  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.)
908
 */
909
910
911
912
913
914
915
916
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);
917
  fd = tor_open_cloexec(filename, O_RDWR|O_CREAT|O_TRUNC, 0600);
918
919
920
921
922
  if (fd < 0) {
    log_warn(LD_FS,"Couldn't open \"%s\" for locking: %s", filename,
             strerror(errno));
    return NULL;
  }
923

924
#ifdef _WIN32
925
  _lseek(fd, 0, SEEK_SET);
926
  if (_locking(fd, blocking ? _LK_LOCK : _LK_NBLCK, 1) < 0) {
927
    if (errno != EACCES && errno != EDEADLOCK)
928
929
930
931
932
933
      log_warn(LD_FS,"Couldn't lock \"%s\": %s", filename, strerror(errno));
    else
      *locked_out = 1;
    close(fd);
    return NULL;
  }
934
#elif defined(HAVE_FLOCK)
935
936
937
938
939
940
941
942
  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;
  }
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
#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;
    }
  }
958
#endif /* defined(_WIN32) || ... */
959
960
961
962
963
964
965

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

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

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

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

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