-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient.c
170 lines (133 loc) · 4.04 KB
/
client.c
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
161
162
163
164
165
166
167
168
169
170
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <netdb.h>
#include <unistd.h>
#include "common.h"
#define PORT "6969"
static const char* prefix = "./client_dir/";
//returns a socket connected to the server
int connect_serv(const char* server) {
struct addrinfo hints;
struct addrinfo* result;
struct addrinfo* rp;
int sfd, s;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
hints.ai_protocol = PF_INET; /* Any protocol */
s = getaddrinfo(server, PORT, NULL, &result);
if(s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
freeaddrinfo(result);
exit(EXIT_FAILURE);
}
for (rp = result; rp != NULL; rp = rp->ai_next) {
sfd = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (sfd == -1)
continue;
if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
break; /* Success */
close(sfd);
sfd = -1;
}
if (rp == NULL) { /* No address succeeded */
fprintf(stderr, "Could not bind\n");
exit(EXIT_FAILURE);
}
freeaddrinfo(result);
return sfd;
}
int put(const char* file, const char* server) {
int sfd = connect_serv(server);
if(sfd < 0) {
fprintf(stderr, "Error connecting");
exit(EXIT_FAILURE);
}
//create headers and send them
msg_header_t msg_header;
make_msg_header(&msg_header, REQUEST_UP, file);
if(msg_header.size != send(sfd, msg_header.data, msg_header.size, 0)) {
fprintf(stderr, "Socket write with msg_header failed\n");
exit(EXIT_FAILURE);
}
if(file_to_socket(sfd, file) == -1) {
fprintf(stderr, "Failed to transmit file\n");
}
printf("Checking for reply\n");
//we expect the reply to be the same as our msg_header_data just with another opcode
//we change change the opcode of our msg_header to the expected and just memcmp
//the data
change_opcode(&msg_header, REPLY_UP);
char* rep_buffer = calloc(msg_header.size, 1);
if(msg_header.size != read(sfd, rep_buffer, msg_header.size)) {
fprintf(stderr, "Socket read failed\n");
exit(EXIT_FAILURE);
}
//todo: differ between error_opcode and bogus
if(0 != memcmp(rep_buffer, msg_header.data, msg_header.size)) {
fprintf(stderr, "Reply was bogus, go panic\n");
} else {
printf("Success!\n");
}
free_msg_header(&msg_header);
free(rep_buffer);
close(sfd);
return EXIT_SUCCESS;
}
int get(const char* file, const char* server) {
int sfd = connect_serv(server);
if(sfd < 0) {
fprintf(stderr, "Error connecting");
exit(EXIT_FAILURE);
}
//create headers and send them
msg_header_t msg_header;
make_msg_header(&msg_header, REQUEST_DOWN, file);
if(msg_header.size != send(sfd, msg_header.data, msg_header.size, 0)) {
fprintf(stderr, "Socket write with msg_header failed\n");
exit(EXIT_FAILURE);
}
change_opcode(&msg_header, REPLY_DOWN);
char* rep_buffer = calloc(msg_header.size, 1);
if(msg_header.size != read(sfd, rep_buffer, msg_header.size)) {
fprintf(stderr, "Socket read failed\n");
exit(EXIT_FAILURE);
}
if(0 != memcmp(rep_buffer, msg_header.data, msg_header.size)) {
fprintf(stderr, "Reply was bogus, go panic\n");
} else {
char* filename_local = prefix_it(file, prefix);
int retval = socket_to_file(sfd, filename_local);
free(filename_local);
return retval;
}
return -1;
}
int main(int argc, char* argv[]) {
if(argc != 4) {
//wrong argc
printf("Wrong number of arguments \n");
exit(EXIT_FAILURE);
}
const char* op = argv[1];
const char* file = argv[2];
const char* server = argv[3];
if(!strcmp(op, "put")) {
printf("Putting file: %s to %s \n", file, server);
return put(file, server);
} else if(!strcmp(op, "get")) {
printf("Getting file: %s from %s \n", file, server);
return get(file, server);
} else {
printf("Unknown command \n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}