/* WebDownloader for X-Window * Copyright (C) 1999-2002 Koshelev Maxim * This Program is free but not GPL!!! You can't modify it * without agreement with author. You can't distribute modified * program but you can distribute unmodified program. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include #include #include #include #include #include #include #include "var.h" #include "dbc.h" /* char *copy_string(); return the same string allocated in new area; */ char *copy_string2(const char *src,int len) { if (src==NULL) return NULL; char *temp=new char[len+1]; if (temp){ strncpy(temp,src,len); temp[len]=0; }; return temp; }; char *copy_string(const char *src) { if (src==NULL) return NULL; return copy_string2(src,strlen(src)); }; /* int equal(const char, const char) params: two strings return: zero if a!=b and nonzero if a==b */ int equal(const char *a,const char *b) { if (!a) { if (b) return 0; return 1; }; if (!b) return 0; while (*a==*b && *a!=0) { a++; b++; }; if (*b==*a) return 1; return 0; }; /* the same as previos one but case insensetive */ int equal_uncase(const char *a,const char *b) { if (!a) { if (b) return 0; return 1; }; if (!b) return 0; if (strcasecmp(a,b)) return 0; return 1; }; /* int equal_first() params: two strings return: non zero if first string is begining of second one else return value is zero; */ int equal_first(const char *a,const char *b) { DBC_RETVAL_IF_FAIL(a!=NULL,0); DBC_RETVAL_IF_FAIL(b!=NULL,0); int la=strlen(a); int lb=strlen(b); if (la==0 || lb==0) return 0; int min=la=strlen(begin)) return 1; return 0; }; int begin_string_uncase(const char *str,const char *begin) { DBC_RETVAL_IF_FAIL(str!=NULL,0); DBC_RETVAL_IF_FAIL(begin!=NULL,0); if (equal_first_uncase(str,begin) && strlen(str)>=strlen(begin)) return 1; return 0; }; /* char *sum_strings() params: list if strings ended by NULL; return: cotatenated string */ char *sum_strings(const char *a,...){ DBC_RETVAL_IF_FAIL(a!=NULL,NULL); va_list args; int l=strlen(a)+1; va_start(args,a); char *s=va_arg(args, char*); while(s){ l+=strlen(s); s=va_arg(args, char*); }; char *r=new char[l]; if (r){ *r=0; strcat(r,a); va_start(args,a); s=va_arg(args, char*); while(s){ strcat(r,s); s=va_arg(args, char*); }; }; return r; }; char *compose_strings_array(int *len,const char *a,int la,const char *b){ DBC_RETVAL_IF_FAIL(a!=NULL,NULL); int lb=(b?strlen(b)+1:0); char *r=new char[la+lb]; memcpy(r,a,la); if (b) memcpy(r+la,b,lb); *len=la+lb; return r; }; // next function reallocate memory for string and return new size int reallocate_string(char **what, int len){ int newlen=len+MAX_LEN+1; char *temp=new char[newlen]; strncpy(temp,*what,len); temp[len+1]=0; delete *what; *what=temp; return newlen; }; /* int empty_string(); params: string return: non zero if string contains only spaces zero if not only spaces */ int empty_string(char *a) { DBC_RETVAL_IF_FAIL(a!=NULL,0); int len=strlen(a); for (int i=0;i inline std::string format_int_xx(Integral what) { if (what>=10) return boost::lexical_cast(what); return std::string("0")+boost::lexical_cast(what); }; /* convert_time(); params: number of seconds, pointer to buffer return: none action: convert number of seconds to nice string HH:MM:SS */ std::string convert_time(int what,int TIME_FORMAT) { int hours = what/int(3600); int mins = (what%3600)/int(60); if (!TIME_FORMAT) { int secs = what%60; return format_int_xx(hours)+":"+format_int_xx(mins)+":"+format_int_xx(secs); }; return format_int_xx(hours)+":"+format_int_xx(mins); }; /* string_to_low(); params: string; return: none; action: convert string to low case; */ void string_to_low(char *what) { DBC_RETURN_IF_FAIL(what!=NULL); while (*what) { if (*what>='A' && *what<='Z') *what+='a'-'A'; what+=1; }; }; /* the same as previos but till delimeter caracter */ void string_to_low(char *what,char delim) { DBC_RETURN_IF_FAIL(what!=NULL); char *temp=index(what,delim); while (*what && what!=temp) { if (*what>='A' && *what<='Z') *what+='a'-'A'; what+=1; }; }; char *index_mult(char *str,const char *what){ DBC_RETVAL_IF_FAIL(str!=NULL,NULL); DBC_RETVAL_IF_FAIL(what!=NULL,NULL); while (*str){ char *a=index(what,*str); if (a) return(str); str++; }; return(NULL); }; /* convert_from_hex() params: char return: integer equal to value in hexademal notation of specifyed character */ int convert_from_hex(unsigned char what) { if (what>='0' && what<='9') return(what-'0'); if (what>='a' && what<='f') return (10+what-'a'); if (what>='A' && what<='F') return (10+what-'A'); return -1; }; int convert_from_hex(char what) { if (what>='0' && what<='9') return(int(what)-'0'); if (what>='a' && what<='f') return (10+int(what)-'a'); if (what>='A' && what<='F') return (10+int(what)-'A'); return -1; }; int convert_from_hex(char a,char b) { int aa=convert_from_hex(a); int bb=convert_from_hex(b); if (aa<0 || bb<0) return 1000; return (aa<<4)|bb; }; /* convert_to_hex(); params: char, pointer to buffer return: none action: coverts character to hexademal string (e.g. ' ' -> "20") */ static const char _dec_to_hex_[16]={ '0','1','2','3','4','5','6','7','8','9', 'A','B','C','D','E','F' }; void convert_to_hex(unsigned char what,char *where) { DBC_RETURN_IF_FAIL(where!=NULL); *where = _dec_to_hex_[what/16]; where[1] = _dec_to_hex_[what%16]; }; void convert_to_hex_s(char what,char *where) { unsigned char b=*((unsigned char*)&what); convert_to_hex(b,where); }; /* parse_percents(); params: string return: new allocated string in which all %xx codes from input string are replaced. */ char *parse_percents(char *what) { DBC_RETVAL_IF_FAIL(what!=NULL,NULL); /* Next string is too ugly because I use "new" in separate threads; */ char *temp=new char[strlen(what)+1]; if (temp==NULL) return(NULL); char *where=temp,*old=what; while (*old) { switch (*old){ case '%':{ int num=convert_from_hex(old[1]); if (num>=0 && old[2]) { int num1=convert_from_hex(old[2]); if (num1>=0){ num=num *16 + num1; *where=char(num); old+=2; break; }; }; }; default:{ *where=*old; }; }; where+=1; old+=1; }; *where=0; return temp; }; /* unparse_percents(); params: string; return: allocated string in which special simbols from input are replaced by %xx; */ char *unparse_percents(char *what) { DBC_RETVAL_IF_FAIL(what!=NULL,NULL); const char *true_chars=".-+%"; const char *false_chars=":<>~ "; char *temp=what; int unparsed_len=0; while (*temp){ if ((*temp<'/' || *temp>'z' || index(false_chars,*temp)!=NULL) && index(true_chars,*temp)==NULL) unparsed_len+=3; else unparsed_len+=1; temp+=1; }; char *rvalue=new char[unparsed_len+1]; if (rvalue){ char *cur=rvalue; temp=what; while (*temp){ if ((*temp<'/' || *temp>'z'|| index(false_chars,*temp)!=NULL) && index(true_chars,*temp)==NULL){ *cur='%'; cur+=1; convert_to_hex(*temp,cur); cur+=1; }else *cur=*temp; cur+=1; temp+=1; }; *cur=0; }; return rvalue; }; static const char *_url_true_chars_=".-+&"; static const char *_url_false_chars_=":<>~% "; #include std::string hexed_string(const std::string &str){ std::string rval(str); std::string::size_type len=rval.length(),pos=0; char buf[4]={'%',0,0,0}; while(pos'z' || index(_url_false_chars_,r)) && index(_url_true_chars_,r)==0){ convert_to_hex_s(r,buf+1); rval.replace(pos,1,buf); pos+=2; len+=2; }; pos++; }; return rval; }; std::string unhexed_string(const std::string &str){ std::string::size_type pos=0; std::string::size_type len=str.length(); std::string rval(str); while((pos=rval.find('%',pos))!=std::string::npos){ if (len=pos+2){ int b=convert_from_hex(rval[pos+1],rval[pos+2]); if (b<256){ char buf[2]={b,0}; rval.replace(pos,3,buf); len-=2; }; }; pos++; }; return rval; }; /* escape_char(); params: string, char to search, escaped character; return: string action: allocate new string with char `what' escaped by char `bywhat' */ char *escape_char(const char *where,char what,char bywhat){ DBC_RETVAL_IF_FAIL(where!=NULL,NULL); int num=0; char *tmp=index(where,what); while(tmp){ num+=1; tmp=index(tmp+1,what); }; if (num){ char *rvalue=new char[strlen(where)+num*2+1]; *rvalue=0; char *r=rvalue; tmp=index(where,what); while(tmp){ if (tmp-where) memcpy(r,where,tmp-where); r+=tmp-where; r[0]=bywhat; r[1]=what; r+=2; where=tmp+1; tmp=index(where,what); }; *r=0; if (*where) memcpy(r,where,strlen(where)+1); return rvalue; }; return(copy_string(where)); }; /* str_non_print_replace(); params: string, char return: none action: replace all character<' ' in string `what' by `symbol' */ void str_non_print_replace(char *what,char symbol){ DBC_RETURN_IF_FAIL(what!=NULL); unsigned char *temp=(unsigned char *)what; while (*temp){ if (*temp<' ') *temp=(unsigned char )symbol; temp+=1; }; while (temp > (unsigned char *)what){ temp--; if (*temp==' ') *temp=0; else break; }; }; /* del_crlf() params: string return: none action: cut string to '\n' or '\r' */ void del_crlf(char *what) { DBC_RETURN_IF_FAIL(what!=NULL); char *tmp; while((tmp=rindex(what,'\n')) || (tmp=rindex(what,'\r'))) { *tmp=0; }; }; /* is_string() params: string return: non zero if there are not only digits in string zero if there are only digits in string */ int is_string(char *what){ DBC_RETVAL_IF_FAIL(what!=NULL,0); char *current=what; while (*current){ if (*current<'0' || *current>'9') return 1; current+=1; }; return 0; }; /* * This function extract string from string with spaces * for example: * given the string ' aa blala' * extracted value will be 'aa' */ char *my_space_locate(char *what){ DBC_RETVAL_IF_FAIL(what!=NULL,NULL); char *tmp=what; while (*tmp){ if (isspace(*tmp)) return(tmp); tmp+=1; }; return NULL; }; char *extract_string(char *src,char *dst) { DBC_RETVAL_IF_FAIL(src!=NULL,NULL); DBC_RETVAL_IF_FAIL(dst!=NULL,NULL); char *tmp=src; while (*tmp && isspace(*tmp)) tmp++; char *space=my_space_locate(tmp); while (*tmp && tmp!=space) { *dst=*tmp; dst++; tmp++; }; *dst=0; return tmp; }; char *extract_string(char *src,char *dst,int num){ DBC_RETVAL_IF_FAIL(src!=NULL,NULL); DBC_RETVAL_IF_FAIL(dst!=NULL,NULL); char *new_src=src; for (int i=0;isrc) b-=1; while (b>src && *b!='/') b-=1; a+=3; break; }; }; default: need_exit=1; }; if (*a==0) break; }while(!need_exit); }; if ((*b=*a)==0) return; b+=1; a+=1; }; *b=0; }; char *normalize_path_full(char *src){ DBC_RETVAL_IF_FAIL(src!=NULL,NULL); if (*src=='~'){ struct passwd *p; char *cur=index(src,'/'); if (src[1]=='/'){ p=getpwuid(getuid()); }else{ if (cur) *cur=0; p=getpwnam(src+1); if (cur) *cur='/'; }; if (p){ char *path=sum_strings(p->pw_dir,cur,NULL); normalize_path(path); return(path); }; }; char *rval=copy_string(src); normalize_path(rval); return(rval); }; /* FIXME: compose_path() should be rewritten!!! */ char *compose_path(const char *left,const char *right){ DBC_RETVAL_IF_FAIL(left!=NULL,NULL); DBC_RETVAL_IF_FAIL(right!=NULL,NULL); char *newpath=sum_strings(left,"/",right,NULL); normalize_path(newpath); return(newpath); }; /* char *compose_path(const char *left,const char *right) { DBC_RETVAL_IF_FAIL(left!=NULL,NULL); DBC_RETVAL_IF_FAIL(right!=NULL,NULL); char *newpath=NULL; int len=strlen(left); if (*right!='/' && (len==0 || left[len-1]!='/')) newpath=sum_strings(left,"/",right, NULL); else newpath=sum_strings(left,right, NULL); len=strlen("/../"); char *up=strstr(newpath,"/../"); while (up){ while (up>newpath && *(up-1)=='/') up-=1; *up=0; char *tmp=rindex(newpath,'/'); *up='/'; if (tmp){ while (tmp>newpath && *(tmp-1)=='/') tmp-=1; memmove(tmp+1,up+len,strlen(up+len)+1); }else{ memmove(newpath,up+len-1,strlen(up+len)+2); }; up=strstr(newpath,"/../"); }; if (!string_ended("/..",newpath)){ char *tmp=newpath+strlen(newpath)-3; while (tmp>newpath && *(tmp-1)=='/') tmp-=1; *tmp=0; tmp=rindex(newpath,'/'); if (tmp){ *tmp=0; }else{ *newpath=0; }; }; // printf("%s + %s -> %s\n",left,right,newpath); return(newpath); }; */ /* char *compose_path(const char *left,const char *right) { DBC_RETVAL_IF_FAIL(left!=NULL,NULL); DBC_RETVAL_IF_FAIL(right!=NULL,NULL); unsigned int ll=strlen(left); unsigned int rl=strlen(right); char *updir="../"; char *thisdir="./"; if (begin_string(right,updir) || equal(right,"..")) { char *tmp=rindex(left,'/'); if (ll && left[ll-1]=='/'){ char *tmp2=tmp; *tmp2=0; tmp=rindex(left,'/'); *tmp2='/'; }; if (tmp) { *tmp=0; int dl=rl>strlen("..")?strlen(updir):strlen(".."); char *tmp2=compose_path(left,right+dl); *tmp='/'; return tmp2; }; }; if (begin_string(right,thisdir)) return compose_path(left,right+strlen(thisdir)); if (ll && left[ll-1]!='/' && rl && *right!='/') return(sum_strings(left,"/",right,NULL)); return(sum_strings(left,right,NULL)); }; */ char *subtract_path(const char *a,const char *b){ DBC_RETVAL_IF_FAIL(a!=NULL,NULL); DBC_RETVAL_IF_FAIL(b!=NULL,NULL); int i=0; char *temp=index(b,'/'); while (temp){ while (*temp=='/') temp+=1; temp=index(temp,'/'); i+=1; }; i-=1; temp=rindex(a,'/'); while (temp && i>0){ *temp=0; char *tmp=rindex(a,'/'); *temp='/'; temp=tmp; i-=1; if (i==0){ tmp=copy_string(a); return tmp; }; }; return copy_string("/"); }; void scroll_string_left(char *str,unsigned int shift){ DBC_RETURN_IF_FAIL(str!=NULL); unsigned int len=strlen(str); if (len<=shift || shift==0) return; char *temp=new char[len+1]; if (temp==NULL) return; // can't allocate memory temp[len]=0; for (unsigned int i=0;i=len?shift+i-len:shift+i; temp[i]=str[realshift]; }; for (unsigned int i=0;i0){ int i=max; while(read(fd,cur,1)>0 && i>0) { i-=1; if (*cur=='\n') break; cur+=1; }; *cur=0; return max-i; }; *where=0; return 0; }; int write_named_string(int fd,const char *name,const char *str){ if (name==NULL || str==NULL) return(0); if (f_wstr_lf(fd,name)<0) return(-1); if (f_wstr_lf(fd,str)<0) return(-1); return 0; }; int write_named_integer(int fd,const char *name,int num){ if (name==NULL) return(0); if (f_wstr_lf(fd,name)<0) return(-1); char str[MAX_LEN]; g_snprintf(str,MAX_LEN,"%d",num); if (f_wstr_lf(fd,str)<0) return(-1); return 0; }; int write_named_time(int fd,const char *name,time_t when){ if (name==NULL) return(0); if (f_wstr_lf(fd,name)<0) return(-1); char str[MAX_LEN]; g_snprintf(str,MAX_LEN,"%ld",(long int)(when)); if (f_wstr_lf(fd,str)<0) return(-1); return 0; }; int write_named_fsize(int fd,const char *name,fsize_t size){ if (name==NULL) return(0); if (f_wstr_lf(fd,name)<0) return(-1); char str[MAX_LEN]; g_snprintf(str,MAX_LEN,"%lli",size); if (f_wstr_lf(fd,str)<0) return(-1); return 0; }; /* length of string with specified integer; */ int int_to_strin_len(int num){ int len=num<0?2:1; num/=10; while (num){ num/=10; len+=1; }; return len; }; /* scanf for int begined from zero */ int sscanf_int(char *str,int *where){ DBC_RETVAL_IF_FAIL(str!=NULL,0); DBC_RETVAL_IF_FAIL(where!=NULL,0); if (str==NULL) return 0; while (*str=='0' && str[1]!='0') str+=1; return(sscanf(str,"%i",where)); }; /* covert path from /lalala/lalala/%[D]_%[M] to /lalala/lalala/12_02 where 12 is current day 02 is current month */ enum DATE_FMTS_ENUM{ DFMT_DAY, DFMT_MONTH, DFMT_YEAR, DFMT_HOURS, DFMT_MINS, DFMT_SECS, DFMT_TIME, DFMT_DATE, DFMT_EXT, DFMT_NONE }; static char* date_fmts[]={ "[D]", //day "[M]", //month "[Y]", //year "[h]", //hours "[m]", //minutes "[s]", //seconds "[T]", // time in format HH:MM "[DATE]", // date in format DD_MM_YEAR "[E]" // extension of a file in upper case }; char *get_extension(const char *name){ if (name==NULL) return(NULL); const char *a=name+strlen(name)-1; while(a>=name){ if (*a=='.'){ a+=1; if (*a==0) return(NULL); char *rval=copy_string(a); string_to_low(rval); return(rval); }; if (*a=='/') return(NULL); a-=1; }; return(NULL); }; char *parse_save_path(const char *str,const char *file){ DBC_RETVAL_IF_FAIL(str!=NULL,NULL); int len=0; char *rval; char *ext=get_extension(file); int extlen=0; const char *a=str; time_t tmptime=time(NULL); struct tm *tmp_tm=new tm; localtime_r(&tmptime,tmp_tm); tmp_tm->tm_year+=1900; tmp_tm->tm_mon+=1; /* calc length of returned string */ while (*a){ if (*a=='%'){ unsigned int i; for (i=0;itm_year); a+=strlen(date_fmts[i]); break; case DFMT_YEAR: len+=int_to_strin_len(tmp_tm->tm_year); a+=strlen(date_fmts[i]); break; default: len+=1; break; }; }else{ len+=1; }; a+=1; }; rval=new char[len+1]; char *b=rval; a=str; #define FMT_TMP_NEXT b+=2;a+=strlen(date_fmts[i]);break while (*a){ if (*a=='%'){ unsigned int i; for (i=0;itm_mday); FMT_TMP_NEXT; case DFMT_MONTH: sprintf(b,"%02i",tmp_tm->tm_mon); FMT_TMP_NEXT; case DFMT_HOURS: sprintf(b,"%02i",tmp_tm->tm_hour); FMT_TMP_NEXT; case DFMT_MINS: sprintf(b,"%02i",tmp_tm->tm_min); FMT_TMP_NEXT; case DFMT_SECS: sprintf(b,"%02i",tmp_tm->tm_sec); FMT_TMP_NEXT; case DFMT_TIME: sprintf(b,"%02i:%02i", tmp_tm->tm_hour,tmp_tm->tm_min); b+=5; a+=strlen(date_fmts[i]); break; case DFMT_DATE: sprintf(b,"%02i_%02i_%i", tmp_tm->tm_mday,tmp_tm->tm_mon, tmp_tm->tm_year); b+=6+int_to_strin_len(tmp_tm->tm_year); a+=strlen(date_fmts[i]); break; case DFMT_YEAR: sprintf(b,"%i",tmp_tm->tm_year); b+=int_to_strin_len(tmp_tm->tm_year); a+=strlen(date_fmts[i]); break; default: *b=*a; b+=1; break; }; }else{ *b=*a; b+=1; }; a+=1; }; delete(tmp_tm); if (ext) delete[] ext; *b=0; return(rval); }; /* tPStr Protected String */ tPStr::tPStr(){ a=NULL; }; tPStr::tPStr(const char*s){ a=copy_string(s); }; bool tPStr::notempty(){ return(a!=NULL && a[0]!=0); }; void tPStr::set(const char *b){ if (a) delete[] a; a=copy_string(b); }; tPStr::~tPStr(){ if (a) delete[] a; }; /***************************************************************/ void make_proxy_host(const char *host,int port){ char *tmp=new char[strlen(host)+10]; char *b=tmp; while(*host!=':' && *host){ *b=*host; host++; b++; }; *b=':'; b++; sprintf(b,"%i",port); if (*tmp!=':' && *tmp) ALL_HISTORIES[PROXY_HISTORY]->add(tmp); delete[] tmp; }; int file_copy(char *from,char *to,char *buf,int size){ FILE *src=fopen(from,"r"); if (src==NULL){ return(-1); }; FILE *dst=fopen(to,"w+"); if (dst==NULL){ fclose(src); return(-1); }; int len=0; int rval=0; while ((len=fread(buf,1,size,src))>0){ if (fwrite(buf,len,1,dst)!=1){ rval=-1; break; }; }; fclose(dst); fclose(src); return(rval); };