-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmaster.cpp
141 lines (114 loc) · 3.53 KB
/
master.cpp
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
//Socket headers.
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
//C++ headers.
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
//C headers.
#include <stdlib.h>
#include <string.h>
#include <cstring>
#include <curl/curl.h>
#include <stdlib.h>
#include <sys/wait.h>
#define WRITE_PORT 9515
#define READ_PORT 9516
typedef struct download_url
{
std::string url;
std::string index;
std::string range;
}download_url;
struct user_data
{
int size;
};
std::string get_file_name(const char * url)
{
int pos;
std::string s(url);
std::string delimiter = "/";
std::string token = s.substr(0, s.find(delimiter));
size_t last = 0;
size_t next = 0;
while ((next = s.find(delimiter, last)) != std::string::npos) {
// cout << s.substr(last, next-last) << endl;
last = next + 1;
}
// cout << "substring:"<<s.substr(last) << endl;
return s.substr(last);
}
using std::cout;
using std::endl;
using std::cin;
size_t header_callback(char *buffer, size_t size, size_t nitems, void *usr_data_temp)
{
user_data *usr_data = (struct user_data *)usr_data_temp;
std::istringstream iss(buffer);
std::string s;
while ( std::getline( iss, s, ' ' ) ) {
if(s == "Content-Length:")
{
std::getline(iss, s, ' ');
std::istringstream temp(s);
temp>>(usr_data->size);
// cout<<s<<endl;
// cout<<buffer<<endl;
}
}
// cout<<buffer<<endl;
return strlen(buffer);
}
int get_file_size(download_url url_struct)
{
user_data usr_data;
curl_global_init(CURL_GLOBAL_ALL);
CURL * curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_URL, url_struct.url.c_str());
curl_easy_setopt(curl_handle,CURLOPT_NOBODY ,1 );
curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, header_callback);
curl_easy_setopt(curl_handle, CURLOPT_HEADERDATA, &usr_data);
CURLcode res = curl_easy_perform(curl_handle);
if(res != CURLE_OK)
{
cout<<curl_easy_strerror(res)<<endl;
}
return usr_data.size;
}
int main()
{
// cout<<"hi"<<endl;
download_url url_struct;
cout<<"Enter the url to download: "<<endl;
// std::cout<<"Enter the download url:"<<std::endl;
std::cin>>url_struct.url;
// url_struct.url = "http://www.inkjettips.com/chapter2.pdf";
int file_size = get_file_size(url_struct);
// cout<<file_size<<endl;
std::vector< std::string > ip_address = { "10.16.160.74", "10.16.160.76", "10.16.160.72"};
int num_slaves = ip_address.size();
int size_per_chunk = file_size / num_slaves;
int pid;
for(int i = 0; i < num_slaves; i++)
{
std::string index = std::to_string(i);
int start_num = i * size_per_chunk, end_num = std::min(start_num + size_per_chunk - 1, file_size);
std::string start = std::to_string(start_num), end = std::to_string(end_num);
std::string range = start+"-"+end;
//1 - ip address, 2 - url, 3 - range, 4 - index (for argv)
pid = fork();
if(pid == 0)
execl("./master_fork", ip_address[i].c_str(), url_struct.url.c_str(),\
range.c_str(),index.c_str(), (char *)0);
}
int status, wpid;
while ((wpid = wait(&status)) > 0);
// part0-bcompare-4.2.8.23479_amd64.deb(A sample file name)
system(("cat part*-"+get_file_name(url_struct.url.c_str())+" > "+get_file_name(url_struct.url.c_str())).c_str());
return 0;
}