/* Copyright (c) 1998 Alexander Yukhimets. All rights reserved. */
#include<stdio.h>
#include<string.h>
#include<signal.h>
#include<unistd.h>
#include<sys/time.h>
#include<sys/types.h>
#include"ftp_xfer.h"
static int interrupt;
static void handler(int sig){
(void)sig;
}
static int remove_cr(char* buf,int len){
int i,j;
for(i=0,j=0;j<len;j++){
if(buf[j]!='\r')buf[i++]=buf[j];
}
return i;
}
static int insert_cr(char* buf,int len,int total){
int i,j;
for(i=len,j=total;i>0;){
if((buf[--j]=buf[--i])=='\n'){
buf[--j]='\r';
if(i>=0 && buf[i]=='\r')i--;
}
}
memmove(buf,&buf[j],len=total-j);
return len;
}
int ftp_xfer_get(char mode,int remote,int local,ftp_xfer_proc proc,void* arg){
static char buf[1024];
fd_set selset;
struct timeval seltime;
int retval;
signal(SIGPIPE,handler);
interrupt=0;
for(;;){
FD_ZERO(&selset);
FD_SET(remote,&selset);
seltime.tv_sec=0;
seltime.tv_usec=100000;
retval=select(remote+1,&selset,NULL,NULL,&seltime);
if(retval<0){
signal(SIGPIPE,SIG_IGN);
interrupt=0;
return 1;
}
if(retval==0){
if(proc && (*proc)(0,arg)){
signal(SIGPIPE,SIG_IGN);
interrupt=0;
return -1;
}
} else {
if((retval=read(remote,buf,1024))<0){
signal(SIGPIPE,SIG_IGN);
interrupt=0;
return -1;
}
if(retval==0){
signal(SIGPIPE,SIG_IGN);
interrupt=0;
return 0;
}
if(mode=='A' || mode=='a' || mode=='T' || mode=='t'){
retval=remove_cr(buf,retval);
}
if(write(local,buf,retval)<0){
signal(SIGPIPE,SIG_IGN);
interrupt=0;
return 2;
}
if(proc && (*proc)(retval,arg)){
signal(SIGPIPE,SIG_IGN);
interrupt=0;
return -1;
}
if(interrupt){
signal(SIGPIPE,SIG_IGN);
interrupt=0;
return 1;
}
}
}
}
int ftp_xfer_put(char mode,int remote,int local,ftp_xfer_proc proc,void* arg){
static char buf[1024];
fd_set selset;
struct timeval seltime;
int retval,len;
signal(SIGPIPE,handler);
interrupt=0;
for(;;){
if((len=read(local,buf,
(mode=='A' || mode=='a' || mode=='T' || mode=='t')?512:1024))<0){
signal(SIGPIPE,SIG_IGN);
interrupt=0;
return 2;
}
if(len==0){
signal(SIGPIPE,SIG_IGN);
interrupt=0;
return 0;
}
if(mode=='A' || mode=='a' || mode=='T' || mode=='t'){
len=insert_cr(buf,len,1024);
}
for(;;){
FD_ZERO(&selset);
FD_SET(remote,&selset);
seltime.tv_sec=0;
seltime.tv_usec=100000;
retval=select(remote+1,NULL,&selset,NULL,&seltime);
if(retval<0){
signal(SIGPIPE,SIG_IGN);
interrupt=0;
return 1;
}
if(retval==0){
if(proc && (*proc)(0,arg)){
signal(SIGPIPE,SIG_IGN);
interrupt=0;
return -1;
}
} else {
if(write(remote,buf,len)<0){
signal(SIGPIPE,SIG_IGN);
interrupt=0;
return 1;
}
if(proc && (*proc)(len,arg)){
signal(SIGPIPE,SIG_IGN);
interrupt=0;
return -1;
}
if(interrupt){
signal(SIGPIPE,SIG_IGN);
interrupt=0;
return 1;
}
break;
}
}
}
}
syntax highlighted by Code2HTML, v. 0.9.1