/**************************************************************************/ /* */ /* Copyright (c) 2000-2005 by Alexandr V. Shutko, Khabarovsk, Russia */ /* All rights reserved. */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* 1. Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* 2. Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND */ /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE */ /* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ /* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS */ /* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, */ /* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT */ /* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR */ /* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, */ /* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE */ /* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */ /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /* Various functions to work with strings */ /* */ /* $Id: util_str.cpp,v 1.14 2005/03/06 07:46:01 regress Exp $ */ /**************************************************************************/ #include "includes.h" static char *last_ptr=NULL; /**************************************************************************/ /* Encode raw data buffer into string (binhex algorihm) */ /**************************************************************************/ int hexencode(char *rstr, char *buf, int buf_size) { int sind, rind; int slen = buf_size; char *hexchars = "0123456789ABCDEF"; for (sind=0,rind=0;sind> 4]; rstr[rind++] = hexchars[buf[sind] & 0x0F]; } rstr[rind] = 0; return(0); } /**************************************************************************/ /* Decode string coded by hexencode() into raw data buffer */ /**************************************************************************/ int hexdecode(char *buf, char *sstr, int buflen) { int sind, rind; int slen = strlen(sstr); char tstr[5]; tstr[0] = '0'; tstr[1] = 'x'; tstr[4] = 0; for (rind=0,sind=0;sind buflen) break; } return(rind); } /**************************************************************************/ /* This func compare strlen with given value and send alarm if it greater */ /**************************************************************************/ BOOL islen_valid(int str_len, int limit, char *fname, struct online_user &user) { if (str_len > limit) { LOG_ALARM(0, ("Warning: User %lu from %s:%ld sent too big %s (%d)...\n", user.uin, inet_ntoa(user.ip), user.udp_port, fname, str_len)); return(False); } return(True); } /**************************************************************************/ /* This func convert string to unsigned long number */ /**************************************************************************/ unsigned long atoul(char *string) { char **valid; valid = NULL; return(strtoul(string, valid, 10)); } /**************************************************************************/ /* This func convert hex string to unsigned long number */ /**************************************************************************/ unsigned long ahextoul(char *string) { unsigned short i; unsigned long resnum = 0; unsigned char lonybble; char *hexchars = "0123456789ABCDEF"; char *p1 = NULL; for (i = 2; string[i] != 0; i++) { if (!(p1 = strchr(hexchars, toupper(string[i])))) { break; } /* get the two nybbles */ lonybble = PTR_DIFF(p1, hexchars); resnum = resnum << 4; resnum += lonybble; } return(resnum); } /**************************************************************************/ /* This func compare strlen with given value and send alarm if it greater */ /**************************************************************************/ BOOL islen_valid(int str_len, int limit, char *fname, Packet &pack) { if (str_len > limit) { LOG_ALARM(0, ("Warning: New user from %s:%d sent too big %s (%d)...\n", inet_ntoa(pack.from_ip), pack.from_port, fname, str_len)); return(False); } return(True); } /*************************************************************************/ /* This func convert string to postrgres format (' -> '', \ -> \\ etc) */ /*************************************************************************/ void convert_to_postgres(char *string, int tsize) { if (strlen(string) > 2048) return; for (unsigned int i=0, t=0; i 2047) return; } } ITrans.translateToServer(tempst3); strncpy(string, tempst3, tsize-1); return; } /*************************************************************************/ /* This func convert string to postrgres format (' -> '', \ -> \\ etc) */ /*************************************************************************/ void convert_to_postgres(char *target_string, int tsize, char *string) { for (unsigned int i=0, t=0; i '', \ -> \\ etc) */ /*************************************************************************/ void convert_to_postgres2(char *target_string, int tsize, char *string) { for (unsigned int i=0, t=0; i= back_len) && (strncmp(s + s_len - back_len, back, back_len)==0)) { ret = True; s[s_len - back_len] = '\0'; s_len = strlen(s); } } return(ret); } /**************************************************************************/ /* Does a string have any uppercase chars in it? */ /**************************************************************************/ BOOL strhasupper(const char *s) { while (*s) { size_t skip = 0; if( skip != 0 ) s += skip; else { if (isupper(*s)) return(True); s++; } } return(False); } /**************************************************************************/ /* Does a string have any lowercase chars in it? */ /**************************************************************************/ BOOL strhaslower(const char *s) { while (*s) { size_t skip = 0; if( skip != 0 ) s += skip; else { if (islower(*s)) return(True); s++; } } return(False); } /**************************************************************************/ /* Find the number of chars in a string */ /**************************************************************************/ size_t count_chars(const char *s,char c) { size_t count=0; while (*s) { size_t skip = 0; if( skip != 0 ) s += skip; else { if (*s == c) count++; s++; } } return(count); } /**************************************************************************/ /* Return True if a string consists only of one particular character. */ /**************************************************************************/ BOOL str_is_all(const char *s,char c) { if(s == NULL) return False; if(!*s) return False; { while (*s) { size_t skip = 0; if( skip != 0 ) s += skip; else { if (*s != c) return False; s++; } } } return True; } /**************************************************************************/ /* safe string copy into a known length string. maxlength does not */ /* include the terminating zero. */ /**************************************************************************/ char *safe_strcpy(char *dest,const char *src, size_t maxlength) { size_t len; if (!dest) return NULL; if (!src) { *dest = 0; return dest; } len = strlen(src); if (len > maxlength) len = maxlength; memcpy(dest, src, len); dest[len] = 0; return dest; } /**************************************************************************/ /* Safe string cat into a string. maxlength does not */ /* include the terminating zero. */ /**************************************************************************/ char *safe_strcat(char *dest, const char *src, size_t maxlength) { size_t src_len, dest_len; if (!dest) return NULL; if (!src) return dest; src_len = strlen(src); dest_len = strlen(dest); if (src_len + dest_len > maxlength) { src_len = maxlength - dest_len; } memcpy(&dest[dest_len], src, src_len); dest[dest_len + src_len] = 0; return dest; } /**************************************************************************/ /* Paranoid strcpy into a buffer of given length (includes terminating */ /* zero. Strips out all but 'a-Z0-9' and replaces with '_'. */ /**************************************************************************/ char *alpha_strcpy(char *dest, const char *src, size_t maxlength) { size_t len, i; if (!dest) return NULL; if (!src) { *dest = 0; return dest; } len = strlen(src); if (len >= maxlength) len = maxlength - 1; for(i = 0; i < len; i++) { int val = (src[i] & 0xff); if(isupper(val) ||islower(val) || isdigit(val)) { dest[i] = src[i]; } else { dest[i] = '_'; } } dest[i] = '\0'; return dest; } /**************************************************************************/ /* Like strncpy but always null terminates. Make sure there is room! */ /* The variable n should always be one less than the available size. */ /**************************************************************************/ char *StrnCpy(char *dest,const char *src,size_t n) { char *d = dest; if (!dest) return(NULL); if (!src) { *dest = 0; return(dest); } while (n-- && (*d++ = *src++)) ; *d = 0; return(dest); } /**************************************************************************/ /* Like strncpy but copies up to the character marker. Always null */ /* terminates. Returns a pointer to the character marker in the source */ /* string (src). */ /**************************************************************************/ char *strncpyn(char *dest, const char *src,size_t n, char c) { char *p; size_t str_len; p = strchr(src, c); if (p == NULL) { return NULL; } str_len = PTR_DIFF(p, src); strncpy(dest, src, MIN(n, str_len)); dest[str_len] = '\0'; return p; } /**************************************************************************/ /* Routine to get hex characters and turn them into a 16 byte array. */ /* the array can be variable length, and any non-hex-numeric */ /* characters are skipped. "0xnn" or "0Xnn" is specially catered */ /* for. Valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n" */ /**************************************************************************/ size_t strhex_to_str(char *p, size_t len, const char *strhex) { size_t i; size_t num_chars = 0; unsigned char lonybble, hinybble; char *hexchars = "0123456789ABCDEF"; char *p1 = NULL, *p2 = NULL; for (i = 0; i < len && strhex[i] != 0; i++) { if (strnequal(strhex, "0x", 2)) { i++; /* skip two chars */ continue; } if (!(p1 = strchr(hexchars, toupper(strhex[i])))) { break; } i++; if (!(p2 = strchr(hexchars, toupper(strhex[i])))) { break; } /* get the two nybbles */ hinybble = PTR_DIFF(p1, hexchars); lonybble = PTR_DIFF(p2, hexchars); p[num_chars] = (hinybble << 4) | lonybble; num_chars++; p1 = NULL; p2 = NULL; } return num_chars; } void strhex_to_arr(char *p, int len, const char *strhex) { size_t i; size_t num_chars = 0; unsigned char lonybble, hinybble; char *hexchars = "0123456789ABCDEF"; char *p1 = NULL, *p2 = NULL; for (i = 0; (int)i < len && strhex[i] != 0; i++) { if (!(p1 = strchr(hexchars, toupper(strhex[i])))) { break; } i++; if (!(p2 = strchr(hexchars, toupper(strhex[i])))) { break; } /* get the two nybbles */ hinybble = PTR_DIFF(p1, hexchars); lonybble = PTR_DIFF(p2, hexchars); p[num_chars] = (hinybble << 4) | lonybble; num_chars++; if (num_chars > 7) return; p1 = NULL; p2 = NULL; } } /**************************************************************************/ /* Check if a string is part of a list */ /**************************************************************************/ BOOL in_list(char *s,char *list,BOOL casesensitive) { pstring tok; char *p=list; if (!list) return(False); while (next_token(&p,tok,LIST_SEP,sizeof(tok))) { if (casesensitive) { if (strcmp(tok,s) == 0) return(True); } else { if (StrCaseCmp(tok,s) == 0) return(True); } } return(False); } /* this is used to prevent lots of mallocs of size 1 */ static char *null_string = NULL; /**************************************************************************/ /* Set a string value, allocing the space for the string */ /**************************************************************************/ BOOL string_init(char **dest,const char *src) { size_t l; if (!src) src = ""; l = strlen(src); if (l == 0) { if (!null_string) { if((null_string = (char *)malloc(1)) == NULL) { return False; } *null_string = 0; } *dest = null_string; } else { (*dest) = (char *)malloc(l+1); if ((*dest) == NULL) { return False; } pstrcpy(*dest,src); } return(True); } /**************************************************************************/ /* Free a string value */ /**************************************************************************/ void string_free(char **s) { if (!s || !(*s)) return; if (*s == null_string) *s = NULL; if (*s) free(*s); *s = NULL; } /**************************************************************************/ /* Set a string value, allocing the space for the string, and */ /* deallocating any existing space */ /**************************************************************************/ BOOL string_set(char **dest,const char *src) { string_free(dest); return(string_init(dest,src)); } /**************************************************************************/ /* Substitute a string for a pattern in another string. */ /**************************************************************************/ void string_sub(char *s,const char *pattern,const char *insert, size_t len) { char *p; ssize_t ls,lp,li, i; if (!insert || !pattern || !s) return; ls = (ssize_t)strlen(s); lp = (ssize_t)strlen(pattern); li = (ssize_t)strlen(insert); if (!*pattern) return; while (lp <= ls && (p = strstr(s,pattern))) { if (len && ((ls + (li-lp)) >= (int)len)) { break; } if (li != lp) { memmove(p+li,p+lp,strlen(p+lp)+1); } for (i=0;i= (int)len)) { break; } if (li != lp) { memmove(p+li,p+lp,strlen(p+lp)+1); } memcpy(p, insert, li); s = p + li; ls += (li-lp); } } /**************************************************************************/ /* Splits out the front and back at a separator. */ /**************************************************************************/ void split_at_first_component(char *path, char *front, char sep, char *back) { char *p = strchr(path, sep); if (p != NULL) *p = 0; if (front != NULL) pstrcpy(front, path); if (p != NULL) { if (back != NULL) { pstrcpy(back, p+1); } *p = sep; } else { if (back != NULL) { back[0] = 0; } } } /**************************************************************************/ /* Splits out the front and back at a separator. */ /**************************************************************************/ void split_at_last_component(char *path, char *front, char sep, char *back) { char *p = strrchr(path, sep); if (p != NULL) { *p = 0; } if (front != NULL) { pstrcpy(front, path); } else if (back != NULL) { pstrcpy(back, path); } if (p != NULL) { if (back != NULL) { pstrcpy(back, p+1); } *p = sep; } else { if (back != NULL && front != NULL) { back[0] = 0; } } } /**************************************************************************/ /* Truncate a string at a specified length */ /**************************************************************************/ char *string_truncate(char *s, int length) { if (s && ((int)strlen(s) > length)) s[length] = 0; return s; } /**************************************************************************/ /* Convert number 2 string */ /**************************************************************************/ char *n2str(unsigned long num) { static cstring result; snprintf(result, sizeof(cstring)-1, "%lu", num); return(result); }