MACSHARED

[email protected] ("THEARTOFWEB PRODUCTION") Thu, 23 Dec 2004 03:12:39 +0000
Newsgroups perl.macperl
Message-ID <[email protected]>
Hi everyone,

below is the code I've been working on. Can anybody give it a shot?

[code]
#!/perl
#
#          MAC SHARED - Share your files on MacOS9
#         Copyleft (C) 2004 , [email protected]
#
#               This file is part of MAC SHARED
#
# MAC SHARED is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# MAC SHARED is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with MAC SHARED; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# You may contact the author of MAC SHARED by e-mail at:
# [email protected]
#
# The latest version of MAC SHARED can be obtained from:
# http://www.theartofweb.altervista.org/ervituzzi
#
# Version: 0.2 Beta ( 23/12/2004 )

use strict;
use warnings;
use MIME::Base64;
use Mac::Files;
use Sys::Hostname;
use Socket qw(:DEFAULT :crlf);
use IO::Socket::INET;
use vars qw(%mvconfig);

&LOAD_CONFIG;

local $SIG{NUM13} = 'IGNORE';

my 
($socket,$client,$date,$request,$get,%header,$file_request,$path_file_request,$content,$size,$shared_content,$auth_value);

my $login_b64 = encode_base64("$mvconfig{USER}:$mvconfig{PASS}","");

$socket = IO::Socket::INET->new(LocalPort => $mvconfig{PORT},
                                 Proto => 'tcp',
                                  Type      => SOCK_STREAM,
                                   Reuse     => 1,
                                    Listen    => 1) || die "$!\n";

$socket->listen();

#
# // MAIN...
#

while (1)
{
	$client = $socket->accept;

	if ($client)
	{
		$date = &get_date();
		$client->autoflush(1);
		recv($client, $request, 10000, 0);
		($get,%header) = &GET_REQUEST( $request );

		if ( $mvconfig{LOGIN} eq "y")
		{
			if ( $header{'Authorization'} ) {

				(undef,$auth_value) = split(" ",$header{'Authorization'},2);
				if ( $auth_value ne $login_b64 )
				{
					#403 Forbidden
					syswrite $client, "HTTP/1.0 403 Forbidden".$CRLF;
					syswrite $client, "Date: $date".$CRLF;
					syswrite $client, "Server: Apache/1.3.0 (unix)".$CRLF;
					syswrite $client, "Content-type: text/html".$CRLF;
					syswrite $client, "$CRLF";
					syswrite $client, "<b>403</b> Access denied!";

					close $client;
   					next;
				}

			} else {

				syswrite $client, "HTTP/1.0 401 Unauthorized".$CRLF;
   				syswrite $client, "WWW-Authenticate: Basic realm=\"MAC 
SHARED\"".$CRLF;
   				syswrite $client, "Date: $date".$CRLF;
   				syswrite $client, "Server: Apache/1.3.0 (unix)".$CRLF;

   				close $client;
   				next;

			}
		}

		$file_request = &GET_PATH( $get );

		if ( $mvconfig{HISTORY} eq "y")
		{
			&SAVE_HISTORY($date,$file_request,\%header);
		}


		if ( $file_request )
		{
			# 'k=' ha un valore
			# Quindi l'utente ha richiesto un file
			#

			$path_file_request = ':shared:' . $file_request;

			if (-e $path_file_request)
			{
				#200 OK

				if (-T $path_file_request)
				{
					$size = get_size($path_file_request);
					syswrite $client, "HTTP/1.0 200 OK".$CRLF;
					syswrite $client, "Date: $date".$CRLF;
					syswrite $client, "Server: Apache/1.3.0 (unix)".$CRLF;
					syswrite $client, "Cache-Control: no-cache".$CRLF;
					syswrite $client, "Content-type: text/plain".$CRLF;
					syswrite $client, "Content-length: $size".$CRLF;
					syswrite $client, "Content-Disposition: inline".$CRLF;
					syswrite $client, "$CRLF";

					open(TEXT,"$path_file_request") || die "$!\n$path_file_request\n";
						while(<TEXT>) { syswrite $client,$_; }
					close(TEXT);

				} elsif (-B $path_file_request) {

					$size = get_size($path_file_request);
					syswrite $client, "HTTP/1.0 200 OK".$CRLF;
					syswrite $client, "Date: $date".$CRLF;
					syswrite $client, "Server: Apache/1.3.0 (unix)".$CRLF;
					syswrite $client, "Cache-Control: no-cache".$CRLF;
					syswrite $client, "Content-type: application/octet-stream".$CRLF;
					syswrite $client, "Content-length: $size".$CRLF;
					syswrite $client, "Content-Disposition: attachment; 
filename=$file_request; size=$size".$CRLF;
					syswrite $client, "$CRLF";

					open(BYNA, "$path_file_request") || die "$!\n$path_file_request\n";
   					binmode(BYNA);
   					while( read(BYNA,$content,4096) )
   					{
    					syswrite $client, $content;
   					}
   					close(BYNA);

				}

			} else {

				# 404 Not Found

				syswrite $client, "HTTP/1.0 404 Not Found".$CRLF;
				syswrite $client, "Date: $date".$CRLF;
				syswrite $client, "Server: Apache/1.3.0 (unix)".$CRLF;
				syswrite $client, "Content-type: text/html".$CRLF;
				syswrite $client, "$CRLF";
				syswrite $client, "<b>404</b> File not found!";

			}

		} else {

			# 'k=' NON ha un valore
			# Quindi mostriamo il contenuto
			# della directory "Shared"

			$shared_content = &GET_SHARED_CONTENT();
			$size = length( $shared_content );
			syswrite $client, "HTTP/1.0 200 OK".$CRLF;
			syswrite $client, "Date: $date".$CRLF;
			syswrite $client, "Server: Apache/1.3.0 (unix)".$CRLF;
			syswrite $client, "Cache-Control: no-cache".$CRLF;
			syswrite $client, "Content-type: text/html".$CRLF;
			syswrite $client, "Content-length: $size".$CRLF;
			syswrite $client, "Content-Disposition: inline".$CRLF;
			syswrite $client, "$CRLF";
			syswrite $client, $shared_content;

			#
			#

		}

		close $client;
	}

}

#
# // Subs...
#

sub get_date {

	my @days   = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
	my @months = 
('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
	my ($sec,$min,$hour,$mday,$mon,$year,$wday) = 
(localtime(time))[0,1,2,3,4,5,6];
	my $time = sprintf("%02d:%02d:%02d",$hour,$min,$sec);
	$year += 1900;

	my $date = "$days[$wday], $mday $months[$mon] $year $time GMT";

}

sub GET_PATH {

	my $get = shift;
	my $chiave = '/k=';
	my $request;
	my $path;

	if ( $get =~ m/$chiave/ )
	{
		(undef,$request,undef) = split(" ",$get);
		(undef,$path) = split("=",$request,2);

		if ($path)
		{
			$path = decode_base64( $path );
		} else {
			$path = undef;
		}
	} else {
		$path = undef;
	}

	return $path;

}

sub GET_REQUEST {

	my $request = shift;
	my @header = split("\n",$request);
	my $header_num = (scalar(@header) - 1);
	my (%header,$header,$key,$value);

	my $get = $header[0];
	chomp($get);

	for my $num (1 .. $header_num)
	{
		next if ($header[$num] !~ m/:/);
		$header = $header[$num];
		chomp($header);
		($key,$value) = split(": ",$header,2);
		$key =~ s/\r//;
		$header{$key} = $value;
	}

	return ($get,%header);

}

sub GET_SHARED_CONTENT {

	my (@DIRS,$single_file,$elemento,$a_href,$elementi_html,$link,$size);

	opendir(DIR,"shared") || die "$!\nshared\n";
		@DIRS = readdir(DIR);
	closedir(DIR);

	my $num_elementi = scalar(@DIRS);

	foreach $single_file (@DIRS)
	{
		chomp($single_file);
		$elemento = ':shared:' . $single_file;
		if (-l $elemento) { next }
		if (-d $elemento) { next }

		$link = encode_base64( $single_file,"" );
		$size = get_size( $elemento );

		if (-T $elemento)
		{
			$a_href = qq~<LI>(T) &nbsp;<A HREF="/k=$link" 
CLASS="LINK_TXT">$single_file</A> &nbsp;( $size bytes )</LI>~;
		} elsif (-B $elemento) {
			$a_href = qq~<LI>(B) &nbsp;<A HREF="/k=$link" 
CLASS="LINK_BYN">$single_file</A> &nbsp;( $size bytes )</LI>~;
		}

		$a_href .= "\n";
		$elementi_html .= $a_href;
		$a_href = "";

	}

	$elementi_html = "" unless $elementi_html;

	my $host = hostname;
	my $welcome = "Hello, welcome to: <b>$host</b> on port: 
<b>$mvconfig{PORT}</b>";

	my $output = qq~
	<HTML>
	<HEAD>
	<TITLE>..:: MAC SHARED ::..</TITLE>
	<META http-equiv="content-type" content="text/html; charset=ISO-8859-1">
	<STYLE TYPE="TEXT/CSS">
	<!--
	BODY { FONT-SIZE:12PX }
	.LOGO {FONT-SIZE:20PX;FONT-FAMILY: Times New Roman}
	A.LINK_DIR {font-family: Verdana;font-size:12px;color:#0064A7