/* Copyright (c) 1998 Alexander Yukhimets. All rights reserved. */
#include<string.h>
#include<time.h>
#include<stdlib.h>
#include<unistd.h>
#include<stdio.h>
#include<ctype.h>
#include<errno.h>
extern int errno;
#define SIZE 1024
#include"status.h"
#include"utils.h"
#include"ftp.h"
#include"ftp_xfer.h"
#include"dirinfo.h"
#include"functions.h"
#include"read_init.h"
#include"little_dialogs.h"
#include"axyftp.h"
extern void print_fileinfo(fileinfo*);
fileinfo** create_file_table(FILE*);
dirinfo* select_dirinfo(dirinfo* orig,int* sel){
dirinfo *di;
fileinfo *top,*fi;
int i;
di=(dirinfo*)WXmalloc(sizeof(dirinfo));
di->dir=WXnewstring(orig->dir);
top=fi=(fileinfo*)WXmalloc(sizeof(fileinfo));
fi->next=NULL;
fi->name=NULL;
fi->user=NULL;
fi->group=NULL;
fi->link=NULL;
for(di->total=0;sel[di->total]>=0;di->total++){
fi->next=copy_fileinfo(orig->files[sel[di->total]+1]);
fi=fi->next;
fi->next=NULL;
}
di->files=(fileinfo**)WXmalloc(sizeof(dirinfo*)*(di->total+1));
fi=top;
for(i=0;i<=di->total;i++){
di->files[i]=fi;
fi=fi->next;
}
return di;
}
void destroy_dirinfo(dirinfo* di){
if(di==NULL)return;
destroy_fileinfo(di->files[0]);
WXfree((char*)di->dir);
WXfree((char*)di);
}
struct _list_progress_data {
WXwidget label;
long got;
};
static int update_list_progress(int len,void* arg){
static char buf[50];
struct _list_progress_data *data;
data=(struct _list_progress_data*)arg;
if(len){
sprintf(buf,"%ld ",data->got+=(long)len);
WXsetLabel(data->label,buf);
}
return check_for_interrupt();
}
int read_remote_list(FILE* ls){
int ret;
struct _list_progress_data lpd;
lpd.got=0;
lpd.label=appdata.listprogress;
ret= ftp_xfer_get('A',appdata.connect.data,fileno(ls),
update_list_progress,(void*)&lpd);
WXsetLabel(lpd.label," ");
return ret;
}
dirinfo* create_remote_dirinfo(char* mask){
dirinfo* current;
FILE * ls;
fileinfo* f;
int result;
current=(dirinfo*)WXmalloc(sizeof(dirinfo));
if((result=ftp_pwd(¤t->dir,&appdata.connect,logfile,check_for_interrupt))!=0){
WXfree((char*)current);
if(result==10){
append_status("CONNECTION LOST\n");
appdata.connected=0;
(void)popup_reconnect_dialog(toplevel);
}
return NULL;
}
append_status(appdata.connect.lastline);
if(mask==NULL || strlen(mask)==0){
result=ftp_list(NULL,NULL,&appdata.connect,logfile,check_for_interrupt);
} else {
result=ftp_list("-ald",mask,&appdata.connect,logfile,check_for_interrupt);
}
if(result==10){
append_status("CONNECTION LOST\n");
appdata.connected=0;
(void)popup_reconnect_dialog(toplevel);
} else {
append_status(appdata.connect.lastline);
}
if(result){
WXfree((char*)current);
return NULL;
}
ls=tmpfile();
result=read_remote_list(ls);
if(result==-1){
append_status("CANCELLED\n");
if(!ftp_abort_data(&appdata.connect,logfile,check_for_interrupt)){
append_status(appdata.connect.lastline);
}
} else if(result){
append_status("CONNECTION FAILED\n");
if(!ftp_close_data(&appdata.connect,logfile,check_for_interrupt)){
append_status(appdata.connect.lastline);
}
} else {
if(!ftp_close_data(&appdata.connect,logfile,check_for_interrupt)){
append_status(appdata.connect.lastline);
}
}
lseek(fileno(ls),0,SEEK_SET);
current->files=create_file_table(ls);
fclose(ls);
current->total=0;
f=current->files[0];
while(f->next!=NULL){
current->total++;
f=f->next;
}
return current;
}
dirinfo* create_local_dirinfo(char* mask){
dirinfo* current;
FILE * ls;
fileinfo* f;
static char* command="/bin/ls -ald ";
char *buf;
int size;
int len;
current=(dirinfo*)WXmalloc(sizeof(dirinfo));
size=SIZE;
while(1) {
buf=WXmalloc(size);
if(getcwd(buf,size)==NULL)
if(errno==ERANGE){
WXfree(buf);
size*=2;
} else {
WXfree(buf);
WXfree((char*)current);
return NULL;
}
else break;
}
current->dir=WXmalloc(strlen(buf)+1);
strcpy(current->dir,buf);
WXfree(buf);
if(!mask)mask="";
len=strlen(mask);
if(len==0){
buf=WXnewstring("/bin/ls -al");
} else {
buf=WXmalloc(strlen(mask)+strlen(command)+1);
strcpy(buf,command);
strcat(buf,mask);
}
if((ls=popen(buf,"r"))==NULL){
perror("create_local_dirinfo");
exit(1);
}
WXfree(buf);
current->files=create_file_table(ls);
pclose(ls);
current->total=0;
f=current->files[0];
while(f->next!=NULL){
current->total++;
f=f->next;
}
return current;
}
int convert_month(char *month){
if(strcmp(month,"Jan")==0) return 1;
if(strcmp(month,"Feb")==0) return 2;
if(strcmp(month,"Mar")==0) return 3;
if(strcmp(month,"Apr")==0) return 4;
if(strcmp(month,"May")==0) return 5;
if(strcmp(month,"Jun")==0) return 6;
if(strcmp(month,"Jul")==0) return 7;
if(strcmp(month,"Aug")==0) return 8;
if(strcmp(month,"Sep")==0) return 9;
if(strcmp(month,"Oct")==0) return 10;
if(strcmp(month,"Nov")==0) return 11;
if(strcmp(month,"Dec")==0) return 12;
return 0;
}
int inthefuture(struct tm *t,int month,fileinfo *fi){
if(month > (t->tm_mon+1)) return 1;
return 0;
}
void set_fields(fileinfo** retval,int total){
char year[5];
int i,month;
time_t bigseconds;
struct tm *t;
bigseconds=time(NULL);
t=localtime(&bigseconds);
sprintf(year,"%.4d",1900+t->tm_year);
for(i=1;i<=total;i++){
/* SIZE */
sprintf(retval[i]->size_str,"%ld",retval[i]->size);
/* DATE */
if(retval[i]->date[0]=='\0'){
month=convert_month(retval[i]->month);
if(month==0){
retval[i]->date[0]='\0';
retval[i]->time[0]='\0';
} else {
if(strchr(retval[i]->time_year,':')!=NULL){
if(inthefuture(t,month,retval[i])){
sprintf(retval[i]->date,"%.4d%.2d%.2d",
t->tm_year+1899,month,retval[i]->day);
} else {
sprintf(retval[i]->date,"%.4d%.2d%.2d",
t->tm_year+1900,month,retval[i]->day);
}
if(strlen(retval[i]->time_year)>=5)
strcpy(retval[i]->time,retval[i]->time_year);
else
sprintf(retval[i]->time,"0%s",retval[i]->time_year);
} else {
sprintf(retval[i]->date,"%s%.2d%.2d",
retval[i]->time_year,month,retval[i]->day);
sprintf(retval[i]->time,"00:00");
}
}
} else {
if(strncmp(year,retval[i]->date,4)==0){
strcpy(retval[i]->time_year,retval[i]->time);
} else {
strncpy(retval[i]->time_year,retval[i]->date,4);
retval[i]->time_year[4]='\0';
}
}
}
return;
}
int check_presence(char* name, fileinfo* top){
while((top=top->next)!=NULL){
if(strcmp(top->name,name)==0)return 1;
}
return 0;
}
fileinfo** create_file_table(FILE *ls){
fileinfo** retval;
fileinfo *top, *current;
char buf[SIZE];
char *line, *s,*result;
int len,num,i;
current=top=(fileinfo*)WXmalloc(sizeof(fileinfo));
current->next=NULL;
current->name=NULL;
current->user=NULL;
current->group=NULL;
current->link=NULL;
num=1;
do {
line=WXmalloc(1);
line[0]='\0';
do {
if((result=fgets(buf,SIZE,ls))==NULL) break;
len=strlen(buf);
s=WXmalloc(strlen(line)+len+1);
strcpy(s,line);
strcat(s,buf);
WXfree(line);
line=s;
} while(len==SIZE-1 && buf[SIZE-2]!='\n');
current->next=create_fileinfo(line);
if(current->next==NULL)current->next=create_nt_fileinfo(line);
if(current->next!=NULL){
current=current->next;
num++;
}
WXfree(line);
} while(result!=NULL);
if(!check_presence("..",top)){
top->next=create_dummy_dir("..",top->next);
num++;
}
if(!check_presence(".",top)){
top->next=create_dummy_dir(".",top->next);
num++;
}
retval=(fileinfo**)WXmalloc(num*sizeof(fileinfo*));
current=top;
for(i=0;i<num;i++){
retval[i]=current;
current=current->next;
}
set_fields(retval,num-1);
return retval;
}
syntax highlighted by Code2HTML, v. 0.9.1