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 : 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 : }
|