I have seen similar questions asked but I seek a more specific way of how to correctly do it. I am creating a client and a server UDP FTP service where the client has options of
- get [file_name]
- put [file_name]
- delete [file_name]
- ls
- exit
Currently, all implementations work except for my ls as I am trying to ensure the contents of "ls" are less than my buffer size so I know whether to receive/send continually. From what I have learned with research, I am getting an error because you cannot do ftell on a popen file descriptor given it is a pipe rather than the full contents of the popen command. Looking for help on how my implementation should be changed (mainly with doing ls -l on the server and sending the contents of it to the client).
My current code is as follows
FILE *fp=popen("ls -l","r");
fseek(fp, 0L, SEEK_END);
long numbytes = ftell(fp);
fseek(fp, 0L, SEEK_SET);
char tmp[SO_SNDBUF];
sprintf(tmp, "%d", numbytes);
n = sendto(sockfd, tmp, strlen(tmp), 0, (struct sockaddr *) &clientaddr, clientlen); //send ls file size
if (n < 0)
error("ERROR in sendto");
if(numbytes<SO_SNDBUF)
{
bzero(buf, SO_SNDBUF);
fread(buf, sizeof(char), numbytes, fp);
n = sendto(sockfd, buf, numbytes, 0, (struct sockaddr *) &clientaddr, clientlen);
if (n < 0)
error("ERROR in sendto");
}
else
{
//outgoing file is larger than buffer size
long totalSent = 0;
while(totalSent<numbytes)
{
bzero(buf, SO_SNDBUF);
if((numbytes-totalSent)<SO_SNDBUF)
{
fread(buf, sizeof(char), numbytes-totalSent, fp);
n = sendto(sockfd, buf, numbytes-totalSent, 0, (struct sockaddr *) &clientaddr, clientlen); //send ls contents
if (n < 0)
error("ERROR in sendto");
}
else
{
fread(buf, sizeof(char), SO_SNDBUF, fp);
n = sendto(sockfd, buf, SO_SNDBUF, 0, (struct sockaddr *) &clientaddr, clientlen); //send ls contents
if (n < 0)
error("ERROR in sendto");
}
totalSent+=n;
}
}
pclose(fp);
The main portion of code that would need modifying is: To correctly get how many bytes ls -l is returning
FILE *fp=popen("ls -l","r");
fseek(fp, 0L, SEEK_END);
long numbytes = ftell(fp);
fseek(fp, 0L, SEEK_SET);
char tmp[SO_SNDBUF];
sprintf(tmp, "%d", numbytes);