Line data Source code
1 : /* util.c 2 : ** strophe XMPP client library -- various utility functions 3 : ** 4 : ** Copyright (C) 2005-2009 Collecta, Inc. 5 : ** 6 : ** This software is provided AS-IS with no warranty, either express 7 : ** or implied. 8 : ** 9 : ** This program is dual licensed under the MIT and GPLv3 licenses. 10 : */ 11 : 12 : /** @file 13 : * Utility functions. 14 : */ 15 : 16 : #include <stdio.h> 17 : #include <string.h> 18 : #include <stdlib.h> 19 : 20 : #ifdef _WIN32 21 : #include <winsock2.h> 22 : #else 23 : #include <sys/time.h> 24 : #include <time.h> 25 : #endif 26 : 27 : #include "strophe.h" 28 : #include "common.h" 29 : #include "ostypes.h" 30 : #include "util.h" 31 : 32 : /** implement our own strdup that uses the ctx allocator */ 33 : /** Duplicate a string. 34 : * This function replaces the standard strdup library call with a version 35 : * that uses the Strophe context object's allocator. 36 : * 37 : * @param ctx a Strophe context object 38 : * @param s a string 39 : * 40 : * @return a newly allocated string with the same data as s or NULL on error 41 : */ 42 202 : char *strophe_strdup(const xmpp_ctx_t *ctx, const char *s) 43 : { 44 202 : return strophe_strndup(ctx, s, SIZE_MAX); 45 : } 46 : 47 : /** Duplicate a string with a maximum length. 48 : * This function replaces the standard strndup library call with a version 49 : * that uses the Strophe context object's allocator. 50 : * 51 : * @param ctx a Strophe context object 52 : * @param s a string 53 : * @param len the maximum length of the string to copy 54 : * 55 : * @return a newly allocated string that contains at most `len` symbols 56 : * of the original string or NULL on error 57 : */ 58 202 : char *strophe_strndup(const xmpp_ctx_t *ctx, const char *s, size_t len) 59 : { 60 202 : char *copy; 61 202 : size_t l; 62 : 63 202 : l = strlen(s); 64 202 : if (l > len) 65 : l = len; 66 : 67 202 : copy = strophe_alloc(ctx, l + 1); 68 202 : if (!copy) { 69 0 : strophe_error(ctx, "xmpp", "failed to allocate required memory"); 70 0 : return NULL; 71 : } 72 : 73 202 : memcpy(copy, s, l); 74 202 : copy[l] = '\0'; 75 : 76 202 : return copy; 77 : } 78 : 79 : /** strtok_r(3) implementation. 80 : * This function has appeared in POSIX.1-2001, but not in C standard. 81 : * For example, visual studio older than 2005 doesn't provide strtok_r() 82 : * nor strtok_s(). 83 : */ 84 32 : char *strophe_strtok_r(char *s, const char *delim, char **saveptr) 85 : { 86 32 : size_t len; 87 : 88 32 : s = s ? s : *saveptr; 89 32 : len = strspn(s, delim); 90 32 : s += len; 91 32 : if (*s == '\0') 92 : return NULL; 93 : 94 22 : len = strcspn(s, delim); 95 22 : *saveptr = s[len] == '\0' ? &s[len] : &s[len + 1]; 96 22 : s[len] = '\0'; 97 : 98 22 : return s; 99 : } 100 : 101 : /** Return an integer based time stamp. 102 : * This function uses gettimeofday or timeGetTime (on Win32 platforms) to 103 : * compute an integer based time stamp. This is used internally by the 104 : * event loop and timed handlers. 105 : * 106 : * @return an integer time stamp 107 : */ 108 0 : uint64_t time_stamp(void) 109 : { 110 : #if defined(_WIN32) || defined(_XBOX_ONE) 111 : 112 : #ifndef __GNUC__ 113 : #define EPOCHFILETIME (116444736000000000i64) 114 : #else 115 : #define EPOCHFILETIME (116444736000000000LL) 116 : #endif 117 : 118 : FILETIME ft; 119 : LARGE_INTEGER li; 120 : __int64 t; 121 : 122 : GetSystemTimeAsFileTime(&ft); 123 : li.LowPart = ft.dwLowDateTime; 124 : li.HighPart = ft.dwHighDateTime; 125 : t = li.QuadPart; /* In 100-nanosecond intervals */ 126 : t -= EPOCHFILETIME; /* Offset to the Epoch time */ 127 : return (uint64_t)(t / 10000); /* Convert to milliseconds */ 128 : #else 129 0 : struct timeval tv; 130 : 131 0 : gettimeofday(&tv, NULL); 132 : 133 0 : return (uint64_t)tv.tv_sec * 1000 + (uint64_t)tv.tv_usec / 1000; 134 : #endif 135 : } 136 : 137 : /** Get the time elapsed between two time stamps. 138 : * This function returns the time elapsed between t1 and t2 by subtracting 139 : * t1 from t2. If t2 happened before t1, the result will be negative. This 140 : * function is used internally by the event loop and timed handlers. 141 : * 142 : * @param t1 first time stamp 143 : * @param t2 second time stamp 144 : * 145 : * @return number of milliseconds between the stamps 146 : */ 147 0 : uint64_t time_elapsed(uint64_t t1, uint64_t t2) 148 : { 149 0 : return (uint64_t)(t2 - t1); 150 : } 151 : 152 : /** Disconnect the stream with a memory error. 153 : * This is a convenience function used internally by various parts of 154 : * the Strophe library for terminating the connection because of a 155 : * memory error. 156 : * 157 : * @param conn a Strophe connection object 158 : */ 159 0 : void disconnect_mem_error(xmpp_conn_t *conn) 160 : { 161 0 : strophe_error(conn->ctx, "xmpp", "Memory allocation error"); 162 0 : xmpp_disconnect(conn); 163 0 : } 164 : 165 0 : int string_to_ul(const char *s, unsigned long *ul) 166 : { 167 0 : char *endptr; 168 0 : *ul = strtoul(s, &endptr, 10); 169 0 : return *endptr != '\0'; 170 : } 171 : 172 0 : void hex_encode(char *writebuf, void *readbuf, size_t len) 173 : { 174 0 : size_t i; 175 0 : for (i = 0; i < len; i++) { 176 0 : sprintf(writebuf, "%02x", ((unsigned char *)readbuf)[i]); 177 0 : writebuf += 2; 178 : } 179 0 : }