-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.pl
133 lines (115 loc) · 3.01 KB
/
server.pl
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
#!/usr/bin/perl
use IO::Socket;
use Data::Dumper;
require "catalog.pl";
require "filesInDir.pl";
require "config.pl";
require "checksum.pl";
require "fileTransfer.pl";
my $server = undef;
my $currentClient = undef;
my $catalogFileName = "catalog.xml";
my $hasNegotiatedCatalog = 0; # true if peers have exchanged catalogs
# INT_handler is the subroutine that is going to be called in response to a SIG_INT from the OS
# (typically when typing CNTRL+C in terminal).
# This implementation will make sure to close the socket, otherlise it might stay open after the server
# is no longer needed
sub INT_handler {
print "Closing server...\n";
stopServer();
exit(0);
}
$SIG{'INT'} = 'INT_handler'; # Use INT_handler as handler for SIG_INT (CNTRL+C)
$SIG{'TSTP'} = 'INT_handler'; # USE INT_handler as handler for SIG_TSTP (CNTRL+Z)
sub startServer($$)
{
my $port = shift;
my $saveDir = shift || './files';
# if (! -d $saveDir)
# {
# mkdir($saveDir, 0755);
# print "Save directory created: $saveDir\n";
# }
$server = IO::Socket::INET->new(
Listen => 5,
LocalAddr => 'localhost',
LocalPort => $port ,
Proto => 'tcp',
Reuse => 1,
) or die "Can't create server socket: $!";
while(my $client = $server->accept)
{
$currentClient = $client;
print "\nNew client!\n";
my $receivedCatalog = receiveFile($client, $saveDir, $hasNegotiatedCatalog);
#if (not $hasNegotiatedCatalog)
$hasNegotiatedCatalog = 1;
if ($receivedCatalog)
{
handleCatalogReceived($receivedCatalog);
}
}
}
sub stopServer()
{
close($server);
}
sub handleCatalogReceived($)
{
my $receivedCatalog = shift || die "handleCatalogReceived called with no catalog\n";
my @filesInCatalog = parseCatalog($receivedCatalog);
my @destinationDirs = allDestinationDirs();
my @localFiles = allFilesFromDirs(@destinationDirs);
my @requestFiles = ();
foreach my $file (@filesInCatalog)
{
my $fileName = $file->{name};
print "File in catalog: $file\n";
my $fileChecksum = $file->{checksum};
if (not hasFileLocally($fileName, $fileChecksum, @localFiles))
{
print "Doesn't have file: $fileName \n";
push(@requestFiles, $file);
}
else
{
print "Have file: $fileName \n";
}
}
print "Files in catalog: ";
print(Dumper @requestFiles);
my $responseCatalog = catalogForFiles(@requestFiles);
print "Response catalog: $responseCatalog\n";
sendString($currentClient, $responseCatalog, $catalogFileName);
print "All done sending\n";
}
sub allFilesFromDirs($)
{
my @allFiles = ();
foreach my $dir (@_)
{
print "Finding all files in dir $dir\n";
my @dirContents = filesReccursive($dir);
@allFiles = (@allFiles, @dirContents);
}
return @allFiles;
}
sub hasFileLocally($$$)
{
my $fileName = shift || die "hasFileLocally called with no file name\n";
my $fileChecksum = shift || die "hasFileLocally called with no checksum\n";
print "local files: ";
print(Dumper @_);
foreach my $localFile (@_)
{
if ($localFile eq $fileName)
{
if (checkMd5ForFile($localFile, $fileChecksum))
{
return 1;
}
}
}
return 0;
}
1;