-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgeneric_server.perl
executable file
·151 lines (127 loc) · 4 KB
/
generic_server.perl
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
# *-*-perl-*-*
eval 'exec perl -Ssw $0 "$@"'
if 0;
#!/usr/local/bin/perl -sw
#
#!/usr/local/bin/perl -Tsw
# perl options:
# -s ("special") variable initialization
# -w issue plenty of warnings on Perl usage
# -T forces ``taint'' checks to be turned on so you can test them.
# Ordinarily these checks are done only when running setuid or setgid.
#
# TODO: find out why -T affects the search for lib's (eg, common.perl)
#
# generic_server.perl: server for transferring files and running commands
#
# Based on Bayesian network server developed for NMSU's GraphLing project,
# itself based on socket server script from Perl man pages (sockets section).
#
require 5.002;
# Load in the common module, making sure the script dir is in Perl's lib path
BEGIN {
my $dir = `dirname $0`; chomp $dir; unshift(@INC, $dir);
require 'common.perl';
# Load in the other modules
require 'generic_protocol.perl';
#
## use strict;
## BEGIN { $ENV{PATH} = '/usr/ucb:/bin' }
use Socket;
use Carp;
}
# Use strict type checking but allow symbolic references for handles
use strict;
no strict "refs";
use vars qw /$port $be_polite $fork/;
# Parse command-line options
#
if (!defined($ARGV[0])) {
my($options) = "options = [-port=N] [-fork]";
my($example) = "ex: $script_name -port=1666";
die "\nusage: $script_name [options] -\n\n$options\n\n$example\n\n";
}
&init_var(*port, 2345); # TCP service port
&init_var(*be_polite, &FALSE); # send connection acknowledgement
## &init_var(*server_dir, ".");
&init_var(*fork, &FALSE); # use fork for processing requests
# Set up the socket for receiving requests
#
my($proto, $ok);
$proto = getprotobyname('tcp');
$ok = socket(Server, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
&debug_out(6, "socket(S,%d,%d,%d) => $ok\n", PF_INET, SOCK_STREAM, $proto);
setsockopt(Server, SOL_SOCKET, SO_REUSEADDR,
pack("l", 1)) || die "setsockopt: $!";
bind(Server, sockaddr_in($port, INADDR_ANY)) || die "bind: $!";
listen(Server,SOMAXCONN) || die "listen: $!";
our($is_server);
our($do_shutdown);
$is_server = &TRUE; # TODO: use accessor function
$do_shutdown = &FALSE;
our($authenticated) = &FALSE;
# Process connection requests until time to quit
#
## chdir $server_dir;
&logmsg ("server started on port $port");
my $paddr;
my $client;
my $child_pid;
while (($paddr = accept($client,Server))) {
my($port,$iaddr) = sockaddr_in($paddr);
&debug_out(5, "port=%s; iaddr=%s\n", $port, unpack("x4", $iaddr));
my $name = gethostbyaddr($iaddr,AF_INET) || "???";
&logmsg("connection from $name [" . inet_ntoa($iaddr) . "] at port $port");
# If multiprocessing desired, spawn off child process to carry out
# the request, having it exit afterwards.
if ($fork) {
$child_pid = fork();
if (!defined($child_pid)) {
&error("Problem issuing fork ($!)\n");
$child_pid = -1;
}
# If this is the child process, then process the request
if ($child_pid == 0) {
&process_client_request($client);
&exit();
}
}
# Otherwise, just carry out the requests directly
else {
&process_client_request($client);
}
close $client;
undef $client;
last if ($do_shutdown);
}
# Clean up shop
#
&exit;
#------------------------------------------------------------------------------
# process_client_request(socket)
#
# Process all of the requests that are received via the socket
#
sub process_client_request {
select($client); $| = 1; select(STDOUT);
&send_command($client, "INFO", "Connected to Generic Server: " . localtime)
if ($be_polite);
$authenticated = &FALSE;
while (<$client>) {
chomp;
&process_request($client, "$_");
last if ($do_shutdown);
}
}
# logmsg(message): write message to the log file with timestamp included
#
sub logmsg {
## OLD: &debug_out(2, "$0 $$: @_ at %s\n", scalar localtime, "\n");
&debug_print(2, "$0 $$: @_ at " . scalar localtime . "\n");
}
# global(variable_name)
#
# Dummy subroutine used for declaring variables as globals.
#
sub global {
}