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