/* Copyright (c) 1998 Alexander Yukhimets. All rights reserved. */
#include"utils.h"
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include"read_init.h"
#include"options_data.h"
#define OPT_BUFSIZ 256
typedef int (*rw_option_func)(int,options_data**);
typedef struct _opt_ver {
char* ver;
rw_option_func readfunc;
} opt_ver;
static opt_ver opt_ver_list[]={
{"\x000\x000\x000",(rw_option_func)NULL},
{"\x000\x000\x001",(rw_option_func)NULL},
{(char*)NULL,(rw_option_func)NULL}
};
static int init_done=0;
static int last_ver;
static int read_options_data_entry_0(int,options_data**);
static int read_options_data_entry_1(int,options_data**);
static void init_ver_list(){
opt_ver_list[0].readfunc=read_options_data_entry_0;
opt_ver_list[1].readfunc=read_options_data_entry_1;
last_ver=1;
init_done=1;
}
/*
static char rotate(char in){
if(in<'A')return in;
if(in<'N')return (in+13);
if(in<='Z')return (in-13);
if(in<'a')return in;
if(in<'n')return (in+13);
if(in<='z')return (in-13);
return in;
}
static void rotate_str(char* str){
while(*str!='\0'){
*str=rotate(*str);
str++;
}
}
*/
static int read_field(int fd,char** bp){
char* buf;
int alloc;
int len;
char* ptr;
alloc=OPT_BUFSIZ;
buf=WXmalloc(alloc);
ptr=buf;
while((len=read(fd,ptr,1))>0){
if(*ptr++=='\0'){
*bp=WXrealloc(buf,ptr-buf);
return 0;
}
if((ptr-buf)>=alloc){
buf=WXrealloc(buf,alloc+=OPT_BUFSIZ);
}
}
WXfree(buf);
return 7;
}
void empty_options_data(options_data *opt){
if(opt==NULL)return;
WXfree(opt->anonpass);
WXfree(opt->maxwidth);
WXfree(opt->progress_treshold);
WXfree(opt->redial);
WXfree(opt->delay);
opt->anonpass=strdup(anonymous_password);
opt->deletions='\1';
opt->recurse_del='\0';
opt->show_session='\1';
opt->columnadjustment='\1';
opt->maxwidth=strdup("30");
opt->show_progress='\1';
opt->progress_treshold=strdup("1");
opt->xferbeep='\1';
opt->redial=strdup("10");
opt->delay=strdup("10");
}
void destroy_options_data(options_data *opt){
if(opt==NULL)return;
WXfree(opt->anonpass);
WXfree(opt->maxwidth);
WXfree(opt->progress_treshold);
WXfree(opt->redial);
WXfree(opt->delay);
WXfree((char*)opt);
}
options_data* create_options_data(options_data* orig){
options_data* opt;
opt=(options_data*)WXmalloc(sizeof(options_data));
opt->anonpass=NULL;
opt->deletions='\0';
opt->recurse_del='\0';
opt->show_session='\0';
opt->columnadjustment='\0';
opt->maxwidth=NULL;
opt->show_progress='\0';
opt->progress_treshold=NULL;
opt->xferbeep='\0';
opt->redial=NULL;
opt->delay=NULL;
if(orig!=NULL){
opt->anonpass=strdup(orig->anonpass);
opt->deletions=orig->deletions;
opt->recurse_del=orig->recurse_del;
opt->show_session=orig->show_session;
opt->columnadjustment=orig->columnadjustment;
opt->maxwidth=strdup(orig->maxwidth);
opt->show_progress=orig->show_progress;
opt->progress_treshold=strdup(orig->progress_treshold);
opt->xferbeep=orig->xferbeep;
opt->redial=strdup(orig->redial);
opt->delay=strdup(orig->delay);
}
return opt;
}
static int read_options_data_entry_1(int fd,options_data** top){
int len;
options_data* sd;
sd=*top=create_options_data(NULL);
if((len=read_field(fd,&sd->anonpass))!=0){
destroy_options_data(sd);
*top=NULL;
return (len==7)?1:(len-1);
}
if((len=read(fd,&sd->deletions,1))<0){
destroy_options_data(sd);
*top=NULL;
return 5;
}
if((len=read(fd,&sd->recurse_del,1))<0){
destroy_options_data(sd);
*top=NULL;
return 5;
}
if((len=read(fd,&sd->show_session,1))<0){
destroy_options_data(sd);
*top=NULL;
return 5;
}
if((len=read(fd,&sd->columnadjustment,1))<0){
destroy_options_data(sd);
*top=NULL;
return 5;
}
if((len=read_field(fd,&sd->maxwidth))!=0){
destroy_options_data(sd);
*top=NULL;
return (len==7)?1:(len-1);
}
if((len=read(fd,&sd->show_progress,1))<0){
destroy_options_data(sd);
*top=NULL;
return 5;
}
if((len=read_field(fd,&sd->progress_treshold))!=0){
destroy_options_data(sd);
*top=NULL;
return (len==7)?1:(len-1);
}
if((len=read(fd,&sd->xferbeep,1))<0){
destroy_options_data(sd);
*top=NULL;
return 5;
}
if((len=read_field(fd,&sd->redial))!=0){
destroy_options_data(sd);
*top=NULL;
return (len==7)?1:(len-1);
}
if((len=read_field(fd,&sd->delay))!=0){
destroy_options_data(sd);
*top=NULL;
return (len==7)?1:(len-1);
}
return 0;
}
static int read_options_data_entry_0(int fd,options_data** top){
int len;
options_data* sd;
sd=*top=create_options_data(NULL);
if((len=read_field(fd,&sd->anonpass))!=0){
destroy_options_data(sd);
*top=NULL;
return (len==7)?1:(len-1);
}
if((len=read(fd,&sd->deletions,1))<0){
destroy_options_data(sd);
*top=NULL;
return 5;
}
if((len=read(fd,&sd->columnadjustment,1))<0){
destroy_options_data(sd);
*top=NULL;
return 5;
}
if((len=read_field(fd,&sd->maxwidth))!=0){
destroy_options_data(sd);
*top=NULL;
return (len==7)?1:(len-1);
}
if((len=read(fd,&sd->xferbeep,1))<0){
destroy_options_data(sd);
*top=NULL;
return 5;
}
sd->recurse_del='\0';
sd->show_session='\1';
sd->show_progress='\1';
sd->progress_treshold=strdup("1");
sd->redial=strdup("10");
sd->delay=strdup("10");
return 0;
}
static int find_ver_index(char* buf,char* file){
int index;
if(!init_done)init_ver_list();
for(index=0;opt_ver_list[index].ver!=NULL;index++){
if(memcmp(buf,opt_ver_list[index].ver,OPTIONS_DATA_VERSION_LENGTH+1)==0)
break;
}
if(index!=last_ver){
char* command;
command=WXmalloc(2*strlen(file)+20);
sprintf(command,"/bin/cp -f %s %s.old",file,file);
(void)system(command);
WXfree(command);
}
if(last_ver<index)return -1;
else return index;
}
int read_options_data(char* file,options_data** top){
int fd,len;
char buf[4];
int index=-1;
if((fd=open(file,O_RDONLY))<0){
fprintf(stderr,"Cannot open options data file %s for reading\n",file);
return 1;
}
if((len=read(fd,buf,OPTIONS_DATA_VERSION_LENGTH+1))
< OPTIONS_DATA_VERSION_LENGTH+1){
fprintf(stderr,"Cannot read the version of options data file %s\n",file);
close(fd);
return 2;
}
if((index=find_ver_index(buf,file))==-1){
fprintf(stderr,"Unknown version of options data file %s\n",file);
close(fd);
return 3;
}
len=(*opt_ver_list[index].readfunc)(fd,top);
return len-1;
}
int write_options_data(char* file,options_data* opt){
int fd;
if((fd=open(file,O_WRONLY|O_CREAT|O_TRUNC,0600))<0){
fprintf(stderr,"Cannot open options data file %s for writing\n",file);
return 1;
}
if(!init_done)init_ver_list();
if(write(fd,opt_ver_list[last_ver].ver,OPTIONS_DATA_VERSION_LENGTH+1)<0){
fprintf(stderr,"Cannot write to options data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,opt->anonpass,strlen(opt->anonpass)+1)<0){
fprintf(stderr,"Cannot write to options data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,&opt->deletions,sizeof(opt->deletions))<0){
fprintf(stderr,"Cannot write to options data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,&opt->recurse_del,sizeof(opt->recurse_del))<0){
fprintf(stderr,"Cannot write to options data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,&opt->show_session,sizeof(opt->show_session))<0){
fprintf(stderr,"Cannot write to options data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,&opt->columnadjustment,sizeof(opt->columnadjustment))<0){
fprintf(stderr,"Cannot write to options data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,opt->maxwidth,strlen(opt->maxwidth)+1)<0){
fprintf(stderr,"Cannot write to options data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,&opt->show_progress,sizeof(opt->show_progress))<0){
fprintf(stderr,"Cannot write to options data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,opt->progress_treshold,strlen(opt->progress_treshold)+1)<0){
fprintf(stderr,"Cannot write to options data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,&opt->xferbeep,sizeof(opt->xferbeep))<0){
fprintf(stderr,"Cannot write to options data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,opt->redial,strlen(opt->redial)+1)<0){
fprintf(stderr,"Cannot write to options data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,opt->delay,strlen(opt->delay)+1)<0){
fprintf(stderr,"Cannot write to options data file %s\n",file);
close(fd);
return 2;
}
close(fd);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1