-
Notifications
You must be signed in to change notification settings - Fork 3
/
lightftpd
94 lines (78 loc) · 2.56 KB
/
lightftpd
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
#!/usr/bin/perl
#
# lightftpd.pl
#
# Author: Liraz Siri <[email protected]>
#
# Copyright (c) 1998 Liraz Siri <[email protected]>, Ariel, Israel
# All rights reserved.
#
# Created: Tue Oct 20 11:31:10 IST 1998
#
# Lightftp - the worlds smallest (practical) ftp protocol daemon EVER.
# paste-a-foo(tm) compliant: .z (6 lines/490 bytes)
#
# Lightftpd is an incredibly compact threaded file transfer server which
# allows simple non-authenticated (that means NO authentication what so ever)
# file transfers between two systems using TCP/IP. (bidirectional)
#
# One data transfer per connection to the server, no non-existant
# directory names (on both sides), please.
#
# We incorporate an interesting feature for the users comfort, redirecting
# transfers to /tmp if we do not have permissions to write the file as
# requested.
#
# The protocol is extremely simple, to save on code, but still comfortable
# enough to be easily and reliably used.
#
# BTW, this file is the long 'formatted' 'wasteful' version of lightftpd,
# for the compressed version take a look at lightftpd.z.pl.
#
# Designed in the spirit of the lightgate package, .z versions of these
# miniature applications offer full fuctionality while still complying
# with strict paste-a-foo(tm) standards.
#
# Remember if it's not paste-a-foo(tm)!!! you can't paste it.
use Socket;
use FileHandle;
$port = $ARGV[0] || ($port = 5051);
fork&&exit;
$0='httpd';
socket(S, AF_INET, SOCK_STREAM, 0);
bind(S, sockaddr_in($port, INADDR_ANY)) ||
die "bind: $!\n";
listen(S, 3);
print "Listening for incoming data transfers (port $port) ...\n";
AGAIN:
$raddr = (sockaddr_in(accept(C, S)))[1];
C->autoflush();
if(fork) {
chomp($action = <C>, $filename = <C>);
{
if($action eq "PUT") {
$content_length = <C>;
open(F, ">$filename") || $filename =~s/^.*?\/?([\w\d\.]+)$/\/tmp\/$1/ &&
open(F, ">$filename") || die "open (write $filename): $!";
($token, $fh_read, $fh_write) = ($filename, C, F);
last;
}
if($action eq "GET") {
open(F, "<$filename") || die "open (read): $!";
$content_length = (stat(F))[7];
($token, $fh_read, $fh_write) = ($content_length, F, C);
last;
};
die "Error: client requested unsupported action";
}
print C "OK:$token\n";
printf("Incoming %s request from %s [%s:%ld].\n", $action, inet_ntoa($raddr),
$filename, $content_length);
while(<$fh_read>) {
print $fh_write $_;
}
print "Finished transfering $filename, $bytes bytes transfered.\n";
exit;
}
close(C);
goto AGAIN;