Back to index

tor  0.2.3.18-rc
compat.c
Go to the documentation of this file.
00001 /* Copyright (c) 2003-2004, Roger Dingledine
00002  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
00003  * Copyright (c) 2007-2012, The Tor Project, Inc. */
00004 /* See LICENSE for licensing information */
00005 
00015 /* This is required on rh7 to make strptime not complain.
00016  * We also need it to make memmem get defined (where available)
00017  */
00018 /* XXXX024 We should just  use AC_USE_SYSTEM_EXTENSIONS in our autoconf,
00019  * and get this (and other important stuff!) automatically. Once we do that,
00020  * make sure to also change the extern char **environ detection in
00021  * configure.in, because whether that is declared or not depends on whether
00022  * we have _GNU_SOURCE defined! Maybe that means that once we take this out,
00023  * we can also take out the configure check. */
00024 #define _GNU_SOURCE
00025 
00026 #include "compat.h"
00027 
00028 #ifdef _WIN32
00029 #include <process.h>
00030 #include <windows.h>
00031 #include <sys/locking.h>
00032 #endif
00033 
00034 #ifdef HAVE_UNAME
00035 #include <sys/utsname.h>
00036 #endif
00037 #ifdef HAVE_UNISTD_H
00038 #include <unistd.h>
00039 #endif
00040 #ifdef HAVE_SYS_FCNTL_H
00041 #include <sys/fcntl.h>
00042 #endif
00043 #ifdef HAVE_PWD_H
00044 #include <pwd.h>
00045 #endif
00046 #ifdef HAVE_GRP_H
00047 #include <grp.h>
00048 #endif
00049 #ifdef HAVE_FCNTL_H
00050 #include <fcntl.h>
00051 #endif
00052 #ifdef HAVE_ERRNO_H
00053 #include <errno.h>
00054 #endif
00055 #ifdef HAVE_ARPA_INET_H
00056 #include <arpa/inet.h>
00057 #endif
00058 #ifdef HAVE_CRT_EXTERNS_H
00059 #include <crt_externs.h>
00060 #endif
00061 
00062 #ifndef HAVE_GETTIMEOFDAY
00063 #ifdef HAVE_FTIME
00064 #include <sys/timeb.h>
00065 #endif
00066 #endif
00067 
00068 /* Includes for the process attaching prevention */
00069 #if defined(HAVE_SYS_PRCTL_H) && defined(__linux__)
00070 #include <sys/prctl.h>
00071 #elif defined(__APPLE__)
00072 #include <sys/types.h>
00073 #include <sys/ptrace.h>
00074 #endif
00075 
00076 #ifdef HAVE_NETDB_H
00077 #include <netdb.h>
00078 #endif
00079 #ifdef HAVE_SYS_PARAM_H
00080 #include <sys/param.h> /* FreeBSD needs this to know what version it is */
00081 #endif
00082 #include <stdio.h>
00083 #include <stdlib.h>
00084 #include <assert.h>
00085 #ifdef HAVE_SIGNAL_H
00086 #include <signal.h>
00087 #endif
00088 #ifdef HAVE_UTIME_H
00089 #include <utime.h>
00090 #endif
00091 #ifdef HAVE_SYS_UTIME_H
00092 #include <sys/utime.h>
00093 #endif
00094 #ifdef HAVE_SYS_MMAN_H
00095 #include <sys/mman.h>
00096 #endif
00097 #ifdef HAVE_SYS_SYSLIMITS_H
00098 #include <sys/syslimits.h>
00099 #endif
00100 #ifdef HAVE_SYS_FILE_H
00101 #include <sys/file.h>
00102 #endif
00103 #if defined(HAVE_SYS_PRCTL_H) && defined(__linux__)
00104 /* Only use the linux prctl;  the IRIX prctl is totally different */
00105 #include <sys/prctl.h>
00106 #endif
00107 
00108 #include "torlog.h"
00109 #include "util.h"
00110 #include "container.h"
00111 #include "address.h"
00112 
00113 /* Inline the strl functions if the platform doesn't have them. */
00114 #ifndef HAVE_STRLCPY
00115 #include "strlcpy.c"
00116 #endif
00117 #ifndef HAVE_STRLCAT
00118 #include "strlcat.c"
00119 #endif
00120 
00123 int
00124 tor_open_cloexec(const char *path, int flags, unsigned mode)
00125 {
00126   int fd;
00127 #ifdef O_CLOEXEC
00128   fd = open(path, flags|O_CLOEXEC, mode);
00129   if (fd >= 0)
00130     return fd;
00131   /* If we got an error, see if it is EINVAL. EINVAL might indicate that,
00132    * even though we were built on a system with O_CLOEXEC support, we
00133    * are running on one without. */
00134   if (errno != EINVAL)
00135     return -1;
00136 #endif
00137 
00138   fd = open(path, flags, mode);
00139 #ifdef FD_CLOEXEC
00140   if (fd >= 0)
00141         fcntl(fd, F_SETFD, FD_CLOEXEC);
00142 #endif
00143   return fd;
00144 }
00145 
00148 FILE *
00149 tor_fopen_cloexec(const char *path, const char *mode)
00150 {
00151   FILE *result = fopen(path, mode);
00152 #ifdef FD_CLOEXEC
00153   if (result != NULL)
00154     fcntl(fileno(result), F_SETFD, FD_CLOEXEC);
00155 #endif
00156   return result;
00157 }
00158 
00159 #if defined(HAVE_SYS_MMAN_H) || defined(RUNNING_DOXYGEN)
00160 
00163 tor_mmap_t *
00164 tor_mmap_file(const char *filename)
00165 {
00166   int fd; /* router file */
00167   char *string;
00168   int page_size;
00169   tor_mmap_t *res;
00170   size_t size, filesize;
00171 
00172   tor_assert(filename);
00173 
00174   fd = tor_open_cloexec(filename, O_RDONLY, 0);
00175   if (fd<0) {
00176     int save_errno = errno;
00177     int severity = (errno == ENOENT) ? LOG_INFO : LOG_WARN;
00178     log_fn(severity, LD_FS,"Could not open \"%s\" for mmap(): %s",filename,
00179            strerror(errno));
00180     errno = save_errno;
00181     return NULL;
00182   }
00183 
00184   /* XXXX why not just do fstat here? */
00185   size = filesize = (size_t) lseek(fd, 0, SEEK_END);
00186   lseek(fd, 0, SEEK_SET);
00187   /* ensure page alignment */
00188   page_size = getpagesize();
00189   size += (size%page_size) ? page_size-(size%page_size) : 0;
00190 
00191   if (!size) {
00192     /* Zero-length file. If we call mmap on it, it will succeed but
00193      * return NULL, and bad things will happen. So just fail. */
00194     log_info(LD_FS,"File \"%s\" is empty. Ignoring.",filename);
00195     errno = ERANGE;
00196     close(fd);
00197     return NULL;
00198   }
00199 
00200   string = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
00201   close(fd);
00202   if (string == MAP_FAILED) {
00203     int save_errno = errno;
00204     log_warn(LD_FS,"Could not mmap file \"%s\": %s", filename,
00205              strerror(errno));
00206     errno = save_errno;
00207     return NULL;
00208   }
00209 
00210   res = tor_malloc_zero(sizeof(tor_mmap_t));
00211   res->data = string;
00212   res->size = filesize;
00213   res->mapping_size = size;
00214 
00215   return res;
00216 }
00218 void
00219 tor_munmap_file(tor_mmap_t *handle)
00220 {
00221   munmap((char*)handle->data, handle->mapping_size);
00222   tor_free(handle);
00223 }
00224 #elif defined(_WIN32)
00225 tor_mmap_t *
00226 tor_mmap_file(const char *filename)
00227 {
00228   TCHAR tfilename[MAX_PATH]= {0};
00229   tor_mmap_t *res = tor_malloc_zero(sizeof(tor_mmap_t));
00230   int empty = 0;
00231   HANDLE file_handle = INVALID_HANDLE_VALUE;
00232   DWORD size_low, size_high;
00233   uint64_t real_size;
00234   res->mmap_handle = NULL;
00235 #ifdef UNICODE
00236   mbstowcs(tfilename,filename,MAX_PATH);
00237 #else
00238   strlcpy(tfilename,filename,MAX_PATH);
00239 #endif
00240   file_handle = CreateFile(tfilename,
00241                            GENERIC_READ, FILE_SHARE_READ,
00242                            NULL,
00243                            OPEN_EXISTING,
00244                            FILE_ATTRIBUTE_NORMAL,
00245                            0);
00246 
00247   if (file_handle == INVALID_HANDLE_VALUE)
00248     goto win_err;
00249 
00250   size_low = GetFileSize(file_handle, &size_high);
00251 
00252   if (size_low == INVALID_FILE_SIZE && GetLastError() != NO_ERROR) {
00253     log_warn(LD_FS,"Error getting size of \"%s\".",filename);
00254     goto win_err;
00255   }
00256   if (size_low == 0 && size_high == 0) {
00257     log_info(LD_FS,"File \"%s\" is empty. Ignoring.",filename);
00258     empty = 1;
00259     goto err;
00260   }
00261   real_size = (((uint64_t)size_high)<<32) | size_low;
00262   if (real_size > SIZE_MAX) {
00263     log_warn(LD_FS,"File \"%s\" is too big to map; not trying.",filename);
00264     goto err;
00265   }
00266   res->size = real_size;
00267 
00268   res->mmap_handle = CreateFileMapping(file_handle,
00269                                        NULL,
00270                                        PAGE_READONLY,
00271                                        size_high,
00272                                        size_low,
00273                                        NULL);
00274   if (res->mmap_handle == NULL)
00275     goto win_err;
00276   res->data = (char*) MapViewOfFile(res->mmap_handle,
00277                                     FILE_MAP_READ,
00278                                     0, 0, 0);
00279   if (!res->data)
00280     goto win_err;
00281 
00282   CloseHandle(file_handle);
00283   return res;
00284  win_err: {
00285     DWORD e = GetLastError();
00286     int severity = (e == ERROR_FILE_NOT_FOUND || e == ERROR_PATH_NOT_FOUND) ?
00287       LOG_INFO : LOG_WARN;
00288     char *msg = format_win32_error(e);
00289     log_fn(severity, LD_FS, "Couldn't mmap file \"%s\": %s", filename, msg);
00290     tor_free(msg);
00291     if (e == ERROR_FILE_NOT_FOUND || e == ERROR_PATH_NOT_FOUND)
00292       errno = ENOENT;
00293     else
00294       errno = EINVAL;
00295   }
00296  err:
00297   if (empty)
00298     errno = ERANGE;
00299   if (file_handle != INVALID_HANDLE_VALUE)
00300     CloseHandle(file_handle);
00301   tor_munmap_file(res);
00302   return NULL;
00303 }
00304 void
00305 tor_munmap_file(tor_mmap_t *handle)
00306 {
00307   if (handle->data)
00308     /* This is an ugly cast, but without it, "data" in struct tor_mmap_t would
00309        have to be redefined as non-const. */
00310     UnmapViewOfFile( (LPVOID) handle->data);
00311 
00312   if (handle->mmap_handle != NULL)
00313     CloseHandle(handle->mmap_handle);
00314   tor_free(handle);
00315 }
00316 #else
00317 tor_mmap_t *
00318 tor_mmap_file(const char *filename)
00319 {
00320   struct stat st;
00321   char *res = read_file_to_str(filename, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
00322   tor_mmap_t *handle;
00323   if (! res)
00324     return NULL;
00325   handle = tor_malloc_zero(sizeof(tor_mmap_t));
00326   handle->data = res;
00327   handle->size = st.st_size;
00328   return handle;
00329 }
00330 void
00331 tor_munmap_file(tor_mmap_t *handle)
00332 {
00333   char *d = (char*)handle->data;
00334   tor_free(d);
00335   memset(handle, 0, sizeof(tor_mmap_t));
00336   tor_free(handle);
00337 }
00338 #endif
00339 
00347 int
00348 tor_snprintf(char *str, size_t size, const char *format, ...)
00349 {
00350   va_list ap;
00351   int r;
00352   va_start(ap,format);
00353   r = tor_vsnprintf(str,size,format,ap);
00354   va_end(ap);
00355   return r;
00356 }
00357 
00361 int
00362 tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
00363 {
00364   int r;
00365   if (size == 0)
00366     return -1; /* no place for the NUL */
00367   if (size > SIZE_T_CEILING)
00368     return -1;
00369 #ifdef _WIN32
00370   r = _vsnprintf(str, size, format, args);
00371 #else
00372   r = vsnprintf(str, size, format, args);
00373 #endif
00374   str[size-1] = '\0';
00375   if (r < 0 || r >= (ssize_t)size)
00376     return -1;
00377   return r;
00378 }
00379 
00395 int
00396 tor_asprintf(char **strp, const char *fmt, ...)
00397 {
00398   int r;
00399   va_list args;
00400   va_start(args, fmt);
00401   r = tor_vasprintf(strp, fmt, args);
00402   va_end(args);
00403   if (!*strp || r < 0) {
00404     log_err(LD_BUG, "Internal error in asprintf");
00405     tor_assert(0);
00406   }
00407   return r;
00408 }
00409 
00415 int
00416 tor_vasprintf(char **strp, const char *fmt, va_list args)
00417 {
00418   /* use a temporary variable in case *strp is in args. */
00419   char *strp_tmp=NULL;
00420 #ifdef HAVE_VASPRINTF
00421   /* If the platform gives us one, use it. */
00422   int r = vasprintf(&strp_tmp, fmt, args);
00423   if (r < 0)
00424     *strp = NULL;
00425   else
00426     *strp = strp_tmp;
00427   return r;
00428 #elif defined(_MSC_VER)
00429   /* On Windows, _vsnprintf won't tell us the length of the string if it
00430    * overflows, so we need to use _vcsprintf to tell how much to allocate */
00431   int len, r;
00432   char *res;
00433   len = _vscprintf(fmt, args);
00434   if (len < 0) {
00435     *strp = NULL;
00436     return -1;
00437   }
00438   strp_tmp = tor_malloc(len + 1);
00439   r = _vsnprintf(strp_tmp, len+1, fmt, args);
00440   if (r != len) {
00441     tor_free(strp_tmp);
00442     *strp = NULL;
00443     return -1;
00444   }
00445   *strp = strp_tmp;
00446   return len;
00447 #else
00448   /* Everywhere else, we have a decent vsnprintf that tells us how many
00449    * characters we need.  We give it a try on a short buffer first, since
00450    * it might be nice to avoid the second vsnprintf call.
00451    */
00452   char buf[128];
00453   int len, r;
00454   va_list tmp_args;
00455   va_copy(tmp_args, args);
00456   len = vsnprintf(buf, sizeof(buf), fmt, tmp_args);
00457   va_end(tmp_args);
00458   if (len < (int)sizeof(buf)) {
00459     *strp = tor_strdup(buf);
00460     return len;
00461   }
00462   strp_tmp = tor_malloc(len+1);
00463   r = vsnprintf(strp_tmp, len+1, fmt, args);
00464   if (r != len) {
00465     tor_free(strp_tmp);
00466     *strp = NULL;
00467     return -1;
00468   }
00469   *strp = strp_tmp;
00470   return len;
00471 #endif
00472 }
00473 
00482 const void *
00483 tor_memmem(const void *_haystack, size_t hlen,
00484            const void *_needle, size_t nlen)
00485 {
00486 #if defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2)
00487   tor_assert(nlen);
00488   return memmem(_haystack, hlen, _needle, nlen);
00489 #else
00490   /* This isn't as fast as the GLIBC implementation, but it doesn't need to
00491    * be. */
00492   const char *p, *end;
00493   const char *haystack = (const char*)_haystack;
00494   const char *needle = (const char*)_needle;
00495   char first;
00496   tor_assert(nlen);
00497 
00498   p = haystack;
00499   end = haystack + hlen;
00500   first = *(const char*)needle;
00501   while ((p = memchr(p, first, end-p))) {
00502     if (p+nlen > end)
00503       return NULL;
00504     if (fast_memeq(p, needle, nlen))
00505       return p;
00506     ++p;
00507   }
00508   return NULL;
00509 #endif
00510 }
00511 
00519 const uint32_t TOR_ISALPHA_TABLE[8] =
00520   { 0, 0, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
00521 const uint32_t TOR_ISALNUM_TABLE[8] =
00522   { 0, 0x3ff0000, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
00523 const uint32_t TOR_ISSPACE_TABLE[8] = { 0x3e00, 0x1, 0, 0, 0, 0, 0, 0 };
00524 const uint32_t TOR_ISXDIGIT_TABLE[8] =
00525   { 0, 0x3ff0000, 0x7e, 0x7e, 0, 0, 0, 0 };
00526 const uint32_t TOR_ISDIGIT_TABLE[8] = { 0, 0x3ff0000, 0, 0, 0, 0, 0, 0 };
00527 const uint32_t TOR_ISPRINT_TABLE[8] =
00528   { 0, 0xffffffff, 0xffffffff, 0x7fffffff, 0, 0, 0, 0x0 };
00529 const uint32_t TOR_ISUPPER_TABLE[8] = { 0, 0, 0x7fffffe, 0, 0, 0, 0, 0 };
00530 const uint32_t TOR_ISLOWER_TABLE[8] = { 0, 0, 0, 0x7fffffe, 0, 0, 0, 0 };
00531 
00535 const char TOR_TOUPPER_TABLE[256] = {
00536   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
00537   16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
00538   32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
00539   48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
00540   64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
00541   80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
00542   96,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
00543   80,81,82,83,84,85,86,87,88,89,90,123,124,125,126,127,
00544   128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
00545   144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
00546   160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
00547   176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
00548   192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
00549   208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
00550   224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
00551   240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
00552 };
00553 const char TOR_TOLOWER_TABLE[256] = {
00554   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
00555   16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
00556   32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
00557   48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
00558   64,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
00559   112,113,114,115,116,117,118,119,120,121,122,91,92,93,94,95,
00560   96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
00561   112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
00562   128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
00563   144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
00564   160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
00565   176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
00566   192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
00567   208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
00568   224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
00569   240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
00570 };
00575 static char *
00576 strtok_helper(char *cp, const char *sep)
00577 {
00578   if (sep[1]) {
00579     while (*cp && strchr(sep, *cp))
00580       ++cp;
00581   } else {
00582     while (*cp && *cp == *sep)
00583       ++cp;
00584   }
00585   return cp;
00586 }
00587 
00590 char *
00591 tor_strtok_r_impl(char *str, const char *sep, char **lasts)
00592 {
00593   char *cp, *start;
00594   tor_assert(*sep);
00595   if (str) {
00596     str = strtok_helper(str, sep);
00597     if (!*str)
00598       return NULL;
00599     start = cp = *lasts = str;
00600   } else if (!*lasts || !**lasts) {
00601     return NULL;
00602   } else {
00603     start = cp = *lasts;
00604   }
00605 
00606   if (sep[1]) {
00607     while (*cp && !strchr(sep, *cp))
00608       ++cp;
00609   } else {
00610     cp = strchr(cp, *sep);
00611   }
00612 
00613   if (!cp || !*cp) {
00614     *lasts = NULL;
00615   } else {
00616     *cp++ = '\0';
00617     *lasts = strtok_helper(cp, sep);
00618   }
00619   return start;
00620 }
00621 
00622 #ifdef _WIN32
00623 
00629 const char *
00630 tor_fix_source_file(const char *fname)
00631 {
00632   const char *cp1, *cp2, *r;
00633   cp1 = strrchr(fname, '/');
00634   cp2 = strrchr(fname, '\\');
00635   if (cp1 && cp2) {
00636     r = (cp1<cp2)?(cp2+1):(cp1+1);
00637   } else if (cp1) {
00638     r = cp1+1;
00639   } else if (cp2) {
00640     r = cp2+1;
00641   } else {
00642     r = fname;
00643   }
00644   return r;
00645 }
00646 #endif
00647 
00653 uint16_t
00654 get_uint16(const void *cp)
00655 {
00656   uint16_t v;
00657   memcpy(&v,cp,2);
00658   return v;
00659 }
00665 uint32_t
00666 get_uint32(const void *cp)
00667 {
00668   uint32_t v;
00669   memcpy(&v,cp,4);
00670   return v;
00671 }
00677 uint64_t
00678 get_uint64(const void *cp)
00679 {
00680   uint64_t v;
00681   memcpy(&v,cp,8);
00682   return v;
00683 }
00684 
00689 void
00690 set_uint16(void *cp, uint16_t v)
00691 {
00692   memcpy(cp,&v,2);
00693 }
00698 void
00699 set_uint32(void *cp, uint32_t v)
00700 {
00701   memcpy(cp,&v,4);
00702 }
00707 void
00708 set_uint64(void *cp, uint64_t v)
00709 {
00710   memcpy(cp,&v,8);
00711 }
00712 
00719 int
00720 replace_file(const char *from, const char *to)
00721 {
00722 #ifndef _WIN32
00723   return rename(from,to);
00724 #else
00725   switch (file_status(to))
00726     {
00727     case FN_NOENT:
00728       break;
00729     case FN_FILE:
00730       if (unlink(to)) return -1;
00731       break;
00732     case FN_ERROR:
00733       return -1;
00734     case FN_DIR:
00735       errno = EISDIR;
00736       return -1;
00737     }
00738   return rename(from,to);
00739 #endif
00740 }
00741 
00743 int
00744 touch_file(const char *fname)
00745 {
00746   if (utime(fname, NULL)!=0)
00747     return -1;
00748   return 0;
00749 }
00750 
00752 struct tor_lockfile_t {
00754   char *filename;
00756   int fd;
00757 };
00758 
00776 tor_lockfile_t *
00777 tor_lockfile_lock(const char *filename, int blocking, int *locked_out)
00778 {
00779   tor_lockfile_t *result;
00780   int fd;
00781   *locked_out = 0;
00782 
00783   log_info(LD_FS, "Locking \"%s\"", filename);
00784   fd = tor_open_cloexec(filename, O_RDWR|O_CREAT|O_TRUNC, 0600);
00785   if (fd < 0) {
00786     log_warn(LD_FS,"Couldn't open \"%s\" for locking: %s", filename,
00787              strerror(errno));
00788     return NULL;
00789   }
00790 
00791 #ifdef _WIN32
00792   _lseek(fd, 0, SEEK_SET);
00793   if (_locking(fd, blocking ? _LK_LOCK : _LK_NBLCK, 1) < 0) {
00794     if (errno != EACCES && errno != EDEADLOCK)
00795       log_warn(LD_FS,"Couldn't lock \"%s\": %s", filename, strerror(errno));
00796     else
00797       *locked_out = 1;
00798     close(fd);
00799     return NULL;
00800   }
00801 #elif defined(HAVE_FLOCK)
00802   if (flock(fd, LOCK_EX|(blocking ? 0 : LOCK_NB)) < 0) {
00803     if (errno != EWOULDBLOCK)
00804       log_warn(LD_FS,"Couldn't lock \"%s\": %s", filename, strerror(errno));
00805     else
00806       *locked_out = 1;
00807     close(fd);
00808     return NULL;
00809   }
00810 #else
00811   {
00812     struct flock lock;
00813     memset(&lock, 0, sizeof(lock));
00814     lock.l_type = F_WRLCK;
00815     lock.l_whence = SEEK_SET;
00816     if (fcntl(fd, blocking ? F_SETLKW : F_SETLK, &lock) < 0) {
00817       if (errno != EACCES && errno != EAGAIN)
00818         log_warn(LD_FS, "Couldn't lock \"%s\": %s", filename, strerror(errno));
00819       else
00820         *locked_out = 1;
00821       close(fd);
00822       return NULL;
00823     }
00824   }
00825 #endif
00826 
00827   result = tor_malloc(sizeof(tor_lockfile_t));
00828   result->filename = tor_strdup(filename);
00829   result->fd = fd;
00830   return result;
00831 }
00832 
00834 void
00835 tor_lockfile_unlock(tor_lockfile_t *lockfile)
00836 {
00837   tor_assert(lockfile);
00838 
00839   log_info(LD_FS, "Unlocking \"%s\"", lockfile->filename);
00840 #ifdef _WIN32
00841   _lseek(lockfile->fd, 0, SEEK_SET);
00842   if (_locking(lockfile->fd, _LK_UNLCK, 1) < 0) {
00843     log_warn(LD_FS,"Error unlocking \"%s\": %s", lockfile->filename,
00844              strerror(errno));
00845   }
00846 #elif defined(HAVE_FLOCK)
00847   if (flock(lockfile->fd, LOCK_UN) < 0) {
00848     log_warn(LD_FS, "Error unlocking \"%s\": %s", lockfile->filename,
00849              strerror(errno));
00850   }
00851 #else
00852   /* Closing the lockfile is sufficient. */
00853 #endif
00854 
00855   close(lockfile->fd);
00856   lockfile->fd = -1;
00857   tor_free(lockfile->filename);
00858   tor_free(lockfile);
00859 }
00860 
00864 #ifndef SEEK_CUR
00865 #define SEEK_CUR 1
00866 #endif
00867 #ifndef SEEK_END
00868 #define SEEK_END 2
00869 #endif
00870 
00873 off_t
00874 tor_fd_getpos(int fd)
00875 {
00876 #ifdef _WIN32
00877   return (off_t) _lseek(fd, 0, SEEK_CUR);
00878 #else
00879   return (off_t) lseek(fd, 0, SEEK_CUR);
00880 #endif
00881 }
00882 
00884 int
00885 tor_fd_seekend(int fd)
00886 {
00887 #ifdef _WIN32
00888   return _lseek(fd, 0, SEEK_END) < 0 ? -1 : 0;
00889 #else
00890   return lseek(fd, 0, SEEK_END) < 0 ? -1 : 0;
00891 #endif
00892 }
00893 
00894 #undef DEBUG_SOCKET_COUNTING
00895 #ifdef DEBUG_SOCKET_COUNTING
00896 
00898 static bitarray_t *open_sockets = NULL;
00900 static int max_socket = -1;
00901 #endif
00902 
00905 static int n_sockets_open = 0;
00906 
00908 static tor_mutex_t *socket_accounting_mutex = NULL;
00909 
00911 static INLINE void
00912 socket_accounting_lock(void)
00913 {
00914   if (PREDICT_UNLIKELY(!socket_accounting_mutex))
00915     socket_accounting_mutex = tor_mutex_new();
00916   tor_mutex_acquire(socket_accounting_mutex);
00917 }
00918 
00920 static INLINE void
00921 socket_accounting_unlock(void)
00922 {
00923   tor_mutex_release(socket_accounting_mutex);
00924 }
00925 
00929 int
00930 tor_close_socket(tor_socket_t s)
00931 {
00932   int r = 0;
00933 
00934   /* On Windows, you have to call close() on fds returned by open(),
00935    * and closesocket() on fds returned by socket().  On Unix, everything
00936    * gets close()'d.  We abstract this difference by always using
00937    * tor_close_socket to close sockets, and always using close() on
00938    * files.
00939    */
00940 #if defined(_WIN32)
00941   r = closesocket(s);
00942 #else
00943   r = close(s);
00944 #endif
00945 
00946   socket_accounting_lock();
00947 #ifdef DEBUG_SOCKET_COUNTING
00948   if (s > max_socket || ! bitarray_is_set(open_sockets, s)) {
00949     log_warn(LD_BUG, "Closing a socket (%d) that wasn't returned by tor_open_"
00950              "socket(), or that was already closed or something.", s);
00951   } else {
00952     tor_assert(open_sockets && s <= max_socket);
00953     bitarray_clear(open_sockets, s);
00954   }
00955 #endif
00956   if (r == 0) {
00957     --n_sockets_open;
00958   } else {
00959     int err = tor_socket_errno(-1);
00960     log_info(LD_NET, "Close returned an error: %s", tor_socket_strerror(err));
00961 #ifdef _WIN32
00962     if (err != WSAENOTSOCK)
00963       --n_sockets_open;
00964 #else
00965     if (err != EBADF)
00966       --n_sockets_open;
00967 #endif
00968     r = -1;
00969   }
00970 
00971   if (n_sockets_open < 0)
00972     log_warn(LD_BUG, "Our socket count is below zero: %d. Please submit a "
00973              "bug report.", n_sockets_open);
00974   socket_accounting_unlock();
00975   return r;
00976 }
00977 
00979 #ifdef DEBUG_SOCKET_COUNTING
00980 
00982 static INLINE void
00983 mark_socket_open(tor_socket_t s)
00984 {
00985   /* XXXX This bitarray business will NOT work on windows: sockets aren't
00986      small ints there. */
00987   if (s > max_socket) {
00988     if (max_socket == -1) {
00989       open_sockets = bitarray_init_zero(s+128);
00990       max_socket = s+128;
00991     } else {
00992       open_sockets = bitarray_expand(open_sockets, max_socket, s+128);
00993       max_socket = s+128;
00994     }
00995   }
00996   if (bitarray_is_set(open_sockets, s)) {
00997     log_warn(LD_BUG, "I thought that %d was already open, but socket() just "
00998              "gave it to me!", s);
00999   }
01000   bitarray_set(open_sockets, s);
01001 }
01002 #else
01003 #define mark_socket_open(s) STMT_NIL
01004 #endif
01005 
01008 tor_socket_t
01009 tor_open_socket(int domain, int type, int protocol)
01010 {
01011   tor_socket_t s;
01012 #ifdef SOCK_CLOEXEC
01013   s = socket(domain, type|SOCK_CLOEXEC, protocol);
01014   if (SOCKET_OK(s))
01015     goto socket_ok;
01016   /* If we got an error, see if it is EINVAL. EINVAL might indicate that,
01017    * even though we were built on a system with SOCK_CLOEXEC support, we
01018    * are running on one without. */
01019   if (errno != EINVAL)
01020     return s;
01021 #endif /* SOCK_CLOEXEC */
01022 
01023   s = socket(domain, type, protocol);
01024   if (! SOCKET_OK(s))
01025     return s;
01026 
01027 #if defined(FD_CLOEXEC)
01028   fcntl(s, F_SETFD, FD_CLOEXEC);
01029 #endif
01030 
01031   goto socket_ok; /* So that socket_ok will not be unused. */
01032 
01033  socket_ok:
01034   socket_accounting_lock();
01035   ++n_sockets_open;
01036   mark_socket_open(s);
01037   socket_accounting_unlock();
01038   return s;
01039 }
01040 
01042 tor_socket_t
01043 tor_accept_socket(tor_socket_t sockfd, struct sockaddr *addr, socklen_t *len)
01044 {
01045   tor_socket_t s;
01046 #if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC)
01047   s = accept4(sockfd, addr, len, SOCK_CLOEXEC);
01048   if (SOCKET_OK(s))
01049     goto socket_ok;
01050   /* If we got an error, see if it is ENOSYS. ENOSYS indicates that,
01051    * even though we were built on a system with accept4 support, we
01052    * are running on one without. Also, check for EINVAL, which indicates that
01053    * we are missing SOCK_CLOEXEC support. */
01054   if (errno != EINVAL && errno != ENOSYS)
01055     return s;
01056 #endif
01057 
01058   s = accept(sockfd, addr, len);
01059   if (!SOCKET_OK(s))
01060     return s;
01061 
01062 #if defined(FD_CLOEXEC)
01063   fcntl(s, F_SETFD, FD_CLOEXEC);
01064 #endif
01065 
01066   goto socket_ok; /* So that socket_ok will not be unused. */
01067 
01068  socket_ok:
01069   socket_accounting_lock();
01070   ++n_sockets_open;
01071   mark_socket_open(s);
01072   socket_accounting_unlock();
01073   return s;
01074 }
01075 
01077 int
01078 get_n_open_sockets(void)
01079 {
01080   int n;
01081   socket_accounting_lock();
01082   n = n_sockets_open;
01083   socket_accounting_unlock();
01084   return n;
01085 }
01086 
01089 void
01090 set_socket_nonblocking(tor_socket_t socket)
01091 {
01092 #if defined(_WIN32)
01093   unsigned long nonblocking = 1;
01094   ioctlsocket(socket, FIONBIO, (unsigned long*) &nonblocking);
01095 #else
01096   fcntl(socket, F_SETFL, O_NONBLOCK);
01097 #endif
01098 }
01099 
01116 /* It would be nicer just to set errno, but that won't work for windows. */
01117 int
01118 tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2])
01119 {
01120 //don't use win32 socketpairs (they are always bad)
01121 #if defined(HAVE_SOCKETPAIR) && !defined(_WIN32)
01122   int r;
01123 
01124 #ifdef SOCK_CLOEXEC
01125   r = socketpair(family, type|SOCK_CLOEXEC, protocol, fd);
01126   if (r == 0)
01127     goto sockets_ok;
01128   /* If we got an error, see if it is EINVAL. EINVAL might indicate that,
01129    * even though we were built on a system with SOCK_CLOEXEC support, we
01130    * are running on one without. */
01131   if (errno != EINVAL)
01132     return -errno;
01133 #endif
01134 
01135   r = socketpair(family, type, protocol, fd);
01136   if (r < 0)
01137     return -errno;
01138 
01139 #if defined(FD_CLOEXEC)
01140   if (SOCKET_OK(fd[0]))
01141     fcntl(fd[0], F_SETFD, FD_CLOEXEC);
01142   if (SOCKET_OK(fd[1]))
01143     fcntl(fd[1], F_SETFD, FD_CLOEXEC);
01144 #endif
01145   goto sockets_ok; /* So that sockets_ok will not be unused. */
01146 
01147  sockets_ok:
01148   socket_accounting_lock();
01149   if (SOCKET_OK(fd[0])) {
01150     ++n_sockets_open;
01151     mark_socket_open(fd[0]);
01152   }
01153   if (SOCKET_OK(fd[1])) {
01154     ++n_sockets_open;
01155     mark_socket_open(fd[1]);
01156   }
01157   socket_accounting_unlock();
01158 
01159   return 0;
01160 #else
01161     /* This socketpair does not work when localhost is down. So
01162      * it's really not the same thing at all. But it's close enough
01163      * for now, and really, when localhost is down sometimes, we
01164      * have other problems too.
01165      */
01166     tor_socket_t listener = -1;
01167     tor_socket_t connector = -1;
01168     tor_socket_t acceptor = -1;
01169     struct sockaddr_in listen_addr;
01170     struct sockaddr_in connect_addr;
01171     int size;
01172     int saved_errno = -1;
01173 
01174     if (protocol
01175 #ifdef AF_UNIX
01176         || family != AF_UNIX
01177 #endif
01178         ) {
01179 #ifdef _WIN32
01180       return -WSAEAFNOSUPPORT;
01181 #else
01182       return -EAFNOSUPPORT;
01183 #endif
01184     }
01185     if (!fd) {
01186       return -EINVAL;
01187     }
01188 
01189     listener = tor_open_socket(AF_INET, type, 0);
01190     if (!SOCKET_OK(listener))
01191       return -tor_socket_errno(-1);
01192     memset(&listen_addr, 0, sizeof(listen_addr));
01193     listen_addr.sin_family = AF_INET;
01194     listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
01195     listen_addr.sin_port = 0;   /* kernel chooses port.  */
01196     if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
01197         == -1)
01198       goto tidy_up_and_fail;
01199     if (listen(listener, 1) == -1)
01200       goto tidy_up_and_fail;
01201 
01202     connector = tor_open_socket(AF_INET, type, 0);
01203     if (!SOCKET_OK(connector))
01204       goto tidy_up_and_fail;
01205     /* We want to find out the port number to connect to.  */
01206     size = sizeof(connect_addr);
01207     if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
01208       goto tidy_up_and_fail;
01209     if (size != sizeof (connect_addr))
01210       goto abort_tidy_up_and_fail;
01211     if (connect(connector, (struct sockaddr *) &connect_addr,
01212                 sizeof(connect_addr)) == -1)
01213       goto tidy_up_and_fail;
01214 
01215     size = sizeof(listen_addr);
01216     acceptor = tor_accept_socket(listener,
01217                                  (struct sockaddr *) &listen_addr, &size);
01218     if (!SOCKET_OK(acceptor))
01219       goto tidy_up_and_fail;
01220     if (size != sizeof(listen_addr))
01221       goto abort_tidy_up_and_fail;
01222     tor_close_socket(listener);
01223     /* Now check we are talking to ourself by matching port and host on the
01224        two sockets.  */
01225     if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
01226       goto tidy_up_and_fail;
01227     if (size != sizeof (connect_addr)
01228         || listen_addr.sin_family != connect_addr.sin_family
01229         || listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
01230         || listen_addr.sin_port != connect_addr.sin_port) {
01231       goto abort_tidy_up_and_fail;
01232     }
01233     fd[0] = connector;
01234     fd[1] = acceptor;
01235 
01236     return 0;
01237 
01238   abort_tidy_up_and_fail:
01239 #ifdef _WIN32
01240     saved_errno = WSAECONNABORTED;
01241 #else
01242     saved_errno = ECONNABORTED; /* I hope this is portable and appropriate.  */
01243 #endif
01244   tidy_up_and_fail:
01245     if (saved_errno < 0)
01246       saved_errno = errno;
01247     if (listener != -1)
01248       tor_close_socket(listener);
01249     if (connector != -1)
01250       tor_close_socket(connector);
01251     if (acceptor != -1)
01252       tor_close_socket(acceptor);
01253     return -saved_errno;
01254 #endif
01255 }
01256 
01259 #define ULIMIT_BUFFER 32 /* keep 32 extra fd's beyond _ConnLimit */
01260 
01272 int
01273 set_max_file_descriptors(rlim_t limit, int *max_out)
01274 {
01275   /* Define some maximum connections values for systems where we cannot
01276    * automatically determine a limit. Re Cygwin, see
01277    * http://archives.seul.org/or/talk/Aug-2006/msg00210.html
01278    * For an iPhone, 9999 should work. For Windows and all other unknown
01279    * systems we use 15000 as the default. */
01280 #ifndef HAVE_GETRLIMIT
01281 #if defined(CYGWIN) || defined(__CYGWIN__)
01282   const char *platform = "Cygwin";
01283   const unsigned long MAX_CONNECTIONS = 3200;
01284 #elif defined(_WIN32)
01285   const char *platform = "Windows";
01286   const unsigned long MAX_CONNECTIONS = 15000;
01287 #else
01288   const char *platform = "unknown platforms with no getrlimit()";
01289   const unsigned long MAX_CONNECTIONS = 15000;
01290 #endif
01291   log_fn(LOG_INFO, LD_NET,
01292          "This platform is missing getrlimit(). Proceeding.");
01293   if (limit > MAX_CONNECTIONS) {
01294     log_warn(LD_CONFIG,
01295              "We do not support more than %lu file descriptors "
01296              "on %s. Tried to raise to %lu.",
01297              (unsigned long)MAX_CONNECTIONS, platform, (unsigned long)limit);
01298     return -1;
01299   }
01300   limit = MAX_CONNECTIONS;
01301 #else /* HAVE_GETRLIMIT */
01302   struct rlimit rlim;
01303 
01304   if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
01305     log_warn(LD_NET, "Could not get maximum number of file descriptors: %s",
01306              strerror(errno));
01307     return -1;
01308   }
01309   if (limit == 0) {
01310     /* If limit == 0, return the maximum value without setting it. */
01311     limit = rlim.rlim_max;
01312     if (limit > INT_MAX)
01313       limit = INT_MAX;
01314     *max_out = (int)limit - ULIMIT_BUFFER;
01315     return 0;
01316   }
01317   if (rlim.rlim_max < limit) {
01318     log_warn(LD_CONFIG,"We need %lu file descriptors available, and we're "
01319              "limited to %lu. Please change your ulimit -n.",
01320              (unsigned long)limit, (unsigned long)rlim.rlim_max);
01321     return -1;
01322   }
01323 
01324   if (rlim.rlim_max > rlim.rlim_cur) {
01325     log_info(LD_NET,"Raising max file descriptors from %lu to %lu.",
01326              (unsigned long)rlim.rlim_cur, (unsigned long)rlim.rlim_max);
01327   }
01328   rlim.rlim_cur = rlim.rlim_max;
01329 
01330   if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
01331     int bad = 1;
01332 #ifdef OPEN_MAX
01333     if (errno == EINVAL && OPEN_MAX < rlim.rlim_cur) {
01334       /* On some platforms, OPEN_MAX is the real limit, and getrlimit() is
01335        * full of nasty lies.  I'm looking at you, OSX 10.5.... */
01336       rlim.rlim_cur = OPEN_MAX;
01337       if (setrlimit(RLIMIT_NOFILE, &rlim) == 0) {
01338         if (rlim.rlim_cur < (rlim_t)limit) {
01339           log_warn(LD_CONFIG, "We are limited to %lu file descriptors by "
01340                  "OPEN_MAX, and ConnLimit is %lu.  Changing ConnLimit; sorry.",
01341                    (unsigned long)OPEN_MAX, (unsigned long)limit);
01342         } else {
01343           log_info(LD_CONFIG, "Dropped connection limit to OPEN_MAX (%lu); "
01344                    "Apparently, %lu was too high and rlimit lied to us.",
01345                    (unsigned long)OPEN_MAX, (unsigned long)rlim.rlim_max);
01346         }
01347         bad = 0;
01348       }
01349     }
01350 #endif /* OPEN_MAX */
01351     if (bad) {
01352       log_warn(LD_CONFIG,"Couldn't set maximum number of file descriptors: %s",
01353                strerror(errno));
01354       return -1;
01355     }
01356   }
01357   /* leave some overhead for logs, etc, */
01358   limit = rlim.rlim_cur;
01359 #endif /* HAVE_GETRLIMIT */
01360 
01361   if (limit < ULIMIT_BUFFER) {
01362     log_warn(LD_CONFIG,
01363              "ConnLimit must be at least %d. Failing.", ULIMIT_BUFFER);
01364     return -1;
01365   }
01366   if (limit > INT_MAX)
01367     limit = INT_MAX;
01368   tor_assert(max_out);
01369   *max_out = (int)limit - ULIMIT_BUFFER;
01370   return 0;
01371 }
01372 
01373 #ifndef _WIN32
01374 
01377 static int
01378 log_credential_status(void)
01379 {
01381 #define CREDENTIAL_LOG_LEVEL LOG_INFO
01382   /* Real, effective and saved UIDs */
01383   uid_t ruid, euid, suid;
01384   /* Read, effective and saved GIDs */
01385   gid_t rgid, egid, sgid;
01386   /* Supplementary groups */
01387   gid_t *sup_gids = NULL;
01388   int sup_gids_size;
01389   /* Number of supplementary groups */
01390   int ngids;
01391 
01392   /* log UIDs */
01393 #ifdef HAVE_GETRESUID
01394   if (getresuid(&ruid, &euid, &suid) != 0 ) {
01395     log_warn(LD_GENERAL, "Error getting changed UIDs: %s", strerror(errno));
01396     return -1;
01397   } else {
01398     log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
01399            "UID is %u (real), %u (effective), %u (saved)",
01400            (unsigned)ruid, (unsigned)euid, (unsigned)suid);
01401   }
01402 #else
01403   /* getresuid is not present on MacOS X, so we can't get the saved (E)UID */
01404   ruid = getuid();
01405   euid = geteuid();
01406   (void)suid;
01407 
01408   log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
01409          "UID is %u (real), %u (effective), unknown (saved)",
01410          (unsigned)ruid, (unsigned)euid);
01411 #endif
01412 
01413   /* log GIDs */
01414 #ifdef HAVE_GETRESGID
01415   if (getresgid(&rgid, &egid, &sgid) != 0 ) {
01416     log_warn(LD_GENERAL, "Error getting changed GIDs: %s", strerror(errno));
01417     return -1;
01418   } else {
01419     log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
01420            "GID is %u (real), %u (effective), %u (saved)",
01421            (unsigned)rgid, (unsigned)egid, (unsigned)sgid);
01422   }
01423 #else
01424   /* getresgid is not present on MacOS X, so we can't get the saved (E)GID */
01425   rgid = getgid();
01426   egid = getegid();
01427   (void)sgid;
01428   log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
01429          "GID is %u (real), %u (effective), unknown (saved)",
01430          (unsigned)rgid, (unsigned)egid);
01431 #endif
01432 
01433   /* log supplementary groups */
01434   sup_gids_size = 64;
01435   sup_gids = tor_malloc(sizeof(gid_t) * 64);
01436   while ((ngids = getgroups(sup_gids_size, sup_gids)) < 0 &&
01437          errno == EINVAL &&
01438          sup_gids_size < NGROUPS_MAX) {
01439     sup_gids_size *= 2;
01440     sup_gids = tor_realloc(sup_gids, sizeof(gid_t) * sup_gids_size);
01441   }
01442 
01443   if (ngids < 0) {
01444     log_warn(LD_GENERAL, "Error getting supplementary GIDs: %s",
01445              strerror(errno));
01446     tor_free(sup_gids);
01447     return -1;
01448   } else {
01449     int i, retval = 0;
01450     char *s = NULL;
01451     smartlist_t *elts = smartlist_new();
01452 
01453     for (i = 0; i<ngids; i++) {
01454       smartlist_add_asprintf(elts, "%u", (unsigned)sup_gids[i]);
01455     }
01456 
01457     s = smartlist_join_strings(elts, " ", 0, NULL);
01458 
01459     log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL, "Supplementary groups are: %s",s);
01460 
01461     tor_free(s);
01462     SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
01463     smartlist_free(elts);
01464     tor_free(sup_gids);
01465 
01466     return retval;
01467   }
01468 
01469   return 0;
01470 }
01471 #endif
01472 
01476 int
01477 switch_id(const char *user)
01478 {
01479 #ifndef _WIN32
01480   struct passwd *pw = NULL;
01481   uid_t old_uid;
01482   gid_t old_gid;
01483   static int have_already_switched_id = 0;
01484 
01485   tor_assert(user);
01486 
01487   if (have_already_switched_id)
01488     return 0;
01489 
01490   /* Log the initial credential state */
01491   if (log_credential_status())
01492     return -1;
01493 
01494   log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL, "Changing user and groups");
01495 
01496   /* Get old UID/GID to check if we changed correctly */
01497   old_uid = getuid();
01498   old_gid = getgid();
01499 
01500   /* Lookup the user and group information, if we have a problem, bail out. */
01501   pw = getpwnam(user);
01502   if (pw == NULL) {
01503     log_warn(LD_CONFIG, "Error setting configured user: %s not found", user);
01504     return -1;
01505   }
01506 
01507   /* Properly switch egid,gid,euid,uid here or bail out */
01508   if (setgroups(1, &pw->pw_gid)) {
01509     log_warn(LD_GENERAL, "Error setting groups to gid %d: \"%s\".",
01510              (int)pw->pw_gid, strerror(errno));
01511     if (old_uid == pw->pw_uid) {
01512       log_warn(LD_GENERAL, "Tor is already running as %s.  You do not need "
01513                "the \"User\" option if you are already running as the user "
01514                "you want to be.  (If you did not set the User option in your "
01515                "torrc, check whether it was specified on the command line "
01516                "by a startup script.)", user);
01517     } else {
01518       log_warn(LD_GENERAL, "If you set the \"User\" option, you must start Tor"
01519                " as root.");
01520     }
01521     return -1;
01522   }
01523 
01524   if (setegid(pw->pw_gid)) {
01525     log_warn(LD_GENERAL, "Error setting egid to %d: %s",
01526              (int)pw->pw_gid, strerror(errno));
01527     return -1;
01528   }
01529 
01530   if (setgid(pw->pw_gid)) {
01531     log_warn(LD_GENERAL, "Error setting gid to %d: %s",
01532              (int)pw->pw_gid, strerror(errno));
01533     return -1;
01534   }
01535 
01536   if (setuid(pw->pw_uid)) {
01537     log_warn(LD_GENERAL, "Error setting configured uid to %s (%d): %s",
01538              user, (int)pw->pw_uid, strerror(errno));
01539     return -1;
01540   }
01541 
01542   if (seteuid(pw->pw_uid)) {
01543     log_warn(LD_GENERAL, "Error setting configured euid to %s (%d): %s",
01544              user, (int)pw->pw_uid, strerror(errno));
01545     return -1;
01546   }
01547 
01548   /* This is how OpenBSD rolls:
01549   if (setgroups(1, &pw->pw_gid) || setegid(pw->pw_gid) ||
01550       setgid(pw->pw_gid) || setuid(pw->pw_uid) || seteuid(pw->pw_uid)) {
01551       setgid(pw->pw_gid) || seteuid(pw->pw_uid) || setuid(pw->pw_uid)) {
01552     log_warn(LD_GENERAL, "Error setting configured UID/GID: %s",
01553     strerror(errno));
01554     return -1;
01555   }
01556   */
01557 
01558   /* We've properly switched egid, gid, euid, uid, and supplementary groups if
01559    * we're here. */
01560 
01561 #if !defined(CYGWIN) && !defined(__CYGWIN__)
01562   /* If we tried to drop privilege to a group/user other than root, attempt to
01563    * restore root (E)(U|G)ID, and abort if the operation succeeds */
01564 
01565   /* Only check for privilege dropping if we were asked to be non-root */
01566   if (pw->pw_uid) {
01567     /* Try changing GID/EGID */
01568     if (pw->pw_gid != old_gid &&
01569         (setgid(old_gid) != -1 || setegid(old_gid) != -1)) {
01570       log_warn(LD_GENERAL, "Was able to restore group credentials even after "
01571                "switching GID: this means that the setgid code didn't work.");
01572       return -1;
01573     }
01574 
01575     /* Try changing UID/EUID */
01576     if (pw->pw_uid != old_uid &&
01577         (setuid(old_uid) != -1 || seteuid(old_uid) != -1)) {
01578       log_warn(LD_GENERAL, "Was able to restore user credentials even after "
01579                "switching UID: this means that the setuid code didn't work.");
01580       return -1;
01581     }
01582   }
01583 #endif
01584 
01585   /* Check what really happened */
01586   if (log_credential_status()) {
01587     return -1;
01588   }
01589 
01590   have_already_switched_id = 1; /* mark success so we never try again */
01591 
01592 #if defined(__linux__) && defined(HAVE_SYS_PRCTL_H) && defined(HAVE_PRCTL)
01593 #ifdef PR_SET_DUMPABLE
01594   if (pw->pw_uid) {
01595     /* Re-enable core dumps if we're not running as root. */
01596     log_info(LD_CONFIG, "Re-enabling coredumps");
01597     if (prctl(PR_SET_DUMPABLE, 1)) {
01598       log_warn(LD_CONFIG, "Unable to re-enable coredumps: %s",strerror(errno));
01599     }
01600   }
01601 #endif
01602 #endif
01603   return 0;
01604 
01605 #else
01606   (void)user;
01607 
01608   log_warn(LD_CONFIG,
01609            "User specified but switching users is unsupported on your OS.");
01610   return -1;
01611 #endif
01612 }
01613 
01614 /* We only use the linux prctl for now. There is no Win32 support; this may
01615  * also work on various BSD systems and Mac OS X - send testing feedback!
01616  *
01617  * On recent Gnu/Linux kernels it is possible to create a system-wide policy
01618  * that will prevent non-root processes from attaching to other processes
01619  * unless they are the parent process; thus gdb can attach to programs that
01620  * they execute but they cannot attach to other processes running as the same
01621  * user. The system wide policy may be set with the sysctl
01622  * kernel.yama.ptrace_scope or by inspecting
01623  * /proc/sys/kernel/yama/ptrace_scope and it is 1 by default on Ubuntu 11.04.
01624  *
01625  * This ptrace scope will be ignored on Gnu/Linux for users with
01626  * CAP_SYS_PTRACE and so it is very likely that root will still be able to
01627  * attach to the Tor process.
01628  */
01631 int
01632 tor_disable_debugger_attach(void)
01633 {
01634   int r, attempted;
01635   r = -1;
01636   attempted = 0;
01637   log_debug(LD_CONFIG,
01638             "Attemping to disable debugger attachment to Tor for "
01639             "unprivileged users.");
01640 #if defined(__linux__) && defined(HAVE_SYS_PRCTL_H) && defined(HAVE_PRCTL)
01641 #ifdef PR_SET_DUMPABLE
01642   attempted = 1;
01643   r = prctl(PR_SET_DUMPABLE, 0);
01644 #endif
01645 #endif
01646 #if defined(__APPLE__) && defined(PT_DENY_ATTACH)
01647   if (r < 0) {
01648     attempted = 1;
01649     r = ptrace(PT_DENY_ATTACH, 0, 0, 0);
01650   }
01651 #endif
01652 
01653   // XXX: TODO - Mac OS X has dtrace and this may be disabled.
01654   // XXX: TODO - Windows probably has something similar
01655   if (r == 0 && attempted) {
01656     log_debug(LD_CONFIG,"Debugger attachment disabled for "
01657               "unprivileged users.");
01658     return 1;
01659   } else if (attempted) {
01660     log_warn(LD_CONFIG, "Unable to disable debugger attaching: %s",
01661              strerror(errno));
01662   }
01663   return r;
01664 }
01665 
01666 #ifdef HAVE_PWD_H
01667 
01669 char *
01670 get_user_homedir(const char *username)
01671 {
01672   struct passwd *pw;
01673   tor_assert(username);
01674 
01675   if (!(pw = getpwnam(username))) {
01676     log_err(LD_CONFIG,"User \"%s\" not found.", username);
01677     return NULL;
01678   }
01679   return tor_strdup(pw->pw_dir);
01680 }
01681 #endif
01682 
01688 int
01689 get_parent_directory(char *fname)
01690 {
01691   char *cp;
01692   int at_end = 1;
01693   tor_assert(fname);
01694 #ifdef _WIN32
01695   /* If we start with, say, c:, then don't consider that the start of the path
01696    */
01697   if (fname[0] && fname[1] == ':') {
01698     fname += 2;
01699   }
01700 #endif
01701   /* Now we want to remove all path-separators at the end of the string,
01702    * and to remove the end of the string starting with the path separator
01703    * before the last non-path-separator.  In perl, this would be
01704    *   s#[/]*$##; s#/[^/]*$##;
01705    * on a unixy platform.
01706    */
01707   cp = fname + strlen(fname);
01708   at_end = 1;
01709   while (--cp >= fname) {
01710     int is_sep = (*cp == '/'
01711 #ifdef _WIN32
01712                   || *cp == '\\'
01713 #endif
01714                   );
01715     if (is_sep) {
01716       if (cp == fname) {
01717         /* This is the first separator in the file name; don't remove it! */
01718         cp[1] = '\0';
01719         return 0;
01720       }
01721       *cp = '\0';
01722       if (! at_end)
01723         return 0;
01724     } else {
01725       at_end = 0;
01726     }
01727   }
01728   return -1;
01729 }
01730 
01731 #ifndef _WIN32
01732 
01736 static char *
01737 alloc_getcwd(void)
01738 {
01739     int saved_errno = errno;
01740 /* We use this as a starting path length. Not too large seems sane. */
01741 #define START_PATH_LENGTH 128
01742 /* Nobody has a maxpath longer than this, as far as I know.  And if they
01743  * do, they shouldn't. */
01744 #define MAX_SANE_PATH_LENGTH 4096
01745     size_t path_length = START_PATH_LENGTH;
01746     char *path = tor_malloc(path_length);
01747 
01748     errno = 0;
01749     while (getcwd(path, path_length) == NULL) {
01750       if (errno == ERANGE && path_length < MAX_SANE_PATH_LENGTH) {
01751         path_length*=2;
01752         path = tor_realloc(path, path_length);
01753       } else {
01754         tor_free(path);
01755         path = NULL;
01756         break;
01757       }
01758     }
01759     errno = saved_errno;
01760     return path;
01761 }
01762 #endif
01763 
01766 char *
01767 make_path_absolute(char *fname)
01768 {
01769 #ifdef _WIN32
01770   char *absfname_malloced = _fullpath(NULL, fname, 1);
01771 
01772   /* We don't want to assume that tor_free can free a string allocated
01773    * with malloc.  On failure, return fname (it's better than nothing). */
01774   char *absfname = tor_strdup(absfname_malloced ? absfname_malloced : fname);
01775   if (absfname_malloced) free(absfname_malloced);
01776 
01777   return absfname;
01778 #else
01779   char *absfname = NULL, *path = NULL;
01780 
01781   tor_assert(fname);
01782 
01783   if (fname[0] == '/') {
01784     absfname = tor_strdup(fname);
01785   } else {
01786     path = alloc_getcwd();
01787     if (path) {
01788       tor_asprintf(&absfname, "%s/%s", path, fname);
01789       tor_free(path);
01790     } else {
01791       /* If getcwd failed, the best we can do here is keep using the
01792        * relative path.  (Perhaps / isn't readable by this UID/GID.) */
01793       log_warn(LD_GENERAL, "Unable to find current working directory: %s",
01794                strerror(errno));
01795       absfname = tor_strdup(fname);
01796     }
01797   }
01798   return absfname;
01799 #endif
01800 }
01801 
01802 #ifndef HAVE__NSGETENVIRON
01803 #ifndef HAVE_EXTERN_ENVIRON_DECLARED
01804 /* Some platforms declare environ under some circumstances, others don't. */
01805 #ifndef RUNNING_DOXYGEN
01806 extern char **environ;
01807 #endif
01808 #endif
01809 #endif
01810 
01813 char **
01814 get_environment(void)
01815 {
01816 #ifdef HAVE__NSGETENVIRON
01817   /* This is for compatibility between OSX versions.  Otherwise (for example)
01818    * when we do a mostly-static build on OSX 10.7, the resulting binary won't
01819    * work on OSX 10.6. */
01820   return *_NSGetEnviron();
01821 #else
01822   return environ;
01823 #endif
01824 }
01825 
01830 int
01831 tor_inet_aton(const char *str, struct in_addr* addr)
01832 {
01833   unsigned a,b,c,d;
01834   char more;
01835   if (tor_sscanf(str, "%3u.%3u.%3u.%3u%c", &a,&b,&c,&d,&more) != 4)
01836     return 0;
01837   if (a > 255) return 0;
01838   if (b > 255) return 0;
01839   if (c > 255) return 0;
01840   if (d > 255) return 0;
01841   addr->s_addr = htonl((a<<24) | (b<<16) | (c<<8) | d);
01842   return 1;
01843 }
01844 
01853 const char *
01854 tor_inet_ntop(int af, const void *src, char *dst, size_t len)
01855 {
01856   if (af == AF_INET) {
01857     if (tor_inet_ntoa(src, dst, len) < 0)
01858       return NULL;
01859     else
01860       return dst;
01861   } else if (af == AF_INET6) {
01862     const struct in6_addr *addr = src;
01863     char buf[64], *cp;
01864     int longestGapLen = 0, longestGapPos = -1, i,
01865       curGapPos = -1, curGapLen = 0;
01866     uint16_t words[8];
01867     for (i = 0; i < 8; ++i) {
01868       words[i] = (((uint16_t)addr->s6_addr[2*i])<<8) + addr->s6_addr[2*i+1];
01869     }
01870     if (words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
01871         words[4] == 0 && ((words[5] == 0 && words[6] && words[7]) ||
01872                           (words[5] == 0xffff))) {
01873       /* This is an IPv4 address. */
01874       if (words[5] == 0) {
01875         tor_snprintf(buf, sizeof(buf), "::%d.%d.%d.%d",
01876                      addr->s6_addr[12], addr->s6_addr[13],
01877                      addr->s6_addr[14], addr->s6_addr[15]);
01878       } else {
01879         tor_snprintf(buf, sizeof(buf), "::%x:%d.%d.%d.%d", words[5],
01880                      addr->s6_addr[12], addr->s6_addr[13],
01881                      addr->s6_addr[14], addr->s6_addr[15]);
01882       }
01883       if ((strlen(buf) + 1) > len) /* +1 for \0 */
01884         return NULL;
01885       strlcpy(dst, buf, len);
01886       return dst;
01887     }
01888     i = 0;
01889     while (i < 8) {
01890       if (words[i] == 0) {
01891         curGapPos = i++;
01892         curGapLen = 1;
01893         while (i<8 && words[i] == 0) {
01894           ++i; ++curGapLen;
01895         }
01896         if (curGapLen > longestGapLen) {
01897           longestGapPos = curGapPos;
01898           longestGapLen = curGapLen;
01899         }
01900       } else {
01901         ++i;
01902       }
01903     }
01904     if (longestGapLen<=1)
01905       longestGapPos = -1;
01906 
01907     cp = buf;
01908     for (i = 0; i < 8; ++i) {
01909       if (words[i] == 0 && longestGapPos == i) {
01910         if (i == 0)
01911           *cp++ = ':';
01912         *cp++ = ':';
01913         while (i < 8 && words[i] == 0)
01914           ++i;
01915         --i; /* to compensate for loop increment. */
01916       } else {
01917         tor_snprintf(cp, sizeof(buf)-(cp-buf), "%x", (unsigned)words[i]);
01918         cp += strlen(cp);
01919         if (i != 7)
01920           *cp++ = ':';
01921       }
01922     }
01923     *cp = '\0';
01924     if ((strlen(buf) + 1) > len) /* +1 for \0 */
01925       return NULL;
01926     strlcpy(dst, buf, len);
01927     return dst;
01928   } else {
01929     return NULL;
01930   }
01931 }
01932 
01942 int
01943 tor_inet_pton(int af, const char *src, void *dst)
01944 {
01945   if (af == AF_INET) {
01946     return tor_inet_aton(src, dst);
01947   } else if (af == AF_INET6) {
01948     struct in6_addr *out = dst;
01949     uint16_t words[8];
01950     int gapPos = -1, i, setWords=0;
01951     const char *dot = strchr(src, '.');
01952     const char *eow; /* end of words. */
01953     if (dot == src)
01954       return 0;
01955     else if (!dot)
01956       eow = src+strlen(src);
01957     else {
01958       unsigned byte1,byte2,byte3,byte4;
01959       char more;
01960       for (eow = dot-1; eow >= src && TOR_ISDIGIT(*eow); --eow)
01961         ;
01962       ++eow;
01963 
01964       /* We use "scanf" because some platform inet_aton()s are too lax
01965        * about IPv4 addresses of the form "1.2.3" */
01966       if (tor_sscanf(eow, "%3u.%3u.%3u.%3u%c",
01967                      &byte1,&byte2,&byte3,&byte4,&more) != 4)
01968         return 0;
01969 
01970       if (byte1 > 255 || byte2 > 255 || byte3 > 255 || byte4 > 255)
01971         return 0;
01972 
01973       words[6] = (byte1<<8) | byte2;
01974       words[7] = (byte3<<8) | byte4;
01975       setWords += 2;
01976     }
01977 
01978     i = 0;
01979     while (src < eow) {
01980       if (i > 7)
01981         return 0;
01982       if (TOR_ISXDIGIT(*src)) {
01983         char *next;
01984         ssize_t len;
01985         long r = strtol(src, &next, 16);
01986         tor_assert(next != NULL);
01987         tor_assert(next != src);
01988 
01989         len = *next == '\0' ? eow - src : next - src;
01990         if (len > 4)
01991           return 0;
01992         if (len > 1 && !TOR_ISXDIGIT(src[1]))
01993           return 0; /* 0x is not valid */
01994 
01995         tor_assert(r >= 0);
01996         tor_assert(r < 65536);
01997         words[i++] = (uint16_t)r;
01998         setWords++;
01999         src = next;
02000         if (*src != ':' && src != eow)
02001           return 0;
02002         ++src;
02003       } else if (*src == ':' && i > 0 && gapPos == -1) {
02004         gapPos = i;
02005         ++src;
02006       } else if (*src == ':' && i == 0 && src+1 < eow && src[1] == ':' &&
02007                  gapPos == -1) {
02008         gapPos = i;
02009         src += 2;
02010       } else {
02011         return 0;
02012       }
02013     }
02014 
02015     if (setWords > 8 ||
02016         (setWords == 8 && gapPos != -1) ||
02017         (setWords < 8 && gapPos == -1))
02018       return 0;
02019 
02020     if (gapPos >= 0) {
02021       int nToMove = setWords - (dot ? 2 : 0) - gapPos;
02022       int gapLen = 8 - setWords;
02023       tor_assert(nToMove >= 0);
02024       memmove(&words[gapPos+gapLen], &words[gapPos],
02025               sizeof(uint16_t)*nToMove);
02026       memset(&words[gapPos], 0, sizeof(uint16_t)*gapLen);
02027     }
02028     for (i = 0; i < 8; ++i) {
02029       out->s6_addr[2*i  ] = words[i] >> 8;
02030       out->s6_addr[2*i+1] = words[i] & 0xff;
02031     }
02032 
02033     return 1;
02034   } else {
02035     return -1;
02036   }
02037 }
02038 
02046 int
02047 tor_lookup_hostname(const char *name, uint32_t *addr)
02048 {
02049   tor_addr_t myaddr;
02050   int ret;
02051 
02052   if ((ret = tor_addr_lookup(name, AF_INET, &myaddr)))
02053     return ret;
02054 
02055   if (tor_addr_family(&myaddr) == AF_INET) {
02056     *addr = tor_addr_to_ipv4h(&myaddr);
02057     return ret;
02058   }
02059 
02060   return -1;
02061 }
02062 
02064 void
02065 tor_init_weak_random(unsigned seed)
02066 {
02067 #ifdef _WIN32
02068   srand(seed);
02069 #else
02070   srandom(seed);
02071 #endif
02072 }
02073 
02077 long
02078 tor_weak_random(void)
02079 {
02080 #ifdef _WIN32
02081   return rand();
02082 #else
02083   return random();
02084 #endif
02085 }
02086 
02088 static char uname_result[256];
02090 static int uname_result_is_set = 0;
02091 
02094 const char *
02095 get_uname(void)
02096 {
02097 #ifdef HAVE_UNAME
02098   struct utsname u;
02099 #endif
02100   if (!uname_result_is_set) {
02101 #ifdef HAVE_UNAME
02102     if (uname(&u) != -1) {
02103       /* (Linux says 0 is success, Solaris says 1 is success) */
02104       strlcpy(uname_result, u.sysname, sizeof(uname_result));
02105     } else
02106 #endif
02107       {
02108 #ifdef _WIN32
02109         OSVERSIONINFOEX info;
02110         int i;
02111         const char *plat = NULL;
02112         static struct {
02113           unsigned major; unsigned minor; const char *version;
02114         } win_version_table[] = {
02115           { 6, 2, "Windows 8" },
02116           { 6, 1, "Windows 7" },
02117           { 6, 0, "Windows Vista" },
02118           { 5, 2, "Windows Server 2003" },
02119           { 5, 1, "Windows XP" },
02120           { 5, 0, "Windows 2000" },
02121           /* { 4, 0, "Windows NT 4.0" }, */
02122           { 4, 90, "Windows Me" },
02123           { 4, 10, "Windows 98" },
02124           /* { 4, 0, "Windows 95" } */
02125           { 3, 51, "Windows NT 3.51" },
02126           { 0, 0, NULL }
02127         };
02128         memset(&info, 0, sizeof(info));
02129         info.dwOSVersionInfoSize = sizeof(info);
02130         if (! GetVersionEx((LPOSVERSIONINFO)&info)) {
02131           strlcpy(uname_result, "Bizarre version of Windows where GetVersionEx"
02132                   " doesn't work.", sizeof(uname_result));
02133           uname_result_is_set = 1;
02134           return uname_result;
02135         }
02136         if (info.dwMajorVersion == 4 && info.dwMinorVersion == 0) {
02137           if (info.dwPlatformId == VER_PLATFORM_WIN32_NT)
02138             plat = "Windows NT 4.0";
02139           else
02140             plat = "Windows 95";
02141         } else {
02142           for (i=0; win_version_table[i].major>0; ++i) {
02143             if (win_version_table[i].major == info.dwMajorVersion &&
02144                 win_version_table[i].minor == info.dwMinorVersion) {
02145               plat = win_version_table[i].version;
02146               break;
02147             }
02148           }
02149         }
02150         if (plat) {
02151           strlcpy(uname_result, plat, sizeof(uname_result));
02152         } else {
02153           if (info.dwMajorVersion > 6 ||
02154               (info.dwMajorVersion==6 && info.dwMinorVersion>2))
02155             tor_snprintf(uname_result, sizeof(uname_result),
02156                          "Very recent version of Windows [major=%d,minor=%d]",
02157                          (int)info.dwMajorVersion,(int)info.dwMinorVersion);
02158           else
02159             tor_snprintf(uname_result, sizeof(uname_result),
02160                          "Unrecognized version of Windows [major=%d,minor=%d]",
02161                          (int)info.dwMajorVersion,(int)info.dwMinorVersion);
02162         }
02163 #if !defined (WINCE)
02164 #ifdef VER_NT_SERVER
02165       if (info.wProductType == VER_NT_SERVER ||
02166           info.wProductType == VER_NT_DOMAIN_CONTROLLER) {
02167         strlcat(uname_result, " [server]", sizeof(uname_result));
02168       }
02169 #endif
02170 #endif
02171 #else
02172         strlcpy(uname_result, "Unknown platform", sizeof(uname_result));
02173 #endif
02174       }
02175     uname_result_is_set = 1;
02176   }
02177   return uname_result;
02178 }
02179 
02180 /*
02181  *   Process control
02182  */
02183 
02184 #if defined(USE_PTHREADS)
02185 
02188 typedef struct tor_pthread_data_t {
02189   void (*func)(void *);
02190   void *data;
02191 } tor_pthread_data_t;
02195 static void *
02196 tor_pthread_helper_fn(void *_data)
02197 {
02198   tor_pthread_data_t *data = _data;
02199   void (*func)(void*);
02200   void *arg;
02201   /* mask signals to worker threads to avoid SIGPIPE, etc */
02202   sigset_t sigs;
02203   /* We're in a subthread; don't handle any signals here. */
02204   sigfillset(&sigs);
02205   pthread_sigmask(SIG_SETMASK, &sigs, NULL);
02206 
02207   func = data->func;
02208   arg = data->data;
02209   tor_free(_data);
02210   func(arg);
02211   return NULL;
02212 }
02213 #endif
02214 
02224 int
02225 spawn_func(void (*func)(void *), void *data)
02226 {
02227 #if defined(USE_WIN32_THREADS)
02228   int rv;
02229   rv = (int)_beginthread(func, 0, data);
02230   if (rv == (int)-1)
02231     return -1;
02232   return 0;
02233 #elif defined(USE_PTHREADS)
02234   pthread_t thread;
02235   tor_pthread_data_t *d;
02236   d = tor_malloc(sizeof(tor_pthread_data_t));
02237   d->data = data;
02238   d->func = func;
02239   if (pthread_create(&thread,NULL,tor_pthread_helper_fn,d))
02240     return -1;
02241   if (pthread_detach(thread))
02242     return -1;
02243   return 0;
02244 #else
02245   pid_t pid;
02246   pid = fork();
02247   if (pid<0)
02248     return -1;
02249   if (pid==0) {
02250     /* Child */
02251     func(data);
02252     tor_assert(0); /* Should never reach here. */
02253     return 0; /* suppress "control-reaches-end-of-non-void" warning. */
02254   } else {
02255     /* Parent */
02256     return 0;
02257   }
02258 #endif
02259 }
02260 
02263 void
02264 spawn_exit(void)
02265 {
02266 #if defined(USE_WIN32_THREADS)
02267   _endthread();
02268   //we should never get here. my compiler thinks that _endthread returns, this
02269   //is an attempt to fool it.
02270   tor_assert(0);
02271   _exit(0);
02272 #elif defined(USE_PTHREADS)
02273   pthread_exit(NULL);
02274 #else
02275   /* http://www.erlenstar.demon.co.uk/unix/faq_2.html says we should
02276    * call _exit, not exit, from child processes. */
02277   _exit(0);
02278 #endif
02279 }
02280 
02282 static int
02283 compute_num_cpus_impl(void)
02284 {
02285 #ifdef _WIN32
02286   SYSTEM_INFO info;
02287   memset(&info, 0, sizeof(info));
02288   GetSystemInfo(&info);
02289   if (info.dwNumberOfProcessors >= 1 && info.dwNumberOfProcessors < INT_MAX)
02290     return (int)info.dwNumberOfProcessors;
02291   else
02292     return -1;
02293 #elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF)
02294   long cpus = sysconf(_SC_NPROCESSORS_CONF);
02295   if (cpus >= 1 && cpus < INT_MAX)
02296     return (int)cpus;
02297   else
02298     return -1;
02299 #else
02300   return -1;
02301 #endif
02302 }
02303 
02304 #define MAX_DETECTABLE_CPUS 16
02305 
02311 int
02312 compute_num_cpus(void)
02313 {
02314   static int num_cpus = -2;
02315   if (num_cpus == -2) {
02316     num_cpus = compute_num_cpus_impl();
02317     tor_assert(num_cpus != -2);
02318     if (num_cpus > MAX_DETECTABLE_CPUS)
02319       log_notice(LD_GENERAL, "Wow!  I detected that you have %d CPUs. I "
02320                  "will not autodetect any more than %d, though.  If you "
02321                  "want to configure more, set NumCPUs in your torrc",
02322                  num_cpus, MAX_DETECTABLE_CPUS);
02323   }
02324   return num_cpus;
02325 }
02326 
02330 void
02331 tor_gettimeofday(struct timeval *timeval)
02332 {
02333 #ifdef _WIN32
02334   /* Epoch bias copied from perl: number of units between windows epoch and
02335    * Unix epoch. */
02336 #define EPOCH_BIAS U64_LITERAL(116444736000000000)
02337 #define UNITS_PER_SEC U64_LITERAL(10000000)
02338 #define USEC_PER_SEC U64_LITERAL(1000000)
02339 #define UNITS_PER_USEC U64_LITERAL(10)
02340   union {
02341     uint64_t ft_64;
02342     FILETIME ft_ft;
02343   } ft;
02344 #if defined (WINCE)
02345   /* wince do not have GetSystemTimeAsFileTime */
02346   SYSTEMTIME stime;
02347   GetSystemTime(&stime);
02348   SystemTimeToFileTime(&stime,&ft.ft_ft);
02349 #else
02350   /* number of 100-nsec units since Jan 1, 1601 */
02351   GetSystemTimeAsFileTime(&ft.ft_ft);
02352 #endif
02353   if (ft.ft_64 < EPOCH_BIAS) {
02354     log_err(LD_GENERAL,"System time is before 1970; failing.");
02355     exit(1);
02356   }
02357   ft.ft_64 -= EPOCH_BIAS;
02358   timeval->tv_sec = (unsigned) (ft.ft_64 / UNITS_PER_SEC);
02359   timeval->tv_usec = (unsigned) ((ft.ft_64 / UNITS_PER_USEC) % USEC_PER_SEC);
02360 #elif defined(HAVE_GETTIMEOFDAY)
02361   if (gettimeofday(timeval, NULL)) {
02362     log_err(LD_GENERAL,"gettimeofday failed.");
02363     /* If gettimeofday dies, we have either given a bad timezone (we didn't),
02364        or segfaulted.*/
02365     exit(1);
02366   }
02367 #elif defined(HAVE_FTIME)
02368   struct timeb tb;
02369   ftime(&tb);
02370   timeval->tv_sec = tb.time;
02371   timeval->tv_usec = tb.millitm * 1000;
02372 #else
02373 #error "No way to get time."
02374 #endif
02375   return;
02376 }
02377 
02378 #if defined(TOR_IS_MULTITHREADED) && !defined(_WIN32)
02379 
02381 #define TIME_FNS_NEED_LOCKS
02382 #endif
02383 
02390 static struct tm *
02391 correct_tm(int islocal, const time_t *timep, struct tm *resultbuf,
02392            struct tm *r)
02393 {
02394   const char *outcome;
02395 
02396   if (PREDICT_LIKELY(r)) {
02397     if (r->tm_year > 8099) { /* We can't strftime dates after 9999 CE. */
02398       r->tm_year = 8099;
02399       r->tm_mon = 11;
02400       r->tm_mday = 31;
02401       r->tm_yday = 365;
02402       r->tm_hour = 23;
02403       r->tm_min = 59;
02404       r->tm_sec = 59;
02405     }
02406     return r;
02407   }
02408 
02409   /* If we get here, gmtime or localtime returned NULL. It might have done
02410    * this because of overrun or underrun, or it might have done it because of
02411    * some other weird issue. */
02412   if (timep) {
02413     if (*timep < 0) {
02414       r = resultbuf;
02415       r->tm_year = 70; /* 1970 CE */
02416       r->tm_mon = 0;
02417       r->tm_mday = 1;
02418       r->tm_yday = 1;
02419       r->tm_hour = 0;
02420       r->tm_min = 0 ;
02421       r->tm_sec = 0;
02422       outcome = "Rounding up to 1970";
02423       goto done;
02424     } else if (*timep >= INT32_MAX) {
02425       /* Rounding down to INT32_MAX isn't so great, but keep in mind that we
02426        * only do it if gmtime/localtime tells us NULL. */
02427       r = resultbuf;
02428       r->tm_year = 137; /* 2037 CE */
02429       r->tm_mon = 11;
02430       r->tm_mday = 31;
02431       r->tm_yday = 365;
02432       r->tm_hour = 23;
02433       r->tm_min = 59;
02434       r->tm_sec = 59;
02435       outcome = "Rounding down to 2037";
02436       goto done;
02437     }
02438   }
02439 
02440   /* If we get here, then gmtime/localtime failed without getting an extreme
02441    * value for *timep */
02442 
02443   tor_fragile_assert();
02444   r = resultbuf;
02445   memset(resultbuf, 0, sizeof(struct tm));
02446   outcome="can't recover";
02447  done:
02448   log_warn(LD_BUG, "%s("I64_FORMAT") failed with error %s: %s",
02449            islocal?"localtime":"gmtime",
02450            timep?I64_PRINTF_ARG(*timep):0,
02451            strerror(errno),
02452            outcome);
02453   return r;
02454 }
02455 
02462 #ifdef HAVE_LOCALTIME_R
02463 struct tm *
02464 tor_localtime_r(const time_t *timep, struct tm *result)
02465 {
02466   struct tm *r;
02467   r = localtime_r(timep, result);
02468   return correct_tm(1, timep, result, r);
02469 }
02470 #elif defined(TIME_FNS_NEED_LOCKS)
02471 struct tm *
02472 tor_localtime_r(const time_t *timep, struct tm *result)
02473 {
02474   struct tm *r;
02475   static tor_mutex_t *m=NULL;
02476   if (!m) { m=tor_mutex_new(); }
02477   tor_assert(result);
02478   tor_mutex_acquire(m);
02479   r = localtime(timep);
02480   if (r)
02481     memcpy(result, r, sizeof(struct tm));
02482   tor_mutex_release(m);
02483   return correct_tm(1, timep, result, r);
02484 }
02485 #else
02486 struct tm *
02487 tor_localtime_r(const time_t *timep, struct tm *result)
02488 {
02489   struct tm *r;
02490   tor_assert(result);
02491   r = localtime(timep);
02492   if (r)
02493     memcpy(result, r, sizeof(struct tm));
02494   return correct_tm(1, timep, result, r);
02495 }
02496 #endif
02497 
02505 #ifdef HAVE_GMTIME_R
02506 struct tm *
02507 tor_gmtime_r(const time_t *timep, struct tm *result)
02508 {
02509   struct tm *r;
02510   r = gmtime_r(timep, result);
02511   return correct_tm(0, timep, result, r);
02512 }
02513 #elif defined(TIME_FNS_NEED_LOCKS)
02514 struct tm *
02515 tor_gmtime_r(const time_t *timep, struct tm *result)
02516 {
02517   struct tm *r;
02518   static tor_mutex_t *m=NULL;
02519   if (!m) { m=tor_mutex_new(); }
02520   tor_assert(result);
02521   tor_mutex_acquire(m);
02522   r = gmtime(timep);
02523   if (r)
02524     memcpy(result, r, sizeof(struct tm));
02525   tor_mutex_release(m);
02526   return correct_tm(0, timep, result, r);
02527 }
02528 #else
02529 struct tm *
02530 tor_gmtime_r(const time_t *timep, struct tm *result)
02531 {
02532   struct tm *r;
02533   tor_assert(result);
02534   r = gmtime(timep);
02535   if (r)
02536     memcpy(result, r, sizeof(struct tm));
02537   return correct_tm(0, timep, result, r);
02538 }
02539 #endif
02540 
02541 #if defined(USE_WIN32_THREADS)
02542 void
02543 tor_mutex_init(tor_mutex_t *m)
02544 {
02545   InitializeCriticalSection(&m->mutex);
02546 }
02547 void
02548 tor_mutex_uninit(tor_mutex_t *m)
02549 {
02550   DeleteCriticalSection(&m->mutex);
02551 }
02552 void
02553 tor_mutex_acquire(tor_mutex_t *m)
02554 {
02555   tor_assert(m);
02556   EnterCriticalSection(&m->mutex);
02557 }
02558 void
02559 tor_mutex_release(tor_mutex_t *m)
02560 {
02561   LeaveCriticalSection(&m->mutex);
02562 }
02563 unsigned long
02564 tor_get_thread_id(void)
02565 {
02566   return (unsigned long)GetCurrentThreadId();
02567 }
02568 #elif defined(USE_PTHREADS)
02569 
02572 static pthread_mutexattr_t attr_reentrant;
02574 static int threads_initialized = 0;
02577 void
02578 tor_mutex_init(tor_mutex_t *mutex)
02579 {
02580   int err;
02581   if (PREDICT_UNLIKELY(!threads_initialized))
02582     tor_threads_init();
02583   err = pthread_mutex_init(&mutex->mutex, &attr_reentrant);
02584   if (PREDICT_UNLIKELY(err)) {
02585     log_err(LD_GENERAL, "Error %d creating a mutex.", err);
02586     tor_fragile_assert();
02587   }
02588 }
02590 void
02591 tor_mutex_acquire(tor_mutex_t *m)
02592 {
02593   int err;
02594   tor_assert(m);
02595   err = pthread_mutex_lock(&m->mutex);
02596   if (PREDICT_UNLIKELY(err)) {
02597     log_err(LD_GENERAL, "Error %d locking a mutex.", err);
02598     tor_fragile_assert();
02599   }
02600 }
02602 void
02603 tor_mutex_release(tor_mutex_t *m)
02604 {
02605   int err;
02606   tor_assert(m);
02607   err = pthread_mutex_unlock(&m->mutex);
02608   if (PREDICT_UNLIKELY(err)) {
02609     log_err(LD_GENERAL, "Error %d unlocking a mutex.", err);
02610     tor_fragile_assert();
02611   }
02612 }
02616 void
02617 tor_mutex_uninit(tor_mutex_t *m)
02618 {
02619   int err;
02620   tor_assert(m);
02621   err = pthread_mutex_destroy(&m->mutex);
02622   if (PREDICT_UNLIKELY(err)) {
02623     log_err(LD_GENERAL, "Error %d destroying a mutex.", err);
02624     tor_fragile_assert();
02625   }
02626 }
02628 unsigned long
02629 tor_get_thread_id(void)
02630 {
02631   union {
02632     pthread_t thr;
02633     unsigned long id;
02634   } r;
02635   r.thr = pthread_self();
02636   return r.id;
02637 }
02638 #endif
02639 
02640 #ifdef TOR_IS_MULTITHREADED
02641 
02642 tor_mutex_t *
02643 tor_mutex_new(void)
02644 {
02645   tor_mutex_t *m = tor_malloc_zero(sizeof(tor_mutex_t));
02646   tor_mutex_init(m);
02647   return m;
02648 }
02650 void
02651 tor_mutex_free(tor_mutex_t *m)
02652 {
02653   if (!m)
02654     return;
02655   tor_mutex_uninit(m);
02656   tor_free(m);
02657 }
02658 #endif
02659 
02660 /* Conditions. */
02661 #ifdef USE_PTHREADS
02662 #if 0
02663 
02664 struct tor_cond_t {
02665   pthread_cond_t cond;
02666 };
02668 tor_cond_t *
02669 tor_cond_new(void)
02670 {
02671   tor_cond_t *cond = tor_malloc_zero(sizeof(tor_cond_t));
02672   if (pthread_cond_init(&cond->cond, NULL)) {
02673     tor_free(cond);
02674     return NULL;
02675   }
02676   return cond;
02677 }
02679 void
02680 tor_cond_free(tor_cond_t *cond)
02681 {
02682   if (!cond)
02683     return;
02684   if (pthread_cond_destroy(&cond->cond)) {
02685     log_warn(LD_GENERAL,"Error freeing condition: %s", strerror(errno));
02686     return;
02687   }
02688   tor_free(cond);
02689 }
02693 int
02694 tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex)
02695 {
02696   return pthread_cond_wait(&cond->cond, &mutex->mutex) ? -1 : 0;
02697 }
02699 void
02700 tor_cond_signal_one(tor_cond_t *cond)
02701 {
02702   pthread_cond_signal(&cond->cond);
02703 }
02705 void
02706 tor_cond_signal_all(tor_cond_t *cond)
02707 {
02708   pthread_cond_broadcast(&cond->cond);
02709 }
02710 #endif
02711 
02712 void
02713 tor_threads_init(void)
02714 {
02715   if (!threads_initialized) {
02716     pthread_mutexattr_init(&attr_reentrant);
02717     pthread_mutexattr_settype(&attr_reentrant, PTHREAD_MUTEX_RECURSIVE);
02718     threads_initialized = 1;
02719     set_main_thread();
02720   }
02721 }
02722 #elif defined(USE_WIN32_THREADS)
02723 #if 0
02724 static DWORD cond_event_tls_index;
02725 struct tor_cond_t {
02726   CRITICAL_SECTION mutex;
02727   smartlist_t *events;
02728 };
02729 tor_cond_t *
02730 tor_cond_new(void)
02731 {
02732   tor_cond_t *cond = tor_malloc_zero(sizeof(tor_cond_t));
02733   InitializeCriticalSection(&cond->mutex);
02734   cond->events = smartlist_new();
02735   return cond;
02736 }
02737 void
02738 tor_cond_free(tor_cond_t *cond)
02739 {
02740   if (!cond)
02741     return;
02742   DeleteCriticalSection(&cond->mutex);
02743   /* XXXX notify? */
02744   smartlist_free(cond->events);
02745   tor_free(cond);
02746 }
02747 int
02748 tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex)
02749 {
02750   HANDLE event;
02751   int r;
02752   tor_assert(cond);
02753   tor_assert(mutex);
02754   event = TlsGetValue(cond_event_tls_index);
02755   if (!event) {
02756     event = CreateEvent(0, FALSE, FALSE, NULL);
02757     TlsSetValue(cond_event_tls_index, event);
02758   }
02759   EnterCriticalSection(&cond->mutex);
02760 
02761   tor_assert(WaitForSingleObject(event, 0) == WAIT_TIMEOUT);
02762   tor_assert(!smartlist_isin(cond->events, event));
02763   smartlist_add(cond->events, event);
02764 
02765   LeaveCriticalSection(&cond->mutex);
02766 
02767   tor_mutex_release(mutex);
02768   r = WaitForSingleObject(event, INFINITE);
02769   tor_mutex_acquire(mutex);
02770 
02771   switch (r) {
02772     case WAIT_OBJECT_0: /* we got the mutex normally. */
02773       break;
02774     case WAIT_ABANDONED: /* holding thread exited. */
02775     case WAIT_TIMEOUT: /* Should never happen. */
02776       tor_assert(0);
02777       break;
02778     case WAIT_FAILED:
02779       log_warn(LD_GENERAL, "Failed to acquire mutex: %d",(int) GetLastError());
02780   }
02781   return 0;
02782 }
02783 void
02784 tor_cond_signal_one(tor_cond_t *cond)
02785 {
02786   HANDLE event;
02787   tor_assert(cond);
02788 
02789   EnterCriticalSection(&cond->mutex);
02790 
02791   if ((event = smartlist_pop_last(cond->events)))
02792     SetEvent(event);
02793 
02794   LeaveCriticalSection(&cond->mutex);
02795 }
02796 void
02797 tor_cond_signal_all(tor_cond_t *cond)
02798 {
02799   tor_assert(cond);
02800 
02801   EnterCriticalSection(&cond->mutex);
02802   SMARTLIST_FOREACH(cond->events, HANDLE, event, SetEvent(event));
02803   smartlist_clear(cond->events);
02804   LeaveCriticalSection(&cond->mutex);
02805 }
02806 #endif
02807 void
02808 tor_threads_init(void)
02809 {
02810 #if 0
02811   cond_event_tls_index = TlsAlloc();
02812 #endif
02813   set_main_thread();
02814 }
02815 #endif
02816 
02817 #if defined(HAVE_MLOCKALL) && HAVE_DECL_MLOCKALL && defined(RLIMIT_MEMLOCK)
02818 
02822 static int
02823 tor_set_max_memlock(void)
02824 {
02825   /* Future consideration for Windows is probably SetProcessWorkingSetSize
02826    * This is similar to setting the memory rlimit of RLIMIT_MEMLOCK
02827    * http://msdn.microsoft.com/en-us/library/ms686234(VS.85).aspx
02828    */
02829 
02830   struct rlimit limit;
02831 
02832   /* RLIM_INFINITY is -1 on some platforms. */
02833   limit.rlim_cur = RLIM_INFINITY;
02834   limit.rlim_max = RLIM_INFINITY;
02835 
02836   if (setrlimit(RLIMIT_MEMLOCK, &limit) == -1) {
02837     if (errno == EPERM) {
02838       log_warn(LD_GENERAL, "You appear to lack permissions to change memory "
02839                            "limits. Are you root?");
02840     }
02841     log_warn(LD_GENERAL, "Unable to raise RLIMIT_MEMLOCK: %s",
02842              strerror(errno));
02843     return -1;
02844   }
02845 
02846   return 0;
02847 }
02848 #endif
02849 
02855 int
02856 tor_mlockall(void)
02857 {
02858   static int memory_lock_attempted = 0;
02859 
02860   if (memory_lock_attempted) {
02861     return 1;
02862   }
02863 
02864   memory_lock_attempted = 1;
02865 
02866   /*
02867    * Future consideration for Windows may be VirtualLock
02868    * VirtualLock appears to implement mlock() but not mlockall()
02869    *
02870    * http://msdn.microsoft.com/en-us/library/aa366895(VS.85).aspx
02871    */
02872 
02873 #if defined(HAVE_MLOCKALL) && HAVE_DECL_MLOCKALL && defined(RLIMIT_MEMLOCK)
02874   if (tor_set_max_memlock() == 0) {
02875     log_debug(LD_GENERAL, "RLIMIT_MEMLOCK is now set to RLIM_INFINITY.");
02876   }
02877 
02878   if (mlockall(MCL_CURRENT|MCL_FUTURE) == 0) {
02879     log_info(LD_GENERAL, "Insecure OS paging is effectively disabled.");
02880     return 0;
02881   } else {
02882     if (errno == ENOSYS) {
02883       /* Apple - it's 2009! I'm looking at you. Grrr. */
02884       log_notice(LD_GENERAL, "It appears that mlockall() is not available on "
02885                              "your platform.");
02886     } else if (errno == EPERM) {
02887       log_notice(LD_GENERAL, "It appears that you lack the permissions to "
02888                              "lock memory. Are you root?");
02889     }
02890     log_notice(LD_GENERAL, "Unable to lock all current and future memory "
02891                            "pages: %s", strerror(errno));
02892     return -1;
02893   }
02894 #else
02895   log_warn(LD_GENERAL, "Unable to lock memory pages. mlockall() unsupported?");
02896   return -1;
02897 #endif
02898 }
02899 
02901 static unsigned long main_thread_id = -1;
02902 
02905 void
02906 set_main_thread(void)
02907 {
02908   main_thread_id = tor_get_thread_id();
02909 }
02911 int
02912 in_main_thread(void)
02913 {
02914   return main_thread_id == tor_get_thread_id();
02915 }
02916 
02928 #if defined(_WIN32)
02929 int
02930 tor_socket_errno(tor_socket_t sock)
02931 {
02932   int optval, optvallen=sizeof(optval);
02933   int err = WSAGetLastError();
02934   if (err == WSAEWOULDBLOCK && SOCKET_OK(sock)) {
02935     if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval, &optvallen))
02936       return err;
02937     if (optval)
02938       return optval;
02939   }
02940   return err;
02941 }
02942 #endif
02943 
02944 #if defined(_WIN32)
02945 #define E(code, s) { code, (s " [" #code " ]") }
02946 struct { int code; const char *msg; } windows_socket_errors[] = {
02947   E(WSAEINTR, "Interrupted function call"),
02948   E(WSAEACCES, "Permission denied"),
02949   E(WSAEFAULT, "Bad address"),
02950   E(WSAEINVAL, "Invalid argument"),
02951   E(WSAEMFILE, "Too many open files"),
02952   E(WSAEWOULDBLOCK,  "Resource temporarily unavailable"),
02953   E(WSAEINPROGRESS, "Operation now in progress"),
02954   E(WSAEALREADY, "Operation already in progress"),
02955   E(WSAENOTSOCK, "Socket operation on nonsocket"),
02956   E(WSAEDESTADDRREQ, "Destination address required"),
02957   E(WSAEMSGSIZE, "Message too long"),
02958   E(WSAEPROTOTYPE, "Protocol wrong for socket"),
02959   E(WSAENOPROTOOPT, "Bad protocol option"),
02960   E(WSAEPROTONOSUPPORT, "Protocol not supported"),
02961   E(WSAESOCKTNOSUPPORT, "Socket type not supported"),
02962   /* What's the difference between NOTSUPP and NOSUPPORT? :) */
02963   E(WSAEOPNOTSUPP, "Operation not supported"),
02964   E(WSAEPFNOSUPPORT,  "Protocol family not supported"),
02965   E(WSAEAFNOSUPPORT, "Address family not supported by protocol family"),
02966   E(WSAEADDRINUSE, "Address already in use"),
02967   E(WSAEADDRNOTAVAIL, "Cannot assign requested address"),
02968   E(WSAENETDOWN, "Network is down"),
02969   E(WSAENETUNREACH, "Network is unreachable"),
02970   E(WSAENETRESET, "Network dropped connection on reset"),
02971   E(WSAECONNABORTED, "Software caused connection abort"),
02972   E(WSAECONNRESET, "Connection reset by peer"),
02973   E(WSAENOBUFS, "No buffer space available"),
02974   E(WSAEISCONN, "Socket is already connected"),
02975   E(WSAENOTCONN, "Socket is not connected"),
02976   E(WSAESHUTDOWN, "Cannot send after socket shutdown"),
02977   E(WSAETIMEDOUT, "Connection timed out"),
02978   E(WSAECONNREFUSED, "Connection refused"),
02979   E(WSAEHOSTDOWN, "Host is down"),
02980   E(WSAEHOSTUNREACH, "No route to host"),
02981   E(WSAEPROCLIM, "Too many processes"),
02982   /* Yes, some of these start with WSA, not WSAE. No, I don't know why. */
02983   E(WSASYSNOTREADY, "Network subsystem is unavailable"),
02984   E(WSAVERNOTSUPPORTED, "Winsock.dll out of range"),
02985   E(WSANOTINITIALISED, "Successful WSAStartup not yet performed"),
02986   E(WSAEDISCON, "Graceful shutdown now in progress"),
02987 #ifdef WSATYPE_NOT_FOUND
02988   E(WSATYPE_NOT_FOUND, "Class type not found"),
02989 #endif
02990   E(WSAHOST_NOT_FOUND, "Host not found"),
02991   E(WSATRY_AGAIN, "Nonauthoritative host not found"),
02992   E(WSANO_RECOVERY, "This is a nonrecoverable error"),
02993   E(WSANO_DATA, "Valid name, no data record of requested type)"),
02994 
02995   /* There are some more error codes whose numeric values are marked
02996    * <b>OS dependent</b>. They start with WSA_, apparently for the same
02997    * reason that practitioners of some craft traditions deliberately
02998    * introduce imperfections into their baskets and rugs "to allow the
02999    * evil spirits to escape."  If we catch them, then our binaries
03000    * might not report consistent results across versions of Windows.
03001    * Thus, I'm going to let them all fall through.
03002    */
03003   { -1, NULL },
03004 };
03008 const char *
03009 tor_socket_strerror(int e)
03010 {
03011   int i;
03012   for (i=0; windows_socket_errors[i].code >= 0; ++i) {
03013     if (e == windows_socket_errors[i].code)
03014       return windows_socket_errors[i].msg;
03015   }
03016   return strerror(e);
03017 }
03018 #endif
03019 
03023 int
03024 network_init(void)
03025 {
03026 #ifdef _WIN32
03027   /* This silly exercise is necessary before windows will allow
03028    * gethostbyname to work. */
03029   WSADATA WSAData;
03030   int r;
03031   r = WSAStartup(0x101,&WSAData);
03032   if (r) {
03033     log_warn(LD_NET,"Error initializing windows network layer: code was %d",r);
03034     return -1;
03035   }
03036   if (sizeof(SOCKET) != sizeof(tor_socket_t)) {
03037     log_warn(LD_BUG,"The tor_socket_t type does not match SOCKET in size; Tor "
03038              "might not work. (Sizes are %d and %d respectively.)",
03039              (int)sizeof(tor_socket_t), (int)sizeof(SOCKET));
03040   }
03041   /* WSAData.iMaxSockets might show the max sockets we're allowed to use.
03042    * We might use it to complain if we're trying to be a server but have
03043    * too few sockets available. */
03044 #endif
03045   return 0;
03046 }
03047 
03048 #ifdef _WIN32
03049 
03053 char *
03054 format_win32_error(DWORD err)
03055 {
03056   TCHAR *str = NULL;
03057   char *result;
03058   DWORD n;
03059 
03060   /* Somebody once decided that this interface was better than strerror(). */
03061   n = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
03062                  FORMAT_MESSAGE_FROM_SYSTEM |
03063                  FORMAT_MESSAGE_IGNORE_INSERTS,
03064                  NULL, err,
03065                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
03066                  (LPVOID)&str,
03067                  0, NULL);
03068 
03069   if (str && n) {
03070 #ifdef UNICODE
03071     size_t len;
03072     if (n > 128*1024)
03073       len = (128 * 1024) * 2 + 1; /* This shouldn't be possible, but let's
03074                                    * make sure. */
03075     else
03076       len = n * 2 + 1;
03077     result = tor_malloc(len);
03078     wcstombs(result,str,len);
03079     result[len-1] = '\0';
03080 #else
03081     result = tor_strdup(str);
03082 #endif
03083   } else {
03084     result = tor_strdup("<unformattable error>");
03085   }
03086   if (str) {
03087     LocalFree(str); /* LocalFree != free() */
03088   }
03089   return result;
03090 }
03091 #endif
03092