mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-09-21 13:34:59 +02:00
r9008@Kushana: nickm | 2006-09-29 13:50:10 -0400
Doxygen comments for code in common. Also simplify a few code paths to be more clear/speedy/correct. svn:r8536
This commit is contained in:
parent
b21e656eaf
commit
87648bdcf8
@ -493,10 +493,23 @@ smartlist_uniq_strings(smartlist_t *sl)
|
|||||||
smartlist_uniq(sl, _compare_string_ptrs, NULL);
|
smartlist_uniq(sl, _compare_string_ptrs, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LEFT_CHILD(i) ( ((i)+1)*2 - 1)
|
/* Heap-based priority queue implementation for O(lg N) insert and remove.
|
||||||
#define RIGHT_CHILD(i) ( ((i)+1)*2 )
|
* Recall that the heap property is that, for every index I, h[I] <
|
||||||
#define PARENT(i) ( ((i)+1)/2 - 1)
|
* H[LEFT_CHILD[I]] and h[I] < H[RIGHT_CHILD[I]].
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* For a 1-indexed array, we would use LEFT_CHILD[x] = 2*x and RIGHT_CHILD[x]
|
||||||
|
* = 2*x + 1. But this is C, so we have to adjust a little. */
|
||||||
|
//#define LEFT_CHILD(i) ( ((i)+1)*2 - 1)
|
||||||
|
//#define RIGHT_CHILD(i) ( ((i)+1)*2 )
|
||||||
|
//#define PARENT(i) ( ((i)+1)/2 - 1)
|
||||||
|
#define LEFT_CHILD(i) ( 2*(i) + 1 )
|
||||||
|
#define RIGHT_CHILD(i) ( 2*(i) + 2 )
|
||||||
|
#define PARENT(i) ( ((i)-1) / 2 )
|
||||||
|
|
||||||
|
/** Helper. <b>sl</b> may have at most one violation of the heap property:
|
||||||
|
* the item at <b>idx</b> may be greater than one or both of its children.
|
||||||
|
* Restore the heap property. */
|
||||||
static INLINE void
|
static INLINE void
|
||||||
smartlist_heapify(smartlist_t *sl,
|
smartlist_heapify(smartlist_t *sl,
|
||||||
int (*compare)(const void *a, const void *b),
|
int (*compare)(const void *a, const void *b),
|
||||||
@ -528,6 +541,8 @@ smartlist_heapify(smartlist_t *sl,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Insert <b>item</b> into the heap stored in <b>sl</b>, where order
|
||||||
|
* is determined by <b>compare</b> */
|
||||||
void
|
void
|
||||||
smartlist_pqueue_add(smartlist_t *sl,
|
smartlist_pqueue_add(smartlist_t *sl,
|
||||||
int (*compare)(const void *a, const void *b),
|
int (*compare)(const void *a, const void *b),
|
||||||
@ -549,6 +564,9 @@ smartlist_pqueue_add(smartlist_t *sl,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Remove and return the top-priority item from the heap stored in <b>sl</b>,
|
||||||
|
* where order is determined by <b>compare</b>. <b>sl</b> must not be
|
||||||
|
* empty. */
|
||||||
void *
|
void *
|
||||||
smartlist_pqueue_pop(smartlist_t *sl,
|
smartlist_pqueue_pop(smartlist_t *sl,
|
||||||
int (*compare)(const void *a, const void *b))
|
int (*compare)(const void *a, const void *b))
|
||||||
@ -564,6 +582,8 @@ smartlist_pqueue_pop(smartlist_t *sl,
|
|||||||
return top;
|
return top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Assert that the heap property is correctly maintained by the heap stored
|
||||||
|
* in <b>sl</b>, where order is determined by <b>compare</b>. */
|
||||||
void
|
void
|
||||||
smartlist_pqueue_assert_ok(smartlist_t *sl,
|
smartlist_pqueue_assert_ok(smartlist_t *sl,
|
||||||
int (*compare)(const void *a, const void *b))
|
int (*compare)(const void *a, const void *b))
|
||||||
@ -609,13 +629,14 @@ smartlist_uniq_digests(smartlist_t *sl)
|
|||||||
DEFINE_MAP_STRUCTS(strmap_t, char *key, strmap_);
|
DEFINE_MAP_STRUCTS(strmap_t, char *key, strmap_);
|
||||||
DEFINE_MAP_STRUCTS(digestmap_t, char key[DIGEST_LEN], digestmap_);
|
DEFINE_MAP_STRUCTS(digestmap_t, char key[DIGEST_LEN], digestmap_);
|
||||||
|
|
||||||
/** Helper: compare strmap_t_entry objects by key value. */
|
/** Helper: compare strmap_entry_t objects by key value. */
|
||||||
static INLINE int
|
static INLINE int
|
||||||
strmap_entries_eq(strmap_entry_t *a, strmap_entry_t *b)
|
strmap_entries_eq(strmap_entry_t *a, strmap_entry_t *b)
|
||||||
{
|
{
|
||||||
return !strcmp(a->key, b->key);
|
return !strcmp(a->key, b->key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Helper: return a hash value for a strmap_entry_t */
|
||||||
static INLINE unsigned int
|
static INLINE unsigned int
|
||||||
strmap_entry_hash(strmap_entry_t *a)
|
strmap_entry_hash(strmap_entry_t *a)
|
||||||
{
|
{
|
||||||
@ -629,6 +650,7 @@ digestmap_entries_eq(digestmap_entry_t *a, digestmap_entry_t *b)
|
|||||||
return !memcmp(a->key, b->key, DIGEST_LEN);
|
return !memcmp(a->key, b->key, DIGEST_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Helper: return a hash value for a digest_map_t */
|
||||||
static INLINE unsigned int
|
static INLINE unsigned int
|
||||||
digestmap_entry_hash(digestmap_entry_t *a)
|
digestmap_entry_hash(digestmap_entry_t *a)
|
||||||
{
|
{
|
||||||
@ -1029,6 +1051,7 @@ digestmap_isempty(digestmap_t *map)
|
|||||||
return HT_EMPTY(&map->head);
|
return HT_EMPTY(&map->head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return the number of items in <b>map</b> */
|
||||||
int
|
int
|
||||||
strmap_size(strmap_t *map)
|
strmap_size(strmap_t *map)
|
||||||
{
|
{
|
||||||
|
@ -77,7 +77,9 @@ const char crypto_c_id[] =
|
|||||||
#define PRIVATE_KEY_OK(k) ((k) && (k)->key && (k)->key->p)
|
#define PRIVATE_KEY_OK(k) ((k) && (k)->key && (k)->key->p)
|
||||||
|
|
||||||
#ifdef TOR_IS_MULTITHREADED
|
#ifdef TOR_IS_MULTITHREADED
|
||||||
|
/** A number of prealloced mutexes for use by openssl. */
|
||||||
static tor_mutex_t **_openssl_mutexes = NULL;
|
static tor_mutex_t **_openssl_mutexes = NULL;
|
||||||
|
/** How many mutexes have we allocated for use by openssl? */
|
||||||
static int _n_openssl_mutexes = -1;
|
static int _n_openssl_mutexes = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -164,6 +166,7 @@ crypto_log_errors(int severity, const char *doing)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_ENGINES
|
#ifndef NO_ENGINES
|
||||||
|
/** Log any OpenSSL engines we're using at NOTICE. */
|
||||||
static void
|
static void
|
||||||
log_engine(const char *fn, ENGINE *e)
|
log_engine(const char *fn, ENGINE *e)
|
||||||
{
|
{
|
||||||
@ -1711,6 +1714,9 @@ base64_decode(char *dest, size_t destlen, const char *src, size_t srclen)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Base-64 encode DIGEST_LINE bytes from <b>digest</b>, remove the trailing =
|
||||||
|
* and newline characters, and store the nul-terminated result in the first
|
||||||
|
* BASE64_DIGEST_LEN+1 bytes of <b>d64</b>. */
|
||||||
int
|
int
|
||||||
digest_to_base64(char *d64, const char *digest)
|
digest_to_base64(char *d64, const char *digest)
|
||||||
{
|
{
|
||||||
@ -1721,6 +1727,9 @@ digest_to_base64(char *d64, const char *digest)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Given a base-64 encoded, nul-terminated digest in <b>d64</b> (without
|
||||||
|
* trailing newline or = characters), decode it and store the result in the
|
||||||
|
* first DIGEST_LEN bytes at <b>digest</b>. */
|
||||||
int
|
int
|
||||||
digest_from_base64(char *digest, const char *d64)
|
digest_from_base64(char *digest, const char *d64)
|
||||||
{
|
{
|
||||||
@ -1803,6 +1812,7 @@ secret_to_key(char *key_out, size_t key_out_len, const char *secret,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TOR_IS_MULTITHREADED
|
#ifdef TOR_IS_MULTITHREADED
|
||||||
|
/** Helper: openssl uses this callback to manipulate mutexes. */
|
||||||
static void
|
static void
|
||||||
_openssl_locking_cb(int mode, int n, const char *file, int line)
|
_openssl_locking_cb(int mode, int n, const char *file, int line)
|
||||||
{
|
{
|
||||||
@ -1819,6 +1829,8 @@ _openssl_locking_cb(int mode, int n, const char *file, int line)
|
|||||||
tor_mutex_release(_openssl_mutexes[n]);
|
tor_mutex_release(_openssl_mutexes[n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Helper: Construct mutexes, and set callbacks to help OpenSSL handle being
|
||||||
|
* multithreaded. */
|
||||||
static int
|
static int
|
||||||
setup_openssl_threading(void)
|
setup_openssl_threading(void)
|
||||||
{
|
{
|
||||||
|
@ -60,8 +60,7 @@ sev_to_string(int severity)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Helper: decide whether to include the function name in the log message.
|
/** Helper: decide whether to include the function name in the log message. */
|
||||||
* */
|
|
||||||
static INLINE int
|
static INLINE int
|
||||||
should_log_function_name(uint32_t domain, int severity)
|
should_log_function_name(uint32_t domain, int severity)
|
||||||
{
|
{
|
||||||
@ -434,6 +433,8 @@ add_callback_log(int loglevelMin, int loglevelMax, log_callback cb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Adjust the configured severity of any logs whose callback function is
|
||||||
|
* <b>cb</b>. */
|
||||||
void
|
void
|
||||||
change_callback_log_severity(int loglevelMin, int loglevelMax,
|
change_callback_log_severity(int loglevelMin, int loglevelMax,
|
||||||
log_callback cb)
|
log_callback cb)
|
||||||
@ -577,7 +578,10 @@ switch_logs_debug(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_EVENT_SET_LOG_CALLBACK
|
#ifdef HAVE_EVENT_SET_LOG_CALLBACK
|
||||||
|
/** A string which, if it appears in a libevent log, should be ignored. */
|
||||||
static const char *suppress_msg = NULL;
|
static const char *suppress_msg = NULL;
|
||||||
|
/** Callback function passed to event_set_log() so we can intercept
|
||||||
|
* log messages from libevent. */
|
||||||
static void
|
static void
|
||||||
libevent_logging_callback(int severity, const char *msg)
|
libevent_logging_callback(int severity, const char *msg)
|
||||||
{
|
{
|
||||||
@ -608,11 +612,13 @@ libevent_logging_callback(int severity, const char *msg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/** Set hook to intercept log messages from libevent. */
|
||||||
void
|
void
|
||||||
configure_libevent_logging(void)
|
configure_libevent_logging(void)
|
||||||
{
|
{
|
||||||
event_set_log_callback(libevent_logging_callback);
|
event_set_log_callback(libevent_logging_callback);
|
||||||
}
|
}
|
||||||
|
/** Ignore any libevent log message that contains <b>msg</b> */
|
||||||
void
|
void
|
||||||
suppress_libevent_log_msg(const char *msg)
|
suppress_libevent_log_msg(const char *msg)
|
||||||
{
|
{
|
||||||
|
@ -29,6 +29,8 @@ const char torgzip_c_id[] =
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "torgzip.h"
|
#include "torgzip.h"
|
||||||
|
|
||||||
|
/** Set to 1 if zlib is a version that supports gzip; set to 0 if it doesn't;
|
||||||
|
* set to -1 if we haven't checked yet. */
|
||||||
static int gzip_is_supported = -1;
|
static int gzip_is_supported = -1;
|
||||||
|
|
||||||
/** Return true iff we support gzip-based compression. Otherwise, we need to
|
/** Return true iff we support gzip-based compression. Otherwise, we need to
|
||||||
@ -49,6 +51,7 @@ is_gzip_supported(void)
|
|||||||
return gzip_is_supported;
|
return gzip_is_supported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return the 'bits' value to tell zlib to use <b>method</b>.*/
|
||||||
static INLINE int
|
static INLINE int
|
||||||
method_bits(compress_method_t method)
|
method_bits(compress_method_t method)
|
||||||
{
|
{
|
||||||
@ -152,6 +155,10 @@ tor_gzip_compress(char **out, size_t *out_len,
|
|||||||
* buffer, using the method described in <b>method</b>. Store the uncompressed
|
* buffer, using the method described in <b>method</b>. Store the uncompressed
|
||||||
* string in *<b>out</b>, and its length in *<b>out_len</b>. Return 0 on
|
* string in *<b>out</b>, and its length in *<b>out_len</b>. Return 0 on
|
||||||
* success, -1 on failure.
|
* success, -1 on failure.
|
||||||
|
*
|
||||||
|
* If <b>complete_only</b> is true, we consider a truncated input as a
|
||||||
|
* failure; otherwise we decompress as much as we can. Warn about truncated
|
||||||
|
* or corrupt inputs at <b>protocol_warn_level</b>.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
tor_gzip_uncompress(char **out, size_t *out_len,
|
tor_gzip_uncompress(char **out, size_t *out_len,
|
||||||
@ -287,7 +294,9 @@ struct tor_zlib_state_t {
|
|||||||
int compress;
|
int compress;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** DOCDOC */
|
/** Construct and return a tor_zlib_state_t object using <b>method</b>. If
|
||||||
|
* <b>compress</b>, it's for compression; otherwise it's for
|
||||||
|
* decompression. */
|
||||||
tor_zlib_state_t *
|
tor_zlib_state_t *
|
||||||
tor_zlib_new(int compress, compress_method_t method)
|
tor_zlib_new(int compress, compress_method_t method)
|
||||||
{
|
{
|
||||||
@ -319,7 +328,16 @@ tor_zlib_new(int compress, compress_method_t method)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** DOCDOC */
|
/** Compress/decommpress some bytes using <b>state</b>. Read up to
|
||||||
|
* *<b>in_len</b> bytes from *<b>in</b>, and write up to *<b>out_len</b> bytes
|
||||||
|
* to *<b>out</b>, adjusting the values as we go. If <b>finish</b> is true,
|
||||||
|
* we've reached the end of the input.
|
||||||
|
*
|
||||||
|
* Return TOR_ZLIB_DONE if we've finished the entire compression/decompression.
|
||||||
|
* Return TOR_ZLIB_OK if we're processed everything from the input.
|
||||||
|
* Return TOR_ZLIB_BUF_FULL if we're out of space on <b>out</b>.
|
||||||
|
* Return TOR_ZLIB_ERR if the stream is corrupt.
|
||||||
|
*/
|
||||||
tor_zlib_output_t
|
tor_zlib_output_t
|
||||||
tor_zlib_process(tor_zlib_state_t *state,
|
tor_zlib_process(tor_zlib_state_t *state,
|
||||||
char **out, size_t *out_len,
|
char **out, size_t *out_len,
|
||||||
@ -349,7 +367,7 @@ tor_zlib_process(tor_zlib_state_t *state,
|
|||||||
return TOR_ZLIB_DONE;
|
return TOR_ZLIB_DONE;
|
||||||
case Z_BUF_ERROR:
|
case Z_BUF_ERROR:
|
||||||
if (state->stream.avail_in == 0)
|
if (state->stream.avail_in == 0)
|
||||||
return Z_OK;
|
return TOR_ZLIB_OK;
|
||||||
return TOR_ZLIB_BUF_FULL;
|
return TOR_ZLIB_BUF_FULL;
|
||||||
case Z_OK:
|
case Z_OK:
|
||||||
if (state->stream.avail_out == 0 || finish)
|
if (state->stream.avail_out == 0 || finish)
|
||||||
@ -362,7 +380,7 @@ tor_zlib_process(tor_zlib_state_t *state,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** DOCDOC */
|
/** Deallocate <b>state</b>. */
|
||||||
void
|
void
|
||||||
tor_zlib_free(tor_zlib_state_t *state)
|
tor_zlib_free(tor_zlib_state_t *state)
|
||||||
{
|
{
|
||||||
|
@ -493,6 +493,8 @@ tor_digest_is_zero(const char *digest)
|
|||||||
return tor_mem_is_zero(digest, DIGEST_LEN);
|
return tor_mem_is_zero(digest, DIGEST_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Helper: common code to check whether the result of a strtol or strtoul or
|
||||||
|
* strtoll is correct. */
|
||||||
#define CHECK_STRTOX_RESULT() \
|
#define CHECK_STRTOX_RESULT() \
|
||||||
/* Was at least one character converted? */ \
|
/* Was at least one character converted? */ \
|
||||||
if (endptr == s) \
|
if (endptr == s) \
|
||||||
@ -530,6 +532,7 @@ tor_parse_long(const char *s, int base, long min, long max,
|
|||||||
CHECK_STRTOX_RESULT();
|
CHECK_STRTOX_RESULT();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** As tor_parse_log, but return an unsigned long */
|
||||||
unsigned long
|
unsigned long
|
||||||
tor_parse_ulong(const char *s, int base, unsigned long min,
|
tor_parse_ulong(const char *s, int base, unsigned long min,
|
||||||
unsigned long max, int *ok, char **next)
|
unsigned long max, int *ok, char **next)
|
||||||
@ -541,7 +544,8 @@ tor_parse_ulong(const char *s, int base, unsigned long min,
|
|||||||
CHECK_STRTOX_RESULT();
|
CHECK_STRTOX_RESULT();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Only base 10 is guaranteed to work for now. */
|
/** As tor_parse_log, but return a unit64_t. Only base 10 is guaranteed to
|
||||||
|
* work for now. */
|
||||||
uint64_t
|
uint64_t
|
||||||
tor_parse_uint64(const char *s, int base, uint64_t min,
|
tor_parse_uint64(const char *s, int base, uint64_t min,
|
||||||
uint64_t max, int *ok, char **next)
|
uint64_t max, int *ok, char **next)
|
||||||
@ -570,6 +574,10 @@ tor_parse_uint64(const char *s, int base, uint64_t min,
|
|||||||
CHECK_STRTOX_RESULT();
|
CHECK_STRTOX_RESULT();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Encode the <b>srclen</b> bytes at <b>src</b> in a NUL-terminated,
|
||||||
|
* uppercase hexadecimal string; store it in the <b>destlen</b>-byte buffer
|
||||||
|
* <b>dest</b>.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
|
base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
|
||||||
{
|
{
|
||||||
@ -589,23 +597,35 @@ base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
|
|||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char HEX_DIGITS[] = "0123456789ABCDEFabcdef";
|
/** Helper: given a hex digit, return its value, or -1 if it isn't hex. */
|
||||||
|
|
||||||
static INLINE int
|
static INLINE int
|
||||||
hex_decode_digit(char c)
|
hex_decode_digit(char c)
|
||||||
{
|
{
|
||||||
const char *cp;
|
switch (c) {
|
||||||
int n;
|
case '0': return 0;
|
||||||
cp = strchr(HEX_DIGITS, c);
|
case '1': return 1;
|
||||||
if (!cp)
|
case '2': return 2;
|
||||||
return -1;
|
case '3': return 3;
|
||||||
n = cp-HEX_DIGITS;
|
case '4': return 4;
|
||||||
if (n<=15)
|
case '5': return 5;
|
||||||
return n; /* digit or uppercase */
|
case '6': return 6;
|
||||||
else
|
case '7': return 7;
|
||||||
return n-6; /* lowercase */
|
case '8': return 8;
|
||||||
|
case '9': return 9;
|
||||||
|
case 'A': case 'a': return 10;
|
||||||
|
case 'B': case 'b': return 11;
|
||||||
|
case 'C': case 'c': return 12;
|
||||||
|
case 'D': case 'd': return 13;
|
||||||
|
case 'E': case 'e': return 14;
|
||||||
|
case 'F': case 'f': return 15;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Given a hexadecimal string of <b>srclen</b> bytes in <b>src/b>, decode it
|
||||||
|
* and store the result in the <b>destlen</b>-byte buffer at <b>dest</b>.
|
||||||
|
* Return 0 on success, -1 on failure. */
|
||||||
int
|
int
|
||||||
base16_decode(char *dest, size_t destlen, const char *src, size_t srclen)
|
base16_decode(char *dest, size_t destlen, const char *src, size_t srclen)
|
||||||
{
|
{
|
||||||
@ -832,6 +852,11 @@ static const char *MONTH_NAMES[] =
|
|||||||
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||||
|
|
||||||
|
/** Set <b>buf</b> to the RFC1123 encoding of the GMT value of <b>t</b>.
|
||||||
|
* The buffer must be at least RFC1123_TIME_LEN+1 bytes long.
|
||||||
|
*
|
||||||
|
* (RFC1123 format is Fri, 29 Sep 2006 15:54:20 GMT)
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
format_rfc1123_time(char *buf, time_t t)
|
format_rfc1123_time(char *buf, time_t t)
|
||||||
{
|
{
|
||||||
@ -848,6 +873,11 @@ format_rfc1123_time(char *buf, time_t t)
|
|||||||
memcpy(buf+8, MONTH_NAMES[tm.tm_mon], 3);
|
memcpy(buf+8, MONTH_NAMES[tm.tm_mon], 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Parse the the RFC1123 encoding of some time (in GMT) from <b>buf</b>,
|
||||||
|
* and store the result in *<b>t</b>.
|
||||||
|
*
|
||||||
|
* Return 0 on succcess, -1 on failure.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
parse_rfc1123_time(const char *buf, time_t *t)
|
parse_rfc1123_time(const char *buf, time_t *t)
|
||||||
{
|
{
|
||||||
@ -896,6 +926,11 @@ parse_rfc1123_time(const char *buf, time_t *t)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Set <b>buf</b> to the ISO???? encoding of the local value of <b>t</b>.
|
||||||
|
* The buffer must be at least ISO_TIME_LEN+1 bytes long.
|
||||||
|
*
|
||||||
|
* (ISO???? format is 2006-10-29 10:57:20)
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
format_local_iso_time(char *buf, time_t t)
|
format_local_iso_time(char *buf, time_t t)
|
||||||
{
|
{
|
||||||
@ -903,6 +938,9 @@ format_local_iso_time(char *buf, time_t t)
|
|||||||
strftime(buf, ISO_TIME_LEN+1, "%Y-%m-%d %H:%M:%S", tor_localtime_r(&t, &tm));
|
strftime(buf, ISO_TIME_LEN+1, "%Y-%m-%d %H:%M:%S", tor_localtime_r(&t, &tm));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Set <b>buf</b> to the ISO???? encoding of the GMT value of <b>t</b>.
|
||||||
|
* The buffer must be at least ISO_TIME_LEN+1 bytes long.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
format_iso_time(char *buf, time_t t)
|
format_iso_time(char *buf, time_t t)
|
||||||
{
|
{
|
||||||
@ -1149,7 +1187,10 @@ write_str_to_file(const char *fname, const char *str, int bin)
|
|||||||
return write_bytes_to_file(fname, str, strlen(str), bin);
|
return write_bytes_to_file(fname, str, strlen(str), bin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DOCDOC */
|
/** Helper: given a set of flags as passed to open(2), open the file
|
||||||
|
* <b>fname</b> and write all the sized_chunk_t structs in <b>chunks</t> to
|
||||||
|
* the file. Do so as atomically as possible e.g. by opening temp files and
|
||||||
|
* renaming. */
|
||||||
static int
|
static int
|
||||||
write_chunks_to_file_impl(const char *fname, const smartlist_t *chunks,
|
write_chunks_to_file_impl(const char *fname, const smartlist_t *chunks,
|
||||||
int open_flags)
|
int open_flags)
|
||||||
@ -1204,7 +1245,8 @@ write_chunks_to_file_impl(const char *fname, const smartlist_t *chunks,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DOCDOC */
|
/* Given a smartlist of sized_chunk_t, write them atomically to a file
|
||||||
|
* <b>fname</b>, overwriting or creating the file as necessary. */
|
||||||
int
|
int
|
||||||
write_chunks_to_file(const char *fname, const smartlist_t *chunks, int bin)
|
write_chunks_to_file(const char *fname, const smartlist_t *chunks, int bin)
|
||||||
{
|
{
|
||||||
@ -1228,7 +1270,8 @@ write_bytes_to_file(const char *fname, const char *str, size_t len,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DOCDOC */
|
/** 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
|
int
|
||||||
append_bytes_to_file(const char *fname, const char *str, size_t len,
|
append_bytes_to_file(const char *fname, const char *str, size_t len,
|
||||||
int bin)
|
int bin)
|
||||||
|
Loading…
Reference in New Issue
Block a user