1 /* Copyright (C) 2000-2015 Lavtech.com corp. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; either version 2 of the License, or
6    (at your option) any later version.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16 */
17 
18 #ifndef _UDM_UTILS_H
19 #define _UDM_UTILS_H
20 
21 #include <stdio.h>
22 
23 /* for time_t */
24 #include <time.h>
25 
26 /* for va_list */
27 #include <stdarg.h>
28 
29 #include <stdlib.h>
30 #include <limits.h>
31 #include <sys/types.h>
32 
33 #include "udm_config.h"
34 #include "udm_uniconv.h" /* for UDM_CHARSET */
35 /*
36   This is used in UdmTime_t2Str and in its callers.
37   Note, on AIX strftime() can return time zone in this format:
38   'GMT+01:00'. So timezone can be longer than 3,4 or five-letter
39   abbreviation.
40 */
41 #define UDM_MAXTIMESTRLEN	64
42 
43 #if !defined(__i386__) || defined(_WIN64)
44 #define udm_put_int4(I, C) do { *((char *)(C))= (char)(I);\
45                                 *(((char *)(C)) + 1)= (char)((I) >> 8);\
46                                 *(((char *)(C)) + 2)= (char)((I) >> 16);\
47                                 *(((char *)(C)) + 3)= (char)((I) >> 24); } while (0)
48 #define udm_get_int4(C) (int4)(((int4)((unsigned char)(C)[0])) +\
49                               (((int4)((unsigned char)(C)[1]) << 8)) +\
50                               (((int4)((unsigned char)(C)[2]) << 16)) +\
51                               (((int4)((unsigned char)(C)[3]) << 24)))
52 #else
53 #define udm_put_int4(I, C) *((int4 *)(C))= (int4)(I)
54 #define udm_get_int4(C) (*((const int4 *)(C)))
55 #endif
56 
57 /* Some useful MACROs */
58 #define UDM_STREND(s)		(s+strlen(s))
59 #define UDM_FREE(x)		{if((x)!=NULL){UdmFree(x);x=NULL;}}
60 #define UDM_SKIP(s,set)		while((*s)&&(strchr(set,*s)))s++;
61 #define UDM_SKIPN(s,set)	while((*s)&&(!strchr(set,*s)))s++;
62 #define UDM_SQR(x)		((x)*(x))
63 #define UDM_CSTR_WITH_LEN(x)  (x), ((size_t) (sizeof(x) - 1))
64 #define UDM_BZERO(s, len)       bzero((void*) (s), (len))
65 
66 /* NULL safe atoi*/
67 #define UDM_ATOI(x)		((x)?atoi(x):0)
68 #define UDM_ATOF(x)		((x)?atof(x):0.0)
69 #define UDM_ATOU(x)		((x)?(urlid_t)strtoul(x, (char**)NULL,10):0)
70 #define UDM_NULL2EMPTY(x)	((x)?(x):&udm_null_char)
71 
72 /* The total size that malloc() consumes in the heap */
73 #define UDM_MALLOC_ALLIGNED_SIZE(sz)  ((((sz) + 15) / 16) * 16)
74 
75 extern char udm_null_char;
76 
77 /* Misc functions */
78 UDM_API(udm_rc_t) UdmInit(void);
79 char *UdmGetStrToken(char * s,char ** last);
80 char *UdmTrim(char * p, const char * delim);
81 char *UdmRTrim(char* p, const char * delim);
82 size_t UdmUnescapeCGIQuery(char *d, const char *s);
83 size_t UdmURLDecode(char *dst, const char *src, size_t length);
84 UDM_API(size_t) UdmURLEncode(char *d, const char *s, size_t length);
85 char *UdmEscapeURI(char *d,const char *s);
86 char *UdmRemove2Dot(char *path);
87 char *UdmBuildParamStr(char * dst,size_t len,const char * src,char ** argv,size_t argc);
88 char *UdmStrRemoveChars(char * str, const char * sep);
89 char *UdmStrRemoveDoubleChars(char * str, const char * sep);
90 size_t UdmStrRemoveDoubleSpaces(char *str);
91 
92 /* This should convert Last-Modified time returned by webserver
93  * to time_t (seconds since the Epoch). -kir
94  */
95 time_t UdmHttpDate2Time_t(const char * date);
96 
97 time_t UdmFTPDate2Time_t(char *date);
98 
99 /***********************************************************
100  * converts time_str to time_t (seconds)
101  * time_str can be exactly number of seconds
102  * or in the form 'xxxA[yyyB[zzzC]]'
103  * (Spaces are allowed between xxx and A and yyy and so on)
104  *   there xxx, yyy, zzz are numbers (can be negative!)
105  *         A, B, C can be one of the following:
106  *		s - second
107  *		M - minute
108  *		h - hour
109  *		d - day
110  *		m - month
111  *		y - year
112  *	(these letters are as in strptime/strftime functions)
113  *
114  * Examples:
115  * 1234 - 1234 seconds
116  * 4h30M - 4 hours and 30 minutes (will return 9000 seconds)
117  * 1y6m-15d - 1 year and six month minus 15 days (will return 45792000 s)
118  * 1h-60M+1s - 1 hour minus 60 minutes plus 1 second (will return 1 s)
119  */
120 time_t Udm_dp2time_t(const char * time_str);
121 
122 
123 /* This one for printing HTTP Last-Modified: header */
124 void UdmTime_t2HttpStr(time_t t, char * time_str, size_t time_str_size);
125 /* This one deals with timezone offset */
126 udm_rc_t UdmInitTZ(void);
127 UDM_API(udm_timer_t) UdmStartTimer(void);
128 double UdmStopTimer(udm_timer_t *ticks);
129 
130 size_t UdmStrToSize(const char *str, char **endptr, int *error);
131 
132 char *UdmStrStore (char *dest, const char *src);
133 
134 /* Probably string missing functions */
135 
136 #ifndef HAVE_BZERO
137 UDM_API(void) bzero(void *b, size_t len);
138 #endif
139 
140 #ifndef HAVE_STRCASECMP
141 UDM_API(int) strcasecmp(const char *s1, const char *s2);
142 #endif
143 
144 #ifndef HAVE_STRNCASECMP
145 int strncasecmp(const char *s1, const char *s2, size_t n);
146 #endif
147 
148 #ifndef HAVE_STRCASESTR
149 char * strcasestr(register const char *s1, register const char *s2);
150 #endif
151 
152 #ifndef HAVE_VSNPRINTF
153 int vsnprintf(char *str, size_t size, const char  *fmt,  va_list ap);
154 #endif
155 
156 UDM_API(int) udm_snprintf(char *str, size_t size, const char *fmt, ...)
157                           __attribute__((format(printf,3,4)));
158 #ifndef HAVE_SNPRINTF
159 #define snprintf udm_snprintf
160 #endif
161 
162 int udm_strnncasecmp(const char *s, size_t slen,
163                             const char *t, size_t tlen);
164 
165 char *udm_strtok_r(char *s, const char *delim, char **save_ptr);
166 #ifndef HAVE_STRTOK_R
167 #define strtok_r udm_rstok_r
168 #endif
169 
170 #if !defined(HAVE_STRNDUP) || defined(EFENCE)
171 char *udm_strndup(const char *str, size_t len);
172 #endif
173 #ifndef HAVE_STRNDUP
174 #define strndup udm_strndup
175 #endif
176 
177 double udm_strntod(const char *s, size_t len);
178 int udm_strntoi(const char *s, size_t len);
179 udm_bool_t udm_strntobool(const char *s, size_t len);
180 
181 const char *udm_memmem(const char *str, size_t str_length,
182                        const char *substr, size_t substr_length);
183 
184 UDM_API(int) UdmHex2Int(int h);
185 UDM_API(int) UdmInt2Hex(int i);
186 
187 
188 size_t UdmHexEncode(char *dst, const char *src, size_t len);
189 size_t UdmHexDecode(char *dst, const char *src, size_t len);
190 
191 #define BASE64_LEN(len) (4 * (((len) + 2) / 3) +2)
192 UDM_API(size_t) udm_base64_encode (const char *s, char *store, size_t length);
193 UDM_API(size_t) udm_base64_decode (char * dst, const char * src, size_t len);
194 char *udm_rfc1522_decode(char * dst, const char *src);
195 
196 /* Whether to allow multuple chunks 'AAA= BB== CC==' */
197 #define UDM_BASE64_ALLOW_MULTIPLE_CHUNKS 1
198 int UdmBase64Decode(const char *src, size_t len,
199                     void *dst0, const char **end, int flags);
200 
201 size_t udm_quoted_printable_decode(const char *src, size_t srclen,
202                                    char *dst, size_t dstlen);
203 
204 /* Build directory */
205 int UdmBuild(char * path, int mode);
206 
207 /* SetEnv */
208 int UdmSetEnv(const char * name,const char * value);
209 void UdmUnsetEnv(const char * name);
210 
211 size_t UdmUniRemoveDoubleSpaces(int *ustr);
212 void UdmUniPrint(int * ustr);
213 
214 ssize_t UdmRecvall(int s, void *buf, size_t len);
215 ssize_t UdmSend(int s, const void *msg, size_t len, int flags);
216 
217 void UdmWriteLock(int fd);
218 void UdmUnLock(int fd);
219 void UdmReadLock(int fd);
220 void UdmReadLockFILE(FILE *f);
221 UDM_API(void) UdmWriteLockFILE(FILE *f);
222 UDM_API(void) UdmUnLockFILE(FILE *f);
223 
224 /**************************** Variable strings *******************************/
225 void UdmStrInit(UDM_STR *str);
226 void UdmStrFree(UDM_STR *str);
227 udm_rc_t UdmStrMemdup(UDM_STR *str, const char *src, size_t length);
228 udm_rc_t UdmStrNDup(UDM_STR *str, const char *src, size_t length);
229 /**************************** Constant string routines ***********************/
230 void UdmConstStrInit(UDM_CONST_STR *str);
231 void UdmConstStrSet(UDM_CONST_STR *str, const char *s, size_t len);
232 void UdmConstStrSetStr(UDM_CONST_STR *str, const char *s);
233 int UdmConstStrNCaseCmp(const UDM_CONST_STR *str, const char *s, size_t length);
234 char *UdmConstStrDup(const UDM_CONST_STR *str);
235 void UdmConstStrTrim(UDM_CONST_STR *str, const char *sep);
236 /************************ Token **********************/
237 typedef struct udm_const_token_st
238 {
239   const char *str;
240   const char *end;
241 } UDM_CONST_TOKEN;
242 #define UdmConstTokenStr(x)              ((x)->str)
243 #define UdmConstTokenEnd(x)              ((x)->end)
244 #define UdmConstTokenLength(x)           ((x)->end - (x)->str)
245 #define UdmConstTokenIsEmpty(x)          ((x)->str == (x)->end)
246 char *UdmConstTokenStrDup(const UDM_CONST_TOKEN *str);
247 void UdmConstTokenSet(UDM_CONST_TOKEN *dst, const char *str, size_t length);
248 /************************ Dynamic strings  ***********/
249 udm_rc_t UdmDSTRInit(UDM_DSTR *dstr, size_t size_page);
250 void UdmDSTRFree(UDM_DSTR *dstr);
251 const char *UdmDSTRPtr(const UDM_DSTR *dstr);
252 size_t UdmDSTRLength(const UDM_DSTR *dstr);
253 size_t UdmDSTRAppend (UDM_DSTR *dstr, const char *data, size_t size_data);
254 size_t UdmDSTRAppendHex(UDM_DSTR *dstr, const char *s, size_t slen);
255 size_t UdmDSTRAppendSTR (UDM_DSTR *dstr, const char *data);
256 size_t UdmDSTRAppendINT4(UDM_DSTR *s, int i);
257 size_t UdmDSTRAppendINT2LE(UDM_DSTR *s, int i);
258 size_t UdmDSTRAppendINT2BE(UDM_DSTR *s, int i);
259 udm_rc_t UdmDSTRAppendCoord(UDM_DSTR *s, uint4 coord);
260 udm_rc_t UdmDSTRAppendRemoveHiLight(UDM_DSTR *dstr, const char *src, size_t length);
261 udm_rc_t UdmDSTRAppendConv(UDM_DSTR *dstr, UDM_CONV *conv,
262                            const char *src, size_t srclen, int flags);
263 int UdmDSTRAppendf (UDM_DSTR *dstr, const char *fmt, ...)
264                     __attribute__((format(printf,2,3)));
265 void UdmDSTRReset (UDM_DSTR *dstr);
266 udm_rc_t UdmDSTRAlloc (UDM_DSTR *dstr, size_t size_data);
267 udm_rc_t UdmDSTRRealloc (UDM_DSTR *dstr, size_t size_data);
268 udm_rc_t UdmDSTRReserve(UDM_DSTR *dstr, size_t additional_size);
269 void UdmDSTRShrinkLast(UDM_DSTR *dstr);
270 double UdmDSTRToDouble(const UDM_DSTR *dstr);
271 int UdmDSTRToInt(const UDM_DSTR *dstr);
272 void UdmDSTRToConstStr(const UDM_DSTR *dstr, UDM_CONST_STR *to);
273 int UdmDSTRCmp(const UDM_DSTR *s1, const UDM_DSTR *s2);
274 int UdmDSTRCaseCmp(const UDM_DSTR *s1, const UDM_DSTR *s2);
275 int UdmDSTRWildCaseCmp(const UDM_DSTR *s1, const UDM_DSTR *s2);
276 udm_rc_t UdmDSTRReadFile(UDM_DSTR *dstr, int df, size_t nbytes);
277 udm_rc_t UdmDSTRAppendURLDecode(UDM_DSTR *dstr, const char *str, size_t length);
278 void UdmDSTRRemoveHighlightWithOffset(UDM_DSTR *dstr, UDM_CHARSET *cset, size_t offset);
279 udm_rc_t UdmDSTRAppendInflate(UDM_DSTR *dstr, const char *src, size_t length);
280 udm_rc_t UdmDSTRAppendDeflate(UDM_DSTR *dstr, const char *src, size_t length);
281 void UdmDSTRPCase(UDM_DSTR *dstr);
282 void UdmDSTRLCase(UDM_DSTR *dstr);
283 void UdmDSTRUCase(UDM_DSTR *dstr);
284 void UdmDSTRBCut(UDM_DSTR *dstr);
285 void UdmDSTRGiveValue(UDM_DSTR *dstr, UDM_STR *to);
286 udm_rc_t UdmDSTRURLDecode(UDM_DSTR *dstr);
287 udm_rc_t UdmDSTRHTMLEncode(UDM_DSTR *dstr);
288 udm_rc_t UdmDSTRAppendURLEncode(UDM_DSTR *dstr, const char *str, size_t length);
289 udm_rc_t UdmDSTRAppendHTMLEncode(UDM_DSTR *dstr, const char *str, size_t length);
290 udm_rc_t UdmDSTRAppendRegexReplace(UDM_DSTR *dst,
291                                    const char *src, size_t srclen,
292                                    const char *pattern, size_t patternlen,
293                                    const char *replacement, size_t replacementlen);
294 udm_rc_t UdmDSTRAppendRegexCut(UDM_DSTR *dst,
295                                const char *src, size_t srclen,
296                                const char *pattern, size_t patternlen);
297 udm_rc_t UdmDSTRAppendBase64Encode(UDM_DSTR *dst, const char *str, size_t length);
298 udm_rc_t UdmDSTRAppendHighlight(UDM_DSTR *dstr,
299                                 const char *src, size_t srclen,
300                                 const char *beg, size_t blen,
301                                 const char *end, size_t elen);
302 /********************************** zint4 stuff ******************************/
303 typedef struct st_udm_zint4_state
304 {
305   int prev;
306   unsigned char *buf, *end;
307   unsigned char bits_left;
308 } UDM_ZINT4_STATE;
309 
310 void udm_zint4_init(UDM_ZINT4_STATE *state, char *buf);
311 void udm_zint4(UDM_ZINT4_STATE *state, int next);
312 void udm_zint4_finalize(UDM_ZINT4_STATE *state);
313 int udm_dezint4(const char *buf, int4 *array, int buf_len);
314 /**************************** end of zint4 stuff *****************************/
315 
316 extern int udm_l1tolower[256];
317 
318 #ifdef HAVE_DEBUG
319 void *UdmBSearch(const void *key, const void *base, size_t nmemb,
320                          size_t size,
321                          int (*compar)(const void *, const void *));
322 void UdmSort(void *base, size_t nmemb, size_t size,
323                     int(*compar)(const void *, const void *));
324 #else
325 #define UdmBSearch bsearch
326 #define UdmSort   qsort
327 #endif
328 
329 #define UDM_MIN(x,y)  ((x) < (y) ? (x) : (y))
330 #define UDM_MAX(x,y)  ((x) > (y) ? (x) : (y))
331 
332 typedef enum
333 {
334   UDM_DIRTYPE_CONF,
335   UDM_DIRTYPE_SHARE,
336   UDM_DIRTYPE_VAR,
337   UDM_DIRTYPE_TMP
338 } udm_dirtype_t;
339 
340 size_t UdmGetDir(char *d, size_t dlen, udm_dirtype_t type);
341 size_t UdmGetFileName(char *d, size_t dlen, udm_dirtype_t type,
342                              const char *fname);
343 
344 int UdmNormalizeDecimal(char *dst, size_t dstsize, const char *src);
345 
346 size_t UdmProcessCurrentResidentSize(void);
347 
348 /************************************/
349 typedef struct
350 {
351   char *ptr;
352 } UDM_MEMROOT_PAGE;
353 
354 
355 typedef struct
356 {
357   size_t nitems;
358   size_t mitems;
359   UDM_MEMROOT_PAGE *Item;
360   size_t page_size;
361   size_t last_page_used_size;
362 } UDM_MEMROOT;
363 
364 
365 void UdmMemrootInit(UDM_MEMROOT *root, size_t page_size);
366 void UdmMemrootFree(UDM_MEMROOT *root);
367 void UdmMemrootReset(UDM_MEMROOT *root);
368 size_t UdmMemrootAllocedMemory(const UDM_MEMROOT *root);
369 size_t UdmMemrootUsedMemory(const UDM_MEMROOT *root);
370 char *UdmMemrootAlloc(UDM_MEMROOT *root, size_t size);
371 char *UdmMemrootStrndup(UDM_MEMROOT *root, const char *str, size_t length);
372 
373 /************************************/
374 
375 #endif /* _UDM_UTILS_H */
376