/* Copyright (c) 1998 Alexander Yukhimets. All rights reserved. */
#include"utils.h"
#include"read_init.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"session_data.h"
#define SD_BUFSIZ 256
typedef int (*rw_entry_func)(int,session_data*);
typedef struct _sd_ver {
char* ver;
rw_entry_func readfunc;
} sd_ver;
static sd_ver sd_ver_list[]={
{"\x000\x000\x000",(rw_entry_func)NULL},
{"\x000\x000\x001",(rw_entry_func)NULL},
{(char*)NULL,(rw_entry_func)NULL}
};
static int init_done=0;
static int last_ver;
static int read_session_data_entry_0(int,session_data*);
static int read_session_data_entry_1(int,session_data*);
static void init_ver_list(){
sd_ver_list[0].readfunc=read_session_data_entry_0;
sd_ver_list[1].readfunc=read_session_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++;
}
}
void print_session_data(session_data*);
static int read_field(int fd,char** bp){
char* buf;
int alloc;
int len;
char* ptr;
alloc=SD_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+=SD_BUFSIZ);
}
}
WXfree(buf);
return 7;
}
void empty_session_data(session_data *sd){
if(sd==NULL)return;
WXfree(sd->profile);
WXfree(sd->host);
WXfree(sd->user);
WXfree(sd->pass);
WXfree(sd->account);
WXfree(sd->comment);
WXfree(sd->remdir);
WXfree(sd->locdir);
WXfree(sd->initcom);
WXfree(sd->locmask);
WXfree(sd->remmask);
sd->profile=strdup("");
sd->host=strdup("");
sd->user=strdup("");
sd->pass=strdup("");
sd->account=strdup("");
sd->comment=strdup("");
sd->anon='\0';
sd->save='\0';
sd->remdir=strdup("");
sd->locdir=strdup("");
sd->initcom=strdup("");
sd->locmask=strdup("");
sd->remmask=strdup("");
sd->port=strdup("21");
}
void destroy_session_data(session_data *sd){
if(sd==NULL)return;
WXfree(sd->profile);
WXfree(sd->host);
WXfree(sd->user);
WXfree(sd->pass);
WXfree(sd->account);
WXfree(sd->comment);
WXfree(sd->remdir);
WXfree(sd->locdir);
WXfree(sd->initcom);
WXfree(sd->locmask);
WXfree(sd->remmask);
WXfree(sd->port);
destroy_session_data(sd->next);
WXfree((char*)sd);
}
session_data* create_session_data(session_data* next){
session_data* sd;
sd=(session_data*)WXmalloc(sizeof(session_data));
sd->profile=NULL;
sd->host=NULL;
sd->user=NULL;
sd->pass=NULL;
sd->account=NULL;
sd->comment=NULL;
sd->anon='\0';
sd->save='\0';
sd->remdir=NULL;
sd->locdir=NULL;
sd->initcom=NULL;
sd->locmask=NULL;
sd->remmask=NULL;
sd->port=NULL;
sd->next=next;
return sd;
}
static int read_session_data_entry_0(int fd,session_data* top){
session_data * sd;
int len;
sd=top->next=create_session_data(NULL);
if((len=read_field(fd,&sd->profile))!=0){
destroy_session_data(sd);
top->next=NULL;
return (len==7)?1:(len-1);
}
if((len=read_field(fd,&sd->host))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((len=read_field(fd,&sd->user))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((len=read_field(fd,&sd->pass))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((len=read_field(fd,&sd->account))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((len=read_field(fd,&sd->comment))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((len=read(fd,&sd->anon,1))<0){
destroy_session_data(sd);
top->next=NULL;
return 5;
}
if((len=read(fd,&sd->save,1))<0){
destroy_session_data(sd);
top->next=NULL;
return 5;
}
if((len=read_field(fd,&sd->remdir))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((len=read_field(fd,&sd->locdir))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((len=read_field(fd,&sd->initcom))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((len=read_field(fd,&sd->locmask))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((len=read_field(fd,&sd->remmask))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
sd->port=strdup("21");
if((!sd->save) && sd->anon){
WXfree(sd->pass);
sd->pass=WXnewstring(anonymous_password);
}
return 0;
}
static int read_session_data_entry_1(int fd,session_data* top){
session_data * sd;
int len;
sd=top->next=create_session_data(NULL);
if((len=read_field(fd,&sd->profile))!=0){
destroy_session_data(sd);
top->next=NULL;
return (len==7)?1:(len-1);
}
if((len=read_field(fd,&sd->host))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((len=read_field(fd,&sd->user))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((len=read_field(fd,&sd->pass))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
rotate_str(sd->pass);
if((len=read_field(fd,&sd->account))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((len=read_field(fd,&sd->comment))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((len=read(fd,&sd->anon,1))<0){
destroy_session_data(sd);
top->next=NULL;
return 5;
}
if((len=read(fd,&sd->save,1))<0){
destroy_session_data(sd);
top->next=NULL;
return 5;
}
if((len=read_field(fd,&sd->remdir))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((len=read_field(fd,&sd->locdir))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((len=read_field(fd,&sd->initcom))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((len=read_field(fd,&sd->locmask))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((len=read_field(fd,&sd->remmask))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((len=read_field(fd,&sd->port))!=0){
destroy_session_data(sd);
top->next=NULL;
return len-1;
}
if((!sd->save) && sd->anon){
WXfree(sd->pass);
sd->pass=WXnewstring(anonymous_password);
}
return 0;
}
static int find_ver_index(char* buf,char* file){
int index;
if(!init_done)init_ver_list();
for(index=0;sd_ver_list[index].ver!=NULL;index++){
if(memcmp(buf,sd_ver_list[index].ver,SESSION_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_session_data(char* file,session_data* top){
int fd,len;
char buf[4];
int index=-1;
if((fd=open(file,O_RDONLY))<0){
fprintf(stderr,"Cannot open session data file %s for reading\n",file);
return 1;
}
if((len=read(fd,buf,SESSION_DATA_VERSION_LENGTH+1))
< SESSION_DATA_VERSION_LENGTH+1){
fprintf(stderr,"Cannot read the version of session data file %s\n",file);
close(fd);
return 2;
}
if((index=find_ver_index(buf,file))==-1){
fprintf(stderr,"Unknown version of session data file %s\n",file);
close(fd);
return 3;
}
while((len=(*sd_ver_list[index].readfunc)(fd,top))==0){
top=top->next;
}
return len-1;
}
int write_session_data(char* file,session_data* top){
int fd;
if((fd=open(file,O_WRONLY|O_CREAT|O_TRUNC,0600))<0){
fprintf(stderr,"Cannot open session data file %s for writing\n",file);
return 1;
}
if(!init_done)init_ver_list();
if(write(fd,sd_ver_list[last_ver].ver,SESSION_DATA_VERSION_LENGTH+1)<0){
fprintf(stderr,"Cannot write to session data file %s\n",file);
close(fd);
return 2;
}
while(top->next!=NULL){
top=top->next;
if(write(fd,top->profile,strlen(top->profile)+1)<0){
fprintf(stderr,"Cannot write to session data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,top->host,strlen(top->host)+1)<0){
fprintf(stderr,"Cannot write to session data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,top->user,strlen(top->user)+1)<0){
fprintf(stderr,"Cannot write to session data file %s\n",file);
close(fd);
return 2;
}
if(top->save){
rotate_str(top->pass);
if(write(fd,top->pass,strlen(top->pass)+1)<0){
fprintf(stderr,"Cannot write to session data file %s\n",file);
rotate_str(top->pass);
close(fd);
return 2;
}
rotate_str(top->pass);
} else {
if(write(fd,"",1)<0){
fprintf(stderr,"Cannot write to session data file %s\n",file);
close(fd);
return 2;
}
}
if(write(fd,top->account,strlen(top->account)+1)<0){
fprintf(stderr,"Cannot write to session data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,top->comment,strlen(top->comment)+1)<0){
fprintf(stderr,"Cannot write to session data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,&top->anon,sizeof(top->anon))<0){
fprintf(stderr,"Cannot write to session data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,&top->save,sizeof(top->save))<0){
fprintf(stderr,"Cannot write to session data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,top->remdir,strlen(top->remdir)+1)<0){
fprintf(stderr,"Cannot write to session data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,top->locdir,strlen(top->locdir)+1)<0){
fprintf(stderr,"Cannot write to session data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,top->initcom,strlen(top->initcom)+1)<0){
fprintf(stderr,"Cannot write to session data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,top->locmask,strlen(top->locmask)+1)<0){
fprintf(stderr,"Cannot write to session data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,top->remmask,strlen(top->remmask)+1)<0){
fprintf(stderr,"Cannot write to session data file %s\n",file);
close(fd);
return 2;
}
if(write(fd,top->port,strlen(top->port)+1)<0){
fprintf(stderr,"Cannot write to session data file %s\n",file);
close(fd);
return 2;
}
}
close(fd);
return 0;
}
void print_session_data(session_data* sd){
printf("\nProfile: %s|\nHost: %s\nUser: %s\nPassowrd: %s\nAccount: %s\n"
"Comment: %s\nAnonymous: %s\nSave Passowrd: %s\nRemDir: %s\n"
"LocDir: %s\nInit Command: %s\nLocMask: %s\nRemMask: %s\nPort: %s\n",
sd->profile,sd->host,sd->user,sd->pass,sd->account,
sd->comment,sd->anon?"YES":"NO",sd->save?"YES":"NO",sd->remdir,
sd->locdir,sd->initcom,sd->locmask,sd->remmask,sd->port);
}
syntax highlighted by Code2HTML, v. 0.9.1