File Coverage

blib/lib/Net/FileShare.pm
Criterion Covered Total %
statement 33 290 11.3
branch 2 166 1.2
condition 5 54 9.2
subroutine 12 22 54.5
pod 4 11 36.3
total 56 543 10.3


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -wT
2             ##
3             ##########################################################################################
4             ## ##
5             ## Net::FileShare.pm 1-07-03 ##
6             ## Gene Gallistel ##
7             ## Copyright (c) 1-07-03 All rights reserved. ##
8             ## ##
9             ## This program is free software. You can redistribute and/or modify this bundle ##
10             ## under the same terms as Perl itself. ##
11             ## ##
12             ##########################################################################################
13             ##
14             ##
15             ##
16             package Net::FileShare;
17 1     1   19356 use POSIX ":sys_wait_h";
  1         7015  
  1         8  
18 1     1   3058 use IO::Socket::INET;
  1         28561  
  1         9  
19 1     1   674 use Carp;
  1         7  
  1         62  
20 1     1   5 use Fcntl qw( O_WRONLY O_RDONLY O_CREAT O_APPEND );
  1         2  
  1         66  
21 1     1   4 use strict;
  1         2  
  1         45  
22 1     1   6 use vars qw( $VERSION @ISA @EXPORT );
  1         1  
  1         108  
23             require Exporter;
24              
25             $VERSION = '0.18';
26             @ISA = qw(Exporter);
27             @EXPORT = qw();
28              
29             ## Command codes for server and client
30 1     1   5 use vars qw( $HELO $GET $LIST $QUIT $PERM_DENY $FILE_NOT_FOUND $INVAL_NAME $UNRECOG_CMD $PATH_EQ_DIR $ACK_CMD);
  1         2  
  1         161  
31             ## Server Greeting
32             $HELO = '1';
33             ## Client Commands
34             $GET = '101';
35             $LIST = '102';
36             $QUIT = '103';
37             ## Server Responses
38             $PERM_DENY = '201';
39             $FILE_NOT_FOUND = '202';
40             $INVAL_NAME = '203';
41             $UNRECOG_CMD = '204';
42             $PATH_EQ_DIR = '205';
43             $ACK_CMD = '301'; # acknowledge a command
44              
45             ## all commands from the server should also contain a message.
46             ## below are a series of stock messages, for the server to send.
47             ## look at the handle_request sub to find their usage.
48 1     1   5 use vars qw( $helo_msg $perm_deny_msg $file_not_found_msg $inval_name_msg $unrecog_cmd_msg $path_eq_dir_msg);
  1         1  
  1         4112  
49             $helo_msg = "Welcome...this server uses Net::FileShare";
50             $perm_deny_msg = "Permission denied";
51             $file_not_found_msg = "File requested was not found";
52             $inval_name_msg = "Invalid file name, name supplied may contain invalid characters";
53             $unrecog_cmd_msg = "Client commands are as follows: list, get, and quit";
54             $path_eq_dir_msg = "Path supplied is a directory, not a file";
55              
56              
57             sub new
58             {
59 1     1 1 4708 my ($class, %args) = @_;
60 1   50     74 bless {
      50        
      50        
      50        
61             _send_only => $args{_send_only} || '0',
62             _socket => $args{_socket} || '1',
63             _directory => $args{_directory} || '???',
64             _debug => $args{_debug} || '0',
65             }, $class;
66             }
67              
68             ## self explanitory
69 1     1 0 28 sub version { $VERSION; }
70              
71             sub DESTROY
72             {
73 2     2   506 my ($self) = shift;
74 2         9 undef %$self;
75 2         2000492 sleep 1;
76             }
77            
78 0     0 0 0 sub REAPER { 1 until (waitpid(-1, WNOHANG) == -1) }
79              
80              
81             ## will test if an object can become a server
82             sub server_run_once
83             {
84 1   50 1 0 22 my ($self, $port) = ($_[0], $_[1] || "3000");
85              
86 1 50       22 croak "Variable _send_only must be set to 1" if ($self->{_send_only} eq 0);
87              
88             ## Create a socket
89 1 50       24 my ($socket) = new IO::Socket::INET(
90             Listen => SOMAXCONN,
91             LocalPort => $port,
92             Reuse => 1,
93             Proto => 'tcp',
94             Timeout => 120)
95             or croak "Unable to create server socket: $!";
96             }
97              
98             sub server_connection
99             {
100 0   0 0 1   my ($self, $port) = ($_[0], $_[1] || "3000");
101 0           my ($hostinfo, $remote);
102              
103 0 0         croak "Variable _send_only must be set to 1" if ($self->{_send_only} eq 0);
104              
105             ## Create a socket
106 0 0         my ($socket) = new IO::Socket::INET(
107             Listen => SOMAXCONN,
108             LocalPort => $port,
109             Reuse => 1,
110             Proto => 'tcp',
111             Timeout => 120)
112             or croak "Unable to create server socket: $!";
113            
114              
115 0           while (1)
116             {
117 0           $SIG{CHLD} = \&REAPER;
118              
119 0 0         last if (!defined($remote = $socket->accept()));
120 0           $hostinfo = gethostbyaddr($remote->peeraddr, AF_INET);
121              
122             ## assign remote to _socket, so all protocol negotiations
123             ## can be done by handle_request
124 0           $self->{_socket} = $remote;
125            
126             ## fork the child so the parent can go back to listening
127 0           my ($pid) = fork();
128              
129             ## signal trouble
130 0 0         unless (defined ($pid)) {
131             ## add logging and debugging info here
132 0 0         $self->debug("Server process $$ fork failed!") if ($self->{_debug} eq 1);
133 0           sleep (5);
134 0           return;
135             }
136             ## parent...should include a recording for child, then next to
137             ## listen for more inbound children
138 0 0         if ( $pid ) {
139 0           next;
140             }
141 0 0         $self->debug("Server process $$ forked successfully") if ($self->{_debug} eq 1);
142 0           $self->handle_request();
143 0           exit;
144              
145             }
146              
147             }
148              
149             sub client_automated
150             {
151 0 0   0 1   if(@_ < 4)
152             {
153 0           croak "Usage: ";
154             }
155 0           my($self, $server, $port, $cmd, $file) = @_;
156 0           my ($serv_cmd, $serv_msg, $clie_cmd, $clie_msg);
157 0           my ($buffer, $packet, $bytes_read) = (8,0,0); ## set buffer to 8 bytes
158 0           my ($written, $read) = (0,0);
159 0           my ($loc);
160 0           my ($directory) = $self->{_directory};
161 0           local *FD;
162 0   0       my $localfd = ref($file) || ref(\$file) eq "GLOB";
163              
164             ## check cmd...if invalid, why go on...
165 0 0 0       if (($cmd =~ m/[Gg][Ee][Tt]/) || ($cmd =~ m/[Ll][Ii][Ss][Tt]|[Ll][Ss]|[Dd][Ii][Rr]/))
166             {
167              
168 0 0         my ($socket) = IO::Socket::INET->new(
169             PeerAddr => $server,
170             PeerPort => $port,
171             Proto => "tcp",
172             Type => SOCK_STREAM)
173             or croak "Cannot establish client socket: $!";
174              
175 0 0         $self->debug("Client connected to host: $server port: $port") if ($self->{_debug} eq 1);
176 0           $self->{_socket} = $socket;
177            
178             ## wait for a helo
179 0           ($serv_cmd, $serv_msg) = $self->recv_cmd();
180 0 0         if ($serv_cmd eq $HELO)
181             {
182 0 0         $self->debug("\n$serv_cmd\t$serv_msg\n") if ($self->{_debug} eq 1);
183              
184             ## if $cmd eq get, a file name should be supplied, else error on usage
185 0 0         if ($cmd =~ m/[Gg][Ee][Tt]/)
    0          
186             {
187             ## quick check length of filename
188 0 0         if (length($file) eq 0)
189             {
190 0           croak "Invalid file name supplied: $!";
191             } else {
192             ## the situation where a filename does exist
193 0           $self->send_cmd($GET,$file);
194 0           ($serv_cmd, $serv_msg) = $self->recv_cmd;
195            
196 0 0         if ($serv_cmd eq $ACK_CMD) {
197 0           syswrite(STDOUT, "$serv_cmd\tFile Size: $serv_msg\n");
198             ## prereq: clients get request has been acknowledged by server
199             ## thus, the $serv_msg supplied contains the requested files size
200 0           my $file_size = $serv_msg;
201              
202             ## opening the file
203 0 0         if($localfd) {
204 0           $loc = $file;
205             } else {
206 0           $loc = \*FD;
207              
208 0 0         unless(sysopen($loc, "$directory/$file", O_CREAT | O_WRONLY))
209             {
210 0           carp "Cannot open $directory/$file\n";
211 0           return undef;
212             }
213             }
214              
215             ## file transfer section
216 0           do {
217 0 0         last if ($bytes_read eq $file_size);
218              
219 0           $read = sysread($socket, $packet, $buffer);
220 0 0 0       unless (defined($read) && ($read eq length($packet))) {
221 0           croak "Error reading socket in client connection";
222             }
223 0           $written = syswrite($loc, $packet, length($packet));
224 0 0 0       unless (defined($written) && ($written eq length($packet))) {
225 0           croak "Unable to write to new file";
226             }
227 0           $bytes_read += $written;
228 0           syswrite(STDOUT, "*");
229             } while ($bytes_read != $file_size);
230              
231              
232 0           syswrite (STDOUT, "\nClosing FH\n");
233 0 0         close $loc
    0          
234             or carp $! ? "Error closing file: $!"
235             : "Exit status $? from close";
236            
237             }
238             }
239             } elsif ($cmd =~ m/[Ll][Ii][Ss][Tt]|[Ll][Ss]|[Dd][Ii][Rr]/) {
240 0           $self->send_cmd($LIST);
241 0           ($serv_cmd, $serv_msg) = $self->recv_cmd; #should be ack_cmd + files
242 0 0         if($serv_cmd eq $ACK_CMD)
243             {
244 0           my @files = split(/\*/, $serv_msg);
245 0           my $files_msg = shift @files;
246 0           syswrite(STDOUT, "$serv_cmd\t$files_msg\n");
247 0           for (my $i=0; $i < $#files; ++$i) {
248 0           syswrite(STDOUT, ">\t$files[$i]\n");
249             }
250             }
251             } else {
252 0           croak "Invalid Command: commands are get or list";
253             }
254             } else {
255 0           croak "Server $server:$port not responding";
256             }
257             } else {
258 0           croak "Invalid Command: commands are get or list";
259             }
260             }
261            
262             sub client_interactive
263             {
264 0     0 1   my ($self,$server,$port) = @_;
265 0           my ($directory) = $self->{_directory};
266 0           my ($serv_cmd, $serv_msg, $clie_cmd, $clie_msg);
267 0           my ($file_size, $loc, $local_file, $tmp);
268 0           my ($buffer, $packet, $bytes_read) = (8,0,0); ## set buffer to 8 bytes
269 0           my ($written, $read) = (0,0);
270 0           local *FD;
271 0   0       my $localfd = ref($local_file) || ref(\$local_file) eq "GLOB";
272            
273 0 0         my ($socket) = IO::Socket::INET->new(
274             PeerAddr => $server,
275             PeerPort => $port,
276             Proto => "tcp",
277             Type => SOCK_STREAM)
278             or croak "Cannot establish client socket: $!";
279              
280 0 0         $self->debug("Client connected to host: $server port: $port") if ($self->{_debug} eq 1);
281              
282 0           $self->{_socket} = $socket;
283              
284 0           ($serv_cmd, $serv_msg) = $self->recv_cmd();
285 0 0         if ($serv_cmd eq $HELO) {
286             ## prereq: client has connected to server,
287             ## server has forked client properly and passed
288             ## onto the handle_request sub. client has now
289             ## received a $HELO + $helo_msg from handle_request
290            
291             ## display cmd and msg from server
292 0           syswrite(STDOUT, "\n$serv_cmd\t$serv_msg\n");
293              
294             ## client enters cmd loop. to exist, client will have to type 'quit'
295             ## minus the quotes of course
296 0           while (1) {
297 0           syswrite(STDOUT, "> Enter Command (list, get, or quit): ");
298              
299             ## read and chomp clients cmd from STDIN. this can be tricky, if
300             ## client specifies 'get filename' instead of get, then filename
301 0           sysread(STDIN, $clie_cmd, 50);
302 0           chomp($clie_cmd);
303            
304             ## handle list cmd, client can type list, ls, or dir, as i often
305             ## get confused when accessing various ftp servs, etc. so i thought
306             ## i would build in support for all
307 0 0         if ($clie_cmd =~ m/^[Ll][Ii][Ss][Tt]|^[Ll][Ss]|^[Dd][Ii][Rr]/) {
    0          
    0          
308 0           $self->send_cmd($LIST);
309 0           ($serv_cmd, $serv_msg) = $self->recv_cmd; #should be ack_cmd + files
310             ## if server acknowledges command
311 0 0         if($serv_cmd eq $ACK_CMD) {
312             ## $serv_msg is * delimited. The first element is a string
313             ## followed by a *, then every file after is followed by a
314             ## * save the last
315 0           my @files = split(/\*/, $serv_msg);
316 0           my $files_msg = shift @files;
317 0           printf "%d\t%s\n", $serv_cmd, $files_msg;
318 0           for (my $i=0; $i < $#files; ++$i) {
319 0           print ">\t$files[$i]\n";
320             }
321             }
322 0           next;
323             } elsif ($clie_cmd =~ m/^[Gg][Ee][Tt]/) {
324             ## initial check...see if client supplied filename in original line
325             ## its quite possible a user might add a space to the end of get, so
326             ## check to see if $clie_cmd is larger 4 chars and contains
327             ## space. if this is the case their should be a file name attached, else
328             ## supply one on the next line.
329 0 0 0       if (($clie_cmd =~ m/^[Gg][Ee][Tt]\s/) && (length($clie_cmd) > 4)) {
330             ## assign filename to $local_file and chomp
331 0           ($tmp, $local_file) = split(/ /, $clie_cmd);
332 0           chomp($local_file);
333             } else {
334 0           syswrite(STDOUT, "> Enter the name of the file you wish to download: ");
335 0           sysread(STDIN, $local_file, 25);
336 0           chomp($local_file);
337             }
338            
339 0           $self->send_cmd($GET,$local_file);
340 0           ($serv_cmd, $serv_msg) = $self->recv_cmd;
341            
342 0 0         if ($serv_cmd eq $ACK_CMD) {
343 0           syswrite(STDOUT, "$serv_cmd\tFile Size: $serv_msg\n");
344             ## prereq: clients get request has been acknowledged by server
345             ## thus, the $serv_msg supplied contains the requested files size
346 0           my $file_size = $serv_msg;
347              
348             ## opening the file
349 0 0         if($localfd) {
350 0           $loc = $local_file;
351             } else {
352 0           $loc = \*FD;
353              
354 0 0         unless(sysopen($loc, "$directory/$local_file", O_CREAT | O_WRONLY))
355             {
356 0           carp "Cannot open $directory/$local_file\n";
357 0           return undef;
358             }
359             }
360              
361             ## file transfer section
362 0           do {
363 0 0         last if ($bytes_read eq $file_size);
364              
365 0           $read = sysread($socket, $packet, $buffer);
366 0 0 0       unless (defined($read) && ($read eq length($packet))) {
367 0           croak "Error reading socket in client connection";
368             }
369 0           $written = syswrite($loc, $packet, length($packet));
370 0 0 0       unless (defined($written) && ($written eq length($packet))) {
371 0           croak "Unable to write to new file";
372             }
373 0           $bytes_read += $written;
374 0           syswrite(STDOUT, "*");
375             } while ($bytes_read != $file_size);
376              
377             ## reset used variables...
378 0           ($read, $written, $bytes_read, $file_size) = (0,0,0,0);
379 0           syswrite (STDOUT, "\nClosing FH\n");
380 0 0         close $loc
    0          
381             or carp $! ? "Error closing file: $!"
382             : "Exit status $? from close";
383 0           next;
384             } else {
385             ## the case where a get request has not been successful
386 0           syswrite(STDOUT, "$serv_cmd\t$serv_msg\n");
387 0           next;
388             }
389             } elsif ($clie_cmd =~ m/[Qq][Uu][Ii][Tt]/) {
390 0           $self->send_cmd($QUIT);
391 0           print "Goodbye!\n";
392 0           exit 0;
393             } else {
394 0           print "The only commands are: list, get, & quit\n";
395 0           next;
396             }
397            
398             }
399             }
400             }
401              
402             sub send_cmd
403             {
404             ## first off, @_ can either have two or three variables passed
405             ## here. if two, (ie. self and cmd) those are command is being sent
406             ## to the other side, if three, (ie self, cmd, msg) cmd and msg are
407             ## sent
408 0 0   0 0   if (@_ > 2) {
409 0           my ($self, $cmd, $data) = @_;
410 0           my ($buf) = "$cmd,$data";
411 0           $self->_send_packet($buf);
412             } else {
413 0           my ($self, $cmd) = @_;
414 0           my ($buf) = "$cmd,";
415 0           $self->_send_packet($buf);
416             }
417             }
418              
419             sub recv_cmd
420             {
421 0     0 0   my ($self) = shift;
422 0           my ($msg);
423              
424             ## read the awaiting message
425 0 0         if (eval { $msg = $self->_recv_packet() }) {
  0            
426            
427 0 0         if (!defined($msg)) {
428              
429             } else {
430 0           my ($type, $buf) = split(/,/, $msg);
431             ## add in check to confirm type is valid
432             ## this should not be a problem on server
433             ## server side, but kill client side...
434              
435             ## return cmd type and buffer
436 0           return($type, $buf);
437             }
438             }
439             }
440              
441             sub debug
442             {
443 0     0 0   my ($self, $msg) = @_;
444 0           syswrite(STDOUT, "$msg\n");
445             }
446              
447             sub handle_request
448             {
449             ## purpose: interface with the client on the behalf
450             ## of the server. provide the client lists of available files
451             ## to download as well as providing the actual file transfer
452             ## piece
453             ## prereq: client has connected to the server, and server has
454             ## successfully forked the client.
455 0     0 0   my ($self) = @_;
456 0           my ($socket) = $self->{_socket};
457 0           my ($directory) = $self->{_directory};
458 0           my ($clie_cmd, $clie_msg, $file_size);
459 0           my ($buffer, $data) = (8, 0);
460              
461             ## begin with sending a $HELO to client
462 0           $self->send_cmd($HELO,$helo_msg);
463              
464 0           do {
465             ##
466 0           my ($loc, $local_file);
467              
468 0           ($clie_cmd, $clie_msg) = $self->recv_cmd;
469            
470 0 0         exit if ($clie_cmd eq $QUIT);
471            
472 0 0 0       if (($clie_cmd ne $GET) && ($clie_cmd ne $LIST)) {
473 0           $self->send_cmd($UNRECOG_CMD,$unrecog_cmd_msg);
474             } else {
475             ## the instance where a client command is equal to either $GET or $LIST
476 0 0         if ($clie_cmd eq $GET) {
    0          
477 0           $local_file = $clie_msg;
478 0 0         $self->debug("Client has requested $directory/$local_file") if ($self->{_debug} eq 1);
479            
480             ## first check...file name contains more than 0 chars
481 0 0         $self->debug("Checking length of filename!") if ($self->{_debug} eq 1);
482 0 0         if (length($local_file) > 0) {
483 0 0         $self->debug("Check Successful") if ($self->{_debug} eq 1);
484              
485             ## second check...first character is a '/' or presence of a '..'
486 0 0         $self->debug("Checking for control characters\n") if ($self->{_debug} eq 1);
487 0 0 0       if (($local_file =~ m/^\//)||($local_file =~ m/^\.\.?$/)) {
488 0 0         $self->debug("Check Failed") if ($self->{_debug} eq 1);
489 0           $self->send_cmd($INVAL_NAME,$inval_name_msg);
490 0           next;
491             }
492 0 0         $self->debug("Check Successful") if ($self->{_debug} eq 1);
493            
494            
495             ## third check...is a file
496 0 0         $self->debug("Checking to see if $local_file is a file") if ($self->{_debug} eq 1);
497 0 0         if (-f "$directory/$local_file") {
498 0 0         $self->debug("Check Successful") if ($self->{_debug} eq 1);
499            
500             ## fourth check...exists and is readable
501 0 0 0       if ((-e "$directory/$local_file") && (-r "$directory/$local_file")) {
502             ## determine size now
503 0           $file_size = (stat("$directory/$local_file"))[7];
504             ## if here, all checks are successful
505 0           $self->send_cmd($ACK_CMD, $file_size);
506             ## begin transfer process here...
507            
508 0 0         $self->debug("Preparing to transfer file...") if ($self->{_debug} eq 1);
509              
510              
511             #my ($loc, $local_file);
512 0           local *FH;
513 0   0       my $localfd = ref($local_file) || ref(\$local_file) eq "GLOB";
514              
515              
516 0 0         if($localfd) {
517 0           $loc = $local_file;
518             } else {
519 0           $loc = \*FH;
520 0 0         unless(sysopen($loc,"$directory/$local_file", O_RDONLY))
521             {
522 0           carp "Cannot open file";
523 0           return undef;
524             }
525            
526             }
527            
528 0           my ($bytes_wrote, $read, $wrote) = (0,0,0);
529 0           while (1) {
530 0 0         last if ($bytes_wrote eq $file_size);
531 0           $read = sysread($loc,$data,$buffer);
532 0           $wrote = syswrite($socket,$data,$buffer);
533 0 0 0       unless ((defined($read)) && (defined($wrote))) {
534 0           croak "Unable to read from file or write to client";
535             }
536 0           $bytes_wrote += $wrote;
537 0           syswrite(STDOUT, "*");
538             }
539 0 0         $self->debug("\nWrote $bytes_wrote bytes of data to client\n") if ($self->{_debug} eq 1);
540 0 0         close $loc
    0          
541             or carp $! ? "Cannot close file: $!"
542             : "Exit status $? from close";
543             #next;
544             ## reset file_size to be zero
545 0           ($file_size) = (0);
546            
547             } else {
548 0 0         $self->debug("Check Failed") if ($self->{_debug} eq 1);
549 0           $self->send_cmd($PERM_DENY,$perm_deny_msg);
550 0           next;
551             }
552             } else {
553 0 0         $self->debug("Check Failed") if ($self->{_debug} eq 1);
554 0           $self->send_cmd($FILE_NOT_FOUND,$file_not_found_msg);
555 0           next;
556             }
557             } else {
558 0 0         $self->debug("Check Failed") if ($self->{_debug} eq 1);
559 0           $self->send_cmd($INVAL_NAME,$inval_name_msg);
560 0           next;
561             }
562             ## end of if $GET
563             } elsif ($clie_cmd eq $LIST) {
564             ## handle list command
565 0 0         $self->debug("Client has requested a list: ") if ($self->{_debug} eq 1);
566 0           my ($directory) = $self->{_directory};
567 0           my ($str,$file);
568 0           $str = "The files available for download are as follows:";
569 0 0         opendir(DIR, $directory) or croak "Cannot open directory $directory: $!";
570 0           while (defined ($file = readdir(DIR))) {
571 0 0 0       if(($file =~ m/^\./) or (-d "$directory/$file")) {
572 0           next;
573             } else {
574 0           $str .= "*$file";
575             }
576             }
577 0           $self->send_cmd($ACK_CMD,$str);
578 0 0         $self->debug("Done") if ($self->{_debug} eq 1);
579             } ## end of elsif $LIST
580             } ## end of inner else loop
581              
582             } while ($clie_cmd ne $QUIT);
583             }
584              
585             sub _send_packet
586             {
587 0     0     my ($self, $packet) = @_;
588 0           my ($socket) = $self->{_socket};
589            
590 0           my ($plen) = length($packet);
591             ## current packet length
592            
593 0 0         croak "Error sending packet: packet > 255 bytes" if ($plen > 255);
594            
595             ## add terminating null to packet
596 0           $packet .= "\0";
597 0           $plen++; ## for addition of null.
598              
599             ## add the packet length
600 0           $packet = chr($plen).$packet;
601 0           $plen++; ## for addition of chr($plen)
602              
603 0           my $wrote_length = syswrite($socket, $packet, $plen);
604            
605             ## checking for errors w/ syswrite
606 0 0         if (!defined($wrote_length)) {
    0          
607 0           croak "Error sending packet: $!";
608             } elsif ($wrote_length != $plen) {
609 0           croak "Error sending packet: wrote $wrote_length of $plen: $!";
610             } else {
611 0           return 'ok';
612             }
613            
614             }
615              
616             sub _recv_packet
617             {
618 0     0     my ($self) = @_;
619 0           my ($socket) = $self->{_socket};
620 0           my ($slen, $buffer, $ret);
621              
622             ## this is a two step process
623             ## first, read in one byte of data
624             ## this will be the length of the packet data
625             ## then read only the amount of data as
626             ## specified by the first byte
627            
628 0           $ret = sysread($socket,$slen,1,0);
629              
630             ## troubleshooting sysread
631 0 0         if(!defined($ret)) {
    0          
632 0           croak "Error Receiving first byte: $!";
633             } elsif (length($slen) != 1) {
634 0           croak "Error Receiving first byte not eq 1: $!";
635             } else {
636             ## convert char to integer
637 0           $slen = ord($slen);
638              
639 0           while ($slen) {
640 0           my ($pbuf);
641 0           $ret = sysread($socket,$pbuf,$slen,0);
642 0 0         if (!defined($ret)) {
643 0           croak "Error Receiving, return not define: $!"
644             } else {
645 0           $slen -= length($pbuf);
646 0           $buffer .= $pbuf;
647             }
648             ## remove trailing null
649 0           chop($buffer);
650 0           return($buffer);
651             }
652             } # end of above else
653             }
654             1;
655              
656             __END__