177 lines
4.2 KiB
C
177 lines
4.2 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/time.h>
|
|
#include <time.h>
|
|
#include <sys/socket.h>
|
|
#include <arpa/inet.h>
|
|
#include <sys/types.h>
|
|
#include <sys/uio.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <strings.h>
|
|
#include <getopt.h>
|
|
|
|
#define BUFFERT 512
|
|
#define BACKLOG 1
|
|
|
|
void usage(char* programName);
|
|
int create_server_socket(int port);
|
|
struct sockaddr_in sock_serv, sock_clt;
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
int sfd, fd;
|
|
unsigned int length = sizeof(struct sockaddr_in);
|
|
long int n, m, count = 0;
|
|
unsigned int nsid;
|
|
ushort clt_port;
|
|
char buffer[BUFFERT], filename[256];
|
|
char dst[INET_ADDRSTRLEN];
|
|
time_t intps;
|
|
struct tm* tmi;
|
|
|
|
// Parse options
|
|
char argchar;
|
|
while ((argchar = getopt(argc, argv, "")) != -1)
|
|
{
|
|
switch (argchar)
|
|
{
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Parse positional arguments
|
|
int port;
|
|
char* file_path;
|
|
if (argv[optind] == NULL || argv[optind + 1] == NULL)
|
|
{
|
|
usage(argv[0]);
|
|
exit(3);
|
|
}
|
|
else
|
|
{
|
|
port = atoi(argv[optind]);
|
|
file_path = argv[optind + 1];
|
|
}
|
|
|
|
// Open a TCP socket over IPv4
|
|
sfd = socket(AF_INET, SOCK_SEQPACKET, 0);
|
|
if (sfd == -1)
|
|
{
|
|
perror("socket fail");
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
int yes = 1;
|
|
if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1 )
|
|
{
|
|
perror("setsockopt error");
|
|
exit(5);
|
|
}
|
|
|
|
int l = sizeof(struct sockaddr_in);
|
|
bzero(&sock_serv, l);
|
|
|
|
/* The following assignment should use; Internet version 4 protocols constant */
|
|
sock_serv.sin_family =/* Q) What goes here? */;
|
|
/* See; man socket */
|
|
|
|
sock_serv.sin_port = htons(atoi(argv[1]));
|
|
|
|
/* Set the IP address to allow connections on any network interface on the server */
|
|
sock_serv.sin_addr.s_addr = htonl(/* Q) What goes here? */);
|
|
/* See; man 4 ip */
|
|
|
|
if (bind(sfd, (struct sockaddr*) &sock_serv, l) == -1)
|
|
{
|
|
perror("bind fail");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
bzero(buffer,BUFFERT);
|
|
listen(sfd,BACKLOG);
|
|
|
|
/* accept() takes "struct sockaddr_in" and returns non-negative integer that is a descriptor for the accepted socket.
|
|
* The missing arguement in the line below will need to have the *address* of the variable required, as the value is updated when the socket is update. eg, &variable
|
|
*/
|
|
nsid = accept(sfd, (struct sockaddr*) &sock_clt, /* Q) What goes here? */);
|
|
/* See; man 2 accept */
|
|
|
|
|
|
if (nsid == -1)
|
|
{
|
|
perror("accept fail");
|
|
return EXIT_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
if(inet_ntop(AF_INET, &sock_clt.sin_addr, dst, INET_ADDRSTRLEN) == NULL)
|
|
{
|
|
perror("socket error");
|
|
exit (4);
|
|
}
|
|
|
|
clt_port = ntohs(sock_clt.sin_port);
|
|
printf("connection : %s:%d\n", dst, clt_port);
|
|
|
|
bzero(filename, 256);
|
|
|
|
intps = time(NULL);
|
|
tmi = localtime(&intps);
|
|
|
|
bzero(filename, 256);
|
|
|
|
sprintf(filename, "saved-file.%d.%d.%d.%d.%d.%d", tmi->tm_mday, tmi->tm_mon+1, 1900+tmi->tm_year, tmi->tm_hour, tmi->tm_min, tmi->tm_sec);
|
|
printf("Creating the copied output file : %s\n", filename);
|
|
|
|
if ((fd = open(filename, O_CREAT | O_WRONLY, 0600)) == -1)
|
|
{
|
|
perror("open fail");
|
|
exit(3);
|
|
}
|
|
|
|
bzero(buffer, BUFFERT);
|
|
|
|
n = recv(nsid, buffer, BUFFERT, 0);
|
|
|
|
while(n)
|
|
{
|
|
if (n==-1)
|
|
{
|
|
perror("recv fail");
|
|
exit(5);
|
|
}
|
|
|
|
if ((m=write(fd,buffer,n))==-1)
|
|
{
|
|
perror("write fail");
|
|
exit(6);
|
|
}
|
|
|
|
count += m;
|
|
|
|
bzero(buffer, BUFFERT);
|
|
|
|
n = recv(nsid, buffer, BUFFERT, 0);
|
|
}
|
|
|
|
close(sfd);
|
|
close(fd);
|
|
}
|
|
|
|
close(nsid);
|
|
printf("End of transmission with %s.%d\n", dst, clt_port);
|
|
|
|
/* Select the appropriate variable in the following function call argument */
|
|
printf("Number of octets received : %ld \n", /* Q) What goes here? */);
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
void usage(char* programName)
|
|
{
|
|
fprintf(stderr, "Usage: %s [OPTIONS] <port-number> <file-to-send>\n", programName);
|
|
}
|