Back to index

tor  0.2.3.19-rc
util.h
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 
00011 #ifndef _TOR_UTIL_H
00012 #define _TOR_UTIL_H
00013 
00014 #include "orconfig.h"
00015 #include "torint.h"
00016 #include "compat.h"
00017 #include "di_ops.h"
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020 #ifdef _WIN32
00021 /* for the correct alias to struct stat */
00022 #include <sys/stat.h>
00023 #endif
00024 
00025 #ifndef O_BINARY
00026 #define O_BINARY 0
00027 #endif
00028 #ifndef O_TEXT
00029 #define O_TEXT 0
00030 #endif
00031 
00032 /* Replace assert() with a variant that sends failures to the log before
00033  * calling assert() normally.
00034  */
00035 #ifdef NDEBUG
00036 /* Nobody should ever want to build with NDEBUG set.  99% of our asserts will
00037  * be outside the critical path anyway, so it's silly to disable bug-checking
00038  * throughout the entire program just because a few asserts are slowing you
00039  * down.  Profile, optimize the critical path, and keep debugging on.
00040  *
00041  * And I'm not just saying that because some of our asserts check
00042  * security-critical properties.
00043  */
00044 #error "Sorry; we don't support building with NDEBUG."
00045 #endif
00046 
00049 #define tor_assert(expr) STMT_BEGIN                                     \
00050     if (PREDICT_UNLIKELY(!(expr))) {                                    \
00051       log_err(LD_BUG, "%s:%d: %s: Assertion %s failed; aborting.",      \
00052           _SHORT_FILE_, __LINE__, __func__, #expr);                     \
00053       fprintf(stderr,"%s:%d %s: Assertion %s failed; aborting.\n",      \
00054               _SHORT_FILE_, __LINE__, __func__, #expr);                 \
00055       abort();                                                          \
00056     } STMT_END
00057 
00058 /* If we're building with dmalloc, we want all of our memory allocation
00059  * functions to take an extra file/line pair of arguments.  If not, not.
00060  * We define DMALLOC_PARAMS to the extra parameters to insert in the
00061  * function prototypes, and DMALLOC_ARGS to the extra arguments to add
00062  * to calls. */
00063 #ifdef USE_DMALLOC
00064 #define DMALLOC_PARAMS , const char *file, const int line
00065 #define DMALLOC_ARGS , _SHORT_FILE_, __LINE__
00066 #else
00067 #define DMALLOC_PARAMS
00068 #define DMALLOC_ARGS
00069 #endif
00070 
00073 // #define tor_fragile_assert() tor_assert(0)
00074 #define tor_fragile_assert()
00075 
00076 /* Memory management */
00077 void *_tor_malloc(size_t size DMALLOC_PARAMS) ATTR_MALLOC;
00078 void *_tor_malloc_zero(size_t size DMALLOC_PARAMS) ATTR_MALLOC;
00079 void *_tor_malloc_roundup(size_t *size DMALLOC_PARAMS) ATTR_MALLOC;
00080 void *_tor_calloc(size_t nmemb, size_t size DMALLOC_PARAMS) ATTR_MALLOC;
00081 void *_tor_realloc(void *ptr, size_t size DMALLOC_PARAMS);
00082 char *_tor_strdup(const char *s DMALLOC_PARAMS) ATTR_MALLOC ATTR_NONNULL((1));
00083 char *_tor_strndup(const char *s, size_t n DMALLOC_PARAMS)
00084   ATTR_MALLOC ATTR_NONNULL((1));
00085 void *_tor_memdup(const void *mem, size_t len DMALLOC_PARAMS)
00086   ATTR_MALLOC ATTR_NONNULL((1));
00087 void _tor_free(void *mem);
00088 #ifdef USE_DMALLOC
00089 extern int dmalloc_free(const char *file, const int line, void *pnt,
00090                         const int func_id);
00091 #define tor_free(p) STMT_BEGIN \
00092     if (PREDICT_LIKELY((p)!=NULL)) {                \
00093       dmalloc_free(_SHORT_FILE_, __LINE__, (p), 0); \
00094       (p)=NULL;                                     \
00095     }                                               \
00096   STMT_END
00097 #else
00098 
00105 #define tor_free(p) STMT_BEGIN                                 \
00106     if (PREDICT_LIKELY((p)!=NULL)) {                           \
00107       free(p);                                                 \
00108       (p)=NULL;                                                \
00109     }                                                          \
00110   STMT_END
00111 #endif
00112 
00113 #define tor_malloc(size)       _tor_malloc(size DMALLOC_ARGS)
00114 #define tor_malloc_zero(size)  _tor_malloc_zero(size DMALLOC_ARGS)
00115 #define tor_calloc(nmemb,size) _tor_calloc(nmemb, size DMALLOC_ARGS)
00116 #define tor_malloc_roundup(szp) _tor_malloc_roundup(szp DMALLOC_ARGS)
00117 #define tor_realloc(ptr, size) _tor_realloc(ptr, size DMALLOC_ARGS)
00118 #define tor_strdup(s)          _tor_strdup(s DMALLOC_ARGS)
00119 #define tor_strndup(s, n)      _tor_strndup(s, n DMALLOC_ARGS)
00120 #define tor_memdup(s, n)       _tor_memdup(s, n DMALLOC_ARGS)
00121 
00122 void tor_log_mallinfo(int severity);
00123 
00125 #if defined(__GNUC__) && __GNUC__ > 3
00126 #define STRUCT_OFFSET(tp, member) __builtin_offsetof(tp, member)
00127 #else
00128  #define STRUCT_OFFSET(tp, member) \
00129    ((off_t) (((char*)&((tp*)0)->member)-(char*)0))
00130 #endif
00131 
00141 #define STRUCT_VAR_P(st, off) ((void*) ( ((char*)(st)) + (off) ) )
00142 
00152 #define SUBTYPE_P(p, subtype, basemember) \
00153   ((void*) ( ((char*)(p)) - STRUCT_OFFSET(subtype, basemember) ))
00154 
00155 /* Logic */
00157 #define bool_eq(a,b) (!(a)==!(b))
00158 
00159 #define bool_neq(a,b) (!(a)!=!(b))
00160 
00161 /* Math functions */
00162 double tor_mathlog(double d) ATTR_CONST;
00163 long tor_lround(double d) ATTR_CONST;
00164 int tor_log2(uint64_t u64) ATTR_CONST;
00165 uint64_t round_to_power_of_2(uint64_t u64);
00166 unsigned round_to_next_multiple_of(unsigned number, unsigned divisor);
00167 uint32_t round_uint32_to_next_multiple_of(uint32_t number, uint32_t divisor);
00168 uint64_t round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor);
00169 int n_bits_set_u8(uint8_t v);
00170 
00171 /* Compute the CEIL of <b>a</b> divided by <b>b</b>, for nonnegative <b>a</b>
00172  * and positive <b>b</b>.  Works on integer types only. Not defined if a+b can
00173  * overflow. */
00174 #define CEIL_DIV(a,b) (((a)+(b)-1)/(b))
00175 
00176 /* String manipulation */
00177 
00179 #define HEX_CHARACTERS "0123456789ABCDEFabcdef"
00180 void tor_strlower(char *s) ATTR_NONNULL((1));
00181 void tor_strupper(char *s) ATTR_NONNULL((1));
00182 int tor_strisprint(const char *s) ATTR_NONNULL((1));
00183 int tor_strisnonupper(const char *s) ATTR_NONNULL((1));
00184 int strcmp_opt(const char *s1, const char *s2);
00185 int strcmpstart(const char *s1, const char *s2) ATTR_NONNULL((1,2));
00186 int strcmp_len(const char *s1, const char *s2, size_t len) ATTR_NONNULL((1,2));
00187 int strcasecmpstart(const char *s1, const char *s2) ATTR_NONNULL((1,2));
00188 int strcmpend(const char *s1, const char *s2) ATTR_NONNULL((1,2));
00189 int strcasecmpend(const char *s1, const char *s2) ATTR_NONNULL((1,2));
00190 int fast_memcmpstart(const void *mem, size_t memlen, const char *prefix);
00191 
00192 void tor_strstrip(char *s, const char *strip) ATTR_NONNULL((1,2));
00193 long tor_parse_long(const char *s, int base, long min,
00194                     long max, int *ok, char **next);
00195 unsigned long tor_parse_ulong(const char *s, int base, unsigned long min,
00196                               unsigned long max, int *ok, char **next);
00197 double tor_parse_double(const char *s, double min, double max, int *ok,
00198                         char **next);
00199 uint64_t tor_parse_uint64(const char *s, int base, uint64_t min,
00200                          uint64_t max, int *ok, char **next);
00201 const char *hex_str(const char *from, size_t fromlen) ATTR_NONNULL((1));
00202 const char *eat_whitespace(const char *s);
00203 const char *eat_whitespace_eos(const char *s, const char *eos);
00204 const char *eat_whitespace_no_nl(const char *s);
00205 const char *eat_whitespace_eos_no_nl(const char *s, const char *eos);
00206 const char *find_whitespace(const char *s);
00207 const char *find_whitespace_eos(const char *s, const char *eos);
00208 const char *find_str_at_start_of_line(const char *haystack,
00209                                       const char *needle);
00210 int string_is_C_identifier(const char *string);
00211 
00212 int tor_mem_is_zero(const char *mem, size_t len);
00213 int tor_digest_is_zero(const char *digest);
00214 int tor_digest256_is_zero(const char *digest);
00215 char *esc_for_log(const char *string) ATTR_MALLOC;
00216 const char *escaped(const char *string);
00217 struct smartlist_t;
00218 void wrap_string(struct smartlist_t *out, const char *string, size_t width,
00219                  const char *prefix0, const char *prefixRest);
00220 int tor_vsscanf(const char *buf, const char *pattern, va_list ap)
00221 #ifdef __GNUC__
00222   __attribute__((format(scanf, 2, 0)))
00223 #endif
00224   ;
00225 int tor_sscanf(const char *buf, const char *pattern, ...)
00226 #ifdef __GNUC__
00227   __attribute__((format(scanf, 2, 3)))
00228 #endif
00229   ;
00230 
00231 void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern, ...)
00232   CHECK_PRINTF(2, 3);
00233 void smartlist_add_vasprintf(struct smartlist_t *sl, const char *pattern,
00234                              va_list args)
00235   CHECK_PRINTF(2, 0);
00236 
00237 int hex_decode_digit(char c);
00238 void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen);
00239 int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen);
00240 
00241 /* Time helpers */
00242 double tv_to_double(const struct timeval *tv);
00243 int64_t tv_to_msec(const struct timeval *tv);
00244 int64_t tv_to_usec(const struct timeval *tv);
00245 long tv_udiff(const struct timeval *start, const struct timeval *end);
00246 long tv_mdiff(const struct timeval *start, const struct timeval *end);
00247 time_t tor_timegm(struct tm *tm);
00248 #define RFC1123_TIME_LEN 29
00249 void format_rfc1123_time(char *buf, time_t t);
00250 int parse_rfc1123_time(const char *buf, time_t *t);
00251 #define ISO_TIME_LEN 19
00252 #define ISO_TIME_USEC_LEN (ISO_TIME_LEN+7)
00253 void format_local_iso_time(char *buf, time_t t);
00254 void format_iso_time(char *buf, time_t t);
00255 void format_iso_time_nospace(char *buf, time_t t);
00256 void format_iso_time_nospace_usec(char *buf, const struct timeval *tv);
00257 int parse_iso_time(const char *buf, time_t *t);
00258 int parse_http_time(const char *buf, struct tm *tm);
00259 int format_time_interval(char *out, size_t out_len, long interval);
00260 
00261 /* Cached time */
00262 #ifdef TIME_IS_FAST
00263 #define approx_time() time(NULL)
00264 #define update_approx_time(t) STMT_NIL
00265 #else
00266 time_t approx_time(void);
00267 void update_approx_time(time_t now);
00268 #endif
00269 
00270 /* Rate-limiter */
00271 
00287 typedef struct ratelim_t {
00288   int rate;
00289   time_t last_allowed;
00290   int n_calls_since_last_time;
00291 } ratelim_t;
00292 
00293 #define RATELIM_INIT(r) { (r), 0, 0 }
00294 
00295 char *rate_limit_log(ratelim_t *lim, time_t now);
00296 
00297 /* File helpers */
00298 ssize_t write_all(tor_socket_t fd, const char *buf, size_t count,int isSocket);
00299 ssize_t read_all(tor_socket_t fd, char *buf, size_t count, int isSocket);
00300 
00302 enum stream_status {
00303   IO_STREAM_OKAY,
00304   IO_STREAM_EAGAIN,
00305   IO_STREAM_TERM,
00306   IO_STREAM_CLOSED
00307 };
00308 
00309 enum stream_status get_string_from_pipe(FILE *stream, char *buf, size_t count);
00310 
00313 typedef enum { FN_ERROR, FN_NOENT, FN_FILE, FN_DIR } file_status_t;
00314 file_status_t file_status(const char *filename);
00315 
00318 typedef unsigned int cpd_check_t;
00319 #define CPD_NONE 0
00320 #define CPD_CREATE 1
00321 #define CPD_CHECK 2
00322 #define CPD_GROUP_OK 4
00323 #define CPD_CHECK_MODE_ONLY 8
00324 int check_private_dir(const char *dirname, cpd_check_t check,
00325                       const char *effective_user);
00326 #define OPEN_FLAGS_REPLACE (O_WRONLY|O_CREAT|O_TRUNC)
00327 #define OPEN_FLAGS_APPEND (O_WRONLY|O_CREAT|O_APPEND)
00328 #define OPEN_FLAGS_DONT_REPLACE (O_CREAT|O_EXCL|O_APPEND|O_WRONLY)
00329 typedef struct open_file_t open_file_t;
00330 int start_writing_to_file(const char *fname, int open_flags, int mode,
00331                           open_file_t **data_out);
00332 FILE *start_writing_to_stdio_file(const char *fname, int open_flags, int mode,
00333                                   open_file_t **data_out);
00334 FILE *fdopen_file(open_file_t *file_data);
00335 int finish_writing_to_file(open_file_t *file_data);
00336 int abort_writing_to_file(open_file_t *file_data);
00337 int write_str_to_file(const char *fname, const char *str, int bin);
00338 int write_bytes_to_file(const char *fname, const char *str, size_t len,
00339                         int bin);
00342 typedef struct sized_chunk_t {
00343   const char *bytes;
00344   size_t len;
00345 } sized_chunk_t;
00346 int write_chunks_to_file(const char *fname, const struct smartlist_t *chunks,
00347                          int bin);
00348 int append_bytes_to_file(const char *fname, const char *str, size_t len,
00349                          int bin);
00350 int write_bytes_to_new_file(const char *fname, const char *str, size_t len,
00351                             int bin);
00352 
00354 #define RFTS_BIN            1
00355 
00356 #define RFTS_IGNORE_MISSING 2
00357 
00358 #ifndef _WIN32
00359 struct stat;
00360 #endif
00361 char *read_file_to_str(const char *filename, int flags, struct stat *stat_out)
00362   ATTR_MALLOC;
00363 const char *parse_config_line_from_str(const char *line,
00364                                        char **key_out, char **value_out);
00365 char *expand_filename(const char *filename);
00366 struct smartlist_t *tor_listdir(const char *dirname);
00367 int path_is_relative(const char *filename);
00368 
00369 /* Process helpers */
00370 void start_daemon(void);
00371 void finish_daemon(const char *desired_cwd);
00372 void write_pidfile(char *filename);
00373 
00374 /* Port forwarding */
00375 void tor_check_port_forwarding(const char *filename,
00376                                int dir_port, int or_port, time_t now);
00377 
00378 typedef struct process_handle_t process_handle_t;
00379 typedef struct process_environment_t process_environment_t;
00380 int tor_spawn_background(const char *const filename, const char **argv,
00381                          process_environment_t *env,
00382                          process_handle_t **process_handle_out);
00383 
00384 #define SPAWN_ERROR_MESSAGE "ERR: Failed to spawn background process - code "
00385 
00386 #ifdef _WIN32
00387 HANDLE load_windows_system_library(const TCHAR *library_name);
00388 #endif
00389 
00390 int environment_variable_names_equal(const char *s1, const char *s2);
00391 
00392 /* DOCDOC process_environment_t */
00393 struct process_environment_t {
00396   char *windows_environment_block;
00399   char **unixoid_environment_block;
00400 };
00401 
00402 process_environment_t *process_environment_make(struct smartlist_t *env_vars);
00403 void process_environment_free(process_environment_t *env);
00404 
00405 struct smartlist_t *get_current_process_environment_variables(void);
00406 
00407 void set_environment_variable_in_smartlist(struct smartlist_t *env_vars,
00408                                            const char *new_var,
00409                                            void (*free_old)(void*),
00410                                            int free_p);
00411 
00412 /* Values of process_handle_t.status. PROCESS_STATUS_NOTRUNNING must be
00413  * 0 because tor_check_port_forwarding depends on this being the initial
00414  * statue of the static instance of process_handle_t */
00415 #define PROCESS_STATUS_NOTRUNNING 0
00416 #define PROCESS_STATUS_RUNNING 1
00417 #define PROCESS_STATUS_ERROR -1
00418 
00419 #ifdef UTIL_PRIVATE
00420 
00422 struct process_handle_t {
00424   int status;
00425 #ifdef _WIN32
00426   HANDLE stdout_pipe;
00427   HANDLE stderr_pipe;
00428   PROCESS_INFORMATION pid;
00429 #else
00430   int stdout_pipe;
00431   int stderr_pipe;
00432   FILE *stdout_handle;
00433   FILE *stderr_handle;
00434   pid_t pid;
00435 #endif // _WIN32
00436 };
00437 #endif
00438 
00439 /* Return values of tor_get_exit_code() */
00440 #define PROCESS_EXIT_RUNNING 1
00441 #define PROCESS_EXIT_EXITED 0
00442 #define PROCESS_EXIT_ERROR -1
00443 int tor_get_exit_code(const process_handle_t *process_handle,
00444                       int block, int *exit_code);
00445 int tor_split_lines(struct smartlist_t *sl, char *buf, int len);
00446 #ifdef _WIN32
00447 ssize_t tor_read_all_handle(HANDLE h, char *buf, size_t count,
00448                             const process_handle_t *process);
00449 #else
00450 ssize_t tor_read_all_handle(FILE *h, char *buf, size_t count,
00451                             const process_handle_t *process,
00452                             int *eof);
00453 #endif
00454 ssize_t tor_read_all_from_process_stdout(
00455     const process_handle_t *process_handle, char *buf, size_t count);
00456 ssize_t tor_read_all_from_process_stderr(
00457     const process_handle_t *process_handle, char *buf, size_t count);
00458 char *tor_join_win_cmdline(const char *argv[]);
00459 
00460 int tor_process_get_pid(process_handle_t *process_handle);
00461 #ifdef _WIN32
00462 HANDLE tor_process_get_stdout_pipe(process_handle_t *process_handle);
00463 #else
00464 FILE *tor_process_get_stdout_pipe(process_handle_t *process_handle);
00465 #endif
00466 
00467 int tor_terminate_process(process_handle_t *process_handle);
00468 void tor_process_handle_destroy(process_handle_t *process_handle,
00469                                 int also_terminate_process);
00470 
00471 #ifdef UTIL_PRIVATE
00472 /* Prototypes for private functions only used by util.c (and unit tests) */
00473 
00474 int format_hex_number_for_helper_exit_status(unsigned int x, char *buf,
00475                                              int max_len);
00476 int format_helper_exit_status(unsigned char child_state,
00477                               int saved_errno, char *hex_errno);
00478 
00479 /* Space for hex values of child state, a slash, saved_errno (with
00480    leading minus) and newline (no null) */
00481 #define HEX_ERRNO_SIZE (sizeof(char) * 2 + 1 + \
00482                         1 + sizeof(int) * 2 + 1)
00483 #endif
00484 
00485 const char *libor_get_digests(void);
00486 
00487 #endif
00488