/*
These functions are belonged to a libray which can be used to transfer file
simplely.
Copyright (C) 1994-1995, Li Suke, School of Software,Peking University
This is free software; you can redistribute it and/or
modify it freely.
This software 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 <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include "rw.h"
/***
* len: store the total receving data byte number
*
*/
ssize_t readall(int fd, void* buf,size_t *len){
size_t nleft;
ssize_t nread;
ssize_t total;
char *ptr;
ptr = buf;
nleft = *len;
total = 0;
while( nleft > 0){
if((nread = read(fd,ptr,*len)) == -1){
perror("readall");
break;
}
if(nread ==0)
break;
nleft -= nread;
ptr += nread;
total += nread;
*len = nleft;
}
*len = total;
return (nread==-1)?-1:0;
}
/***
* len: store the total sending data byte number
*
*/
ssize_t writeall(int fd, void* buf,size_t *len){
size_t nleft;
ssize_t nwrite;
ssize_t total;
const char *ptr;
ptr = buf;
nleft = *len;
total = 0;
while( nleft > 0){
if((nwrite = write(fd,ptr,*len))== -1){
perror("write all");
break;
}
nleft -= nwrite;
ptr += nwrite;
total += nwrite;
*len = nleft;
}
*len = total;
return (nwrite==-1)?-1:0;
}
/* read the commond from client, the command format is
content+\r\n
return value:
0: succesful
-1: failure
*/
int read_cmd(int sockfd,char* cmd_buf,int len){
char line[MAX_LEN];
int my_len = 0;
int total_len =0;
char *ptr;
int can_read;
if(len > MAX_LEN)
len = MAX_LEN;
can_read = 1;
strcpy(cmd_buf,"\0");
while(can_read){
if((my_len = read(sockfd, line,len))<0 ){
perror("read");
return -1;
}
total_len = total_len + my_len;
if(total_len > len){
printf("Recieve command error!\n");
return -1;
}
if((ptr=strstr(line,"\r\n"))==NULL){
if(total_len <= len)
strcat(cmd_buf, line);
}else{
strncat(cmd_buf,line,ptr-line);
can_read = 0;
}
printf("Client requests file: %s\n",cmd_buf);
}
return 0;
}
/* Send a file to client
return value:
0: successful
-1: failure
*/
int send_file(int sockfd,char *file_name)
{
int file_fd;
int file_size;
int read_left;
int len;
int error_flag;
int readlen;
struct stat file_state;
char buffer[MAX_LEN];
int dot_number = 0;
if((file_fd = open(file_name,O_RDONLY)) == -1){
perror("open");
return -1;
}
if(fstat(file_fd, &file_state)==-1){
perror("fstat");
return -1;
}
file_size = file_state.st_size;
read_left = file_size;
len = MAX_LEN;
while(read_left > 0){
/* now read the file */
readlen = MAX_LEN;
error_flag = readall(file_fd,buffer,&readlen);
if(error_flag<0 ){
return -1;
}
read_left -= readlen;
len = readlen;
error_flag = writeall(sockfd,buffer,&len);
if(error_flag == -1)
return -1;
if(readlen ==0 && read_left!=0){
printf("the file is not read fully!\n");
return -1;
}
if(read_left ==0){
printf("\nServer sent file over!\n");
}
}
close(file_fd);
return 0;
}