-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpublictext
More file actions
executable file
·149 lines (115 loc) · 3.82 KB
/
publictext
File metadata and controls
executable file
·149 lines (115 loc) · 3.82 KB
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
#!/usr/bin/env lua
--
-- publictext
-- ucspi-tcp text://protocol server
--
local assert = assert
local io = require( 'io' )
local ipairs = ipairs
local os = require( 'os' )
local pcall = pcall
local table = require( 'table' )
local tonumber = tonumber
local tostring = tostring
_ENV = nil
local EOL = '\r\n'
local SP = ' '
local _request = nil
local function REQUEST( aRequest )
_request = aRequest or _request or io.stdin:read() or os.exit( false )
return _request
end
local function LOG( aStatus, aSize )
local aBuffer = {}
aBuffer[ #aBuffer + 1 ] = os.getenv( 'TCPREMOTEHOST' ) or os.getenv( 'TCPREMOTEIP' ) or '-' -- remotehost
aBuffer[ #aBuffer + 1 ] = os.getenv( 'TCPREMOTEINFO' ) or '-' -- rfc931
aBuffer[ #aBuffer + 1 ] = '-' -- authuser
aBuffer[ #aBuffer + 1 ] = ( '[%s]' ):format( os.date( '!%Y-%m-%dT%TZ' ) ) -- [date]
aBuffer[ #aBuffer + 1 ] = ( '%q' ):format( REQUEST() or '' ) -- "request"
aBuffer[ #aBuffer + 1 ] = tostring( aStatus or '-' ) -- status
aBuffer[ #aBuffer + 1 ] = tostring( aSize or '0' ) -- bytes
io.stderr:write( table.concat( aBuffer, ' ' ), '\n' )
end
local function STATUS( aStatus, aDescription )
local aStatus = assert( tonumber( aStatus ) )
assert( aDescription )
assert( 0 ~= aDescription:len() )
assert( 1024 >= aDescription:len() )
assert( not aDescription:find( '%c' ) )
io.stdout:write( aStatus, SP, aDescription, EOL )
io.stdout:flush()
end
local function CHUNK( aFile )
return function() return aFile:read( 4096 ) end
end
local function OK( aFile, aType, aSize )
STATUS( 20, assert( aType ) )
LOG( 20, assert( aSize ) )
for aChunk in CHUNK( assert( aFile ) ) do
io.stdout:write( aChunk )
io.stdout:flush()
end
aFile:close()
os.exit( true )
end
local function REDIRECT( aLocation )
STATUS( 30, aLocation )
LOG( 30 )
os.exit( true )
end
local function NOK()
STATUS( 40, 'NOK' )
LOG( 40 )
os.exit( false )
end
local function LINK( aFile, aType )
if aType ~= '.lnk' then return end
local aLocation = assert( aFile:read():match( '^(%C+)' ) )
assert( aFile:close() )
REDIRECT( aLocation )
end
local function QUOTE( anArgument )
return ( "'%s'" ):format( assert( anArgument ):gsub( "'", "'\\''" ) )
end
local function TYPE( aFileName )
local aCommand = ( 'file --brief --mime-type --mime-encoding %s 2>/dev/null' ):format( assert( QUOTE( aFileName ) ) )
local aHandle = assert( io.popen( aCommand, 'r' ) )
local aType = assert( aHandle:read() )
assert( aHandle:close() )
return aType
end
local function FILE( aName, anExtension )
local someTypes = { '.lnk', '' }
for _, aType in ipairs( someTypes ) do
local aFileName = ( '%s.%s%s' ):format( aName, anExtension, aType )
local aFile = io.open( aFileName, 'rb' )
if aFile then
local aSize = assert( aFile:seek( 'end' ) )
assert( aFile:seek( 'set' ) )
LINK( aFile, aType )
return aFile, TYPE( aFileName ), aSize
end
end
end
local function HANDLE()
local aRequest = REQUEST()
assert( aRequest )
aRequest = assert( REQUEST( aRequest:match( '^(%C+)' ) ) )
assert( 0 ~= aRequest:len() )
assert( 1024 >= aRequest:len() )
assert( not aRequest:find( '%s' ) )
assert( aRequest == aRequest:lower() )
assert( 'text://' == aRequest:sub( 1, 7 ) )
local aName, anExtension = aRequest:match( '/([%w-]+)%.(%w+)$' )
if '/' == aRequest:sub( -1, -1 ) then aName = 'index' anExtension = 'txt' end
if not aName then REDIRECT( ( '%s/' ):format( aRequest ) ) end
assert( aName )
assert( 0 ~= aName:len() )
assert( 128 >= aName:len() )
assert( anExtension )
assert( 0 ~= anExtension:len() )
assert( 3 >= anExtension:len() )
local aFile, aType, aSize = FILE( aName, anExtension )
OK( aFile, aType, aSize )
end
if not pcall( HANDLE ) then NOK() end