diff options
Diffstat (limited to 'src/common/util.c')
-rw-r--r-- | src/common/util.c | 75 |
1 files changed, 59 insertions, 16 deletions
diff --git a/src/common/util.c b/src/common/util.c index 6c6ce088ca..59be5ebb7b 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -493,6 +493,8 @@ tor_digest_is_zero(const char *digest) 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() \ /* Was at least one character converted? */ \ if (endptr == s) \ @@ -530,6 +532,7 @@ tor_parse_long(const char *s, int base, long min, long max, CHECK_STRTOX_RESULT(); } +/** As tor_parse_log, but return an unsigned long */ unsigned long tor_parse_ulong(const char *s, int base, unsigned long min, 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(); } -/** 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 tor_parse_uint64(const char *s, int base, uint64_t min, 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(); } +/** 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 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'; } -static const char HEX_DIGITS[] = "0123456789ABCDEFabcdef"; - +/** Helper: given a hex digit, return its value, or -1 if it isn't hex. */ static INLINE int hex_decode_digit(char c) { - const char *cp; - int n; - cp = strchr(HEX_DIGITS, c); - if (!cp) - return -1; - n = cp-HEX_DIGITS; - if (n<=15) - return n; /* digit or uppercase */ - else - return n-6; /* lowercase */ + switch (c) { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + 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 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", "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 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); } +/** 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 parse_rfc1123_time(const char *buf, time_t *t) { @@ -896,6 +926,11 @@ parse_rfc1123_time(const char *buf, time_t *t) 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 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)); } +/** 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 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); } -/* 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 write_chunks_to_file_impl(const char *fname, const smartlist_t *chunks, int open_flags) @@ -1204,7 +1245,8 @@ write_chunks_to_file_impl(const char *fname, const smartlist_t *chunks, 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 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; } -/* 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 append_bytes_to_file(const char *fname, const char *str, size_t len, int bin) |