#include <basic/errcode.h> #include <basic/misc.h> /*==========*/ /* ???? */ /*==========*/ static char *_hex_char="0123456789ABCDEF"; static unsigned char _char_offset(char c) {/*{{{*/ unsigned char b; for(b=0; b<16; b++) if(_hex_char[b] == c) return(b); return('\xff'); }/*}}}*/ char *expand_to_str(unsigned char *hex, int size, char *str) {/*{{{*/ char *strtmp; int strsize; int i; unsigned char h; if(!hex || size < 0 || !str) return(NULL); strsize=size*2; ALLOC_MULTI_RETERR(strtmp, char, strsize+1, NULL); for(i=0; i<size; i++) { h=hex[i]; strtmp[i*2]=_hex_char[h >> 4]; strtmp[i*2+1]=_hex_char[h & 0x0F]; } strncpy(str, strtmp, strsize); str[strsize]=ZERO; free(strtmp); return(str); }/*}}}*/ unsigned char *collapse_from_str(char *str, int size, unsigned char *hex) {/*{{{*/ unsigned char *hextmp; int hexsize; int i; unsigned char high,low; if(!str || size < 0 || size & 0x01 || !hex) return(NULL); hexsize=size/2; ALLOC_MULTI_RETERR(hextmp, unsigned char, hexsize+1, NULL); for(i=0; i<size; i+=2) { high=_char_offset(str[i]); low=_char_offset(str[i+1]); if(high == 0xff || low == 0xff) { free(hextmp); return(NULL); } hextmp[i/2]=high<<4 | low; } memcpy(hex, hextmp, hexsize); free(hextmp); return(hex); }/*}}}*/ char *trim_head_space(char *str) {/*{{{*/ if(str) { int i, j; int len; len=strlen(str); i=0; while(str[i] == SPACE && i < len) i++; for(j=i; j<len; j++) str[j-i]=str[j]; str[j-i]=ZERO; } return(str); }/*}}}*/ char *trim_tail_space(char *str) {/*{{{*/ if(str) { int i; if(str[0] == ZERO) return(0); for(i=strlen(str)-1; i>=0; i--) if(str[i] != SPACE) break; str[i+1]=ZERO; } return(str); }/*}}}*/ char *trim_tail_space_notnull(char *str) {/*{{{*/ if(str) { trim_tail_space(str); if(str[0] == ZERO) strcpy(str, SPACES); } return(str); }/*}}}*/ char *trim_redundant_space(char *str) {/*{{{*/ if(str) { int i; int str_size, str_real_size; enum { NOT_FOUND, FOUND } found; str_size=strlen(str); trim_head_space(str); trim_tail_space(str); found=NOT_FOUND; str_real_size=0; for(i=0; i<str_size; i++) { if(str[i]==SPACE && found==NOT_FOUND) { found=FOUND; str[str_real_size++]=str[i]; continue; } if(str[i]==SPACE && found==FOUND) { continue; } found=NOT_FOUND; str[str_real_size++]=str[i]; } str[str_real_size]=ZERO; } return(str); }/*}}}*/ char *trim_space(char *str) {/*{{{*/ trim_head_space(str); trim_tail_space(str); return(str); }/*}}}*/ char *pad_space(char *str, int buflen) {/*{{{*/ if(buflen <= 0) return(NULL); if(str) { int str_len; if((str_len=strlen(str)) < buflen) { memset(str+str_len, SPACE, buflen-str_len); str[buflen]=ZERO; } } return(str); }/*}}}*/ char *expand_tab(char *str, int buflen, int unit) {/*{{{*/ int slen; char *tmpstr; int src_index, dest_index; if(!str) return(NULL); if(unit <= 0 || unit > 8) unit=4; if(buflen > 0) { int tabcount; slen=0; tabcount=0; while(str[slen] != ZERO) { if(str[slen] == TAB) tabcount++; slen++; } if(slen+tabcount*(unit-1) > buflen-1) return(NULL); } else slen=strlen(str); ALLOC_MULTI_RETERR(tmpstr, char, slen+1, NULL); strcpy(tmpstr, str); for(src_index=0, dest_index=0; src_index<slen; src_index++) { if(tmpstr[src_index] == TAB) { memset(str+dest_index, SPACE, unit); dest_index+=unit; } else { str[dest_index]=tmpstr[src_index]; dest_index++; } } str[dest_index]=ZERO; free(tmpstr); return(str); }/*}}}*/ unsigned int get_hash(unsigned char *data, int len) {/*{{{*/ unsigned int hash; int i; if(!data || len <= 0) return(0); hash=0x3e9a168c; for(i=0; i<len; i++) hash=(hash << 5) + hash + *data++; return(hash); }/*}}}*/ int wrap_size(unsigned char *msg_in, int *msg_size, unsigned char *msg_out) {/*{{{*/ char buf[10]; if(!msg_in || !msg_size || *msg_size < 0 || *msg_size > MSG_SIZE-MSG_SIZE_SIZE || !msg_out) return(RET_ERR_PARA); sprintf(buf, "%06X", *msg_size); memmove(msg_out+MSG_SIZE_SIZE, msg_in, *msg_size); memcpy(msg_out, buf, SHORT_NUMBER_SIZE); (*msg_size)+=MSG_SIZE_SIZE; msg_out[*msg_size]=ZERO; return(0); }/*}}}*/ int unwrap_size(unsigned char *msg_in, int *msg_size, unsigned char *msg_out) {/*{{{*/ char buf[10]; if(!msg_in || !msg_size || *msg_size > MSG_SIZE || *msg_size < MSG_SIZE_SIZE || !msg_out) return(RET_ERR_PARA); memcpy(buf, msg_in, MSG_SIZE_SIZE); buf[MSG_SIZE_SIZE]=ZERO; *msg_size=strtol(buf, NULL, 16); memmove(msg_out, msg_in+MSG_SIZE_SIZE, *msg_size); msg_out[*msg_size]=ZERO; return(0); }/*}}}*/ int split_str(char *str, char delim, char ***arrp) {/*{{{*/ char *in; char **arr; int str_size; char delimiter[2]; char *itemp, *currp; int item_num; int item_alloc_num; if(!arrp) return(RET_ERR_PARA); *arrp=(char **)NULL; if(!str || (str_size=strlen(str)) <= 0 || str_size > MSG_SIZE) return(RET_ERR_PARA); if(!(in=strdup(str))) return(RET_ERR_ALLOC); if(delim == ZERO) { int len=strlen(in); while(len--) if(in[len] == TAB) in[len]=SPACE; delim=SPACE; } if(delim == SPACE) trim_redundant_space(in); delimiter[0]=delim; delimiter[1]=ZERO; item_num=item_alloc_num=0; arr=(char **)NULL; if((itemp=strtok_r(in, delimiter, &currp))) { do { #define _EXPAND_NUM 5 if(item_num == item_alloc_num) EXPAND_ARRAY(arr, char *, _EXPAND_NUM, item_alloc_num, OUT_ARRAY); if(!(arr[item_num]=strdup(itemp))) goto OUT_ARRAY; item_num++; } while((itemp=strtok_r(NULL, delimiter, &currp))); } free(in); *arrp=arr; return(item_num); OUT_ARRAY: FREE_PTR_ARRAY(arr, item_num); free(in); return(RET_ERR_ALLOC); }/*}}}*/ char *str_toupper(char *str) {/*{{{*/ if(str) { int c; int len; len=strlen(str); while(len--) { c=toupper(str[len]); str[len]=c; } } return(str); }/*}}}*/ char *str_tolower(char *str) {/*{{{*/ if(str) { int c; int len; len=strlen(str); while(len--) { c=tolower(str[len]); str[len]=c; } } return(str); }/*}}}*/ char *replace_str(char *src, char *old, char *rep, char *dest) {/*{{{*/ int len; int count; int src_size, old_size, rep_size, dest_size; char *srcp, *oldp, *destp, *allocp; if(!src) return(NULL); src_size=strlen(src); if(!old || !rep) { if(!dest) ALLOC_MULTI_RETERR(dest, char, src_size+1, NULL); if(src != dest) strcpy(dest, src); return(dest); } old_size=strlen(old); rep_size=strlen(rep); if(rep_size > old_size) { count=0; oldp=srcp=src; while((oldp=strstr(srcp, old))) { srcp=oldp+old_size; count++; } dest_size=src_size+count*(rep_size-old_size); } else dest_size=src_size; if(dest == src) // ?????????????? { ALLOC_MULTI_RETERR(allocp, char, dest_size+1, NULL); } else { if(!dest) // ??? ALLOC_MULTI_RETERR(allocp, char, dest_size+1, NULL); else allocp=dest; } oldp=srcp=src; destp=allocp; while((oldp=strstr(srcp, old))) { len=oldp-srcp; memcpy(destp, srcp, len); destp+=len; memcpy(destp, rep, rep_size); destp+=rep_size; srcp=oldp+old_size; } len=src+src_size-srcp; memcpy(destp, srcp, len); destp+=len; *destp=ZERO; if(dest == src) // ?????????????? { strcpy(dest, allocp); free(allocp); } else { if(!dest) // ??? dest=allocp; } return(dest); }/*}}}*/ int str_is_dec(char *str) {/*{{{*/ if(str) { int i; int len=strlen(str); for(i=0; i<len; i++) if(!isdigit(str[i])) return(0); return(1); } return(0); }/*}}}*/ int str_is_hex(char *str) {/*{{{*/ if(str) { int i; for(i=0; i<strlen(str); i++) if(!isxdigit(str[i])) return(0); return(1); } return(0); }/*}}}*/ int dec_to_hex(int dec) {/*{{{*/ char buf[20]; sprintf(buf, "%d", dec); return(strtol(buf, NULL, 16)); }/*}}}*/ int pack_size(int org_size, int unit) {/*{{{*/ int res; if(org_size <= 0) return(0); if(unit <= 1) return(org_size); res=org_size % unit; return(res ? org_size+unit-res : org_size); }/*}}}*/ /*======*/ /* ?? */ /*======*/ unsigned short get_crc_16(unsigned char *p, int count) {/*{{{*/ static unsigned short a_crc_16[16]= { 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400 }; unsigned short r, crc = 0; while(count--) { r=a_crc_16[crc & 0xF]; crc=(crc>>4) & 0x0FFF; crc=crc^r^a_crc_16[*p & 0xF]; r=a_crc_16[crc & 0xF]; crc=(crc>>4) & 0x0FFF; crc=crc^r^a_crc_16[(*p>>4) & 0xF]; p++; } return(crc); }/*}}}*/ /*========*/ /* ??? */ /*========*/ int random_int(int min_val, int max_val, unsigned int *seedp) {/*{{{*/ if(min_val != max_val) { struct timeval time_val; unsigned int seed; if(min_val > max_val) { int tmp; tmp=min_val; min_val=max_val; max_val=tmp; } if(seedp) { if(*seedp == 0) { gettimeofday(&time_val, NULL); *seedp=(unsigned int)time_val.tv_usec; } } else { gettimeofday(&time_val, NULL); seed=time_val.tv_usec; seedp=&seed; } return(rand_r(seedp)%(max_val-min_val+1)+min_val); } return(min_val); }/*}}}*/ int random_array_int(int array[], int num) {/*{{{*/ if(!array || num <= 0) return(RET_ERR_PARA); if(num > 1) { int *arraytmp; int idx; unsigned int seed=0; ALLOC_MULTI_RETERR(arraytmp, int, num, RET_ERR_ALLOC); memcpy(arraytmp, array, num*sizeof(int)); while(num > 0) { idx=random_int(0, num-1, &seed); array[num-1]=arraytmp[idx]; memmove(&arraytmp[idx], &arraytmp[idx+1], (num-idx-1)*sizeof(int)); num--; } free(arraytmp); } return(0); }/*}}}*/ static char CHARBASE[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; char *random_password(char *password, int size) {/*{{{*/ if(!password) return(password); CLR_BUF(password); if(size <= 0) return(password); unsigned int seed=0; int i; for(i=0; i<size; ++i) { password[i]=CHARBASE[random_int(0, strlen(CHARBASE)-1, &seed)]; } password[size]=ZERO; return(password); }/*}}}*/ /*==============*/ /* ?????? */ /*==============*/ char *extract_dirname(char *filename, char *dirname) {/*{{{*/ if(dirname) { CLR_BUF(dirname); if(filename) { char fullname[LONG_FILE_NM_SIZE+1]; char *p; int len; strcpy(fullname, filename); len=strlen(fullname); if(strcmp(fullname, "/")) { if(fullname[len-1] == SLASH) fullname[len-1]=ZERO; if((p=strrchr(fullname, SLASH))) { len=p-fullname+1; strncpy(dirname, fullname, len); if(len > 1) len--; dirname[len]=ZERO; } else strcpy(dirname, "."); } else strcpy(dirname, "/"); } } return(dirname); }/*}}}*/ char *extract_basename(char *filename, char *basename) {/*{{{*/ if(basename) { CLR_BUF(basename); if(filename) { char fullname[LONG_FILE_NM_SIZE+1]; char *p; int len; strcpy(fullname, filename); len=strlen(fullname); if(strcmp(fullname, "/")) { if(fullname[len-1] == SLASH) fullname[len-1]=ZERO; if((p=strrchr(fullname, SLASH))) strcpy(basename, p+1); else strcpy(basename, fullname); } else strcpy(basename, "/"); } } return(basename); }/*}}}*/ int remove_dir(char *path) {/*{{{*/ struct stat st; int len; DIR *dirp; struct dirent *dp; char buf[LONG_FILE_NM_SIZE+1]; int result; if(stat(path, &st) != 0 || !S_ISDIR(st.st_mode)) { return(-1); } len=strlen(path); dirp=opendir(path); while((dp=readdir(dirp))) { if(dp->d_name[0] == '.') continue; sprintf(buf, "%s/%s", path, dp->d_name); if(stat(buf, &st) != 0) { closedir(dirp); return(-1); } //printf("%s\n", buf); if(S_ISDIR(st.st_mode)) { if((result=remove_dir(buf))) { closedir(dirp); return(result); } } else if(unlink(buf)) { closedir(dirp); return(-2); } } closedir(dirp); if(rmdir(path)) { return(-3); } return(0); }/*}}}*/ int create_dir(char *dir) {/*{{{*/ int res; struct stat st; if(!dir) return(RET_ERR_PARA); if(stat(dir, &st)) { if((res=get_last_error(NULL)) != ENOENT) { return(-1); } if(mkdir(dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1) { return(-2); } } else { if(!S_ISDIR(st.st_mode) || !(st.st_mode & S_IRUSR) || !(st.st_mode & S_IWUSR) || !(st.st_mode & S_IXUSR)) { return(-3); } } return(0); }/*}}}*/