-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.c
More file actions
160 lines (125 loc) · 3.8 KB
/
server.c
File metadata and controls
160 lines (125 loc) · 3.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Aidan Fitzpatrick (fitzpatricka)
/*
* sever.c -- a simple HTTP/1.0 server.
* Hopefully should be easy to adapt to newer versions of HTTP and expand to
* more MIME types.
*
* A large portion of this program is based off information from beej's guide
* http://beej.us/guide/bgnet/
*/
#ifndef HEAD_INCLUDE
//Libraries
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
//Custom Files
#include "process.h"
#define QUEUE 10 // How many connections can be queued
// (How many simultaneous incoming connections)
#define MAXDATASIZE 256 // the maximum size we can get at once
// This variable is changed when the program is started to be the address
// which is passeddd in as the second argument. Otherwise it is only prepended
// to paths to files.
char pre_path[100] = ".";
#define HEAD_INCLUDE 1
#endif
// Macro for getting the address of the client (useful if support for ipv6 is added later)
void *get_in_addr(struct sockaddr *sockaddr){
if(sockaddr->sa_family == AF_INET){
return &(((struct sockaddr_in*)sockaddr)->sin_addr);
}
return &(((struct sockaddr_in6*)sockaddr)->sin6_addr);
}
int main(int argc, char *argv[]){
//socket stuff
int sockfd, new_fd; // sockfd is our listening socket, new_fd for new connections.
struct addrinfo hints, *servinfo, *p;
struct sockaddr_storage their_addr; // address information for new connections.
socklen_t addr_len;
struct sigaction sa;
int yes = 1;
char s[INET_ADDRSTRLEN];
int rv;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
//client stuff
char buf[MAXDATASIZE];
int numbytes; // for recieved data
if(argc < 3){
fprintf(stderr, "not enough arguments\nusage: server port path_to_root\n");
return 1;
}
char* port = argv[1];
if(strcmp(argv[2], ".") == 0){
pre_path[0] = '\0'; //remove pre_path if root is current directory
} else {
strcpy(pre_path, argv[2]); //copy the path_to_root into the pre_path global variable.
}
// loads up the nitty gritty of *servinfo
if((rv = getaddrinfo(NULL, port, &hints, &servinfo)) != 0){
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// find a socket to bind to
for(p = servinfo; p != NULL; p = p->ai_next){
if((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){
perror("server: socket");
continue;
}
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
perror("setsockopt");
exit(1);
}
if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1){
close(sockfd);
perror("server: bind");
continue;
}
// we'll break as soon as we find one
break;
}
// Here we've either got a bound socket, or no socket, so need to check.
if (p == NULL){
fprintf(stderr, "server: failed to bind socket\n");
perror("recvfrom");
exit(1);
}
freeaddrinfo(servinfo); // don't need this anymore.
if(listen(sockfd, QUEUE) == -1){
// listen errored
perror("listen");
exit(1);
}
printf("server: waiting for connections...\n");
while(1){ // Time to accept() some requests
addr_len = sizeof(their_addr);
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &addr_len);
if(new_fd == -1){
perror("accept");
continue;
}
inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof(s));
printf("server: got connection from %s\n", s);
if((numbytes = recv(new_fd, buf, MAXDATASIZE-1, 0)) == -1){
perror("recv");
continue;
}
buf[numbytes] = '\0';
printf("data recieved: %s\n", buf);
processRequest(buf, new_fd, pre_path); // Pass it off for response.
close(new_fd);
}
printf("lolnope jk\n");
return 0;
}