aboutsummaryrefslogtreecommitdiff
path: root/src/common/util.h
blob: 6f23e219a691c81d78293ef687414e8f0512d79c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* Copyright 2003-2004 Roger Dingledine
 * Copyright 2004-2005 Roger Dingledine, Nick Mathewson */
/* See LICENSE for licensing information */
/* $Id$ */

/**
 * \file util.h
 * \brief Headers for util.c
 **/

#ifndef __UTIL_H
#define __UTIL_H
#define UTIL_H_ID "$Id$"

#include "orconfig.h"
#include "torint.h"
#include "compat.h"
#include <stdio.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif

/** Replace assert() with a variant that sends failures to the log before
 * calling assert() normally.
 */
#ifdef NDEBUG
/* Nobody should ever want to build with NDEBUG set.  99% of your asserts will
 * be outside the critical path anyway, so it's silly to disable bugchecking
 * throughout the entire program just because a few asserts are slowing you
 * down.  Profile, optimize the critical path, and keep debugging on.
 *
 * And I'm not just saying that because some of our asserts check
 * security-critical properties.
 */
#error "Sorry; we don't support building with NDEBUG."
#else
#define tor_assert(expr) do {                                 \
 if (!(expr)) {                                               \
   log(LOG_ERR, "%s:%d: %s: Assertion %s failed; aborting.",  \
       _SHORT_FILE_, __LINE__, __FUNCTION__, #expr);          \
   fprintf(stderr,"%s:%d %s: Assertion %s failed; aborting.\n", \
       _SHORT_FILE_, __LINE__, __FUNCTION__, #expr);          \
   abort();  /* unreached */                                  \
 } } while (0)
#endif

/* Memory management */
void *_tor_malloc(const char *file, const int line, size_t size);
void *_tor_malloc_zero(const char *file, const int line, size_t size);
void *_tor_realloc(const char *file, const int line, void *ptr, size_t size);
char *_tor_strdup(const char *file, const int line, const char *s);
char *_tor_strndup(const char *file, const int line, const char *s, size_t n);
#define tor_free(p) do { if (p) {free(p); (p)=NULL;} } while (0)

#define tor_malloc(size)       _tor_malloc(_SHORT_FILE_, __LINE__, size)
#define tor_malloc_zero(size)  _tor_malloc_zero(_SHORT_FILE_, __LINE__, size)
#define tor_realloc(ptr, size) _tor_realloc(_SHORT_FILE_, __LINE__, ptr, size)
#define tor_strdup(s)          _tor_strdup(_SHORT_FILE_, __LINE__, s)
#define tor_strndup(s, n)      _tor_strndup(_SHORT_FILE_, __LINE__, s, n)

/* String manipulation */
#define HEX_CHARACTERS "0123456789ABCDEFabcdef"
void tor_strlower(char *s);
int strcmpstart(const char *s1, const char *s2);
int strcasecmpstart(const char *s1, const char *s2);
int strcmpend(const char *s1, const char *s2);
int strcasecmpend(const char *s1, const char *s2);
int tor_strstrip(char *s, const char *strip);
typedef enum {
  ALWAYS_TERMINATE, NEVER_TERMINATE, TERMINATE_IF_EVEN
} part_finish_rule_t;
int tor_strpartition(char *dest, size_t dest_len,
                     const char *s, const char *insert, size_t n,
                     part_finish_rule_t rule);
long tor_parse_long(const char *s, int base, long min,
                    long max, int *ok, char **next);
unsigned long tor_parse_ulong(const char *s, int base, unsigned long min,
                              unsigned long max, int *ok, char **next);
uint64_t tor_parse_uint64(const char *s, int base, uint64_t min,
                         uint64_t max, int *ok, char **next);
const char *hex_str(const char *from, size_t fromlen);
const char *eat_whitespace(const char *s);
const char *eat_whitespace_no_nl(const char *s);
const char *find_whitespace(const char *s);

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

/* Time helpers */
long tv_udiff(struct timeval *start, struct timeval *end);
void tv_addms(struct timeval *a, long ms);
void tv_add(struct timeval *a, struct timeval *b);
int tv_cmp(struct timeval *a, struct timeval *b);
time_t tor_timegm(struct tm *tm);
#define RFC1123_TIME_LEN 29
void format_rfc1123_time(char *buf, time_t t);
int parse_rfc1123_time(const char *buf, time_t *t);
#define ISO_TIME_LEN 19
void format_local_iso_time(char *buf, time_t t);
void format_iso_time(char *buf, time_t t);
int parse_iso_time(const char *buf, time_t *t);

/* File helpers */
int write_all(int fd, const char *buf, size_t count, int isSocket);
int read_all(int fd, char *buf, size_t count, int isSocket);

typedef enum { FN_ERROR, FN_NOENT, FN_FILE, FN_DIR} file_status_t;
file_status_t file_status(const char *filename);

typedef enum { CPD_NONE, CPD_CREATE, CPD_CHECK } cpd_check_t;
int check_private_dir(const char *dirname, cpd_check_t check);
int write_str_to_file(const char *fname, const char *str, int bin);
int write_bytes_to_file(const char *fname, const char *str, size_t len,
                        int bin);
char *read_file_to_str(const char *filename, int bin);
char *parse_line_from_str(char *line, char **key_out, char **value_out);
char *expand_filename(const char *filename);

/* Net helpers */
int is_internal_IP(uint32_t ip);
int is_local_IP(uint32_t ip);
int parse_addr_port(const char *addrport, char **address, uint32_t *addr,
                    uint16_t *port);
int parse_addr_and_port_range(const char *s, uint32_t *addr_out,
                              uint32_t *mask_out, uint16_t *port_min_out,
                              uint16_t *port_max_out);
#define INET_NTOA_BUF_LEN 16
int tor_inet_ntoa(struct in_addr *in, char *buf, size_t buf_len);
int is_plausible_address(const char *name);

/* Process helpers */
void start_daemon(const char *desired_cwd);
void finish_daemon(void);
void write_pidfile(char *filename);

#endif