c socket send file that contain LIST
I'm developing a small FTP Server and i have a trouble with the LIST command. Here all the code of my ftp server:
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <signal.h>
#include <dirent.h>
#include "prototypes.h"
int main(int argc, char *argv[]){
check_before_start(argc, argv);
int sockd, newsockd, socket_len, rc, rc_list, fd, fpl, i;
int NumPorta = atoi(argv[1]);
struct sockaddr_in serv_addr, cli_addr; /* strutture contenenti indirizzo del server e del client */
off_t offset = 0, offset_list = 0; /* variabile di tipo offset */
struct stat stat_buf; /* struttura contenente informazioni sul file scelto */
struct hostent *local_ip; /* struttura contenente ip server */
static char filename[1024], buffer[256], saved_user[256]; /* dichiaro static cosė viene direttamente inizializzato a 0 l'array */
char *user_string = NULL, *username = NULL, *pass_string = NULL, *password = NULL, *other = NULL; /* puntatori per uso vario */
size_t fsize; /* grandezza file */
char **files;
FILE *fp_list;
size_t count;
if((sockd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
perror("Errore creazione socket\n");
exit(EXIT_FAILURE);
}
bzero((char *) &serv_addr, sizeof(serv_addr)); /* bzero scrive dei null bytes dove specificato per la lunghezza specificata */
serv_addr.sin_family = AF_INET; /* la famiglia dei protocolli */
serv_addr.sin_port = htons(NumPorta); /* porta htons converte nell'ordine dei byte di rete */
serv_addr.sin_addr.s_addr = INADDR_ANY; /* dato che č un server bisogna associargli l'indirizzo della macchina su cui sta girando */
if(bind(sockd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){
perror("Errore di bind\n");
onexit(0, sockd, 0, 1);
}
if(listen(sockd, 5) < 0){
perror("Errore nella funzione listen");
onexit(0, sockd, 0, 1);
}
socket_len = sizeof(cli_addr);
if((local_ip = gethostbyname("localhost")) == NULL){
perror("gethostbyname()");
exit(1);
}
signal (SIGINT, ( void *)sig_handler); /* se premuto CTRL+C il server termina */
while(1){
if((newsockd = accept(sockd, (struct sockaddr *) &cli_addr, (socklen_t *) &socket_len)) < 0){
perror("Errore nella connessione\n");
onexit(newsockd, sockd, 0, 2);
}
/* inet_ntoa converte un hostname in un ip decimale puntato */
fprintf(stdout, "Ricevuta richiesta di connessione dall' indirizzo %s\n", inet_ntoa(cli_addr.sin_addr));
/************************* MESSAGGIO DI BENVENUTO *************************/
sprintf(buffer, "220 FTPUtils SERVER [%s]", local_ip->h_name);
if(send(newsockd, buffer, strlen(buffer), 0) < 0){
perror("Errore durante l'invio");
onexit(newsockd, sockd, 0, 2);
}
memset(buffer, '0', sizeof(buffer));
/************************* FINE MESSAGGIO DI BENVENUTO *************************/
/************************* INIZIO PARTE LOGIN *************************/
/************************* RICEVIAMO NOME UTENTE E MANDIAMO CONFERMA *************************/
if(recv(newsockd, buffer, sizeof(buffer), 0) < 0){
perror("Errore nella ricezione del nome utente");
onexit(newsockd, sockd, 0, 2);
}
user_string = strtok(buffer, " ");
username = strtok(NULL, "\n");
fprintf(stdout, "%s %s\n", user_string, username);
sprintf(saved_user, "%s", username);
memset(buffer, '0', sizeof(buffer));
strcpy(buffer, "USEROK\n");
if(send(newsockd, buffer, strlen(buffer), 0) < 0){
perror("Errore durante l'invio");
onexit(newsockd, sockd, 0, 2);
}
memset(buffer, '0', sizeof(buffer));
/************************* FINE NOME UTENTE *************************/
/************************* RICEVIAMO PASSWORD E MANDIAMO CONFERMA *************************/
if(recv(newsockd, buffer, sizeof(buffer), 0) < 0){
perror("Errore nella ricezione del nome utente");
onexit(newsockd, sockd, 0, 2);
}
pass_string = strtok(buffer, " ");
password = strtok(NULL, "\n");
fprintf(stdout, "%s %s\n", pass_string, password);
memset(buffer, '0', sizeof(buffer));
strcpy(buffer, "PASSOK\n");
if(send(newsockd, buffer, strlen(buffer), 0) < 0){
perror("Errore durante l'invio");
onexit(newsockd, sockd, 0, 2);
}
memset(buffer, '0', sizeof(buffer));
/************************* FINE PASSWORD *************************/
/************************* INVIO CONFERMA LOG IN *************************/
sprintf(buffer, "230 USER %s logged in\n", saved_user);
if(send(newsockd, buffer, strlen(buffer), 0) < 0){
perror("Errore durante l'invio");
onexit(newsockd, sockd, 0, 2);
}
memset(buffer, '0', sizeof(buffer));
/************************* FINE CONFERMA LOG IN *************************/
/************************* FINE PARTE LOGIN *************************/
/************************* RICEZIONE RICHIESTA LIST E INVIO LISTA *************************/
if(recv(newsockd, buffer, sizeof(buffer), 0) < 0){
perror("Errore nella ricezione del nome utente");
onexit(newsockd, sockd, 0, 2);
}
other = strtok(buffer, "\n");
if(strcmp(other, "LIST") == 0){
printf("Ricevuta richiesta LIST\n");
} else onexit(newsockd, sockd, 0, 2);
count = file_list("/home/pol/c-dev", &files);
if((fp_list = fopen("listfiles.txt", "w")) == NULL){
perror("Impossibile aprire il file per la scrittura LIST");
exit(EXIT_FAILURE);
}
for(i=0; i < count; i++){
if(strcmp(files[i], "DIR ..") == 0 || strcmp(files[i], "DIR .") == 0){
continue;
} else{
fprintf(fp_list, "%s\n", files[i]);
}
}
return 0;
if((fpl = open("listfiles.txt", O_RDONLY)) < 0){
perror("open file with open");
exit(1);
}
if(fstat(fpl, &stat_buf) < 0){
perror("Errore fstat");
onexit(newsockd, sockd, 0, 2);
}
fsize = stat_buf.st_size;
if(send(newsockd, &fsize, sizeof(fsize), 0) < 0){
perror("Errore durante l'invio grande file list");
onexit(newsockd, sockd, 0, 2);
}
rc_list = sendfile(newsockd, fpl, &offset_list, stat_buf.st_size);
if(rc_list == -1){
perror("Invio file list non riuscito");
close(newsockd);
close(sockd);
fclose(fp_list);
}
if(rc_list != fsize){
fprintf(stderr, "Trasferimento incompleto: %d di %d bytes\n", rc_list, (int)stat_buf.st_size);
close(newsockd);
close(sockd);
fclose(fp_list);
}
fclose(fp_list);
close(fpl);
fsize = 0;
printf("File inviato\n");
memset(buffer, '0', sizeof(buffer));
/************************* FINE RICEZIONE LIST E INVIO LISTA *************************/
/* other non useful things */
and the function that do the file list:
Code:
size_t file_list(char *path, char ***ls){
DIR *dp;
struct stat fileStat;
struct dirent *ep = NULL;
size_t len, count = 0;
int file = 0;
*ls = NULL;
dp = opendir (path);
if(dp == NULL){
fprintf(stderr, "Non esiste la directory: %s\n", path);
exit(1);
}
ep = readdir(dp);
while(NULL != ep){
count++;
ep = readdir(dp);
}
rewinddir(dp);
*ls = calloc(count, sizeof(char *));
count = 0;
ep = readdir(dp);
while(NULL != ep){
if((file = open(ep->d_name, O_RDONLY)) < 0){
perror("apertura file");
exit(1);
}
if(fstat(file, &fileStat) != 0){
perror("filestat");
free(*ls);
exit(EXIT_FAILURE);
}
if(S_ISDIR(fileStat.st_mode)){
len = strlen(ep->d_name);
(*ls)[count] = malloc(len+5); /* lunghezza stringa + "DIR \n" */
strcpy((*ls)[count], "DIR "); /* copio DIR */
strcat((*ls)[count++], ep->d_name);
free((*ls)[count]);
ep = readdir(dp);
} else{
(*ls)[count++] = strdup(ep->d_name);
ep = readdir(dp);
}
(void)closedir(dp);
return count;
}
}
My problem is that the file that will be created (listfiles.txt) contain only 1 name -.-''
I've tried the function file_list in a separate and smaller program and it works perfectly so it isn't his fault!
But i don't know why there is the strange behaviour!