Back to index

tor  0.2.3.19-rc
Classes | Defines | Typedefs | Enumerations | Functions
util.h File Reference

Headers for util.c. More...

#include "orconfig.h"
#include "torint.h"
#include "compat.h"
#include "di_ops.h"
#include <stdio.h>
#include <stdlib.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  ratelim_t
 A ratelim_t remembers how often an event is occurring, and how often it's allowed to occur. More...
struct  sized_chunk_t
 An ad-hoc type to hold a string of characters and a count; used by write_chunks_to_file. More...
struct  process_environment_t

Defines

#define O_BINARY   0
#define O_TEXT   0
#define tor_assert(expr)
 Like assert(3), but send assertion failures to the log as well as to stderr.
#define DMALLOC_PARAMS
#define DMALLOC_ARGS
#define tor_fragile_assert()
 Define this if you want Tor to crash when any problem comes up, so you can get a coredump and track things down.
#define tor_free(p)
 Release memory allocated by tor_malloc, tor_realloc, tor_strdup, etc.
#define tor_malloc(size)   _tor_malloc(size DMALLOC_ARGS)
#define tor_malloc_zero(size)   _tor_malloc_zero(size DMALLOC_ARGS)
#define tor_calloc(nmemb, size)   _tor_calloc(nmemb, size DMALLOC_ARGS)
#define tor_malloc_roundup(szp)   _tor_malloc_roundup(szp DMALLOC_ARGS)
#define tor_realloc(ptr, size)   _tor_realloc(ptr, size DMALLOC_ARGS)
#define tor_strdup(s)   _tor_strdup(s DMALLOC_ARGS)
#define tor_strndup(s, n)   _tor_strndup(s, n DMALLOC_ARGS)
#define tor_memdup(s, n)   _tor_memdup(s, n DMALLOC_ARGS)
#define STRUCT_OFFSET(tp, member)   ((off_t) (((char*)&((tp*)0)->member)-(char*)0))
 Return the offset of member within the type tp, in bytes.
#define STRUCT_VAR_P(st, off)   ((void*) ( ((char*)(st)) + (off) ) )
 Macro: yield a pointer to the field at position off within the structure st.
#define SUBTYPE_P(p, subtype, basemember)   ((void*) ( ((char*)(p)) - STRUCT_OFFSET(subtype, basemember) ))
 Macro: yield a pointer to an enclosing structure given a pointer to a substructure at offset off.
#define bool_eq(a, b)   (!(a)==!(b))
 Macro: true if two values have the same boolean value.
#define bool_neq(a, b)   (!(a)!=!(b))
 Macro: true if two values have different boolean values.
#define CEIL_DIV(a, b)   (((a)+(b)-1)/(b))
#define HEX_CHARACTERS   "0123456789ABCDEFabcdef"
 Allowable characters in a hexadecimal string.
#define RFC1123_TIME_LEN   29
#define ISO_TIME_LEN   19
#define ISO_TIME_USEC_LEN   (ISO_TIME_LEN+7)
#define RATELIM_INIT(r)   { (r), 0, 0 }
#define CPD_NONE   0
#define CPD_CREATE   1
#define CPD_CHECK   2
#define CPD_GROUP_OK   4
#define CPD_CHECK_MODE_ONLY   8
#define OPEN_FLAGS_REPLACE   (O_WRONLY|O_CREAT|O_TRUNC)
#define OPEN_FLAGS_APPEND   (O_WRONLY|O_CREAT|O_APPEND)
#define OPEN_FLAGS_DONT_REPLACE   (O_CREAT|O_EXCL|O_APPEND|O_WRONLY)
#define RFTS_BIN   1
 Flag for read_file_to_str: open the file in binary mode.
#define RFTS_IGNORE_MISSING   2
 Flag for read_file_to_str: it's okay if the file doesn't exist.
#define SPAWN_ERROR_MESSAGE   "ERR: Failed to spawn background process - code "
#define PROCESS_STATUS_NOTRUNNING   0
#define PROCESS_STATUS_RUNNING   1
#define PROCESS_STATUS_ERROR   -1
#define PROCESS_EXIT_RUNNING   1
#define PROCESS_EXIT_EXITED   0
#define PROCESS_EXIT_ERROR   -1

Typedefs

typedef struct ratelim_t ratelim_t
 A ratelim_t remembers how often an event is occurring, and how often it's allowed to occur.
typedef unsigned int cpd_check_t
 Possible behaviors for check_private_dir() on encountering a nonexistent directory; see that function's documentation for details.
typedef struct open_file_t
typedef struct sized_chunk_t sized_chunk_t
 An ad-hoc type to hold a string of characters and a count; used by write_chunks_to_file.
typedef struct process_handle_t
typedef struct process_environment_t

Enumerations

enum  stream_status { IO_STREAM_OKAY, IO_STREAM_EAGAIN, IO_STREAM_TERM, IO_STREAM_CLOSED }
 Status of an I/O stream. More...
enum  file_status_t { FN_ERROR, FN_NOENT, FN_FILE, FN_DIR }
 Return values from file_status(); see that function's documentation for details. More...

Functions

void * _tor_malloc (size_t size DMALLOC_PARAMS) ATTR_MALLOC
 Allocate a chunk of size bytes of memory, and return a pointer to result.
void * _tor_malloc_zero (size_t size DMALLOC_PARAMS) ATTR_MALLOC
 Allocate a chunk of size bytes of memory, fill the memory with zero bytes, and return a pointer to the result.
void * _tor_malloc_roundup (size_t *size DMALLOC_PARAMS) ATTR_MALLOC
void * _tor_calloc (size_t nmemb, size_t size DMALLOC_PARAMS) ATTR_MALLOC
 Allocate a chunk of nmemb*size bytes of memory, fill the memory with zero bytes, and return a pointer to the result.
void * _tor_realloc (void *ptr, size_t size DMALLOC_PARAMS)
 Change the size of the memory block pointed to by ptr to size bytes long; return the new memory block.
char * _tor_strdup (const char *s DMALLOC_PARAMS) ATTR_MALLOC ATTR_NONNULL((1))
 Return a newly allocated copy of the NUL-terminated string s.
char * _tor_strndup (const char *s, size_t n DMALLOC_PARAMS) ATTR_MALLOC ATTR_NONNULL((1))
 Allocate and return a new string containing the first n characters of s.
void * _tor_memdup (const void *mem, size_t len DMALLOC_PARAMS) ATTR_MALLOC ATTR_NONNULL((1))
 Allocate a chunk of len bytes, with the same contents as the len bytes starting at mem.
void _tor_free (void *mem)
 Helper for places that need to take a function pointer to the right spelling of "free()".
void tor_log_mallinfo (int severity)
 Call the platform malloc info function, and dump the results to the log at level severity.
double tor_mathlog (double d) ATTR_CONST
 Returns the natural logarithm of d base 2.
long tor_lround (double d) ATTR_CONST
 Return the long integer closest to d.
int tor_log2 (uint64_t u64) ATTR_CONST
 Returns floor(log2(u64)).
uint64_t round_to_power_of_2 (uint64_t u64)
 Return the power of 2 closest to u64.
unsigned round_to_next_multiple_of (unsigned number, unsigned divisor)
 Return the lowest x such that x is at least number, and x modulo divisor == 0.
uint32_t round_uint32_to_next_multiple_of (uint32_t number, uint32_t divisor)
 Return the lowest x such that x is at least number, and x modulo divisor == 0.
uint64_t round_uint64_to_next_multiple_of (uint64_t number, uint64_t divisor)
 Return the lowest x such that x is at least number, and x modulo divisor == 0.
int n_bits_set_u8 (uint8_t v)
 Return the number of bits set in v.
void tor_strlower (char *s) ATTR_NONNULL((1))
 Convert all alphabetic characters in the nul-terminated string s to lowercase.
void tor_strupper (char *s) ATTR_NONNULL((1))
 Convert all alphabetic characters in the nul-terminated string s to lowercase.
int tor_strisprint (const char *s) ATTR_NONNULL((1))
 Return 1 if every character in s is printable, else return 0.
int tor_strisnonupper (const char *s) ATTR_NONNULL((1))
 Return 1 if no character in s is uppercase, else return 0.
int strcmp_opt (const char *s1, const char *s2)
 As strcmp, except that either string may be NULL.
int strcmpstart (const char *s1, const char *s2) ATTR_NONNULL((1
int int strcmp_len (const char *s1, const char *s2, size_t len) ATTR_NONNULL((1
int int int strcasecmpstart (const char *s1, const char *s2) ATTR_NONNULL((1
int int int int strcmpend (const char *s1, const char *s2) ATTR_NONNULL((1
int int int int int strcasecmpend (const char *s1, const char *s2) ATTR_NONNULL((1
int int int int int int fast_memcmpstart (const void *mem, size_t memlen, const char *prefix)
 Compare the value of the string prefix with the start of the memlen-byte memory chunk at mem.
void tor_strstrip (char *s, const char *strip) ATTR_NONNULL((1
void long tor_parse_long (const char *s, int base, long min, long max, int *ok, char **next)
 Extract a long from the start of s, in the given numeric base.
unsigned long tor_parse_ulong (const char *s, int base, unsigned long min, unsigned long max, int *ok, char **next)
 As tor_parse_long(), but return an unsigned long.
double tor_parse_double (const char *s, double min, double max, int *ok, char **next)
 As tor_parse_long(), but return a double.
uint64_t tor_parse_uint64 (const char *s, int base, uint64_t min, uint64_t max, int *ok, char **next)
 As tor_parse_long, but return a uint64_t.
const char * hex_str (const char *from, size_t fromlen) ATTR_NONNULL((1))
 Return a pointer to a NUL-terminated hexadecimal string encoding the first fromlen bytes of from.
const char * eat_whitespace (const char *s)
 Return a pointer to the first char of s that is not whitespace and not a comment, or to the terminating NUL if no such character exists.
const char * eat_whitespace_eos (const char *s, const char *eos)
 Return a pointer to the first char of s that is not whitespace and not a comment, or to the terminating NUL if no such character exists.
const char * eat_whitespace_no_nl (const char *s)
 Return a pointer to the first char of s that is not a space or a tab or a \r, or to the terminating NUL if no such character exists.
const char * eat_whitespace_eos_no_nl (const char *s, const char *eos)
 As eat_whitespace_no_nl, but stop at eos whether we have found a non-whitespace character or not.
const char * find_whitespace (const char *s)
 Return a pointer to the first char of s that is whitespace or #, or to the terminating NUL if no such character exists.
const char * find_whitespace_eos (const char *s, const char *eos)
 As find_whitespace, but stop at eos whether we have found a whitespace or not.
const char * find_str_at_start_of_line (const char *haystack, const char *needle)
 Return the first occurrence of needle in haystack that occurs at the start of a line (that is, at the beginning of haystack or immediately after a newline).
int string_is_C_identifier (const char *string)
 Returns true if string could be a C identifier.
int tor_mem_is_zero (const char *mem, size_t len)
 Return true iff the 'len' bytes at 'mem' are all zero.
int tor_digest_is_zero (const char *digest)
 Return true iff the DIGEST_LEN bytes in digest are all zero.
int tor_digest256_is_zero (const char *digest)
 Return true iff the DIGEST256_LEN bytes in digest are all zero.
char * esc_for_log (const char *string) ATTR_MALLOC
 Allocate and return a new string representing the contents of s, surrounded by quotes and using standard C escapes.
const char * escaped (const char *string)
 Allocate and return a new string representing the contents of s, surrounded by quotes and using standard C escapes.
void wrap_string (struct smartlist_t *out, const char *string, size_t width, const char *prefix0, const char *prefixRest)
 Rudimentary string wrapping code: given a un-wrapped string (no newlines!), break the string into newline-terminated lines of no more than width characters long (not counting newline) and insert them into out in order.
int tor_vsscanf (const char *buf, const char *pattern, va_list ap)
 Locale-independent, minimal, no-surprises scanf variant, accepting only a restricted pattern format.
int tor_sscanf (const char *buf, const char *pattern,...)
 Minimal sscanf replacement: parse buf according to pattern and store the results in the corresponding argument fields.
void smartlist_add_asprintf (struct smartlist_t *sl, const char *pattern,...) CHECK_PRINTF(2
void void smartlist_add_vasprintf (struct smartlist_t *sl, const char *pattern, va_list args) CHECK_PRINTF(2
void void int hex_decode_digit (char c)
 Helper: given a hex digit, return its value, or -1 if it isn't hex.
void base16_encode (char *dest, size_t destlen, const char *src, size_t srclen)
 Encode the srclen bytes at src in a NUL-terminated, uppercase hexadecimal string; store it in the destlen-byte buffer dest.
int base16_decode (char *dest, size_t destlen, const char *src, size_t srclen)
 Given a hexadecimal string of srclen bytes in src, decode it and store the result in the destlen-byte buffer at dest.
double tv_to_double (const struct timeval *tv)
 Converts struct timeval to a double value.
int64_t tv_to_msec (const struct timeval *tv)
 Converts timeval to milliseconds.
int64_t tv_to_usec (const struct timeval *tv)
 Converts timeval to microseconds.
long tv_udiff (const struct timeval *start, const struct timeval *end)
 Return the number of microseconds elapsed between *start and *end.
long tv_mdiff (const struct timeval *start, const struct timeval *end)
 Return the number of milliseconds elapsed between *start and *end.
time_t tor_timegm (struct tm *tm)
 Return a time_t given a struct tm.
void format_rfc1123_time (char *buf, time_t t)
 Set buf to the RFC1123 encoding of the GMT value of t.
int parse_rfc1123_time (const char *buf, time_t *t)
 Parse the RFC1123 encoding of some time (in GMT) from buf, and store the result in *t.
void format_local_iso_time (char *buf, time_t t)
 Set buf to the ISO8601 encoding of the local value of t.
void format_iso_time (char *buf, time_t t)
 Set buf to the ISO8601 encoding of the GMT value of t.
void format_iso_time_nospace (char *buf, time_t t)
 As format_iso_time, but use the yyyy-mm-ddThh:mm:ss format to avoid embedding an internal space.
void format_iso_time_nospace_usec (char *buf, const struct timeval *tv)
 As format_iso_time_nospace, but include microseconds in decimal fixed-point format.
int parse_iso_time (const char *buf, time_t *t)
 Given an ISO-formatted UTC time value (after the epoch) in cp, parse it and store its value in *t.
int parse_http_time (const char *buf, struct tm *tm)
 Given a date in one of the three formats allowed by HTTP (ugh), parse it into tm.
int format_time_interval (char *out, size_t out_len, long interval)
 Given an interval in seconds, try to write it to the out_len-byte buffer in out in a human-readable form.
time_t approx_time (void)
 Return a cached estimate of the current time from when update_approx_time() was last called.
void update_approx_time (time_t now)
 Update the cached estimate of the current time.
char * rate_limit_log (ratelim_t *lim, time_t now)
 If the rate-limiter lim is ready at now, return a newly allocated string indicating how many messages were suppressed, suitable to append to a log message.
ssize_t write_all (tor_socket_t fd, const char *buf, size_t count, int isSocket)
 Write count bytes from buf to fd.
ssize_t read_all (tor_socket_t fd, char *buf, size_t count, int isSocket)
 Read from fd to buf, until we get count bytes or reach the end of the file.
enum stream_status get_string_from_pipe (FILE *stream, char *buf, size_t count)
 Reads from stream and stores input in buf_out making sure it's below count bytes.
file_status_t file_status (const char *filename)
 Return FN_ERROR if filename can't be read, FN_NOENT if it doesn't exist, FN_FILE if it is a regular file, or FN_DIR if it's a directory.
int check_private_dir (const char *dirname, cpd_check_t check, const char *effective_user)
 Check whether dirname exists and is private.
int start_writing_to_file (const char *fname, int open_flags, int mode, open_file_t **data_out)
 Try to start writing to the file in fname, passing the flags open_flags to the open() syscall, creating the file (if needed) with access value mode.
FILE * start_writing_to_stdio_file (const char *fname, int open_flags, int mode, open_file_t **data_out)
 Combines start_writing_to_file with fdopen_file(): arguments are as for start_writing_to_file, but.
FILE * fdopen_file (open_file_t *file_data)
 Given file_data from start_writing_to_file(), return a stdio FILE* that can be used to write to the same file.
int finish_writing_to_file (open_file_t *file_data)
 Finish writing to file_data: close the file handle, free memory as needed, and if using a temporary file, replace the original file with the temporary file.
int abort_writing_to_file (open_file_t *file_data)
 Finish writing to file_data: close the file handle, free memory as needed, and if using a temporary file, delete it.
int write_str_to_file (const char *fname, const char *str, int bin)
 Create a file named fname with the contents str.
int write_bytes_to_file (const char *fname, const char *str, size_t len, int bin)
 As write_str_to_file, but does not assume a NUL-terminated string.
int write_chunks_to_file (const char *fname, const struct smartlist_t *chunks, int bin)
int append_bytes_to_file (const char *fname, const char *str, size_t len, int bin)
 As write_bytes_to_file, but if the file already exists, append the bytes to the end of the file instead of overwriting it.
int write_bytes_to_new_file (const char *fname, const char *str, size_t len, int bin)
 Like write_str_to_file(), but also return -1 if there was a file already residing in fname.
char * read_file_to_str (const char *filename, int flags, struct stat *stat_out) ATTR_MALLOC
 Read the contents of filename into a newly allocated string; return the string on success or NULL on failure.
const char * parse_config_line_from_str (const char *line, char **key_out, char **value_out)
 Given a string containing part of a configuration file or similar format, advance past comments and whitespace and try to parse a single line.
char * expand_filename (const char *filename)
 Expand any homedir prefix on filename; return a newly allocated string.
struct smartlist_ttor_listdir (const char *dirname)
 Return a new list containing the filenames in the directory dirname.
int path_is_relative (const char *filename)
 Return true iff filename is a relative path.
void start_daemon (void)
 Start putting the process into daemon mode: fork and drop all resources except standard fds.
void finish_daemon (const char *desired_cwd)
 Finish putting the process into daemon mode: drop standard fds, and tell the parent process to exit.
void write_pidfile (char *filename)
 Write the current process ID, followed by NL, into filename.
void tor_check_port_forwarding (const char *filename, int dir_port, int or_port, time_t now)
int tor_spawn_background (const char *const filename, const char **argv, process_environment_t *env, process_handle_t **process_handle_out)
 Start a program in the background.
int environment_variable_names_equal (const char *s1, const char *s2)
 Return non-zero iff getenv would consider s1 and s2 to have the same name as strings in a process's environment.
process_environment_tprocess_environment_make (struct smartlist_t *env_vars)
 Make a process_environment_t containing the environment variables specified in env_vars (as C strings of the form "NAME=VALUE").
void process_environment_free (process_environment_t *env)
 Free env (assuming it was produced by process_environment_make).
struct smartlist_tget_current_process_environment_variables (void)
 Return a newly allocated smartlist containing every variable in this process's environment, as a NUL-terminated string of the form "NAME=VALUE".
void set_environment_variable_in_smartlist (struct smartlist_t *env_vars, const char *new_var, void(*free_old)(void *), int free_p)
 For each string s in env_vars such that environment_variable_names_equal(s, new_var), remove it; if free_p is non-zero, call free_old(s).
int tor_get_exit_code (const process_handle_t *process_handle, int block, int *exit_code)
 Get the exit code of a process specified by process_handle and store it in exit_code, if set to a non-NULL value.
int tor_split_lines (struct smartlist_t *sl, char *buf, int len)
 Split buf into lines, and add to smartlist.
ssize_t tor_read_all_handle (FILE *h, char *buf, size_t count, const process_handle_t *process, int *eof)
 Read from a handle h into buf, up to count bytes.
ssize_t tor_read_all_from_process_stdout (const process_handle_t *process_handle, char *buf, size_t count)
 Read from stdout of a process until the process exits.
ssize_t tor_read_all_from_process_stderr (const process_handle_t *process_handle, char *buf, size_t count)
 Read from stdout of a process until the process exits.
char * tor_join_win_cmdline (const char *argv[])
 Format a command line for use on Windows, which takes the command as a string rather than string array.
int tor_process_get_pid (process_handle_t *process_handle)
 Return the Process ID of process_handle.
FILE * tor_process_get_stdout_pipe (process_handle_t *process_handle)
int tor_terminate_process (process_handle_t *process_handle)
 Terminate the process of process_handle.
void tor_process_handle_destroy (process_handle_t *process_handle, int also_terminate_process)
 Destroy all resources allocated by the process handle in process_handle.
const char * libor_get_digests (void)
 Return a string describing the digest of the source files in src/common/.

Detailed Description

Headers for util.c.

Definition in file util.h.


Class Documentation

struct ratelim_t

A ratelim_t remembers how often an event is occurring, and how often it's allowed to occur.

Typical usage is something like:

    if (possibly_very_frequent_event()) {
      const int INTERVAL = 300;
      static ratelim_t warning_limit = RATELIM_INIT(INTERVAL);
      char *m;
      if ((m = rate_limit_log(&warning_limit, approx_time()))) {
        log_warn(LD_GENERAL, "The event occurred!%s", m);
        tor_free(m);
      }
    }
   

Definition at line 287 of file util.h.

Class Members
time_t last_allowed
int n_calls_since_last_time
int rate
struct sized_chunk_t

An ad-hoc type to hold a string of characters and a count; used by write_chunks_to_file.

Definition at line 342 of file util.h.

Class Members
const char * bytes
size_t len
struct process_environment_t

Definition at line 393 of file util.h.

Class Members
char ** unixoid_environment_block A pointer to a NULL-terminated array of pointers to NUL-terminated strings of the form "NAME=VALUE".
char * windows_environment_block A pointer to a sorted empty-string-terminated sequence of NUL-terminated strings of the form "NAME=VALUE".

Define Documentation

#define bool_eq (   a,
 
)    (!(a)==!(b))

Macro: true if two values have the same boolean value.

Definition at line 157 of file util.h.

#define bool_neq (   a,
 
)    (!(a)!=!(b))

Macro: true if two values have different boolean values.

Definition at line 159 of file util.h.

#define CEIL_DIV (   a,
 
)    (((a)+(b)-1)/(b))

Definition at line 174 of file util.h.

#define CPD_CHECK   2

Definition at line 321 of file util.h.

#define CPD_CHECK_MODE_ONLY   8

Definition at line 323 of file util.h.

#define CPD_CREATE   1

Definition at line 320 of file util.h.

#define CPD_GROUP_OK   4

Definition at line 322 of file util.h.

#define CPD_NONE   0

Definition at line 319 of file util.h.

#define DMALLOC_ARGS

Definition at line 68 of file util.h.

#define DMALLOC_PARAMS

Definition at line 67 of file util.h.

#define HEX_CHARACTERS   "0123456789ABCDEFabcdef"

Allowable characters in a hexadecimal string.

Definition at line 179 of file util.h.

#define ISO_TIME_LEN   19

Definition at line 251 of file util.h.

#define ISO_TIME_USEC_LEN   (ISO_TIME_LEN+7)

Definition at line 252 of file util.h.

#define O_BINARY   0

Definition at line 26 of file util.h.

#define O_TEXT   0

Definition at line 29 of file util.h.

#define OPEN_FLAGS_APPEND   (O_WRONLY|O_CREAT|O_APPEND)

Definition at line 327 of file util.h.

#define OPEN_FLAGS_DONT_REPLACE   (O_CREAT|O_EXCL|O_APPEND|O_WRONLY)

Definition at line 328 of file util.h.

#define OPEN_FLAGS_REPLACE   (O_WRONLY|O_CREAT|O_TRUNC)

Definition at line 326 of file util.h.

#define PROCESS_EXIT_ERROR   -1

Definition at line 442 of file util.h.

#define PROCESS_EXIT_EXITED   0

Definition at line 441 of file util.h.

#define PROCESS_EXIT_RUNNING   1

Definition at line 440 of file util.h.

#define PROCESS_STATUS_ERROR   -1

Definition at line 417 of file util.h.

#define PROCESS_STATUS_NOTRUNNING   0

Definition at line 415 of file util.h.

#define PROCESS_STATUS_RUNNING   1

Definition at line 416 of file util.h.

#define RATELIM_INIT (   r)    { (r), 0, 0 }

Definition at line 293 of file util.h.

#define RFC1123_TIME_LEN   29

Definition at line 248 of file util.h.

#define RFTS_BIN   1

Flag for read_file_to_str: open the file in binary mode.

Definition at line 354 of file util.h.

#define RFTS_IGNORE_MISSING   2

Flag for read_file_to_str: it's okay if the file doesn't exist.

Definition at line 356 of file util.h.

#define SPAWN_ERROR_MESSAGE   "ERR: Failed to spawn background process - code "

Definition at line 384 of file util.h.

#define STRUCT_OFFSET (   tp,
  member 
)    ((off_t) (((char*)&((tp*)0)->member)-(char*)0))

Return the offset of member within the type tp, in bytes.

Definition at line 128 of file util.h.

#define STRUCT_VAR_P (   st,
  off 
)    ((void*) ( ((char*)(st)) + (off) ) )

Macro: yield a pointer to the field at position off within the structure st.

Example:

   struct a { int foo; int bar; } x;
   off_t bar_offset = STRUCT_OFFSET(struct a, bar);
   int *bar_p = STRUCT_VAR_P(&x, bar_offset);
   *bar_p = 3;
 

Definition at line 141 of file util.h.

#define SUBTYPE_P (   p,
  subtype,
  basemember 
)    ((void*) ( ((char*)(p)) - STRUCT_OFFSET(subtype, basemember) ))

Macro: yield a pointer to an enclosing structure given a pointer to a substructure at offset off.

Example:

   struct base { ... };
   struct subtype { int x; struct base b; } x;
   struct base *bp = &x.base;
   struct *sp = SUBTYPE_P(bp, struct subtype, b);
 

Definition at line 152 of file util.h.

#define tor_assert (   expr)
Value:
STMT_BEGIN                                     \
    if (PREDICT_UNLIKELY(!(expr))) {                                    \
      log_err(LD_BUG, "%s:%d: %s: Assertion %s failed; aborting.",      \
          _SHORT_FILE_, __LINE__, __func__, #expr);                     \
      fprintf(stderr,"%s:%d %s: Assertion %s failed; aborting.\n",      \
              _SHORT_FILE_, __LINE__, __func__, #expr);                 \
      abort();                                                          \
    } STMT_END

Like assert(3), but send assertion failures to the log as well as to stderr.

Definition at line 49 of file util.h.

#define tor_calloc (   nmemb,
  size 
)    _tor_calloc(nmemb, size DMALLOC_ARGS)

Definition at line 115 of file util.h.

#define tor_fragile_assert ( )

Define this if you want Tor to crash when any problem comes up, so you can get a coredump and track things down.

Definition at line 74 of file util.h.

#define tor_free (   p)
Value:
STMT_BEGIN                                 \
    if (PREDICT_LIKELY((p)!=NULL)) {                           \
      free(p);                                                 \
      (p)=NULL;                                                \
    }                                                          \
  STMT_END

Release memory allocated by tor_malloc, tor_realloc, tor_strdup, etc.

Unlike the free() function, tor_free() will still work on NULL pointers, and it sets the pointer value to NULL after freeing it.

This is a macro. If you need a function pointer to release memory from tor_malloc(), use _tor_free().

Definition at line 105 of file util.h.

#define tor_malloc (   size)    _tor_malloc(size DMALLOC_ARGS)

Definition at line 113 of file util.h.

#define tor_malloc_roundup (   szp)    _tor_malloc_roundup(szp DMALLOC_ARGS)

Definition at line 116 of file util.h.

#define tor_malloc_zero (   size)    _tor_malloc_zero(size DMALLOC_ARGS)

Definition at line 114 of file util.h.

#define tor_memdup (   s,
 
)    _tor_memdup(s, n DMALLOC_ARGS)

Definition at line 120 of file util.h.

#define tor_realloc (   ptr,
  size 
)    _tor_realloc(ptr, size DMALLOC_ARGS)

Definition at line 117 of file util.h.

#define tor_strdup (   s)    _tor_strdup(s DMALLOC_ARGS)

Definition at line 118 of file util.h.

#define tor_strndup (   s,
 
)    _tor_strndup(s, n DMALLOC_ARGS)

Definition at line 119 of file util.h.


Typedef Documentation

typedef unsigned int cpd_check_t

Possible behaviors for check_private_dir() on encountering a nonexistent directory; see that function's documentation for details.

Definition at line 318 of file util.h.

typedef struct open_file_t

Definition at line 329 of file util.h.

typedef struct process_environment_t

Definition at line 379 of file util.h.

typedef struct process_handle_t

Definition at line 378 of file util.h.

typedef struct ratelim_t ratelim_t

A ratelim_t remembers how often an event is occurring, and how often it's allowed to occur.

Typical usage is something like:

    if (possibly_very_frequent_event()) {
      const int INTERVAL = 300;
      static ratelim_t warning_limit = RATELIM_INIT(INTERVAL);
      char *m;
      if ((m = rate_limit_log(&warning_limit, approx_time()))) {
        log_warn(LD_GENERAL, "The event occurred!%s", m);
        tor_free(m);
      }
    }
   
typedef struct sized_chunk_t sized_chunk_t

An ad-hoc type to hold a string of characters and a count; used by write_chunks_to_file.


Enumeration Type Documentation

Return values from file_status(); see that function's documentation for details.

Enumerator:
FN_ERROR 
FN_NOENT 
FN_FILE 
FN_DIR 

Definition at line 313 of file util.h.

Status of an I/O stream.

Enumerator:
IO_STREAM_OKAY 
IO_STREAM_EAGAIN 
IO_STREAM_TERM 
IO_STREAM_CLOSED 

Definition at line 302 of file util.h.


Function Documentation

void* _tor_calloc ( size_t  nmemb,
size_t size  DMALLOC_PARAMS 
)

Allocate a chunk of nmemb*size bytes of memory, fill the memory with zero bytes, and return a pointer to the result.

Log and terminate the process on error. (Same as calloc(nmemb,size), but never returns NULL.)

XXXX This implementation probably asserts in cases where it could work, because it only tries dividing SIZE_MAX by size (according to the calloc(3) man page, the size of an element of the nmemb-element array to be allocated), not by nmemb (which could in theory be smaller than size). Don't do that then.

Definition at line 187 of file util.c.

{
  /* You may ask yourself, "wouldn't it be smart to use calloc instead of
   * malloc+memset?  Perhaps libc's calloc knows some nifty optimization trick
   * we don't!"  Indeed it does, but its optimizations are only a big win when
   * we're allocating something very big (it knows if it just got the memory
   * from the OS in a pre-zeroed state).  We don't want to use tor_malloc_zero
   * for big stuff, so we don't bother with calloc. */
  void *result;
  size_t max_nmemb = (size == 0) ? SIZE_MAX : SIZE_MAX/size;

  tor_assert(nmemb < max_nmemb);

  result = _tor_malloc_zero((nmemb * size) DMALLOC_FN_ARGS);
  return result;
}

Here is the call graph for this function:

void _tor_free ( void *  mem)

Helper for places that need to take a function pointer to the right spelling of "free()".

Definition at line 288 of file util.c.

{
  tor_free(mem);
}

Here is the caller graph for this function:

void* _tor_malloc ( size_t size  DMALLOC_PARAMS)

Allocate a chunk of size bytes of memory, and return a pointer to result.

On error, log and terminate the process. (Same as malloc(size), but never returns NULL.)

file and line are used if dmalloc is enabled, and ignored otherwise.

Definition at line 128 of file util.c.

{
  void *result;

  tor_assert(size < SIZE_T_CEILING);

#ifndef MALLOC_ZERO_WORKS
  /* Some libc mallocs don't work when size==0. Override them. */
  if (size==0) {
    size=1;
  }
#endif

#ifdef USE_DMALLOC
  result = dmalloc_malloc(file, line, size, DMALLOC_FUNC_MALLOC, 0, 0);
#else
  result = malloc(size);
#endif

  if (PREDICT_UNLIKELY(result == NULL)) {
    log_err(LD_MM,"Out of memory on malloc(). Dying.");
    /* If these functions die within a worker process, they won't call
     * spawn_exit, but that's ok, since the parent will run out of memory soon
     * anyway. */
    exit(1);
  }
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void* _tor_malloc_roundup ( size_t *size  DMALLOC_PARAMS)
void* _tor_malloc_zero ( size_t size  DMALLOC_PARAMS)

Allocate a chunk of size bytes of memory, fill the memory with zero bytes, and return a pointer to the result.

Log and terminate the process on error. (Same as calloc(size,1), but never returns NULL.)

Definition at line 162 of file util.c.

{
  /* You may ask yourself, "wouldn't it be smart to use calloc instead of
   * malloc+memset?  Perhaps libc's calloc knows some nifty optimization trick
   * we don't!"  Indeed it does, but its optimizations are only a big win when
   * we're allocating something very big (it knows if it just got the memory
   * from the OS in a pre-zeroed state).  We don't want to use tor_malloc_zero
   * for big stuff, so we don't bother with calloc. */
  void *result = _tor_malloc(size DMALLOC_FN_ARGS);
  memset(result, 0, size);
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void* _tor_memdup ( const void *  mem,
size_t len  DMALLOC_PARAMS 
)

Allocate a chunk of len bytes, with the same contents as the len bytes starting at mem.

Definition at line 275 of file util.c.

{
  char *dup;
  tor_assert(len < SIZE_T_CEILING);
  tor_assert(mem);
  dup = _tor_malloc(len DMALLOC_FN_ARGS);
  memcpy(dup, mem, len);
  return dup;
}

Here is the call graph for this function:

void* _tor_realloc ( void *  ptr,
size_t size  DMALLOC_PARAMS 
)

Change the size of the memory block pointed to by ptr to size bytes long; return the new memory block.

On error, log and terminate. (Like realloc(ptr,size), but never returns NULL.)

Definition at line 209 of file util.c.

{
  void *result;

  tor_assert(size < SIZE_T_CEILING);

#ifdef USE_DMALLOC
  result = dmalloc_realloc(file, line, ptr, size, DMALLOC_FUNC_REALLOC, 0);
#else
  result = realloc(ptr, size);
#endif

  if (PREDICT_UNLIKELY(result == NULL)) {
    log_err(LD_MM,"Out of memory on realloc(). Dying.");
    exit(1);
  }
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* _tor_strdup ( const char *s  DMALLOC_PARAMS)

Return a newly allocated copy of the NUL-terminated string s.

On error, log and terminate. (Like strdup(s), but never returns NULL.)

Definition at line 233 of file util.c.

{
  char *dup;
  tor_assert(s);

#ifdef USE_DMALLOC
  dup = dmalloc_strdup(file, line, s, 0);
#else
  dup = strdup(s);
#endif
  if (PREDICT_UNLIKELY(dup == NULL)) {
    log_err(LD_MM,"Out of memory on strdup(). Dying.");
    exit(1);
  }
  return dup;
}
char* _tor_strndup ( const char *  s,
size_t n  DMALLOC_PARAMS 
)

Allocate and return a new string containing the first n characters of s.

If s is longer than n characters, only the first n are copied. The result is always NUL-terminated. (Like strndup(s,n), but never returns NULL.)

Definition at line 257 of file util.c.

{
  char *dup;
  tor_assert(s);
  tor_assert(n < SIZE_T_CEILING);
  dup = _tor_malloc((n+1) DMALLOC_FN_ARGS);
  /* Performance note: Ordinarily we prefer strlcpy to strncpy.  But
   * this function gets called a whole lot, and platform strncpy is
   * much faster than strlcpy when strlen(s) is much longer than n.
   */
  strncpy(dup, s, n);
  dup[n]='\0';
  return dup;
}

Here is the call graph for this function:

int abort_writing_to_file ( open_file_t file_data)

Finish writing to file_data: close the file handle, free memory as needed, and if using a temporary file, delete it.

Definition at line 2170 of file util.c.

{
  return finish_writing_to_file_impl(file_data, 1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int append_bytes_to_file ( const char *  fname,
const char *  str,
size_t  len,
int  bin 
)

As write_bytes_to_file, but if the file already exists, append the bytes to the end of the file instead of overwriting it.

Definition at line 2243 of file util.c.

{
  return write_bytes_to_file_impl(fname, str, len,
                                  OPEN_FLAGS_APPEND|(bin?O_BINARY:O_TEXT));
}

Here is the call graph for this function:

Here is the caller graph for this function:

time_t approx_time ( void  )

Return a cached estimate of the current time from when update_approx_time() was last called.

This is a hack to avoid calling time(NULL) on critical paths: please do not even think of calling it anywhere else.

Definition at line 1671 of file util.c.

{
  return cached_approx_time;
}

Here is the caller graph for this function:

int base16_decode ( char *  dest,
size_t  destlen,
const char *  src,
size_t  srclen 
)

Given a hexadecimal string of srclen bytes in src, decode it and store the result in the destlen-byte buffer at dest.

Return 0 on success, -1 on failure.

Definition at line 1051 of file util.c.

{
  const char *end;

  int v1,v2;
  if ((srclen % 2) != 0)
    return -1;
  if (destlen < srclen/2 || destlen > SIZE_T_CEILING)
    return -1;
  end = src+srclen;
  while (src<end) {
    v1 = _hex_decode_digit(*src);
    v2 = _hex_decode_digit(*(src+1));
    if (v1<0||v2<0)
      return -1;
    *(uint8_t*)dest = (v1<<4)|v2;
    ++dest;
    src+=2;
  }
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void base16_encode ( char *  dest,
size_t  destlen,
const char *  src,
size_t  srclen 
)

Encode the srclen bytes at src in a NUL-terminated, uppercase hexadecimal string; store it in the destlen-byte buffer dest.

Definition at line 996 of file util.c.

{
  const char *end;
  char *cp;

  tor_assert(destlen >= srclen*2+1);
  tor_assert(destlen < SIZE_T_CEILING);

  cp = dest;
  end = src+srclen;
  while (src<end) {
    *cp++ = "0123456789ABCDEF"[ (*(const uint8_t*)src) >> 4 ];
    *cp++ = "0123456789ABCDEF"[ (*(const uint8_t*)src) & 0xf ];
    ++src;
  }
  *cp = '\0';
}
int check_private_dir ( const char *  dirname,
cpd_check_t  check,
const char *  effective_user 
)

Check whether dirname exists and is private.

If yes return 0. If it does not exist, and check&CPD_CREATE is set, try to create it and return 0 on success. If it does not exist, and check&CPD_CHECK, and we think we can create it, return 0. Else return -1. If CPD_GROUP_OK is set, then it's okay if the directory is group-readable, but in all cases we create the directory mode 0700. If CPD_CHECK_MODE_ONLY is set, then we don't alter the directory permissions if they are too permissive: we just return -1. When effective_user is not NULL, check permissions against the given user and its primary group.

Definition at line 1847 of file util.c.

{
  int r;
  struct stat st;
  char *f;
#ifndef _WIN32
  int mask;
  struct passwd *pw = NULL;
  uid_t running_uid;
  gid_t running_gid;
#else
  (void)effective_user;
#endif

  tor_assert(dirname);
  f = tor_strdup(dirname);
  clean_name_for_stat(f);
  r = stat(f, &st);
  tor_free(f);
  if (r) {
    if (errno != ENOENT) {
      log_warn(LD_FS, "Directory %s cannot be read: %s", dirname,
               strerror(errno));
      return -1;
    }
    if (check & CPD_CREATE) {
      log_info(LD_GENERAL, "Creating directory %s", dirname);
#if defined (_WIN32) && !defined (WINCE)
      r = mkdir(dirname);
#else
      r = mkdir(dirname, 0700);
#endif
      if (r) {
        log_warn(LD_FS, "Error creating directory %s: %s", dirname,
            strerror(errno));
        return -1;
      }
    } else if (!(check & CPD_CHECK)) {
      log_warn(LD_FS, "Directory %s does not exist.", dirname);
      return -1;
    }
    /* XXXX In the case where check==CPD_CHECK, we should look at the
     * parent directory a little harder. */
    return 0;
  }
  if (!(st.st_mode & S_IFDIR)) {
    log_warn(LD_FS, "%s is not a directory", dirname);
    return -1;
  }
#ifndef _WIN32
  if (effective_user) {
    /* Look up the user and group information.
     * If we have a problem, bail out. */
    pw = getpwnam(effective_user);
    if (pw == NULL) {
      log_warn(LD_CONFIG, "Error setting configured user: %s not found",
               effective_user);
      return -1;
    }
    running_uid = pw->pw_uid;
    running_gid = pw->pw_gid;
  } else {
    running_uid = getuid();
    running_gid = getgid();
  }

  if (st.st_uid != running_uid) {
    struct passwd *pw = NULL;
    char *process_ownername = NULL;

    pw = getpwuid(running_uid);
    process_ownername = pw ? tor_strdup(pw->pw_name) : tor_strdup("<unknown>");

    pw = getpwuid(st.st_uid);

    log_warn(LD_FS, "%s is not owned by this user (%s, %d) but by "
        "%s (%d). Perhaps you are running Tor as the wrong user?",
                         dirname, process_ownername, (int)running_uid,
                         pw ? pw->pw_name : "<unknown>", (int)st.st_uid);

    tor_free(process_ownername);
    return -1;
  }
  if ((check & CPD_GROUP_OK) && st.st_gid != running_gid) {
    struct group *gr;
    char *process_groupname = NULL;
    gr = getgrgid(running_gid);
    process_groupname = gr ? tor_strdup(gr->gr_name) : tor_strdup("<unknown>");
    gr = getgrgid(st.st_gid);

    log_warn(LD_FS, "%s is not owned by this group (%s, %d) but by group "
             "%s (%d).  Are you running Tor as the wrong user?",
             dirname, process_groupname, (int)running_gid,
             gr ?  gr->gr_name : "<unknown>", (int)st.st_gid);

    tor_free(process_groupname);
    return -1;
  }
  if (check & CPD_GROUP_OK) {
    mask = 0027;
  } else {
    mask = 0077;
  }
  if (st.st_mode & mask) {
    unsigned new_mode;
    if (check & CPD_CHECK_MODE_ONLY) {
      log_warn(LD_FS, "Permissions on directory %s are too permissive.",
               dirname);
      return -1;
    }
    log_warn(LD_FS, "Fixing permissions on directory %s", dirname);
    new_mode = st.st_mode;
    new_mode |= 0700; /* Owner should have rwx */
    new_mode &= ~mask; /* Clear the other bits that we didn't want set...*/
    if (chmod(dirname, new_mode)) {
      log_warn(LD_FS, "Could not chmod directory %s: %s", dirname,
          strerror(errno));
      return -1;
    } else {
      return 0;
    }
  }
#endif
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* eat_whitespace ( const char *  s)

Return a pointer to the first char of s that is not whitespace and not a comment, or to the terminating NUL if no such character exists.

Definition at line 662 of file util.c.

{
  tor_assert(s);

  while (1) {
    switch (*s) {
    case '\0':
    default:
      return s;
    case ' ':
    case '\t':
    case '\n':
    case '\r':
      ++s;
      break;
    case '#':
      ++s;
      while (*s && *s != '\n')
        ++s;
    }
  }
}

Here is the caller graph for this function:

const char* eat_whitespace_eos ( const char *  s,
const char *  eos 
)

Return a pointer to the first char of s that is not whitespace and not a comment, or to the terminating NUL if no such character exists.

Definition at line 689 of file util.c.

{
  tor_assert(s);
  tor_assert(eos && s <= eos);

  while (s < eos) {
    switch (*s) {
    case '\0':
    default:
      return s;
    case ' ':
    case '\t':
    case '\n':
    case '\r':
      ++s;
      break;
    case '#':
      ++s;
      while (s < eos && *s && *s != '\n')
        ++s;
    }
  }
  return s;
}

Here is the caller graph for this function:

const char* eat_whitespace_eos_no_nl ( const char *  s,
const char *  eos 
)

As eat_whitespace_no_nl, but stop at eos whether we have found a non-whitespace character or not.

Definition at line 727 of file util.c.

{
  while (s < eos && (*s == ' ' || *s == '\t' || *s == '\r'))
    ++s;
  return s;
}

Here is the caller graph for this function:

const char* eat_whitespace_no_nl ( const char *  s)

Return a pointer to the first char of s that is not a space or a tab or a \r, or to the terminating NUL if no such character exists.

Definition at line 717 of file util.c.

{
  while (*s == ' ' || *s == '\t' || *s == '\r')
    ++s;
  return s;
}

Here is the caller graph for this function:

int environment_variable_names_equal ( const char *  s1,
const char *  s2 
)

Return non-zero iff getenv would consider s1 and s2 to have the same name as strings in a process's environment.

Definition at line 3906 of file util.c.

{
  size_t s1_name_len = str_num_before(s1, '=');
  size_t s2_name_len = str_num_before(s2, '=');

  return (s1_name_len == s2_name_len &&
          tor_memeq(s1, s2, s1_name_len));
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* esc_for_log ( const char *  s)

Allocate and return a new string representing the contents of s, surrounded by quotes and using standard C escapes.

Generally, we use this for logging values that come in over the network to keep them from tricking users, and for sending certain values to the controller.

We trust values from the resolver, OS, configuration file, and command line to not be maliciously ill-formed. We validate incoming routerdescs and SOCKS requests and addresses from BEGIN cells as they're parsed; afterwards, we trust them as non-malicious.

Definition at line 1086 of file util.c.

{
  const char *cp;
  char *result, *outp;
  size_t len = 3;
  if (!s) {
    return tor_strdup("(null)");
  }

  for (cp = s; *cp; ++cp) {
    switch (*cp) {
      case '\\':
      case '\"':
      case '\'':
      case '\r':
      case '\n':
      case '\t':
        len += 2;
        break;
      default:
        if (TOR_ISPRINT(*cp) && ((uint8_t)*cp)<127)
          ++len;
        else
          len += 4;
        break;
    }
  }

  result = outp = tor_malloc(len);
  *outp++ = '\"';
  for (cp = s; *cp; ++cp) {
    switch (*cp) {
      case '\\':
      case '\"':
      case '\'':
        *outp++ = '\\';
        *outp++ = *cp;
        break;
      case '\n':
        *outp++ = '\\';
        *outp++ = 'n';
        break;
      case '\t':
        *outp++ = '\\';
        *outp++ = 't';
        break;
      case '\r':
        *outp++ = '\\';
        *outp++ = 'r';
        break;
      default:
        if (TOR_ISPRINT(*cp) && ((uint8_t)*cp)<127) {
          *outp++ = *cp;
        } else {
          tor_snprintf(outp, 5, "\\%03o", (int)(uint8_t) *cp);
          outp += 4;
        }
        break;
    }
  }

  *outp++ = '\"';
  *outp++ = 0;

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* escaped ( const char *  s)

Allocate and return a new string representing the contents of s, surrounded by quotes and using standard C escapes.

THIS FUNCTION IS NOT REENTRANT. Don't call it from outside the main thread. Also, each call invalidates the last-returned value, so don't try log_warn(LD_GENERAL, "%s %s", escaped(a), escaped(b));

Definition at line 1161 of file util.c.

{
  static char *_escaped_val = NULL;
  tor_free(_escaped_val);

  if (s)
    _escaped_val = esc_for_log(s);
  else
    _escaped_val = NULL;

  return _escaped_val;
}

Here is the call graph for this function:

char* expand_filename ( const char *  filename)

Expand any homedir prefix on filename; return a newly allocated string.

Definition at line 2616 of file util.c.

{
  tor_assert(filename);
#ifdef _WIN32
  return tor_strdup(filename);
#else
  if (*filename == '~') {
    char *home, *result=NULL;
    const char *rest;

    if (filename[1] == '/' || filename[1] == '\0') {
      home = getenv("HOME");
      if (!home) {
        log_warn(LD_CONFIG, "Couldn't find $HOME environment variable while "
                 "expanding \"%s\"; defaulting to \"\".", filename);
        home = tor_strdup("");
      } else {
        home = tor_strdup(home);
      }
      rest = strlen(filename)>=2?(filename+2):"";
    } else {
#ifdef HAVE_PWD_H
      char *username, *slash;
      slash = strchr(filename, '/');
      if (slash)
        username = tor_strndup(filename+1,slash-filename-1);
      else
        username = tor_strdup(filename+1);
      if (!(home = get_user_homedir(username))) {
        log_warn(LD_CONFIG,"Couldn't get homedir for \"%s\"",username);
        tor_free(username);
        return NULL;
      }
      tor_free(username);
      rest = slash ? (slash+1) : "";
#else
      log_warn(LD_CONFIG, "Couldn't expend homedir on system without pwd.h");
      return tor_strdup(filename);
#endif
    }
    tor_assert(home);
    /* Remove trailing slash. */
    if (strlen(home)>1 && !strcmpend(home,PATH_SEPARATOR)) {
      home[strlen(home)-1] = '\0';
    }
    tor_asprintf(&result,"%s"PATH_SEPARATOR"%s",home,rest);
    tor_free(home);
    return result;
  } else {
    return tor_strdup(filename);
  }
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

int int int int int int fast_memcmpstart ( const void *  mem,
size_t  memlen,
const char *  prefix 
)

Compare the value of the string prefix with the start of the memlen-byte memory chunk at mem.

Return as for strcmp.

[As fast_memcmp(mem, prefix, strlen(prefix)) but returns -1 if memlen is less than strlen(prefix).]

Definition at line 649 of file util.c.

{
  size_t plen = strlen(prefix);
  if (memlen < plen)
    return -1;
  return fast_memcmp(mem, prefix, plen);
}

Here is the caller graph for this function:

FILE* fdopen_file ( open_file_t file_data)

Given file_data from start_writing_to_file(), return a stdio FILE* that can be used to write to the same file.

The caller should not mix stdio calls with non-stdio calls.

Definition at line 2086 of file util.c.

{
  tor_assert(file_data);
  if (file_data->stdio_file)
    return file_data->stdio_file;
  tor_assert(file_data->fd >= 0);
  if (!(file_data->stdio_file = fdopen(file_data->fd,
                                       file_data->binary?"ab":"a"))) {
    log_warn(LD_FS, "Couldn't fdopen \"%s\" [%d]: %s", file_data->filename,
             file_data->fd, strerror(errno));
  }
  return file_data->stdio_file;
}

Here is the caller graph for this function:

file_status_t file_status ( const char *  fname)

Return FN_ERROR if filename can't be read, FN_NOENT if it doesn't exist, FN_FILE if it is a regular file, or FN_DIR if it's a directory.

On FN_ERROR, sets errno.

Definition at line 1812 of file util.c.

{
  struct stat st;
  char *f;
  int r;
  f = tor_strdup(fname);
  clean_name_for_stat(f);
  r = stat(f, &st);
  tor_free(f);
  if (r) {
    if (errno == ENOENT) {
      return FN_NOENT;
    }
    return FN_ERROR;
  }
  if (st.st_mode & S_IFDIR)
    return FN_DIR;
  else if (st.st_mode & S_IFREG)
    return FN_FILE;
  else
    return FN_ERROR;
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* find_str_at_start_of_line ( const char *  haystack,
const char *  needle 
)

Return the first occurrence of needle in haystack that occurs at the start of a line (that is, at the beginning of haystack or immediately after a newline).

Return NULL if no such string is found.

Definition at line 785 of file util.c.

{
  size_t needle_len = strlen(needle);

  do {
    if (!strncmp(haystack, needle, needle_len))
      return haystack;

    haystack = strchr(haystack, '\n');
    if (!haystack)
      return NULL;
    else
      ++haystack;
  } while (*haystack);

  return NULL;
}

Here is the caller graph for this function:

const char* find_whitespace ( const char *  s)

Return a pointer to the first char of s that is whitespace or #, or to the terminating NUL if no such character exists.

Definition at line 738 of file util.c.

{
  /* tor_assert(s); */
  while (1) {
    switch (*s)
    {
    case '\0':
    case '#':
    case ' ':
    case '\r':
    case '\n':
    case '\t':
      return s;
    default:
      ++s;
    }
  }
}

Here is the caller graph for this function:

const char* find_whitespace_eos ( const char *  s,
const char *  eos 
)

As find_whitespace, but stop at eos whether we have found a whitespace or not.

Definition at line 760 of file util.c.

{
  /* tor_assert(s); */
  while (s < eos) {
    switch (*s)
    {
    case '\0':
    case '#':
    case ' ':
    case '\r':
    case '\n':
    case '\t':
      return s;
    default:
      ++s;
    }
  }
  return s;
}

Here is the caller graph for this function:

void finish_daemon ( const char *  desired_cwd)

Finish putting the process into daemon mode: drop standard fds, and tell the parent process to exit.

(Note: it's safe to call this more than once: calls after the first are ignored. Calls start_daemon first if it hasn't been called already.)

Definition at line 3006 of file util.c.

{
  int nullfd;
  char c = '.';
  if (finish_daemon_called)
    return;
  if (!start_daemon_called)
    start_daemon();
  finish_daemon_called = 1;

  if (!desired_cwd)
    desired_cwd = "/";
   /* Don't hold the wrong FS mounted */
  if (chdir(desired_cwd) < 0) {
    log_err(LD_GENERAL,"chdir to \"%s\" failed. Exiting.",desired_cwd);
    exit(1);
  }

  nullfd = tor_open_cloexec("/dev/null", O_RDWR, 0);
  if (nullfd < 0) {
    log_err(LD_GENERAL,"/dev/null can't be opened. Exiting.");
    exit(1);
  }
  /* close fds linking to invoking terminal, but
   * close usual incoming fds, but redirect them somewhere
   * useful so the fds don't get reallocated elsewhere.
   */
  if (dup2(nullfd,0) < 0 ||
      dup2(nullfd,1) < 0 ||
      dup2(nullfd,2) < 0) {
    log_err(LD_GENERAL,"dup2 failed. Exiting.");
    exit(1);
  }
  if (nullfd > 2)
    close(nullfd);
  /* signal success */
  if (write(daemon_filedes[1], &c, sizeof(char)) != sizeof(char)) {
    log_err(LD_GENERAL,"write failed. Exiting.");
  }
  close(daemon_filedes[1]);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int finish_writing_to_file ( open_file_t file_data)

Finish writing to file_data: close the file handle, free memory as needed, and if using a temporary file, replace the original file with the temporary file.

Definition at line 2162 of file util.c.

{
  return finish_writing_to_file_impl(file_data, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void format_iso_time ( char *  buf,
time_t  t 
)

Set buf to the ISO8601 encoding of the GMT value of t.

The buffer must be at least ISO_TIME_LEN+1 bytes long.

Definition at line 1482 of file util.c.

{
  struct tm tm;
  strftime(buf, ISO_TIME_LEN+1, "%Y-%m-%d %H:%M:%S", tor_gmtime_r(&t, &tm));
}

Here is the call graph for this function:

void format_iso_time_nospace ( char *  buf,
time_t  t 
)

As format_iso_time, but use the yyyy-mm-ddThh:mm:ss format to avoid embedding an internal space.

Definition at line 1491 of file util.c.

{
  format_iso_time(buf, t);
  buf[10] = 'T';
}

Here is the call graph for this function:

Here is the caller graph for this function:

void format_iso_time_nospace_usec ( char *  buf,
const struct timeval tv 
)

As format_iso_time_nospace, but include microseconds in decimal fixed-point format.

Requires that buf be at least ISO_TIME_USEC_LEN+1 bytes long.

Definition at line 1501 of file util.c.

{
  tor_assert(tv);
  format_iso_time_nospace(buf, tv->tv_sec);
  tor_snprintf(buf+ISO_TIME_LEN, 8, ".%06d", (int)tv->tv_usec);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void format_local_iso_time ( char *  buf,
time_t  t 
)

Set buf to the ISO8601 encoding of the local value of t.

The buffer must be at least ISO_TIME_LEN+1 bytes long.

(ISO8601 format is 2006-10-29 10:57:20)

Definition at line 1472 of file util.c.

{
  struct tm tm;
  strftime(buf, ISO_TIME_LEN+1, "%Y-%m-%d %H:%M:%S", tor_localtime_r(&t, &tm));
}

Here is the call graph for this function:

Here is the caller graph for this function:

void format_rfc1123_time ( char *  buf,
time_t  t 
)

Set buf to the RFC1123 encoding of the GMT value of t.

The buffer must be at least RFC1123_TIME_LEN+1 bytes long.

(RFC1123 format is Fri, 29 Sep 2006 15:54:20 GMT)

Definition at line 1385 of file util.c.

{
  struct tm tm;

  tor_gmtime_r(&t, &tm);

  strftime(buf, RFC1123_TIME_LEN+1, "___, %d ___ %Y %H:%M:%S GMT", &tm);
  tor_assert(tm.tm_wday >= 0);
  tor_assert(tm.tm_wday <= 6);
  memcpy(buf, WEEKDAY_NAMES[tm.tm_wday], 3);
  tor_assert(tm.tm_mon >= 0);
  tor_assert(tm.tm_mon <= 11);
  memcpy(buf+8, MONTH_NAMES[tm.tm_mon], 3);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int format_time_interval ( char *  out,
size_t  out_len,
long  interval 
)

Given an interval in seconds, try to write it to the out_len-byte buffer in out in a human-readable form.

Return 0 on success, -1 on failure.

Definition at line 1622 of file util.c.

{
  /* We only report seconds if there's no hours. */
  long sec = 0, min = 0, hour = 0, day = 0;
  if (interval < 0)
    interval = -interval;

  if (interval >= 86400) {
    day = interval / 86400;
    interval %= 86400;
  }
  if (interval >= 3600) {
    hour = interval / 3600;
    interval %= 3600;
  }
  if (interval >= 60) {
    min = interval / 60;
    interval %= 60;
  }
  sec = interval;

  if (day) {
    return tor_snprintf(out, out_len, "%ld days, %ld hours, %ld minutes",
                        day, hour, min);
  } else if (hour) {
    return tor_snprintf(out, out_len, "%ld hours, %ld minutes", hour, min);
  } else if (min) {
    return tor_snprintf(out, out_len, "%ld minutes, %ld seconds", min, sec);
  } else {
    return tor_snprintf(out, out_len, "%ld seconds", sec);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Return a newly allocated smartlist containing every variable in this process's environment, as a NUL-terminated string of the form "NAME=VALUE".

Note that on some/many/most/all OSes, the parent process can put strings not of that form in our environment; callers should try to not get crashed by that.

The returned strings are heap-allocated, and must be freed by the caller.

Definition at line 4025 of file util.c.

{
  smartlist_t *sl = smartlist_new();

  char **environ_tmp; /* Not const char ** ? Really? */
  for (environ_tmp = get_environment(); *environ_tmp; ++environ_tmp) {
    smartlist_add(sl, tor_strdup(*environ_tmp));
  }

  return sl;
}

Here is the call graph for this function:

Here is the caller graph for this function:

enum stream_status get_string_from_pipe ( FILE *  stream,
char *  buf_out,
size_t  count 
)

Reads from stream and stores input in buf_out making sure it's below count bytes.

If the string has a trailing newline, we strip it off.

This function is specifically created to handle input from managed proxies, according to the pluggable transports spec. Make sure it fits your needs before using it.

Returns: IO_STREAM_CLOSED: If the stream is closed. IO_STREAM_EAGAIN: If there is nothing to read and we should check back later. IO_STREAM_TERM: If something is wrong with the stream. IO_STREAM_OKAY: If everything went okay and we got a string in buf_out.

Definition at line 4377 of file util.c.

{
  char *retval;
  size_t len;

  tor_assert(count <= INT_MAX);

  retval = fgets(buf_out, (int)count, stream);

  if (!retval) {
    if (feof(stream)) {
      /* Program has closed stream (probably it exited) */
      /* TODO: check error */
      return IO_STREAM_CLOSED;
    } else {
      if (EAGAIN == errno) {
        /* Nothing more to read, try again next time */
        return IO_STREAM_EAGAIN;
      } else {
        /* There was a problem, abandon this child process */
        return IO_STREAM_TERM;
      }
    }
  } else {
    len = strlen(buf_out);
    if (len == 0) {
      /* this probably means we got a NUL at the start of the string. */
      return IO_STREAM_EAGAIN;
    }

    if (buf_out[len - 1] == '\n') {
      /* Remove the trailing newline */
      buf_out[len - 1] = '\0';
    } else {
      /* No newline; check whether we overflowed the buffer */
      if (!feof(stream))
        log_info(LD_GENERAL,
                 "Line from stream was truncated: %s", buf_out);
      /* TODO: What to do with this error? */
    }

    return IO_STREAM_OKAY;
  }

  /* We should never get here */
  return IO_STREAM_TERM;
}

Here is the caller graph for this function:

void void int hex_decode_digit ( char  c)

Helper: given a hex digit, return its value, or -1 if it isn't hex.

Definition at line 1042 of file util.c.

{
  return _hex_decode_digit(c);
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* hex_str ( const char *  from,
size_t  fromlen 
)

Return a pointer to a NUL-terminated hexadecimal string encoding the first fromlen bytes of from.

(fromlen must be <= 32.) The result does not need to be deallocated, but repeated calls to hex_str will trash old results.

Definition at line 507 of file util.c.

{
  static char buf[65];
  if (fromlen>(sizeof(buf)-1)/2)
    fromlen = (sizeof(buf)-1)/2;
  base16_encode(buf,sizeof(buf),from,fromlen);
  return buf;
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* libor_get_digests ( void  )

Return a string describing the digest of the source files in src/common/.

Definition at line 7 of file util_codedigest.c.

{
  return ""
#include "common_sha1.i"
    ;
}

Here is the caller graph for this function:

int n_bits_set_u8 ( uint8_t  v)

Return the number of bits set in v.

Definition at line 457 of file util.c.

{
  static const int nybble_table[] = {
    0, /* 0000 */
    1, /* 0001 */
    1, /* 0010 */
    2, /* 0011 */
    1, /* 0100 */
    2, /* 0101 */
    2, /* 0110 */
    3, /* 0111 */
    1, /* 1000 */
    2, /* 1001 */
    2, /* 1010 */
    3, /* 1011 */
    2, /* 1100 */
    3, /* 1101 */
    3, /* 1110 */
    4, /* 1111 */
  };

  return nybble_table[v & 15] + nybble_table[v>>4];
}

Here is the caller graph for this function:

const char* parse_config_line_from_str ( const char *  line,
char **  key_out,
char **  value_out 
)

Given a string containing part of a configuration file or similar format, advance past comments and whitespace and try to parse a single line.

If we parse a line successfully, set *key_out to a new string holding the key portion and *value_out to a new string holding the value portion of the line, and return a pointer to the start of the next line. If we run out of data, return a pointer to the end of the string. If we encounter an error, return NULL.

Definition at line 2473 of file util.c.

{
  /* I believe the file format here is supposed to be:
     FILE = (EMPTYLINE | LINE)* (EMPTYLASTLINE | LASTLINE)?

     EMPTYLASTLINE = SPACE* | COMMENT
     EMPTYLINE = EMPTYLASTLINE NL
     SPACE = ' ' | '\r' | '\t'
     COMMENT = '#' NOT-NL*
     NOT-NL = Any character except '\n'
     NL = '\n'

     LASTLINE = SPACE* KEY SPACE* VALUES
     LINE = LASTLINE NL
     KEY = KEYCHAR+
     KEYCHAR = Any character except ' ', '\r', '\n', '\t', '#', "\"

     VALUES = QUOTEDVALUE | NORMALVALUE
     QUOTEDVALUE = QUOTE QVCHAR* QUOTE EOLSPACE?
     QUOTE = '"'
     QVCHAR = KEYCHAR | ESC ('n' | 't' | 'r' | '"' | ESC |'\'' | OCTAL | HEX)
     ESC = "\\"
     OCTAL = ODIGIT (ODIGIT ODIGIT?)?
     HEX = ('x' | 'X') HEXDIGIT HEXDIGIT
     ODIGIT = '0' .. '7'
     HEXDIGIT = '0'..'9' | 'a' .. 'f' | 'A' .. 'F'
     EOLSPACE = SPACE* COMMENT?

     NORMALVALUE = (VALCHAR | ESC ESC_IGNORE | CONTINUATION)* EOLSPACE?
     VALCHAR = Any character except ESC, '#', and '\n'
     ESC_IGNORE = Any character except '#' or '\n'
     CONTINUATION = ESC NL ( COMMENT NL )*
   */

  const char *key, *val, *cp;
  int continuation = 0;

  tor_assert(key_out);
  tor_assert(value_out);

  *key_out = *value_out = NULL;
  key = val = NULL;
  /* Skip until the first keyword. */
  while (1) {
    while (TOR_ISSPACE(*line))
      ++line;
    if (*line == '#') {
      while (*line && *line != '\n')
        ++line;
    } else {
      break;
    }
  }

  if (!*line) { /* End of string? */
    *key_out = *value_out = NULL;
    return line;
  }

  /* Skip until the next space or \ followed by newline. */
  key = line;
  while (*line && !TOR_ISSPACE(*line) && *line != '#' &&
         ! (line[0] == '\\' && line[1] == '\n'))
    ++line;
  *key_out = tor_strndup(key, line-key);

  /* Skip until the value. */
  while (*line == ' ' || *line == '\t')
    ++line;

  val = line;

  /* Find the end of the line. */
  if (*line == '\"') { // XXX No continuation handling is done here
    if (!(line = unescape_string(line, value_out, NULL)))
       return NULL;
    while (*line == ' ' || *line == '\t')
      ++line;
    if (*line && *line != '#' && *line != '\n')
      return NULL;
  } else {
    /* Look for the end of the line. */
    while (*line && *line != '\n' && (*line != '#' || continuation)) {
      if (*line == '\\' && line[1] == '\n') {
        continuation = 1;
        line += 2;
      } else if (*line == '#') {
        do {
          ++line;
        } while (*line && *line != '\n');
        if (*line == '\n')
          ++line;
      } else {
        ++line;
      }
    }

    if (*line == '\n') {
      cp = line++;
    } else {
      cp = line;
    }
    /* Now back cp up to be the last nonspace character */
    while (cp>val && TOR_ISSPACE(*(cp-1)))
      --cp;

    tor_assert(cp >= val);

    /* Now copy out and decode the value. */
    *value_out = tor_strndup(val, cp-val);
    if (continuation) {
      char *v_out, *v_in;
      v_out = v_in = *value_out;
      while (*v_in) {
        if (*v_in == '#') {
          do {
            ++v_in;
          } while (*v_in && *v_in != '\n');
          if (*v_in == '\n')
            ++v_in;
        } else if (v_in[0] == '\\' && v_in[1] == '\n') {
          v_in += 2;
        } else {
          *v_out++ = *v_in++;
        }
      }
      *v_out = '\0';
    }
  }

  if (*line == '#') {
    do {
      ++line;
    } while (*line && *line != '\n');
  }
  while (TOR_ISSPACE(*line)) ++line;

  return line;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int parse_http_time ( const char *  date,
struct tm *  tm 
)

Given a date in one of the three formats allowed by HTTP (ugh), parse it into tm.

Return 0 on success, negative on failure.

Definition at line 1551 of file util.c.

{
  const char *cp;
  char month[4];
  char wkday[4];
  int i;
  unsigned tm_mday, tm_year, tm_hour, tm_min, tm_sec;

  tor_assert(tm);
  memset(tm, 0, sizeof(*tm));

  /* First, try RFC1123 or RFC850 format: skip the weekday.  */
  if ((cp = strchr(date, ','))) {
    ++cp;
    if (*cp != ' ')
      return -1;
    ++cp;
    if (tor_sscanf(cp, "%2u %3s %4u %2u:%2u:%2u GMT",
               &tm_mday, month, &tm_year,
               &tm_hour, &tm_min, &tm_sec) == 6) {
      /* rfc1123-date */
      tm_year -= 1900;
    } else if (tor_sscanf(cp, "%2u-%3s-%2u %2u:%2u:%2u GMT",
                      &tm_mday, month, &tm_year,
                      &tm_hour, &tm_min, &tm_sec) == 6) {
      /* rfc850-date */
    } else {
      return -1;
    }
  } else {
    /* No comma; possibly asctime() format. */
    if (tor_sscanf(date, "%3s %3s %2u %2u:%2u:%2u %4u",
               wkday, month, &tm_mday,
               &tm_hour, &tm_min, &tm_sec, &tm_year) == 7) {
      tm_year -= 1900;
    } else {
      return -1;
    }
  }
  tm->tm_mday = (int)tm_mday;
  tm->tm_year = (int)tm_year;
  tm->tm_hour = (int)tm_hour;
  tm->tm_min = (int)tm_min;
  tm->tm_sec = (int)tm_sec;

  month[3] = '\0';
  /* Okay, now decode the month. */
  /* set tm->tm_mon to dummy value so the check below fails. */
  tm->tm_mon = -1;
  for (i = 0; i < 12; ++i) {
    if (!strcasecmp(MONTH_NAMES[i], month)) {
      tm->tm_mon = i;
    }
  }

  if (tm->tm_year < 0 ||
      tm->tm_mon < 0  || tm->tm_mon > 11 ||
      tm->tm_mday < 1 || tm->tm_mday > 31 ||
      tm->tm_hour < 0 || tm->tm_hour > 23 ||
      tm->tm_min < 0  || tm->tm_min > 59 ||
      tm->tm_sec < 0  || tm->tm_sec > 60)
    return -1; /* Out of range, or bad month. */

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int parse_iso_time ( const char *  cp,
time_t *  t 
)

Given an ISO-formatted UTC time value (after the epoch) in cp, parse it and store its value in *t.

Return 0 on success, -1 on failure. Ignore extraneous stuff in cp separated by whitespace from the end of the time string.

Definition at line 1513 of file util.c.

{
  struct tm st_tm;
  unsigned int year=0, month=0, day=0, hour=0, minute=0, second=0;
  if (tor_sscanf(cp, "%u-%2u-%2u %2u:%2u:%2u", &year, &month,
                &day, &hour, &minute, &second) < 6) {
    char *esc = esc_for_log(cp);
    log_warn(LD_GENERAL, "ISO time %s was unparseable", esc);
    tor_free(esc);
    return -1;
  }
  if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ||
          hour > 23 || minute > 59 || second > 60) {
    char *esc = esc_for_log(cp);
    log_warn(LD_GENERAL, "ISO time %s was nonsensical", esc);
    tor_free(esc);
    return -1;
  }
  st_tm.tm_year = year-1900;
  st_tm.tm_mon = month-1;
  st_tm.tm_mday = day;
  st_tm.tm_hour = hour;
  st_tm.tm_min = minute;
  st_tm.tm_sec = second;

  if (st_tm.tm_year < 70) {
    char *esc = esc_for_log(cp);
    log_warn(LD_GENERAL, "Got invalid ISO time %s. (Before 1970)", esc);
    tor_free(esc);
    return -1;
  }
  *t = tor_timegm(&st_tm);
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int parse_rfc1123_time ( const char *  buf,
time_t *  t 
)

Parse the RFC1123 encoding of some time (in GMT) from buf, and store the result in *t.

Return 0 on success, -1 on failure.

Definition at line 1406 of file util.c.

{
  struct tm tm;
  char month[4];
  char weekday[4];
  int i, m;
  unsigned tm_mday, tm_year, tm_hour, tm_min, tm_sec;

  if (strlen(buf) != RFC1123_TIME_LEN)
    return -1;
  memset(&tm, 0, sizeof(tm));
  if (tor_sscanf(buf, "%3s, %2u %3s %u %2u:%2u:%2u GMT", weekday,
             &tm_mday, month, &tm_year, &tm_hour,
             &tm_min, &tm_sec) < 7) {
    char *esc = esc_for_log(buf);
    log_warn(LD_GENERAL, "Got invalid RFC1123 time %s", esc);
    tor_free(esc);
    return -1;
  }
  if (tm_mday < 1 || tm_mday > 31 || tm_hour > 23 || tm_min > 59 ||
      tm_sec > 60) {
    char *esc = esc_for_log(buf);
    log_warn(LD_GENERAL, "Got invalid RFC1123 time %s", esc);
    tor_free(esc);
    return -1;
  }
  tm.tm_mday = (int)tm_mday;
  tm.tm_year = (int)tm_year;
  tm.tm_hour = (int)tm_hour;
  tm.tm_min = (int)tm_min;
  tm.tm_sec = (int)tm_sec;

  m = -1;
  for (i = 0; i < 12; ++i) {
    if (!strcmp(month, MONTH_NAMES[i])) {
      m = i;
      break;
    }
  }
  if (m<0) {
    char *esc = esc_for_log(buf);
    log_warn(LD_GENERAL, "Got invalid RFC1123 time %s: No such month", esc);
    tor_free(esc);
    return -1;
  }
  tm.tm_mon = m;

  if (tm.tm_year < 1970) {
    char *esc = esc_for_log(buf);
    log_warn(LD_GENERAL,
             "Got invalid RFC1123 time %s. (Before 1970)", esc);
    tor_free(esc);
    return -1;
  }
  tm.tm_year -= 1900;

  *t = tor_timegm(&tm);
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int path_is_relative ( const char *  filename)

Return true iff filename is a relative path.

Definition at line 2915 of file util.c.

{
  if (filename && filename[0] == '/')
    return 0;
#ifdef _WIN32
  else if (filename && filename[0] == '\\')
    return 0;
  else if (filename && strlen(filename)>3 && TOR_ISALPHA(filename[0]) &&
           filename[1] == ':' && filename[2] == '\\')
    return 0;
#endif
  else
    return 1;
}

Here is the caller graph for this function:

Free env (assuming it was produced by process_environment_make).

Definition at line 3918 of file util.c.

{
  if (env == NULL) return;

  /* As both an optimization hack to reduce consing on Unixoid systems
   * and a nice way to ensure that some otherwise-Windows-specific
   * code will always get tested before changes to it get merged, the
   * strings which env->unixoid_environment_block points to are packed
   * into env->windows_environment_block. */
  tor_free(env->unixoid_environment_block);
  tor_free(env->windows_environment_block);

  tor_free(env);
}

Here is the caller graph for this function:

Make a process_environment_t containing the environment variables specified in env_vars (as C strings of the form "NAME=VALUE").

Definition at line 3937 of file util.c.

{
  process_environment_t *env = tor_malloc_zero(sizeof(process_environment_t));
  size_t n_env_vars = smartlist_len(env_vars);
  size_t i;
  size_t total_env_length;
  smartlist_t *env_vars_sorted;

  tor_assert(n_env_vars + 1 != 0);
  env->unixoid_environment_block = tor_calloc(n_env_vars + 1, sizeof(char *));
  /* env->unixoid_environment_block is already NULL-terminated,
   * because we assume that NULL == 0 (and check that during compilation). */

  total_env_length = 1; /* terminating NUL of terminating empty string */
  for (i = 0; i < n_env_vars; ++i) {
    const char *s = smartlist_get(env_vars, i);
    size_t slen = strlen(s);

    tor_assert(slen + 1 != 0);
    tor_assert(slen + 1 < SIZE_MAX - total_env_length);
    total_env_length += slen + 1;
  }

  env->windows_environment_block = tor_malloc_zero(total_env_length);
  /* env->windows_environment_block is already
   * (NUL-terminated-empty-string)-terminated. */

  /* Some versions of Windows supposedly require that environment
   * blocks be sorted.  Or maybe some Windows programs (or their
   * runtime libraries) fail to look up strings in non-sorted
   * environment blocks.
   *
   * Also, sorting strings makes it easy to find duplicate environment
   * variables and environment-variable strings without an '=' on all
   * OSes, and they can cause badness.  Let's complain about those. */
  env_vars_sorted = smartlist_new();
  smartlist_add_all(env_vars_sorted, env_vars);
  smartlist_sort_strings(env_vars_sorted);

  /* Now copy the strings into the environment blocks. */
  {
    char *cp = env->windows_environment_block;
    const char *prev_env_var = NULL;

    for (i = 0; i < n_env_vars; ++i) {
      const char *s = smartlist_get(env_vars_sorted, i);
      size_t slen = strlen(s);
      size_t s_name_len = str_num_before(s, '=');

      if (s_name_len == slen) {
        log_warn(LD_GENERAL,
                 "Preparing an environment containing a variable "
                 "without a value: %s",
                 s);
      }
      if (prev_env_var != NULL &&
          environment_variable_names_equal(s, prev_env_var)) {
        log_warn(LD_GENERAL,
                 "Preparing an environment containing two variables "
                 "with the same name: %s and %s",
                 prev_env_var, s);
      }

      prev_env_var = s;

      /* Actually copy the string into the environment. */
      memcpy(cp, s, slen+1);
      env->unixoid_environment_block[i] = cp;
      cp += slen+1;
    }

    tor_assert(cp == env->windows_environment_block + total_env_length - 1);
  }

  smartlist_free(env_vars_sorted);

  return env;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* rate_limit_log ( ratelim_t lim,
time_t  now 
)

If the rate-limiter lim is ready at now, return a newly allocated string indicating how many messages were suppressed, suitable to append to a log message.

Otherwise return NULL.

Definition at line 1711 of file util.c.

{
  int n;
  if ((n = rate_limit_is_ready(lim, now))) {
    if (n == 1) {
      return tor_strdup("");
    } else {
      char *cp=NULL;
      tor_asprintf(&cp,
                   " [%d similar message(s) suppressed in last %d seconds]",
                   n-1, lim->rate);
      return cp;
    }
  } else {
    return NULL;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

ssize_t read_all ( tor_socket_t  fd,
char *  buf,
size_t  count,
int  isSocket 
)

Read from fd to buf, until we get count bytes or reach the end of the file.

isSocket must be 1 if fd was returned by socket() or accept(), and 0 if fd was returned by open(). Return the number of bytes read, or -1 on error. Only use if fd is a blocking fd.

Definition at line 1762 of file util.c.

{
  size_t numread = 0;
  ssize_t result;

  if (count > SIZE_T_CEILING || count > SSIZE_T_MAX)
    return -1;

  while (numread != count) {
    if (isSocket)
      result = tor_socket_recv(fd, buf+numread, count-numread, 0);
    else
      result = read((int)fd, buf+numread, count-numread);
    if (result<0)
      return -1;
    else if (result == 0)
      break;
    numread += result;
  }
  return (ssize_t)numread;
}

Here is the caller graph for this function:

char* read_file_to_str ( const char *  filename,
int  flags,
struct stat *  stat_out 
)

Read the contents of filename into a newly allocated string; return the string on success or NULL on failure.

If stat_out is provided, store the result of stat()ing the file into stat_out.

If flags & RFTS_BIN, open the file in binary mode. If flags & RFTS_IGNORE_MISSING, don't warn if the file doesn't exist.

Definition at line 2279 of file util.c.

{
  int fd; /* router file */
  struct stat statbuf;
  char *string;
  ssize_t r;
  int bin = flags & RFTS_BIN;

  tor_assert(filename);

  fd = tor_open_cloexec(filename,O_RDONLY|(bin?O_BINARY:O_TEXT),0);
  if (fd<0) {
    int severity = LOG_WARN;
    int save_errno = errno;
    if (errno == ENOENT && (flags & RFTS_IGNORE_MISSING))
      severity = LOG_INFO;
    log_fn(severity, LD_FS,"Could not open \"%s\": %s",filename,
           strerror(errno));
    errno = save_errno;
    return NULL;
  }

  if (fstat(fd, &statbuf)<0) {
    int save_errno = errno;
    close(fd);
    log_warn(LD_FS,"Could not fstat \"%s\".",filename);
    errno = save_errno;
    return NULL;
  }

  if ((uint64_t)(statbuf.st_size)+1 >= SIZE_T_CEILING)
    return NULL;

  string = tor_malloc((size_t)(statbuf.st_size+1));

  r = read_all(fd,string,(size_t)statbuf.st_size,0);
  if (r<0) {
    int save_errno = errno;
    log_warn(LD_FS,"Error reading from file \"%s\": %s", filename,
             strerror(errno));
    tor_free(string);
    close(fd);
    errno = save_errno;
    return NULL;
  }
  string[r] = '\0'; /* NUL-terminate the result. */

#ifdef _WIN32
  if (!bin && strchr(string, '\r')) {
    log_debug(LD_FS, "We didn't convert CRLF to LF as well as we hoped "
              "when reading %s. Coping.",
              filename);
    tor_strstrip(string, "\r");
    r = strlen(string);
  }
  if (!bin) {
    statbuf.st_size = (size_t) r;
  } else
#endif
    if (r != statbuf.st_size) {
      /* Unless we're using text mode on win32, we'd better have an exact
       * match for size. */
      int save_errno = errno;
      log_warn(LD_FS,"Could read only %d of %ld bytes of file \"%s\".",
               (int)r, (long)statbuf.st_size,filename);
      tor_free(string);
      close(fd);
      errno = save_errno;
      return NULL;
    }
  close(fd);
  if (stat_out) {
    memcpy(stat_out, &statbuf, sizeof(struct stat));
  }

  return string;
}

Here is the call graph for this function:

Here is the caller graph for this function:

unsigned round_to_next_multiple_of ( unsigned  number,
unsigned  divisor 
)

Return the lowest x such that x is at least number, and x modulo divisor == 0.

Definition at line 428 of file util.c.

{
  number += divisor - 1;
  number -= number % divisor;
  return number;
}

Here is the caller graph for this function:

uint64_t round_to_power_of_2 ( uint64_t  u64)

Return the power of 2 closest to u64.

Definition at line 415 of file util.c.

{
  int lg2 = tor_log2(u64);
  uint64_t low = U64_LITERAL(1) << lg2, high = U64_LITERAL(1) << (lg2+1);
  if (high - u64 < u64 - low)
    return high;
  else
    return low;
}

Here is the call graph for this function:

Here is the caller graph for this function:

uint32_t round_uint32_to_next_multiple_of ( uint32_t  number,
uint32_t  divisor 
)

Return the lowest x such that x is at least number, and x modulo divisor == 0.

Definition at line 438 of file util.c.

{
  number += divisor - 1;
  number -= number % divisor;
  return number;
}

Here is the caller graph for this function:

uint64_t round_uint64_to_next_multiple_of ( uint64_t  number,
uint64_t  divisor 
)

Return the lowest x such that x is at least number, and x modulo divisor == 0.

Definition at line 448 of file util.c.

{
  number += divisor - 1;
  number -= number % divisor;
  return number;
}

Here is the caller graph for this function:

void set_environment_variable_in_smartlist ( struct smartlist_t env_vars,
const char *  new_var,
void(*)(void *)  free_old,
int  free_p 
)

For each string s in env_vars such that environment_variable_names_equal(s, new_var), remove it; if free_p is non-zero, call free_old(s).

If new_var contains '=', insert it into env_vars.

Definition at line 4042 of file util.c.

{
  SMARTLIST_FOREACH_BEGIN(env_vars, const char *, s) {
    if (environment_variable_names_equal(s, new_var)) {
      SMARTLIST_DEL_CURRENT(env_vars, s);
      if (free_p) {
        free_old((void *)s);
      }
    }
  } SMARTLIST_FOREACH_END(s);

  if (strchr(new_var, '=') != NULL) {
    smartlist_add(env_vars, (void *)new_var);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void smartlist_add_asprintf ( struct smartlist_t sl,
const char *  pattern,
  ... 
)
void void smartlist_add_vasprintf ( struct smartlist_t sl,
const char *  pattern,
va_list  args 
)
void start_daemon ( void  )

Start putting the process into daemon mode: fork and drop all resources except standard fds.

The parent process never returns, but stays around until finish_daemon is called. (Note: it's safe to call this more than once: calls after the first are ignored.)

Definition at line 2949 of file util.c.

{
  pid_t pid;

  if (start_daemon_called)
    return;
  start_daemon_called = 1;

  if (pipe(daemon_filedes)) {
    log_err(LD_GENERAL,"pipe failed; exiting. Error was %s", strerror(errno));
    exit(1);
  }
  pid = fork();
  if (pid < 0) {
    log_err(LD_GENERAL,"fork failed. Exiting.");
    exit(1);
  }
  if (pid) {  /* Parent */
    int ok;
    char c;

    close(daemon_filedes[1]); /* we only read */
    ok = -1;
    while (0 < read(daemon_filedes[0], &c, sizeof(char))) {
      if (c == '.')
        ok = 1;
    }
    fflush(stdout);
    if (ok == 1)
      exit(0);
    else
      exit(1); /* child reported error */
  } else { /* Child */
    close(daemon_filedes[0]); /* we only write */

    pid = setsid(); /* Detach from controlling terminal */
    /*
     * Fork one more time, so the parent (the session group leader) can exit.
     * This means that we, as a non-session group leader, can never regain a
     * controlling terminal.   This part is recommended by Stevens's
     * _Advanced Programming in the Unix Environment_.
     */
    if (fork() != 0) {
      exit(0);
    }
    set_main_thread(); /* We are now the main thread. */

    return;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int start_writing_to_file ( const char *  fname,
int  open_flags,
int  mode,
open_file_t **  data_out 
)

Try to start writing to the file in fname, passing the flags open_flags to the open() syscall, creating the file (if needed) with access value mode.

If the O_APPEND flag is set, we append to the original file. Otherwise, we open a new temporary file in the same directory, and either replace the original or remove the temporary file when we're done.

Return the fd for the newly opened file, and store working data in *data_out. The caller should not close the fd manually: instead, call finish_writing_to_file() or abort_writing_to_file(). Returns -1 on failure.

NOTE: When not appending, the flags O_CREAT and O_TRUNC are treated as true and the flag O_EXCL is treated as false.

NOTE: Ordinarily, O_APPEND means "seek to the end of the file before each write()". We don't do that.

Definition at line 2024 of file util.c.

{
  open_file_t *new_file = tor_malloc_zero(sizeof(open_file_t));
  const char *open_name;
  int append = 0;

  tor_assert(fname);
  tor_assert(data_out);
#if (O_BINARY != 0 && O_TEXT != 0)
  tor_assert((open_flags & (O_BINARY|O_TEXT)) != 0);
#endif
  new_file->fd = -1;
  new_file->filename = tor_strdup(fname);
  if (open_flags & O_APPEND) {
    open_name = fname;
    new_file->rename_on_close = 0;
    append = 1;
    open_flags &= ~O_APPEND;
  } else {
    tor_asprintf(&new_file->tempname, "%s.tmp", fname);
    open_name = new_file->tempname;
    /* We always replace an existing temporary file if there is one. */
    open_flags |= O_CREAT|O_TRUNC;
    open_flags &= ~O_EXCL;
    new_file->rename_on_close = 1;
  }
  if (open_flags & O_BINARY)
    new_file->binary = 1;

  new_file->fd = tor_open_cloexec(open_name, open_flags, mode);
  if (new_file->fd < 0) {
    log_warn(LD_FS, "Couldn't open \"%s\" (%s) for writing: %s",
        open_name, fname, strerror(errno));
    goto err;
  }
  if (append) {
    if (tor_fd_seekend(new_file->fd) < 0) {
      log_warn(LD_FS, "Couldn't seek to end of file \"%s\": %s", open_name,
               strerror(errno));
      goto err;
    }
  }

  *data_out = new_file;

  return new_file->fd;

 err:
  if (new_file->fd >= 0)
    close(new_file->fd);
  *data_out = NULL;
  tor_free(new_file->filename);
  tor_free(new_file->tempname);
  tor_free(new_file);
  return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

FILE* start_writing_to_stdio_file ( const char *  fname,
int  open_flags,
int  mode,
open_file_t **  data_out 
)

Combines start_writing_to_file with fdopen_file(): arguments are as for start_writing_to_file, but.

Definition at line 2103 of file util.c.

{
  FILE *res;
  if (start_writing_to_file(fname, open_flags, mode, data_out)<0)
    return NULL;
  if (!(res = fdopen_file(*data_out))) {
    abort_writing_to_file(*data_out);
    *data_out = NULL;
  }
  return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int int int int int strcasecmpend ( const char *  s1,
const char *  s2 
)
int int int strcasecmpstart ( const char *  s1,
const char *  s2 
)
int int strcmp_len ( const char *  s1,
const char *  s2,
size_t  len 
)
int strcmp_opt ( const char *  s1,
const char *  s2 
)

As strcmp, except that either string may be NULL.

The NULL string is considered to be before any non-NULL string.

Definition at line 567 of file util.c.

{
  if (!s1) {
    if (!s2)
      return 0;
    else
      return -1;
  } else if (!s2) {
    return 1;
  } else {
    return strcmp(s1, s2);
  }
}

Here is the caller graph for this function:

int int int int strcmpend ( const char *  s1,
const char *  s2 
)
int strcmpstart ( const char *  s1,
const char *  s2 
)
int string_is_C_identifier ( const char *  string)

Returns true if string could be a C identifier.

A C identifier must begin with a letter or an underscore and the rest of its characters can be letters, numbers or underscores. No length limit is imposed.

Definition at line 808 of file util.c.

{
  size_t iter;
  size_t length = strlen(string);
  if (!length)
    return 0;

  for (iter = 0; iter < length ; iter++) {
    if (iter == 0) {
      if (!(TOR_ISALPHA(string[iter]) ||
            string[iter] == '_'))
        return 0;
    } else {
      if (!(TOR_ISALPHA(string[iter]) ||
            TOR_ISDIGIT(string[iter]) ||
            string[iter] == '_'))
        return 0;
    }
  }

  return 1;
}

Here is the caller graph for this function:

void tor_check_port_forwarding ( const char *  filename,
int  dir_port,
int  or_port,
time_t  now 
)

Definition at line 4427 of file util.c.

{
/* When fw-helper succeeds, how long do we wait until running it again */
#define TIME_TO_EXEC_FWHELPER_SUCCESS 300
/* When fw-helper failed to start, how long do we wait until running it again
 */
#define TIME_TO_EXEC_FWHELPER_FAIL 60

  /* Static variables are initialized to zero, so child_handle.status=0
   * which corresponds to it not running on startup */
  static process_handle_t *child_handle=NULL;

  static time_t time_to_run_helper = 0;
  int stdout_status, stderr_status, retval;
  const char *argv[10];
  char s_dirport[6], s_orport[6];

  tor_assert(filename);

  /* Set up command line for tor-fw-helper */
  snprintf(s_dirport, sizeof s_dirport, "%d", dir_port);
  snprintf(s_orport, sizeof s_orport, "%d", or_port);

  /* TODO: Allow different internal and external ports */
  argv[0] = filename;
  argv[1] = "--internal-or-port";
  argv[2] = s_orport;
  argv[3] = "--external-or-port";
  argv[4] = s_orport;
  argv[5] = "--internal-dir-port";
  argv[6] = s_dirport;
  argv[7] = "--external-dir-port";
  argv[8] = s_dirport;
  argv[9] = NULL;

  /* Start the child, if it is not already running */
  if ((!child_handle || child_handle->status != PROCESS_STATUS_RUNNING) &&
      time_to_run_helper < now) {
    int status;

    /* Assume tor-fw-helper will succeed, start it later*/
    time_to_run_helper = now + TIME_TO_EXEC_FWHELPER_SUCCESS;

    if (child_handle) {
      tor_process_handle_destroy(child_handle, 1);
      child_handle = NULL;
    }

#ifdef _WIN32
    /* Passing NULL as lpApplicationName makes Windows search for the .exe */
    status = tor_spawn_background(NULL, argv, NULL, &child_handle);
#else
    status = tor_spawn_background(filename, argv, NULL, &child_handle);
#endif

    if (PROCESS_STATUS_ERROR == status) {
      log_warn(LD_GENERAL, "Failed to start port forwarding helper %s",
              filename);
      time_to_run_helper = now + TIME_TO_EXEC_FWHELPER_FAIL;
      return;
    }

    log_info(LD_GENERAL,
             "Started port forwarding helper (%s) with pid '%d'",
             filename, tor_process_get_pid(child_handle));
  }

  /* If child is running, read from its stdout and stderr) */
  if (child_handle && PROCESS_STATUS_RUNNING == child_handle->status) {
    /* Read from stdout/stderr and log result */
    retval = 0;
#ifdef _WIN32
    stdout_status = log_from_handle(child_handle->stdout_pipe, LOG_INFO);
    stderr_status = log_from_handle(child_handle->stderr_pipe, LOG_WARN);
    /* If we got this far (on Windows), the process started */
    retval = 0;
#else
    stdout_status = log_from_pipe(child_handle->stdout_handle,
                    LOG_INFO, filename, &retval);
    stderr_status = log_from_pipe(child_handle->stderr_handle,
                    LOG_WARN, filename, &retval);
#endif
    if (retval) {
      /* There was a problem in the child process */
      time_to_run_helper = now + TIME_TO_EXEC_FWHELPER_FAIL;
    }

    /* Combine the two statuses in order of severity */
    if (-1 == stdout_status || -1 == stderr_status)
      /* There was a failure */
      retval = -1;
#ifdef _WIN32
    else if (!child_handle || tor_get_exit_code(child_handle, 0, NULL) !=
             PROCESS_EXIT_RUNNING) {
      /* process has exited or there was an error */
      /* TODO: Do something with the process return value */
      /* TODO: What if the process output something since
       * between log_from_handle and tor_get_exit_code? */
      retval = 1;
    }
#else
    else if (1 == stdout_status || 1 == stderr_status)
      /* stdout or stderr was closed, the process probably
       * exited. It will be reaped by waitpid() in main.c */
      /* TODO: Do something with the process return value */
      retval = 1;
#endif
    else
      /* Both are fine */
      retval = 0;

    /* If either pipe indicates a failure, act on it */
    if (0 != retval) {
      if (1 == retval) {
        log_info(LD_GENERAL, "Port forwarding helper terminated");
        child_handle->status = PROCESS_STATUS_NOTRUNNING;
      } else {
        log_warn(LD_GENERAL, "Failed to read from port forwarding helper");
        child_handle->status = PROCESS_STATUS_ERROR;
      }

      /* TODO: The child might not actually be finished (maybe it failed or
         closed stdout/stderr), so maybe we shouldn't start another? */
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tor_digest256_is_zero ( const char *  digest)

Return true iff the DIGEST256_LEN bytes in digest are all zero.

Definition at line 865 of file util.c.

{
  return tor_mem_is_zero(digest, DIGEST256_LEN);
}

Here is the call graph for this function:

int tor_digest_is_zero ( const char *  digest)

Return true iff the DIGEST_LEN bytes in digest are all zero.

Definition at line 855 of file util.c.

{
  static const uint8_t ZERO_DIGEST[] = {
    0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
  };
  return tor_memeq(digest, ZERO_DIGEST, DIGEST_LEN);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tor_get_exit_code ( const process_handle_t process_handle,
int  block,
int *  exit_code 
)

Get the exit code of a process specified by process_handle and store it in exit_code, if set to a non-NULL value.

If block is set to true, the call will block until the process has exited. Otherwise if the process is still running, the function will return PROCESS_EXIT_RUNNING, and exit_code will be left unchanged. Returns PROCESS_EXIT_EXITED if the process did exit. If there is a failure, PROCESS_EXIT_ERROR will be returned and the contents of exit_code (if non-NULL) will be undefined. N.B. Under *nix operating systems, this will probably not work in Tor, because waitpid() is called in main.c to reap any terminated child processes.

Definition at line 3827 of file util.c.

{
#ifdef _WIN32
  DWORD retval;
  BOOL success;

  if (block) {
    /* Wait for the process to exit */
    retval = WaitForSingleObject(process_handle->pid.hProcess, INFINITE);
    if (retval != WAIT_OBJECT_0) {
      log_warn(LD_GENERAL, "WaitForSingleObject() failed (%d): %s",
              (int)retval, format_win32_error(GetLastError()));
      return PROCESS_EXIT_ERROR;
    }
  } else {
    retval = WaitForSingleObject(process_handle->pid.hProcess, 0);
    if (WAIT_TIMEOUT == retval) {
      /* Process has not exited */
      return PROCESS_EXIT_RUNNING;
    } else if (retval != WAIT_OBJECT_0) {
      log_warn(LD_GENERAL, "WaitForSingleObject() failed (%d): %s",
               (int)retval, format_win32_error(GetLastError()));
      return PROCESS_EXIT_ERROR;
    }
  }

  if (exit_code != NULL) {
    success = GetExitCodeProcess(process_handle->pid.hProcess,
                                 (PDWORD)exit_code);
    if (!success) {
      log_warn(LD_GENERAL, "GetExitCodeProcess() failed: %s",
               format_win32_error(GetLastError()));
      return PROCESS_EXIT_ERROR;
    }
  }
#else
  int stat_loc;
  int retval;

  retval = waitpid(process_handle->pid, &stat_loc, block?0:WNOHANG);
  if (!block && 0 == retval) {
    /* Process has not exited */
    return PROCESS_EXIT_RUNNING;
  } else if (retval != process_handle->pid) {
    log_warn(LD_GENERAL, "waitpid() failed for PID %d: %s",
             process_handle->pid, strerror(errno));
    return PROCESS_EXIT_ERROR;
  }

  if (!WIFEXITED(stat_loc)) {
    log_warn(LD_GENERAL, "Process %d did not exit normally",
             process_handle->pid);
    return PROCESS_EXIT_ERROR;
  }

  if (exit_code != NULL)
    *exit_code = WEXITSTATUS(stat_loc);
#endif // _WIN32

  return PROCESS_EXIT_EXITED;
}

Here is the caller graph for this function:

char* tor_join_win_cmdline ( const char *  argv[])

Format a command line for use on Windows, which takes the command as a string rather than string array.

Follows the rules from "Parsing C++ Command-Line Arguments" in MSDN. Algorithm based on list2cmdline in the Python subprocess module. Returns a newly allocated string

Definition at line 3169 of file util.c.

{
  smartlist_t *argv_list;
  char *joined_argv;
  int i;

  /* Format each argument and put the result in a smartlist */
  argv_list = smartlist_new();
  for (i=0; argv[i] != NULL; i++) {
    smartlist_add(argv_list, (void *)format_win_cmdline_argument(argv[i]));
  }

  /* Join the arguments with whitespace */
  joined_argv = smartlist_join_strings(argv_list, " ", 0, NULL);

  /* Free the newly allocated arguments, and the smartlist */
  SMARTLIST_FOREACH(argv_list, char *, arg,
  {
    tor_free(arg);
  });
  smartlist_free(argv_list);

  return joined_argv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct smartlist_t* tor_listdir ( const char *  dirname) [read]

Return a new list containing the filenames in the directory dirname.

Return NULL on error or if dirname is not a directory.

Definition at line 2852 of file util.c.

{
  smartlist_t *result;
#ifdef _WIN32
  char *pattern=NULL;
  TCHAR tpattern[MAX_PATH] = {0};
  char name[MAX_PATH*2+1] = {0};
  HANDLE handle;
  WIN32_FIND_DATA findData;
  tor_asprintf(&pattern, "%s\\*", dirname);
#ifdef UNICODE
  mbstowcs(tpattern,pattern,MAX_PATH);
#else
  strlcpy(tpattern, pattern, MAX_PATH);
#endif
  if (INVALID_HANDLE_VALUE == (handle = FindFirstFile(tpattern, &findData))) {
    tor_free(pattern);
    return NULL;
  }
  result = smartlist_new();
  while (1) {
#ifdef UNICODE
    wcstombs(name,findData.cFileName,MAX_PATH);
    name[sizeof(name)-1] = '\0';
#else
    strlcpy(name,findData.cFileName,sizeof(name));
#endif
    if (strcmp(name, ".") &&
        strcmp(name, "..")) {
      smartlist_add(result, tor_strdup(name));
    }
    if (!FindNextFile(handle, &findData)) {
      DWORD err;
      if ((err = GetLastError()) != ERROR_NO_MORE_FILES) {
        char *errstr = format_win32_error(err);
        log_warn(LD_FS, "Error reading directory '%s': %s", dirname, errstr);
        tor_free(errstr);
      }
      break;
    }
  }
  FindClose(handle);
  tor_free(pattern);
#else
  DIR *d;
  struct dirent *de;
  if (!(d = opendir(dirname)))
    return NULL;

  result = smartlist_new();
  while ((de = readdir(d))) {
    if (!strcmp(de->d_name, ".") ||
        !strcmp(de->d_name, ".."))
      continue;
    smartlist_add(result, tor_strdup(de->d_name));
  }
  closedir(d);
#endif
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tor_log2 ( uint64_t  u64)

Returns floor(log2(u64)).

If u64 is 0, (incorrectly) returns 0.

Definition at line 383 of file util.c.

{
  int r = 0;
  if (u64 >= (U64_LITERAL(1)<<32)) {
    u64 >>= 32;
    r = 32;
  }
  if (u64 >= (U64_LITERAL(1)<<16)) {
    u64 >>= 16;
    r += 16;
  }
  if (u64 >= (U64_LITERAL(1)<<8)) {
    u64 >>= 8;
    r += 8;
  }
  if (u64 >= (U64_LITERAL(1)<<4)) {
    u64 >>= 4;
    r += 4;
  }
  if (u64 >= (U64_LITERAL(1)<<2)) {
    u64 >>= 2;
    r += 2;
  }
  if (u64 >= (U64_LITERAL(1)<<1)) {
    u64 >>= 1;
    r += 1;
  }
  return r;
}

Here is the caller graph for this function:

void tor_log_mallinfo ( int  severity)

Call the platform malloc info function, and dump the results to the log at level severity.

If no such function exists, do nothing.

Definition at line 327 of file util.c.

{
#ifdef HAVE_MALLINFO
  struct mallinfo mi;
  memset(&mi, 0, sizeof(mi));
  mi = mallinfo();
  tor_log(severity, LD_MM,
      "mallinfo() said: arena=%d, ordblks=%d, smblks=%d, hblks=%d, "
      "hblkhd=%d, usmblks=%d, fsmblks=%d, uordblks=%d, fordblks=%d, "
      "keepcost=%d",
      mi.arena, mi.ordblks, mi.smblks, mi.hblks,
      mi.hblkhd, mi.usmblks, mi.fsmblks, mi.uordblks, mi.fordblks,
      mi.keepcost);
#else
  (void)severity;
#endif
#ifdef USE_DMALLOC
  dmalloc_log_changed(0, /* Since the program started. */
                      1, /* Log info about non-freed pointers. */
                      0, /* Do not log info about freed pointers. */
                      0  /* Do not log individual pointers. */
                      );
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

long tor_lround ( double  d)

Return the long integer closest to d.

We define this wrapper here so that not all users of math.h need to use the right incancations to get the c99 functions.

Definition at line 370 of file util.c.

{
#if defined(HAVE_LROUND)
  return lround(d);
#elif defined(HAVE_RINT)
  return (long)rint(d);
#else
  return (long)(d > 0 ? d + 0.5 : ceil(d - 0.5));
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

double tor_mathlog ( double  d)

Returns the natural logarithm of d base 2.

We define this wrapper here so as to make it easier not to conflict with Tor's log() macro.

Definition at line 361 of file util.c.

{
  return log(d);
}

Here is the caller graph for this function:

int tor_mem_is_zero ( const char *  mem,
size_t  len 
)

Return true iff the 'len' bytes at 'mem' are all zero.

Definition at line 833 of file util.c.

{
  static const char ZERO[] = {
    0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
  };
  while (len >= sizeof(ZERO)) {
    /* It's safe to use fast_memcmp here, since the very worst thing an
     * attacker could learn is how many initial bytes of a secret were zero */
    if (fast_memcmp(mem, ZERO, sizeof(ZERO)))
      return 0;
    len -= sizeof(ZERO);
    mem += sizeof(ZERO);
  }
  /* Deal with leftover bytes. */
  if (len)
    return fast_memeq(mem, ZERO, len);

  return 1;
}

Here is the caller graph for this function:

double tor_parse_double ( const char *  s,
double  min,
double  max,
int *  ok,
char **  next 
)

As tor_parse_long(), but return a double.

Definition at line 944 of file util.c.

{
  char *endptr;
  double r;

  errno = 0;
  r = strtod(s, &endptr);
  CHECK_STRTOX_RESULT();
}

Here is the caller graph for this function:

void long tor_parse_long ( const char *  s,
int  base,
long  min,
long  max,
int *  ok,
char **  next 
)

Extract a long from the start of s, in the given numeric base.

If base is 0, s is parsed as a decimal, octal, or hex number in the syntax of a C integer literal. If there is unconverted data and next is provided, set *next to the first unconverted character. An error has occurred if no characters are converted; or if there are unconverted characters and next is NULL; or if the parsed value is not between min and max. When no error occurs, return the parsed value and set *ok (if provided) to

  1. When an error occurs, return 0 and set *ok (if provided) to 0.

Definition at line 906 of file util.c.

{
  char *endptr;
  long r;

  if (base < 0) {
    if (ok)
      *ok = 0;
    return 0;
  }

  errno = 0;
  r = strtol(s, &endptr, base);
  CHECK_STRTOX_RESULT();
}

Here is the caller graph for this function:

uint64_t tor_parse_uint64 ( const char *  s,
int  base,
uint64_t  min,
uint64_t  max,
int *  ok,
char **  next 
)

As tor_parse_long, but return a uint64_t.

Only base 10 is guaranteed to work for now.

Definition at line 957 of file util.c.

{
  char *endptr;
  uint64_t r;

  if (base < 0) {
    if (ok)
      *ok = 0;
    return 0;
  }

  errno = 0;
#ifdef HAVE_STRTOULL
  r = (uint64_t)strtoull(s, &endptr, base);
#elif defined(_WIN32)
#if defined(_MSC_VER) && _MSC_VER < 1300
  tor_assert(base <= 10);
  r = (uint64_t)_atoi64(s);
  endptr = (char*)s;
  while (TOR_ISSPACE(*endptr)) endptr++;
  while (TOR_ISDIGIT(*endptr)) endptr++;
#else
  r = (uint64_t)_strtoui64(s, &endptr, base);
#endif
#elif SIZEOF_LONG == 8
  r = (uint64_t)strtoul(s, &endptr, base);
#else
#error "I don't know how to parse 64-bit numbers."
#endif

  CHECK_STRTOX_RESULT();
}

Here is the caller graph for this function:

unsigned long tor_parse_ulong ( const char *  s,
int  base,
unsigned long  min,
unsigned long  max,
int *  ok,
char **  next 
)

As tor_parse_long(), but return an unsigned long.

Definition at line 925 of file util.c.

{
  char *endptr;
  unsigned long r;

  if (base < 0) {
    if (ok)
      *ok = 0;
    return 0;
  }

  errno = 0;
  r = strtoul(s, &endptr, base);
  CHECK_STRTOX_RESULT();
}

Here is the caller graph for this function:

int tor_process_get_pid ( process_handle_t process_handle)

Return the Process ID of process_handle.

Definition at line 3397 of file util.c.

{
#ifdef _WIN32
  return (int) process_handle->pid.dwProcessId;
#else
  return (int) process_handle->pid;
#endif
}

Here is the caller graph for this function:

FILE* tor_process_get_stdout_pipe ( process_handle_t process_handle)

Definition at line 3415 of file util.c.

{
  return process_handle->stdout_handle;
}

Here is the caller graph for this function:

void tor_process_handle_destroy ( process_handle_t process_handle,
int  also_terminate_process 
)

Destroy all resources allocated by the process handle in process_handle.

If also_terminate_process is true, also terminate the process of the process handle.

Definition at line 3780 of file util.c.

{
  if (!process_handle)
    return;

  if (also_terminate_process) {
    if (tor_terminate_process(process_handle) < 0) {
      log_notice(LD_GENERAL, "Failed to terminate process with PID '%d'",
                 tor_process_get_pid(process_handle));
    } else {
      log_info(LD_GENERAL, "Terminated process with PID '%d'",
               tor_process_get_pid(process_handle));
    }
  }

  process_handle->status = PROCESS_STATUS_NOTRUNNING;

#ifdef _WIN32
  if (process_handle->stdout_pipe)
    CloseHandle(process_handle->stdout_pipe);

  if (process_handle->stderr_pipe)
    CloseHandle(process_handle->stderr_pipe);
#else
  if (process_handle->stdout_handle)
    fclose(process_handle->stdout_handle);

  if (process_handle->stderr_handle)
    fclose(process_handle->stderr_handle);
#endif

  memset(process_handle, 0x0f, sizeof(process_handle_t));
  tor_free(process_handle);
}

Here is the call graph for this function:

Here is the caller graph for this function:

ssize_t tor_read_all_from_process_stderr ( const process_handle_t process_handle,
char *  buf,
size_t  count 
)

Read from stdout of a process until the process exits.

Definition at line 4194 of file util.c.

{
#ifdef _WIN32
  return tor_read_all_handle(process_handle->stderr_pipe, buf, count,
                             process_handle);
#else
  return tor_read_all_handle(process_handle->stderr_handle, buf, count,
                             process_handle, NULL);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

ssize_t tor_read_all_from_process_stdout ( const process_handle_t process_handle,
char *  buf,
size_t  count 
)

Read from stdout of a process until the process exits.

Definition at line 4180 of file util.c.

{
#ifdef _WIN32
  return tor_read_all_handle(process_handle->stdout_pipe, buf, count,
                             process_handle);
#else
  return tor_read_all_handle(process_handle->stdout_handle, buf, count,
                             process_handle, NULL);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

ssize_t tor_read_all_handle ( FILE *  h,
char *  buf,
size_t  count,
const process_handle_t process,
int *  eof 
)

Read from a handle h into buf, up to count bytes.

If process is NULL, the function will return immediately if there is nothing more to read. Otherwise data will be read until end of file, or count bytes are read. Returns the number of bytes read, or -1 on error. Sets eof to true if eof is not NULL and the end of the file has been reached.

Definition at line 4133 of file util.c.

{
  size_t numread = 0;
  char *retval;

  if (eof)
    *eof = 0;

  if (count > SIZE_T_CEILING || count > SSIZE_T_MAX)
    return -1;

  while (numread != count) {
    /* Use fgets because that is what we use in log_from_pipe() */
    retval = fgets(buf+numread, (int)(count-numread), h);
    if (NULL == retval) {
      if (feof(h)) {
        log_debug(LD_GENERAL, "fgets() reached end of file");
        if (eof)
          *eof = 1;
        break;
      } else {
        if (EAGAIN == errno) {
          if (process)
            continue;
          else
            break;
        } else {
          log_warn(LD_GENERAL, "fgets() from handle failed: %s",
                   strerror(errno));
          return -1;
        }
      }
    }
    tor_assert(retval != NULL);
    tor_assert(strlen(retval) + numread <= count);
    numread += strlen(retval);
  }

  log_debug(LD_GENERAL, "fgets() read %d bytes from handle", (int)numread);
  return (ssize_t)numread;
}

Here is the caller graph for this function:

int tor_spawn_background ( const char *const  filename,
const char **  argv,
process_environment_t env,
process_handle_t **  process_handle_out 
)

Start a program in the background.

If filename contains a '/', then it will be treated as an absolute or relative path. Otherwise, on non-Windows systems, the system path will be searched for filename. On Windows, only the current directory will be searched. Here, to search the system path (as well as the application directory, current working directory, and system directories), set filename to NULL.

The strings in argv will be passed as the command line arguments of the child program (following convention, argv[0] should normally be the filename of the executable, and this must be the case if filename is NULL). The last element of argv must be NULL. A handle to the child process will be returned in process_handle (which must be non-NULL). Read process_handle.status to find out if the process was successfully launched. For convenience, process_handle.status is returned by this function.

Some parts of this code are based on the POSIX subprocess module from Python, and example code from http://msdn.microsoft.com/en-us/library/ms682499%28v=vs.85%29.aspx.

Definition at line 3478 of file util.c.

{
#ifdef _WIN32
  HANDLE stdout_pipe_read = NULL;
  HANDLE stdout_pipe_write = NULL;
  HANDLE stderr_pipe_read = NULL;
  HANDLE stderr_pipe_write = NULL;
  process_handle_t *process_handle;
  int status;

  STARTUPINFOA siStartInfo;
  BOOL retval = FALSE;

  SECURITY_ATTRIBUTES saAttr;
  char *joined_argv;

  saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
  saAttr.bInheritHandle = TRUE;
  /* TODO: should we set explicit security attributes? (#2046, comment 5) */
  saAttr.lpSecurityDescriptor = NULL;

  /* Assume failure to start process */
  status = PROCESS_STATUS_ERROR;

  /* Set up pipe for stdout */
  if (!CreatePipe(&stdout_pipe_read, &stdout_pipe_write, &saAttr, 0)) {
    log_warn(LD_GENERAL,
      "Failed to create pipe for stdout communication with child process: %s",
      format_win32_error(GetLastError()));
    return status;
  }
  if (!SetHandleInformation(stdout_pipe_read, HANDLE_FLAG_INHERIT, 0)) {
    log_warn(LD_GENERAL,
      "Failed to configure pipe for stdout communication with child "
      "process: %s", format_win32_error(GetLastError()));
    return status;
  }

  /* Set up pipe for stderr */
  if (!CreatePipe(&stderr_pipe_read, &stderr_pipe_write, &saAttr, 0)) {
    log_warn(LD_GENERAL,
      "Failed to create pipe for stderr communication with child process: %s",
      format_win32_error(GetLastError()));
    return status;
  }
  if (!SetHandleInformation(stderr_pipe_read, HANDLE_FLAG_INHERIT, 0)) {
    log_warn(LD_GENERAL,
      "Failed to configure pipe for stderr communication with child "
      "process: %s", format_win32_error(GetLastError()));
    return status;
  }

  /* Create the child process */

  /* Windows expects argv to be a whitespace delimited string, so join argv up
   */
  joined_argv = tor_join_win_cmdline(argv);

  process_handle = process_handle_new();
  process_handle->status = status;

  ZeroMemory(&(process_handle->pid), sizeof(PROCESS_INFORMATION));
  ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
  siStartInfo.cb = sizeof(STARTUPINFO);
  siStartInfo.hStdError = stderr_pipe_write;
  siStartInfo.hStdOutput = stdout_pipe_write;
  siStartInfo.hStdInput = NULL;
  siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

  /* Create the child process */

  retval = CreateProcessA(filename,      // module name
                 joined_argv,   // command line
  /* TODO: should we set explicit security attributes? (#2046, comment 5) */
                 NULL,          // process security attributes
                 NULL,          // primary thread security attributes
                 TRUE,          // handles are inherited
  /*(TODO: set CREATE_NEW CONSOLE/PROCESS_GROUP to make GetExitCodeProcess()
   * work?) */
                 0,             // creation flags
                 (env==NULL) ? NULL : env->windows_environment_block,
                 NULL,          // use parent's current directory
                 &siStartInfo,  // STARTUPINFO pointer
                 &(process_handle->pid));  // receives PROCESS_INFORMATION

  tor_free(joined_argv);

  if (!retval) {
    log_warn(LD_GENERAL,
      "Failed to create child process %s: %s", filename?filename:argv[0],
      format_win32_error(GetLastError()));
    tor_free(process_handle);
  } else  {
    /* TODO: Close hProcess and hThread in process_handle->pid? */
    process_handle->stdout_pipe = stdout_pipe_read;
    process_handle->stderr_pipe = stderr_pipe_read;
    status = process_handle->status = PROCESS_STATUS_RUNNING;
  }

  /* TODO: Close pipes on exit */
  *process_handle_out = process_handle;
  return status;
#else // _WIN32
  pid_t pid;
  int stdout_pipe[2];
  int stderr_pipe[2];
  int fd, retval;
  ssize_t nbytes;
  process_handle_t *process_handle;
  int status;

  const char *error_message = SPAWN_ERROR_MESSAGE;
  size_t error_message_length;

  /* Represents where in the process of spawning the program is;
     this is used for printing out the error message */
  unsigned char child_state = CHILD_STATE_INIT;

  char hex_errno[HEX_ERRNO_SIZE];

  static int max_fd = -1;

  status = PROCESS_STATUS_ERROR;

  /* We do the strlen here because strlen() is not signal handler safe,
     and we are not allowed to use unsafe functions between fork and exec */
  error_message_length = strlen(error_message);

  child_state = CHILD_STATE_PIPE;

  /* Set up pipe for redirecting stdout and stderr of child */
  retval = pipe(stdout_pipe);
  if (-1 == retval) {
    log_warn(LD_GENERAL,
      "Failed to set up pipe for stdout communication with child process: %s",
       strerror(errno));
    return status;
  }

  retval = pipe(stderr_pipe);
  if (-1 == retval) {
    log_warn(LD_GENERAL,
      "Failed to set up pipe for stderr communication with child process: %s",
      strerror(errno));

    close(stdout_pipe[0]);
    close(stdout_pipe[1]);

    return status;
  }

  child_state = CHILD_STATE_MAXFD;

#ifdef _SC_OPEN_MAX
  if (-1 != max_fd) {
    max_fd = (int) sysconf(_SC_OPEN_MAX);
    if (max_fd == -1)
      max_fd = DEFAULT_MAX_FD;
      log_warn(LD_GENERAL,
               "Cannot find maximum file descriptor, assuming %d", max_fd);
  }
#else
  max_fd = DEFAULT_MAX_FD;
#endif

  child_state = CHILD_STATE_FORK;

  pid = fork();
  if (0 == pid) {
    /* In child */

    child_state = CHILD_STATE_DUPOUT;

    /* Link child stdout to the write end of the pipe */
    retval = dup2(stdout_pipe[1], STDOUT_FILENO);
    if (-1 == retval)
        goto error;

    child_state = CHILD_STATE_DUPERR;

    /* Link child stderr to the write end of the pipe */
    retval = dup2(stderr_pipe[1], STDERR_FILENO);
    if (-1 == retval)
        goto error;

    child_state = CHILD_STATE_REDIRECT;

    /* Link stdin to /dev/null */
    fd = open("/dev/null", O_RDONLY); /* NOT cloexec, obviously. */
    if (fd != -1)
      dup2(fd, STDIN_FILENO);
    else
      goto error;

    child_state = CHILD_STATE_CLOSEFD;

    close(stderr_pipe[0]);
    close(stderr_pipe[1]);
    close(stdout_pipe[0]);
    close(stdout_pipe[1]);
    close(fd);

    /* Close all other fds, including the read end of the pipe */
    /* XXX: We should now be doing enough FD_CLOEXEC setting to make
     * this needless. */
    for (fd = STDERR_FILENO + 1; fd < max_fd; fd++) {
      close(fd);
    }

    child_state = CHILD_STATE_EXEC;

    /* Call the requested program. We need the cast because
       execvp doesn't define argv as const, even though it
       does not modify the arguments */
    if (env)
      execve(filename, (char *const *) argv, env->unixoid_environment_block);
    else
      execvp(filename, (char *const *) argv);

    /* If we got here, the exec or open(/dev/null) failed */

    child_state = CHILD_STATE_FAILEXEC;

  error:
    {
      /* XXX: are we leaking fds from the pipe? */
      int n;

      n = format_helper_exit_status(child_state, errno, hex_errno);

      if (n >= 0) {
        /* Write the error message. GCC requires that we check the return
           value, but there is nothing we can do if it fails */
        /* TODO: Don't use STDOUT, use a pipe set up just for this purpose */
        nbytes = write(STDOUT_FILENO, error_message, error_message_length);
        nbytes = write(STDOUT_FILENO, hex_errno, n);
      }
    }

    (void) nbytes;

    _exit(255);
    /* Never reached, but avoids compiler warning */
    return status;
  }

  /* In parent */

  if (-1 == pid) {
    log_warn(LD_GENERAL, "Failed to fork child process: %s", strerror(errno));
    close(stdout_pipe[0]);
    close(stdout_pipe[1]);
    close(stderr_pipe[0]);
    close(stderr_pipe[1]);
    return status;
  }

  process_handle = process_handle_new();
  process_handle->status = status;
  process_handle->pid = pid;

  /* TODO: If the child process forked but failed to exec, waitpid it */

  /* Return read end of the pipes to caller, and close write end */
  process_handle->stdout_pipe = stdout_pipe[0];
  retval = close(stdout_pipe[1]);

  if (-1 == retval) {
    log_warn(LD_GENERAL,
            "Failed to close write end of stdout pipe in parent process: %s",
            strerror(errno));
  }

  process_handle->stderr_pipe = stderr_pipe[0];
  retval = close(stderr_pipe[1]);

  if (-1 == retval) {
    log_warn(LD_GENERAL,
            "Failed to close write end of stderr pipe in parent process: %s",
            strerror(errno));
  }

  status = process_handle->status = PROCESS_STATUS_RUNNING;
  /* Set stdout/stderr pipes to be non-blocking */
  fcntl(process_handle->stdout_pipe, F_SETFL, O_NONBLOCK);
  fcntl(process_handle->stderr_pipe, F_SETFL, O_NONBLOCK);
  /* Open the buffered IO streams */
  process_handle->stdout_handle = fdopen(process_handle->stdout_pipe, "r");
  process_handle->stderr_handle = fdopen(process_handle->stderr_pipe, "r");

  *process_handle_out = process_handle;
  return process_handle->status;
#endif // _WIN32
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tor_split_lines ( smartlist_t sl,
char *  buf,
int  len 
)

Split buf into lines, and add to smartlist.

The buffer buf will be modified. The resulting smartlist will consist of pointers to buf, so there is no need to free the contents of sl. buf must be a NUL-terminated string. len should be set to the length of the buffer excluding the NUL. Non-printable characters (including NUL) will be replaced with "."

Definition at line 4212 of file util.c.

{
  /* Index in buf of the start of the current line */
  int start = 0;
  /* Index in buf of the current character being processed */
  int cur = 0;
  /* Are we currently in a line */
  char in_line = 0;

  /* Loop over string */
  while (cur < len) {
    /* Loop until end of line or end of string */
    for (; cur < len; cur++) {
      if (in_line) {
        if ('\r' == buf[cur] || '\n' == buf[cur]) {
          /* End of line */
          buf[cur] = '\0';
          /* Point cur to the next line */
          cur++;
          /* Line starts at start and ends with a nul */
          break;
        } else {
          if (!TOR_ISPRINT(buf[cur]))
            buf[cur] = '.';
        }
      } else {
        if ('\r' == buf[cur] || '\n' == buf[cur]) {
          /* Skip leading vertical space */
          ;
        } else {
          in_line = 1;
          start = cur;
          if (!TOR_ISPRINT(buf[cur]))
            buf[cur] = '.';
        }
      }
    }
    /* We are at the end of the line or end of string. If in_line is true there
     * is a line which starts at buf+start and ends at a NUL. cur points to
     * the character after the NUL. */
    if (in_line)
      smartlist_add(sl, (void *)(buf+start));
    in_line = 0;
  }
  return smartlist_len(sl);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tor_sscanf ( const char *  buf,
const char *  pattern,
  ... 
)

Minimal sscanf replacement: parse buf according to pattern and store the results in the corresponding argument fields.

Differs from sscanf in that it: Only handles u, x, c and Ns. Does not handle arbitrarily long widths. u and x do not consume any space. Is locale-independent. Returns -1 on malformed patterns.

(As with other locale-independent functions, we need this to parse data that is in ASCII without worrying that the C library's locale-handling will make miscellaneous characters look like numbers, spaces, and so on.)

Definition at line 2814 of file util.c.

{
  int r;
  va_list ap;
  va_start(ap, pattern);
  r = tor_vsscanf(buf, pattern, ap);
  va_end(ap);
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tor_strisnonupper ( const char *  s)

Return 1 if no character in s is uppercase, else return 0.

Definition at line 554 of file util.c.

{
  while (*s) {
    if (TOR_ISUPPER(*s))
      return 0;
    s++;
  }
  return 1;
}

Here is the caller graph for this function:

int tor_strisprint ( const char *  s)

Return 1 if every character in s is printable, else return 0.

Definition at line 541 of file util.c.

{
  while (*s) {
    if (!TOR_ISPRINT(*s))
      return 0;
    s++;
  }
  return 1;
}

Here is the caller graph for this function:

void tor_strlower ( char *  s)

Convert all alphabetic characters in the nul-terminated string s to lowercase.

Definition at line 519 of file util.c.

{
  while (*s) {
    *s = TOR_TOLOWER(*s);
    ++s;
  }
}

Here is the caller graph for this function:

void tor_strstrip ( char *  s,
const char *  strip 
)
void tor_strupper ( char *  s)

Convert all alphabetic characters in the nul-terminated string s to lowercase.

Definition at line 530 of file util.c.

{
  while (*s) {
    *s = TOR_TOUPPER(*s);
    ++s;
  }
}

Here is the caller graph for this function:

int tor_terminate_process ( process_handle_t process_handle)

Terminate the process of process_handle.

Code borrowed from Python's os.kill.

Definition at line 3371 of file util.c.

{
#ifdef _WIN32
  if (tor_get_exit_code(process_handle, 0, NULL) == PROCESS_EXIT_RUNNING) {
    HANDLE handle;
    /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
       attempt to open and terminate the process. */
    handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE,
                         process_handle->pid.dwProcessId);
    if (!handle)
      return -1;

    if (!TerminateProcess(handle, 0))
      return -1;
    else
      return 0;
  }
#else /* Unix */
  return kill(process_handle->pid, SIGTERM);
#endif

  return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

time_t tor_timegm ( struct tm *  tm)

Return a time_t given a struct tm.

The result is given in GMT, and does not account for leap seconds.

Definition at line 1343 of file util.c.

{
  /* This is a pretty ironclad timegm implementation, snarfed from Python2.2.
   * It's way more brute-force than fiddling with tzset().
   */
  time_t year, days, hours, minutes, seconds;
  int i;
  year = tm->tm_year + 1900;
  if (year < 1970 || tm->tm_mon < 0 || tm->tm_mon > 11) {
    log_warn(LD_BUG, "Out-of-range argument to tor_timegm");
    return -1;
  }
  tor_assert(year < INT_MAX);
  days = 365 * (year-1970) + n_leapdays(1970,(int)year);
  for (i = 0; i < tm->tm_mon; ++i)
    days += days_per_month[i];
  if (tm->tm_mon > 1 && IS_LEAPYEAR(year))
    ++days;
  days += tm->tm_mday - 1;
  hours = days*24 + tm->tm_hour;

  minutes = hours*60 + tm->tm_min;
  seconds = minutes*60 + tm->tm_sec;
  return seconds;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tor_vsscanf ( const char *  buf,
const char *  pattern,
va_list  ap 
)

Locale-independent, minimal, no-surprises scanf variant, accepting only a restricted pattern format.

For more info on what it supports, see tor_sscanf() documentation.

Definition at line 2736 of file util.c.

{
  int n_matched = 0;

  while (*pattern) {
    if (*pattern != '%') {
      if (*buf == *pattern) {
        ++buf;
        ++pattern;
        continue;
      } else {
        return n_matched;
      }
    } else {
      int width = -1;
      ++pattern;
      if (TOR_ISDIGIT(*pattern)) {
        width = digit_to_num(*pattern++);
        while (TOR_ISDIGIT(*pattern)) {
          width *= 10;
          width += digit_to_num(*pattern++);
          if (width > MAX_SCANF_WIDTH)
            return -1;
        }
        if (!width) /* No zero-width things. */
          return -1;
      }
      if (*pattern == 'u' || *pattern == 'x') {
        unsigned *u = va_arg(ap, unsigned *);
        const int base = (*pattern == 'u') ? 10 : 16;
        if (!*buf)
          return n_matched;
        if (scan_unsigned(&buf, u, width, base)<0)
          return n_matched;
        ++pattern;
        ++n_matched;
      } else if (*pattern == 's') {
        char *s = va_arg(ap, char *);
        if (width < 0)
          return -1;
        if (scan_string(&buf, s, width)<0)
          return n_matched;
        ++pattern;
        ++n_matched;
      } else if (*pattern == 'c') {
        char *ch = va_arg(ap, char *);
        if (width != -1)
          return -1;
        if (!*buf)
          return n_matched;
        *ch = *buf++;
        ++pattern;
        ++n_matched;
      } else if (*pattern == '%') {
        if (*buf != '%')
          return n_matched;
        ++buf;
        ++pattern;
      } else {
        return -1; /* Unrecognized pattern component. */
      }
    }
  }

  return n_matched;
}

Here is the call graph for this function:

Here is the caller graph for this function:

long tv_mdiff ( const struct timeval start,
const struct timeval end 
)

Return the number of milliseconds elapsed between *start and *end.

Definition at line 1308 of file util.c.

{
  long mdiff;
  long secdiff = end->tv_sec - start->tv_sec;

  if (labs(secdiff+1) > LONG_MAX/1000) {
    log_warn(LD_GENERAL, "comparing times on millisecond detail too far "
             "apart: %ld seconds", secdiff);
    return LONG_MAX;
  }

  /* Subtract and round */
  mdiff = secdiff*1000L +
      ((long)end->tv_usec - (long)start->tv_usec + 500L) / 1000L;
  return mdiff;
}

Here is the caller graph for this function:

double tv_to_double ( const struct timeval tv)

Converts struct timeval to a double value.

Preserves microsecond precision, but just barely. Error is approx +/- 0.1 usec when dealing with epoch values.

Definition at line 1257 of file util.c.

{
  double conv = tv->tv_sec;
  conv += tv->tv_usec/1000000.0;
  return conv;
}
int64_t tv_to_msec ( const struct timeval tv)

Converts timeval to milliseconds.

Definition at line 1268 of file util.c.

{
  int64_t conv = ((int64_t)tv->tv_sec)*1000L;
  /* Round ghetto-style */
  conv += ((int64_t)tv->tv_usec+500)/1000L;
  return conv;
}
int64_t tv_to_usec ( const struct timeval tv)

Converts timeval to microseconds.

Definition at line 1280 of file util.c.

{
  int64_t conv = ((int64_t)tv->tv_sec)*1000000L;
  conv += tv->tv_usec;
  return conv;
}
long tv_udiff ( const struct timeval start,
const struct timeval end 
)

Return the number of microseconds elapsed between *start and *end.

Definition at line 1290 of file util.c.

{
  long udiff;
  long secdiff = end->tv_sec - start->tv_sec;

  if (labs(secdiff+1) > LONG_MAX/1000000) {
    log_warn(LD_GENERAL, "comparing times on microsecond detail too far "
             "apart: %ld seconds", secdiff);
    return LONG_MAX;
  }

  udiff = secdiff*1000000L + (end->tv_usec - start->tv_usec);
  return udiff;
}

Here is the caller graph for this function:

void update_approx_time ( time_t  now)

Update the cached estimate of the current time.

This function SHOULD be called once per second, and MUST be called before the first call to get_approx_time.

Definition at line 1680 of file util.c.

{
  cached_approx_time = now;
}

Here is the caller graph for this function:

void wrap_string ( smartlist_t out,
const char *  string,
size_t  width,
const char *  prefix0,
const char *  prefixRest 
)

Rudimentary string wrapping code: given a un-wrapped string (no newlines!), break the string into newline-terminated lines of no more than width characters long (not counting newline) and insert them into out in order.

Precede the first line with prefix0, and subsequent lines with prefixRest.

Definition at line 1187 of file util.c.

{
  size_t p0Len, pRestLen, pCurLen;
  const char *eos, *prefixCur;
  tor_assert(out);
  tor_assert(string);
  tor_assert(width);
  if (!prefix0)
    prefix0 = "";
  if (!prefixRest)
    prefixRest = "";

  p0Len = strlen(prefix0);
  pRestLen = strlen(prefixRest);
  tor_assert(width > p0Len && width > pRestLen);
  eos = strchr(string, '\0');
  tor_assert(eos);
  pCurLen = p0Len;
  prefixCur = prefix0;

  while ((eos-string)+pCurLen > width) {
    const char *eol = string + width - pCurLen;
    while (eol > string && *eol != ' ')
      --eol;
    /* eol is now the last space that can fit, or the start of the string. */
    if (eol > string) {
      size_t line_len = (eol-string) + pCurLen + 2;
      char *line = tor_malloc(line_len);
      memcpy(line, prefixCur, pCurLen);
      memcpy(line+pCurLen, string, eol-string);
      line[line_len-2] = '\n';
      line[line_len-1] = '\0';
      smartlist_add(out, line);
      string = eol + 1;
    } else {
      size_t line_len = width + 2;
      char *line = tor_malloc(line_len);
      memcpy(line, prefixCur, pCurLen);
      memcpy(line+pCurLen, string, width - pCurLen);
      line[line_len-2] = '\n';
      line[line_len-1] = '\0';
      smartlist_add(out, line);
      string += width-pCurLen;
    }
    prefixCur = prefixRest;
    pCurLen = pRestLen;
  }

  if (string < eos) {
    size_t line_len = (eos-string) + pCurLen + 2;
    char *line = tor_malloc(line_len);
    memcpy(line, prefixCur, pCurLen);
    memcpy(line+pCurLen, string, eos-string);
    line[line_len-2] = '\n';
    line[line_len-1] = '\0';
    smartlist_add(out, line);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

ssize_t write_all ( tor_socket_t  fd,
const char *  buf,
size_t  count,
int  isSocket 
)

Write count bytes from buf to fd.

isSocket must be 1 if fd was returned by socket() or accept(), and 0 if fd was returned by open(). Return the number of bytes written, or -1 on error. Only use if fd is a blocking fd.

Definition at line 1738 of file util.c.

{
  size_t written = 0;
  ssize_t result;
  tor_assert(count < SSIZE_T_MAX);

  while (written != count) {
    if (isSocket)
      result = tor_socket_send(fd, buf+written, count-written, 0);
    else
      result = write((int)fd, buf+written, count-written);
    if (result<0)
      return -1;
    written += result;
  }
  return (ssize_t)count;
}

Here is the caller graph for this function:

int write_bytes_to_file ( const char *  fname,
const char *  str,
size_t  len,
int  bin 
)

As write_str_to_file, but does not assume a NUL-terminated string.

Instead, we write len bytes, starting at str.

Definition at line 2233 of file util.c.

{
  return write_bytes_to_file_impl(fname, str, len,
                                  OPEN_FLAGS_REPLACE|(bin?O_BINARY:O_TEXT));
}

Here is the call graph for this function:

Here is the caller graph for this function:

int write_bytes_to_new_file ( const char *  fname,
const char *  str,
size_t  len,
int  bin 
)

Like write_str_to_file(), but also return -1 if there was a file already residing in fname.

Definition at line 2253 of file util.c.

{
  return write_bytes_to_file_impl(fname, str, len,
                                  OPEN_FLAGS_DONT_REPLACE|
                                  (bin?O_BINARY:O_TEXT));
}

Here is the call graph for this function:

Here is the caller graph for this function:

int write_chunks_to_file ( const char *  fname,
const struct smartlist_t chunks,
int  bin 
)
void write_pidfile ( char *  filename)

Write the current process ID, followed by NL, into filename.

Definition at line 3063 of file util.c.

{
  FILE *pidfile;

  if ((pidfile = fopen(filename, "w")) == NULL) {
    log_warn(LD_FS, "Unable to open \"%s\" for writing: %s", filename,
             strerror(errno));
  } else {
#ifdef _WIN32
    fprintf(pidfile, "%d\n", (int)_getpid());
#else
    fprintf(pidfile, "%d\n", (int)getpid());
#endif
    fclose(pidfile);
  }
}

Here is the caller graph for this function:

int write_str_to_file ( const char *  fname,
const char *  str,
int  bin 
)

Create a file named fname with the contents str.

Overwrite the previous fname if possible. Return 0 on success, -1 on failure.

This function replaces the old file atomically, if possible. This function, and all other functions in util.c that create files, create them with mode 0600.

Definition at line 1982 of file util.c.

{
#ifdef _WIN32
  if (!bin && strchr(str, '\r')) {
    log_warn(LD_BUG,
             "We're writing a text string that already contains a CR.");
  }
#endif
  return write_bytes_to_file(fname, str, strlen(str), bin);
}

Here is the call graph for this function:

Here is the caller graph for this function: