00001 
00002 
00003 
00004 
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 <stdio.h>
00018 #include <stdlib.h>
00019 
00020 #ifndef O_BINARY
00021 #define O_BINARY 0
00022 #endif
00023 #ifndef O_TEXT
00024 #define O_TEXT 0
00025 #endif
00026 
00027 
00028 
00029 
00030 #ifdef NDEBUG
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 #error "Sorry; we don't support building with NDEBUG."
00040 #endif
00041 
00044 #define tor_assert(expr) STMT_BEGIN                                     \
00045     if (PREDICT_UNLIKELY(!(expr))) {                                    \
00046       log_err(LD_BUG, "%s:%d: %s: Assertion %s failed; aborting.",      \
00047           _SHORT_FILE_, __LINE__, __func__, #expr);                     \
00048       fprintf(stderr,"%s:%d %s: Assertion %s failed; aborting.\n",      \
00049               _SHORT_FILE_, __LINE__, __func__, #expr);                 \
00050       abort();                                                          \
00051     } STMT_END
00052 
00053 
00054 
00055 
00056 
00057 
00058 #ifdef USE_DMALLOC
00059 #define DMALLOC_PARAMS , const char *file, const int line
00060 #define DMALLOC_ARGS , _SHORT_FILE_, __LINE__
00061 #else
00062 #define DMALLOC_PARAMS
00063 #define DMALLOC_ARGS
00064 #endif
00065 
00068 
00069 #define tor_fragile_assert()
00070 
00071 
00072 void *_tor_malloc(size_t size DMALLOC_PARAMS) ATTR_MALLOC;
00073 void *_tor_malloc_zero(size_t size DMALLOC_PARAMS) ATTR_MALLOC;
00074 void *_tor_malloc_roundup(size_t *size DMALLOC_PARAMS) ATTR_MALLOC;
00075 void *_tor_realloc(void *ptr, size_t size DMALLOC_PARAMS);
00076 char *_tor_strdup(const char *s DMALLOC_PARAMS) ATTR_MALLOC ATTR_NONNULL((1));
00077 char *_tor_strndup(const char *s, size_t n DMALLOC_PARAMS)
00078   ATTR_MALLOC ATTR_NONNULL((1));
00079 void *_tor_memdup(const void *mem, size_t len DMALLOC_PARAMS)
00080   ATTR_MALLOC ATTR_NONNULL((1));
00081 void _tor_free(void *mem);
00082 #ifdef USE_DMALLOC
00083 extern int dmalloc_free(const char *file, const int line, void *pnt,
00084                         const int func_id);
00085 #define tor_free(p) STMT_BEGIN \
00086     if (PREDICT_LIKELY((p)!=NULL)) {                \
00087       dmalloc_free(_SHORT_FILE_, __LINE__, (p), 0); \
00088       (p)=NULL;                                     \
00089     }                                               \
00090   STMT_END
00091 #else
00092 
00099 #define tor_free(p) STMT_BEGIN                                 \
00100     if (PREDICT_LIKELY((p)!=NULL)) {                           \
00101       free(p);                                                 \
00102       (p)=NULL;                                                \
00103     }                                                          \
00104   STMT_END
00105 #endif
00106 
00107 #define tor_malloc(size)       _tor_malloc(size DMALLOC_ARGS)
00108 #define tor_malloc_zero(size)  _tor_malloc_zero(size DMALLOC_ARGS)
00109 #define tor_malloc_roundup(szp) _tor_malloc_roundup(szp DMALLOC_ARGS)
00110 #define tor_realloc(ptr, size) _tor_realloc(ptr, size DMALLOC_ARGS)
00111 #define tor_strdup(s)          _tor_strdup(s DMALLOC_ARGS)
00112 #define tor_strndup(s, n)      _tor_strndup(s, n DMALLOC_ARGS)
00113 #define tor_memdup(s, n)       _tor_memdup(s, n DMALLOC_ARGS)
00114 
00115 void tor_log_mallinfo(int severity);
00116 
00118 #if defined(__GNUC__) && __GNUC__ > 3
00119 #define STRUCT_OFFSET(tp, member) __builtin_offsetof(tp, member)
00120 #else
00121  #define STRUCT_OFFSET(tp, member) \
00122    ((off_t) (((char*)&((tp*)0)->member)-(char*)0))
00123 #endif
00124 
00134 #define STRUCT_VAR_P(st, off) ((void*) ( ((char*)(st)) + (off) ) )
00135 
00145 #define SUBTYPE_P(p, subtype, basemember) \
00146   ((void*) ( ((char*)(p)) - STRUCT_OFFSET(subtype, basemember) ))
00147 
00148 
00150 #define bool_eq(a,b) (!(a)==!(b))
00151 
00152 #define bool_neq(a,b) (!(a)!=!(b))
00153 
00154 
00155 double tor_mathlog(double d) ATTR_CONST;
00156 long tor_lround(double d) ATTR_CONST;
00157 int tor_log2(uint64_t u64) ATTR_CONST;
00158 uint64_t round_to_power_of_2(uint64_t u64);
00159 unsigned round_to_next_multiple_of(unsigned number, unsigned divisor);
00160 uint32_t round_uint32_to_next_multiple_of(uint32_t number, uint32_t divisor);
00161 uint64_t round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor);
00162 
00163 
00164 
00166 #define HEX_CHARACTERS "0123456789ABCDEFabcdef"
00167 void tor_strlower(char *s) ATTR_NONNULL((1));
00168 void tor_strupper(char *s) ATTR_NONNULL((1));
00169 int tor_strisprint(const char *s) ATTR_PURE ATTR_NONNULL((1));
00170 int tor_strisnonupper(const char *s) ATTR_PURE ATTR_NONNULL((1));
00171 int strcmpstart(const char *s1, const char *s2) ATTR_PURE ATTR_NONNULL((1,2));
00172 int strcmp_len(const char *s1, const char *s2, size_t len)
00173   ATTR_PURE ATTR_NONNULL((1,2));
00174 int strcasecmpstart(const char *s1, const char *s2)
00175   ATTR_PURE ATTR_NONNULL((1,2));
00176 int strcmpend(const char *s1, const char *s2) ATTR_PURE ATTR_NONNULL((1,2));
00177 int strcasecmpend(const char *s1, const char *s2)
00178   ATTR_PURE ATTR_NONNULL((1,2));
00179 int memcmpstart(const void *mem, size_t memlen,
00180                 const char *prefix) ATTR_PURE;
00181 
00182 void tor_strstrip(char *s, const char *strip) ATTR_NONNULL((1,2));
00183 long tor_parse_long(const char *s, int base, long min,
00184                     long max, int *ok, char **next);
00185 unsigned long tor_parse_ulong(const char *s, int base, unsigned long min,
00186                               unsigned long max, int *ok, char **next);
00187 double tor_parse_double(const char *s, double min, double max, int *ok,
00188                         char **next);
00189 uint64_t tor_parse_uint64(const char *s, int base, uint64_t min,
00190                          uint64_t max, int *ok, char **next);
00191 const char *hex_str(const char *from, size_t fromlen) ATTR_NONNULL((1));
00192 const char *eat_whitespace(const char *s) ATTR_PURE;
00193 const char *eat_whitespace_eos(const char *s, const char *eos) ATTR_PURE;
00194 const char *eat_whitespace_no_nl(const char *s) ATTR_PURE;
00195 const char *eat_whitespace_eos_no_nl(const char *s, const char *eos) ATTR_PURE;
00196 const char *find_whitespace(const char *s) ATTR_PURE;
00197 const char *find_whitespace_eos(const char *s, const char *eos) ATTR_PURE;
00198 const char *find_str_at_start_of_line(const char *haystack, const char *needle)
00199   ATTR_PURE;
00200 int tor_mem_is_zero(const char *mem, size_t len) ATTR_PURE;
00201 int tor_digest_is_zero(const char *digest) ATTR_PURE;
00202 int tor_digest256_is_zero(const char *digest) ATTR_PURE;
00203 char *esc_for_log(const char *string) ATTR_MALLOC;
00204 const char *escaped(const char *string);
00205 struct smartlist_t;
00206 void wrap_string(struct smartlist_t *out, const char *string, size_t width,
00207                  const char *prefix0, const char *prefixRest);
00208 int tor_vsscanf(const char *buf, const char *pattern, va_list ap);
00209 int tor_sscanf(const char *buf, const char *pattern, ...)
00210 #ifdef __GNUC__
00211   __attribute__((format(scanf, 2, 3)))
00212 #endif
00213   ;
00214 
00215 int hex_decode_digit(char c);
00216 void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen);
00217 int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen);
00218 
00219 
00220 double tv_to_double(const struct timeval *tv);
00221 int64_t tv_to_msec(const struct timeval *tv);
00222 int64_t tv_to_usec(const struct timeval *tv);
00223 long tv_udiff(const struct timeval *start, const struct timeval *end);
00224 long tv_mdiff(const struct timeval *start, const struct timeval *end);
00225 time_t tor_timegm(struct tm *tm);
00226 #define RFC1123_TIME_LEN 29
00227 void format_rfc1123_time(char *buf, time_t t);
00228 int parse_rfc1123_time(const char *buf, time_t *t);
00229 #define ISO_TIME_LEN 19
00230 void format_local_iso_time(char *buf, time_t t);
00231 void format_iso_time(char *buf, time_t t);
00232 int parse_iso_time(const char *buf, time_t *t);
00233 int parse_http_time(const char *buf, struct tm *tm);
00234 int format_time_interval(char *out, size_t out_len, long interval);
00235 
00236 
00237 #ifdef TIME_IS_FAST
00238 #define approx_time() time(NULL)
00239 #define update_approx_time(t) STMT_NIL
00240 #else
00241 time_t approx_time(void);
00242 void update_approx_time(time_t now);
00243 #endif
00244 
00245 
00246 void ftime_set_maximum_sloppiness(int seconds);
00247 void ftime_set_estimated_skew(int seconds);
00248 
00249 
00250 int ftime_maybe_after(time_t now, time_t when);
00251 int ftime_maybe_before(time_t now, time_t when);
00252 int ftime_definitely_after(time_t now, time_t when);
00253 int ftime_definitely_before(time_t now, time_t when);
00254 
00255 
00256 ssize_t write_all(int fd, const char *buf, size_t count, int isSocket);
00257 ssize_t read_all(int fd, char *buf, size_t count, int isSocket);
00258 
00261 typedef enum { FN_ERROR, FN_NOENT, FN_FILE, FN_DIR } file_status_t;
00262 file_status_t file_status(const char *filename);
00263 
00266 typedef enum { CPD_NONE, CPD_CREATE, CPD_CHECK } cpd_check_t;
00267 int check_private_dir(const char *dirname, cpd_check_t check);
00268 #define OPEN_FLAGS_REPLACE (O_WRONLY|O_CREAT|O_TRUNC)
00269 #define OPEN_FLAGS_APPEND (O_WRONLY|O_CREAT|O_APPEND)
00270 typedef struct open_file_t open_file_t;
00271 int start_writing_to_file(const char *fname, int open_flags, int mode,
00272                           open_file_t **data_out);
00273 FILE *start_writing_to_stdio_file(const char *fname, int open_flags, int mode,
00274                                   open_file_t **data_out);
00275 FILE *fdopen_file(open_file_t *file_data);
00276 int finish_writing_to_file(open_file_t *file_data);
00277 int abort_writing_to_file(open_file_t *file_data);
00278 int write_str_to_file(const char *fname, const char *str, int bin);
00279 int write_bytes_to_file(const char *fname, const char *str, size_t len,
00280                         int bin);
00283 typedef struct sized_chunk_t {
00284   const char *bytes;
00285   size_t len;
00286 } sized_chunk_t;
00287 int write_chunks_to_file(const char *fname, const struct smartlist_t *chunks,
00288                          int bin);
00289 int append_bytes_to_file(const char *fname, const char *str, size_t len,
00290                          int bin);
00291 
00293 #define RFTS_BIN            1
00294 
00295 #define RFTS_IGNORE_MISSING 2
00296 
00297 struct stat;
00298 char *read_file_to_str(const char *filename, int flags, struct stat *stat_out)
00299   ATTR_MALLOC;
00300 const char *parse_config_line_from_str(const char *line,
00301                                        char **key_out, char **value_out);
00302 char *expand_filename(const char *filename);
00303 struct smartlist_t *tor_listdir(const char *dirname);
00304 int path_is_relative(const char *filename) ATTR_PURE;
00305 
00306 
00307 void start_daemon(void);
00308 void finish_daemon(const char *desired_cwd);
00309 void write_pidfile(char *filename);
00310 
00311 const char *libor_get_digests(void);
00312 
00313 #endif
00314