· 9 years ago · Oct 14, 2016, 01:36 PM
1/* fileserver.c */
2//#define _DEFAULT_SOURCE
3
4#include <signal.h>
5#include <sys/wait.h>
6#include <stdio.h>
7#include <fcntl.h>
8#include <sys/stat.h>
9#include <sys/types.h>
10#include <unistd.h>
11#include <string.h>
12#include <stdlib.h>
13#include <netdb.h>
14#include <errno.h>
15#include <sys/socket.h>
16#include <netinet/in.h>
17#include <arpa/inet.h>
18
19#define MAX_BUF 1024
20#define MAX_CONN 10
21
22int main(int argc, char * argv[]) {
23
24 struct sockaddr_in sin;
25 socklen_t len;
26 FILE *fp;
27 int fd;
28
29 char *skey_argv, *skey_decoded, *srv_prt, *temp, *conf_fname, *filename_t;
30 char buf[MAX_BUF], filename[MAX_BUF]; //filename_t[MAX_BUF];
31 int srv_prtnum, block_size;
32 int s, new_s;
33 int ch_forked, n = 0;
34
35 long bytes_sent = 0;
36
37 //$ fileserver portnumber secretkey configfile.dat
38 if (argc == 4) {
39 srv_prt = argv[1];
40 skey_argv = argv[2];
41 conf_fname = argv[3];
42 } else {
43 printf("usage: $fileserver portnumber secretkey configfile.dat\n");
44 exit(1);
45 }
46
47 srv_prtnum = atoi(srv_prt);
48
49 //reading block_size
50 fp = fopen(conf_fname, "r");
51 //fscanf stops scanning at whitespace
52 fscanf(fp, "%d", &block_size);
53 printf("block size: %d\n", block_size);
54 fclose(fp);
55
56 char read_buf[block_size];
57
58 //Build address data structure
59 memset((char *) &sin, 0, sizeof(sin));
60 sin.sin_family = AF_INET;
61 sin.sin_addr.s_addr = INADDR_ANY;
62 sin.sin_port = htons(srv_prtnum);
63
64 /* setup passive open */
65 //socket creates an UN-named socket inside the kernel
66 //and returns an integer known as socket descriptor
67 //domain/family as its first argument
68 // SOCK_STREAM specifies the transport layer protocol
69 if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
70 perror("simplex-talk: socket");
71 exit(1);
72 }
73
74 //bind assigns the details of struct sockaddr_in sin to
75 //the socket s just created. It is like giving a telephone number
76 //to the line(socket) requested above || Naming a socket
77 //|| giving a transport address to the socket
78 if ((bind(s, (struct sockaddr *) &sin, sizeof(sin))) < 0) {
79 perror("simplex-talk: bind");
80 exit(1);
81 }
82
83 //maximum number of client connections that will
84 //queue to this listening socket
85 listen(s, MAX_CONN);
86 len = sizeof sin;
87 printf("Server running \n");
88
89 while (1) {
90
91 //accept(), the server is put to sleep
92 //and when for an incoming client request,
93 //the three way TCP handshake* is complete,
94 //the function accept () wakes up and
95 //returns the socket descriptor representing the client socket.
96 if ((new_s = accept(s, (struct sockaddr *) &sin, &len)) < 0) {
97 perror("simplex-talk: accept");
98 exit(1);
99 }
100 //printf("Here3\n");
101 if (!(ch_forked = fork())) {
102
103 close(s);
104 //Read the message into buffer
105 if ((n = read(new_s, buf, sizeof(buf) - 1)) > 0) {
106 buf[n] = '\0';
107 }
108 //Decode the message stored in buf
109 skey_decoded = strtok_r(buf, "$", &temp);
110 filename_t = strtok_r(NULL, "$", &temp);
111 strcpy(filename, "./filedeposit/");
112 strcat(filename, filename_t);
113
114 //check filename later
115
116 if (strcmp(skey_decoded, skey_argv) == 0) {
117
118 if (access(filename, F_OK) != -1) {
119 // file exists
120 fd = open(filename, O_RDWR, S_IRUSR | S_IWUSR |S_IXUSR);
121
122 while (read(fd, read_buf, block_size) >0){
123 //writing to the client
124 n = write(new_s, read_buf, block_size);
125 bytes_sent += n;
126 }
127
128 printf("Bytes sent by server on socket: %ld\n", bytes_sent);
129
130 close(fd);
131
132 } else {
133 // file doesn't exist
134 printf("File does not exist\n");
135 close(new_s);
136 exit(1);
137 }
138 } else
139 printf("Key mismatch\n");
140 close(new_s);
141 exit(1);
142 }
143 close(new_s);
144 }
145
146 return (0);
147}