/* 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 <string.h>
#include "fsearch.h"
#include "dbc.h"
#include "signal.h"
#include "var.h"
#include "face/fsface.h"
#include "face/lod.h"
#include "main.h"
#include "xml.h"
#include "ntlocale.h"
#include "face/themes.h"
using namespace d4x;
d4xEnginesList D4X_SEARCH_ENGINES;
char *cut_string(const char *str,int a,int b){
if (b<a) return NULL;
char *rval=new char[b-a+1];
memcpy(rval,str+a,b-a);
rval[b-a]=0;
return(rval);
};
char *str_regex_replace(const char *str){
char *badchars="[]\\.(){}:=";
int len=strlen(str);
const char *c=str;
while(*c){
if (index(badchars,*c))
len++;
c++;
};
char *rval=new char[len+1];
char *b=rval;
c=str;
while(*c){
if (index(badchars,*c)){
*b='\\';
b++;
};
*b=*c;
b++;
c++;
};
*b=0;
return(rval);
};
/****************************************************************/
void d4xSearchEngine::prepare_url(d4x::URL &adr,int size,const char *file,int num){
char data[100];
char *tmp=NULL,*tmp1;
char *f=unparse_percents((char*)file);
sprintf(data,"%i",num);
if (size>0){
tmp=str_replace(urlsize.get(),"[:num:]",data);
sprintf(data,"%li",size);
tmp1=str_replace(tmp,"[:size:]",data);
delete[] tmp;
tmp=str_replace(tmp1,"[:file:]",f);
}else{
tmp=str_replace(urlnosize.get(),"[:num:]",data);
tmp1=str_replace(tmp,"[:file:]",f);
delete[] tmp;
tmp=tmp1;
};
delete[] f;
adr=std::string(tmp);
delete[] tmp;
};
d4xSearchEngine *d4xEnginesList::first(){
return((d4xSearchEngine*)(tQueue::first()));
};
d4xSearchEngine *d4xEnginesList::next(){
return((d4xSearchEngine*)(tQueue::next()));
};
d4xSearchEngine *d4xEnginesList::prev(){
return((d4xSearchEngine*)(tQueue::prev()));
};
int d4xEnginesList::load(){
char *tmp=sum_strings(D4X_SHARE_PATH,"/ftpsearch.xml",NULL);
tQueue *data=d4x_xml_parse_file(tmp);
delete[] tmp;
char *cur=CFG.SEARCH_ENGINES;
if (data){
d4xXmlObject *obj=NULL;
while ((obj=(d4xXmlObject *)(data->first()))){
data->del(obj);
if (equal_uncase(obj->name.get(),"ftpsearch")){
d4xXmlField *fld=obj->get_attr("name");
d4xXmlObject *urlsize=obj->find_obj("urlsize");
d4xXmlObject *urlnosize=obj->find_obj("urlnosize");
d4xXmlObject *match=obj->find_obj("match");
if (fld && urlsize && urlnosize && match){
d4xSearchEngine *engine=new d4xSearchEngine;
engine->name.set(fld->value.get());
engine->urlsize.set(urlsize->value.get());
engine->urlnosize.set(urlnosize->value.get());
engine->match.set(match->value.get());
d4xFtpRegex test;
regex_t regs[2];
if (test.compile(match->value.get(),"test") &&
test.compile_regexes(regs)){
if (*cur){
if (*cur=='1')
engine->used=1;
cur++;
};
insert(engine);
regfree(regs);
regfree(regs+1);
}else
delete(engine);
};
};
delete(obj);
};
delete(data);
};
return(0);
};
d4xSearchEngine *d4xEnginesList::get_by_num(int num){
tNode *a=First;
while(a && num>0){
num--;
a=a->prev;
};
return((d4xSearchEngine*)a);
};
void d4xEnginesList::names2array(char **arr){
if (First){
int i=0;
tNode *a=First;
while(a){
arr[i++]=((d4xSearchEngine*)a)->name.get();
a=a->prev;
};
}else{
arr[0]=_("Check your installation of the Downloader");
};
};
d4xSearchEngine *d4xEnginesList::get_next_used_engine(d4xSearchEngine *cur){
d4xSearchEngine *b;
if (cur)
b=(d4xSearchEngine *)(cur->prev);
else
b=(d4xSearchEngine *)First;
while (b && b->used==0){
b=(d4xSearchEngine *)(b->prev);
};
return (b);
};
/****************************************************************/
d4xFtpRegex::d4xFtpRegex():left(NULL),center(NULL),right(NULL){};
int d4xFtpRegex::compile(const char *str,const char *file){
char *f=str_regex_replace(file);
char *s=str_replace(str,"[:file:]",f);
delete[] f;
char *a=strstr(s,"(:");
if (!a){
delete[] s;
return(0);
};
char *b=strstr(a+2,":)");
if (!b){
delete[] s;
return(0);
};
free();
left=cut_string(s,0,a-s);
center=cut_string(s,a-s+2,b-s);
right=cut_string(s,b-s+2,strlen(s));
delete[] s;
return(1);
};
int d4xFtpRegex::compile_regexes(regex_t *regs){
if (regcomp(regs,left,0))
return(0);
if (regcomp(regs+1,center,0)){
regfree(regs);
return(0);
};
return(1);
};
char *d4xFtpRegex::cut(const char *str,regex_t *regs){
regmatch_t rval[10];
regmatch_t rval2[10];
if (regexec(regs,str,10,rval,0)==0){
for (int i=0;i<100;i++){
if (rval[i].rm_so==-1) break;
if (regexec(regs+1,str+rval[i].rm_eo,10,rval2,0)==0){
if (rval2[0].rm_so==0)
return(cut_string(str+rval[i].rm_eo,0,rval2[0].rm_eo));
};
};
};
return(NULL);
};
void d4xFtpRegex::print(){
printf("%s\n%s\n%s\n",left,center,right);
};
void d4xFtpRegex::free(){
if (left) delete[] left;
if (right) delete[] right;
if (center) delete[] center;
left=right=center=NULL;
};
d4xFtpRegex::~d4xFtpRegex(){
free();
};
/****************************************************************/
tFtpSearchCtrl::tFtpSearchCtrl(){
for (int i=0;i<DL_FS_LAST;i++){
queues[i]=new tDList(i);
queues[i]->init(0);
};
view=(GtkTreeView *)NULL;
parent=(tMain*)NULL;
log=(tMLog*)NULL;
};
void tFtpSearchCtrl::init(GtkTreeView *v, tMain *papa,tMLog *mylog){
parent=papa;
view=v;
log=mylog;
};
void tFtpSearchCtrl::add(tDownload *what){
DBC_RETURN_IF_FAIL(what!=NULL);
what->info.proto=D_PROTO_SEARCH;
what->action=ACTION_NONE; //reping only flag
what->ActStatus=0; //cumulative reping flag
queues[DL_FS_WAIT]->insert(what);
if (view){
fs_list_add(view,what);
fs_list_show();
};
};
void tFtpSearchCtrl::reping(tDownload *what){
what->action=ACTION_REPING;
what->myowner->del(what);
if (what->config==NULL){
what->config=new tCfg;
what->set_default_cfg();
};
if (what->split){
delete(what->split);
what->split=NULL;
};
queues[DL_FS_WAIT]->insert(what);
fs_list_set_icon(view,what,LPE_WAIT);
};
void tFtpSearchCtrl::remove(tDownload *what){
DBC_RETURN_IF_FAIL(what!=NULL);
switch(what->owner()){
case DL_FS_RUN:
stop_thread(what);
what->action=ACTION_DELETE;
fs_list_set_icon(view,what,LPE_STOP_WAIT);
break;
case DL_FS_STOP:
case DL_FS_WAIT:
what->myowner->del(what);
remove_from_clist(what);
delete(what);
break;
default:
printf("WARNING: bug in ftp search!\n");
};
};
void tFtpSearchCtrl::remove_from_clist(tDownload *what){
if (view){
fs_list_remove(view,what);
if (queues[DL_FS_WAIT]->count()+
queues[DL_FS_STOP]->count()+
queues[DL_FS_RUN]->count()==0)
fs_list_hide();
};
};
void tFtpSearchCtrl::stop_all_offline(){
tDownload *tmp=queues[DL_FS_RUN]->last();
while(tmp){
tDownload *tmpnext=queues[DL_FS_RUN]->next();
stop_thread(tmp);
if (tmp->action!=ACTION_DELETE)
tmp->action=ACTION_CONTINUE;
tmp=tmpnext;
};
};
void tFtpSearchCtrl::cycle(){
/* stoping completed and failed */
if (CFG.OFFLINE_MODE) return;
tDownload *tmp=queues[DL_FS_RUN]->last();
while (tmp){
tDownload *tmpnext=queues[DL_FS_RUN]->next();
fs_list_set_count(view,tmp);
if (tmp->status==DOWNLOAD_REAL_STOP ||
tmp->status==DOWNLOAD_COMPLETE ||
tmp->status==DOWNLOAD_FATAL) {
queues[DL_FS_RUN]->del(tmp);
parent->prepare_for_stoping(tmp);
real_stop_thread(tmp);
parent->post_stopping(tmp);
switch(tmp->action){
case ACTION_DELETE:{
if (tmp->fsearch){
tDownload *a=ALL_DOWNLOADS->find(tmp);
if (a){
if (a->ALTS!=NULL){
a->ALTS->ftp_searching=0;
a->ALTS->set_find_sens();
};
};
};
remove_from_clist(tmp);
delete(tmp);
break;
};
case ACTION_CONTINUE:{
queues[DL_FS_WAIT]->insert(tmp);
fs_list_set_icon(view,tmp,LPE_WAIT);
if (tmp->config==NULL){
tmp->config=new tCfg;
tmp->set_default_cfg();
};
if (tmp->split){
delete(tmp->split);
tmp->split=NULL;
};
break;
};
default:{
if (view){
switch (tmp->status){
case DOWNLOAD_COMPLETE:{
fs_list_set_icon(view,tmp,LPE_COMPLETE);
if (tmp->fsearch){
tDownload *a=ALL_DOWNLOADS->find(tmp);
if (a){
if (a->ALTS==NULL) a->ALTS=new d4xAltList;
a->ALTS->fill_from_ftpsearch(tmp);
a->ALTS->ftp_searching=0;
a->ALTS->set_find_sens();
remove_from_clist(tmp);
delete(tmp);
tmp=NULL;
};
};
break;
};
case DOWNLOAD_REAL_STOP:
fs_list_set_icon(view,tmp,LPE_PAUSE);
break;
default:
fs_list_set_icon(view,tmp,LPE_STOP);
};
};
if (tmp) queues[DL_FS_STOP]->insert(tmp);
break;
};
};
};
tmp=tmpnext;
};
/* runing new */
tmp=queues[DL_FS_WAIT]->last();
while (tmp!=NULL && queues[DL_FS_RUN]->count()<5){
tDownload *tmpnext=queues[DL_FS_WAIT]->next();
if (parent->run_new_thread(tmp))
break;
queues[DL_FS_WAIT]->del(tmp);
queues[DL_FS_RUN]->insert(tmp);
if (view)
fs_list_set_icon(view,tmp,LPE_RUN);
tmp=tmpnext;
};
};
tFtpSearchCtrl::~tFtpSearchCtrl(){
tDownload *tmp=queues[DL_FS_STOP]->last();
while(tmp){
remove(tmp);
tmp=queues[DL_FS_STOP]->last();
};
tmp=queues[DL_FS_WAIT]->last();
while(tmp){
remove(tmp);
tmp=queues[DL_FS_WAIT]->last();
};
tmp=queues[DL_FS_RUN]->last();
while(tmp){
remove(tmp);
tmp=queues[DL_FS_RUN]->next();
};
while(queues[DL_FS_RUN]->count()){
cycle();
};
for (int i=0;i<DL_FS_LAST;i++){
delete(queues[i]);
};
};
syntax highlighted by Code2HTML, v. 0.9.1