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