/* 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 "cookie.h" #include "locstr.h" #include "var.h" #include "ntlocale.h" #include #include #include #include #include #include #include #include #include /* determine which cookies file is newer Netscape or Mozilla's one It's allowed to use non reentrant variance of readdir() cos here's first place where readdir() is used */ char *d4x_get_best_in_subdir(const char *path,time_t *a){ DIR *d=opendir(path); char *best=NULL; time_t besttime=0; if (d){ struct dirent *de=NULL; while((de=readdir(d))){ if (de->d_name && !equal(de->d_name,"..") && !equal(de->d_name,".")){ char *tmppath=sum_strings(path,"/",de->d_name,NULL); struct stat s; stat(tmppath,&s); if (S_ISDIR(s.st_mode)){ char *p=sum_strings(tmppath,"/","cookies.txt",NULL); if (stat(p,&s)==0 && S_ISREG(s.st_mode) && (best==NULL || besttimed_name && !equal(de->d_name,"..") && !equal(de->d_name,".")){ tmppath=sum_strings(HOME_VARIABLE,"/.mozilla/",de->d_name,NULL); struct stat s; stat(tmppath,&s); if (S_ISDIR(s.st_mode)){ time_t a; char *p1=d4x_get_best_in_subdir(tmppath,&a); if (p1 && a>besttime){ if (best) delete[] best; best=p1; besttime=a; }; }; delete[] tmppath; }; }; closedir(d); }; tmppath=sum_strings(HOME_VARIABLE,"/.netscape/cookies",NULL); struct stat s; if (stat(tmppath,&s)==0 && S_ISREG(s.st_mode) && (s.st_mtime>besttime || best==NULL)){ if (best) delete[] best; best=tmppath; }else delete[] tmppath; return(best); }; /*******************************************************/ tCookie::tCookie(){ time_of_life=time_t(0); myown=0; }; void tCookie::set_time(time_t t){ time_of_life=t; }; void tCookie::set_time(const std::string &what){ time_of_life=strtoll(what.c_str(), (char **)NULL, 10); }; void tCookie::init(char *a,char *b,char *c,char *d){ host=a; path=b; name=c; value=d; }; time_t tCookie::get_time(){ return time_of_life;}; void tCookie::print(){ }; int tCookie::parse(char *str,const char *srchost,const char *srcpath){ char *cur=str; while(cur && *cur){ cur=skip_spaces(cur); char *n=index(cur,';'); if (n) *n=0; char *eq=index(cur,'='); if (eq){ *eq=0; char *a=copy_string(cur); char *b=a+strlen(a)-1; while (isspace(*b) && b>a){ *b=0; b--; }; b=skip_spaces(eq+1); char *c=copy_string(b); b=c+strlen(c)-1; while (isspace(*b) && b>c){ *b=0; b--; }; if (name.empty()){ name=a; value=c; }; if (equal_uncase(a,"expires")){ time_of_life=ctime_to_time(c); }; if (equal_uncase(a,"path")){ path=c; }; if (equal_uncase(a,"domain")){ host=c; }; delete[] a; delete[] c; *eq='='; }; if (n){ *n=';'; n+=1; }; cur=n; }; if (time_of_life==0) time_of_life=time(NULL)+30*3600; if (srchost && host.empty()) host=srchost; if (srcpath && path.empty()){ path=std::string("/")+srcpath; }; if (name.empty() || value.empty() || path.empty() || host.empty()) return(1); return(0); }; int cmp_back(const char *a,const char *b){ const char *bb=b+strlen(b)-1; const char *aa=a+strlen(a)-1; while(bb>b && aa>a){ if (*bb!=*aa) return(*bb-*aa); bb--;aa--; }; if (bb>b) return(-1); if (aa>a) return(1); return(0); }; int tCookie::cmp(tAbstractSortNode *b){ DBC_RETVAL_IF_FAIL(b!=NULL,0); // printf("%s %s %i\n",((tCookie *)b)->host.get(),host.get(),cmp_back(((tCookie *)b)->host.get(),host.get())); return(cmp_back(((tCookie *)b)->host.c_str(),host.c_str())); }; tCookie::~tCookie(){ }; /* */ tCookie *tCookiesTree::find_exact(tCookie *cookie){ tCookie *temp=find(cookie->host.c_str()); while (temp){ if (cookie->path==temp->path && cookie->name==temp->name){ return temp; }; temp=find(temp,cookie->host.c_str()); }; return(NULL); }; tCookie *tCookiesTree::find(const char *what) { DBC_RETVAL_IF_FAIL(what!=NULL,NULL); if (Top && string_ended(((tCookie*)Top)->host.c_str(),what)==0) return((tCookie*)Top); // if (Top) printf("--- find from %s ---\n",((tCookie *)Top)->host.get()); return find((tCookie *)Top,what); }; tCookie *tCookiesTree::find(tCookie *begin,const char *what) { tCookie *temp=begin; while (temp) { // printf("%s %s ",temp->host.get(),what); int a=cmp_back(what,temp->host.c_str()); if (a<0){ temp=(tCookie *)(temp->more); }else { temp=(tCookie *)(temp->less); }; if (temp && string_ended(temp->host.c_str(),what)==0){ return temp; }; }; return NULL; }; char *D4X_COOKIES_FILE="cookies.txt"; void tCookiesTree::load_from_file(int fd,int myown){ char temp[MAX_LEN]; while (f_rstr(fd,temp,MAX_LEN)){ if (*temp!='#'){ tCookie *cookie=new tCookie; std::istringstream ist(temp); std::string s,t; ist>>cookie->host>>s>>cookie->path>>s>>t>>cookie->name>>cookie->value; cookie->set_time(t); cookie->myown=myown; if (cookie->path.empty() || find_exact(cookie)) delete(cookie); else add(cookie); }; }; }; void tCookiesTree::save_cookie(int fd,tCookie *what){ if (what->myown){ f_wstr(fd,what->host.c_str()); f_wstr(fd,"\tFALSE\t"); f_wstr(fd,hexed_string(what->path).c_str()); f_wstr(fd,"\tFALSE\t"); static char str[MAX_LEN]; sprintf(str,"%ld",(long int)(what->get_time())); f_wstr(fd,str); f_wchar(fd,'\t'); f_wstr(fd,hexed_string(what->name).c_str()); f_wchar(fd,'\t'); f_wstr(fd,hexed_string(what->value).c_str()); f_wchar(fd,'\n'); }; if (what->less) save_cookie(fd,(tCookie *)(what->less)); if (what->more) save_cookie(fd,(tCookie *)(what->more)); }; void tCookiesTree::save_cookies(){ char *path=sum_strings(HOME_VARIABLE,"/",CFG_DIR,"/",D4X_COOKIES_FILE,NULL); int fd=open(path,O_TRUNC | O_CREAT |O_RDWR,S_IRUSR | S_IWUSR); delete[] path; if (fd>=0){ if (Top) save_cookie(fd,(tCookie*)Top); close(fd); }; }; void tCookiesTree::load_cookies(){ char *path=d4x_get_best_cookies(); MainLog->add(_("Loading cookies"),LOG_WARNING | LOG_DETAILED); if (path!=NULL){ int fd=open(path,O_RDONLY); if (fd>=0){ load_from_file(fd); close(fd); MainLog->myprintf(LOG_OK|LOG_DETAILED,_("%i cookies loaded from browsers' files"),NUM); }else{ MainLog->myprintf(LOG_ERROR|LOG_DETAILED,_("Can't open cookies file %s!"),path); }; delete[] path; }; path=sum_strings(HOME_VARIABLE,"/",CFG_DIR,"/",D4X_COOKIES_FILE,NULL); int fd=open(path,O_RDONLY); delete[] path; if (fd>=0){ load_from_file(fd,1); close(fd); MainLog->myprintf(LOG_OK|LOG_DETAILED,_("%i cookies loaded"),NUM); }; }; tCookiesTree::~tCookiesTree(){ while (Top){ tCookie *temp=(tCookie *)Top; del((tCookie*)Top); delete(temp); }; };