1
|
|
|
#!/usr/bin/env php |
|
|
|
|
2
|
|
|
<?php |
3
|
|
|
if ($argc > 1) { |
4
|
|
|
$configfile=$argv[1]; |
5
|
|
|
} else { |
6
|
|
|
$configfile="default.phtml"; |
7
|
|
|
} |
8
|
|
|
|
9
|
|
|
$ARLoader = 'ftp'; |
10
|
|
|
$currentDir = getcwd(); |
11
|
|
|
$ariadne = dirname($currentDir).'/lib/'; |
12
|
|
|
|
13
|
|
|
if (!@include_once($ariadne."/bootstrap.php")) { |
14
|
|
|
chdir(substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/'))); |
15
|
|
|
$ariadne = dirname(getcwd()).'/lib/'; |
16
|
|
|
|
17
|
|
|
if(!include_once($ariadne."/bootstrap.php")){ |
18
|
|
|
echo "could not find Ariadne"; |
19
|
|
|
exit(1); |
20
|
|
|
} |
21
|
|
|
|
22
|
|
|
chdir($currentDir); |
23
|
|
|
} |
24
|
|
|
|
25
|
|
|
require_once($ariadne."/configs/ftp/$configfile"); |
26
|
|
|
require_once($ariadne."/modules/mod_mimemagic.php"); |
27
|
|
|
|
28
|
|
|
/* this function has been taken from the php manual */ |
29
|
|
|
|
30
|
|
|
function ftp_ErrorHandler ($errno, $errmsg, $filename, $linenum, $vars) { |
31
|
|
|
if ($errno!= 2 && $errno!=8 ) { |
32
|
|
|
// timestamp for the error entry |
33
|
|
|
$dt = date("Y-m-d H:i:s (T)"); |
34
|
|
|
|
35
|
|
|
// define an assoc array of error string |
36
|
|
|
// in reality the only entries we should |
37
|
|
|
// consider are 2,8,256,512 and 1024 |
|
|
|
|
38
|
|
|
$errortype = array ( |
39
|
|
|
1 => "Error", |
40
|
|
|
2 => "Warning", |
41
|
|
|
4 => "Parsing Error", |
42
|
|
|
8 => "Notice", |
43
|
|
|
16 => "Core Error", |
44
|
|
|
32 => "Core Warning", |
45
|
|
|
64 => "Compile Error", |
46
|
|
|
128 => "Compile Warning", |
47
|
|
|
256 => "User Error", |
48
|
|
|
512 => "User Warning", |
49
|
|
|
1024=> "User Notice" |
50
|
|
|
); |
51
|
|
|
// set of errors for which a var trace will be saved |
52
|
|
|
$user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE); |
53
|
|
|
|
54
|
|
|
$err = "<errorentry>\n"; |
55
|
|
|
$err .= "\t<datetime>".$dt."</datetime>\n"; |
56
|
|
|
$err .= "\t<errornum>".$errno."</errnumber>\n"; |
57
|
|
|
$err .= "\t<errortype>".$errortype[$errno]."</errortype>\n"; |
58
|
|
|
$err .= "\t<errormsg>".$errmsg."</errormsg>\n"; |
59
|
|
|
$err .= "\t<scriptname>".$filename."</scriptname>\n"; |
60
|
|
|
$err .= "\t<scriptlinenum>".$linenum."</scriptlinenum>\n"; |
61
|
|
|
|
62
|
|
|
if (in_array($errno, $user_errors)) { |
63
|
|
|
$err .= "\t<vartrace>".wddx_serialize_value($vars,"Variables")."</vartrace>\n"; |
64
|
|
|
} |
65
|
|
|
$err .= "</errorentry>\n\n"; |
66
|
|
|
|
67
|
|
|
debug($err); |
68
|
|
|
} |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
|
72
|
|
|
function ftp_OpenDC() { |
73
|
|
|
global $FTP, $ftp_config; |
74
|
|
|
|
75
|
|
|
$FTP->DC["transfered"]=0; |
76
|
|
|
if ($FTP->DC["mode"]==="active") { |
77
|
|
|
$socket=socket_create(AF_INET, SOCK_STREAM, 0); |
78
|
|
|
if ($socket>=0) { |
79
|
|
|
debug("ftp: opened socket"); |
80
|
|
|
@socket_bind($socket, $ftp_config['server_ip']); |
|
|
|
|
81
|
|
|
$result=socket_connect($socket, $FTP->DC["address"], $FTP->DC["port"]); |
82
|
|
|
if ($result < 0) { |
83
|
|
|
ftp_Tell(425, "Couldn't build data connection (rm: connection error: ".strerror($result).")"); |
84
|
|
|
$result=false; |
85
|
|
|
} else { |
86
|
|
|
debug("ftp: connected"); |
87
|
|
|
$FTP->DC["msgsocket"]=$socket; |
88
|
|
|
$result=true; |
89
|
|
|
} |
90
|
|
|
} else { |
91
|
|
|
ftp_Tell(425, "Couldn't build data connection (rm: socket error: ".strerror($socket).")"); |
92
|
|
|
$result=false; |
93
|
|
|
} |
94
|
|
|
} else { |
95
|
|
|
// do passive mode |
96
|
|
|
debug("ftp::OpenDC waiting on socket accept"); |
97
|
|
|
$counter = 0; |
98
|
|
|
$msgsocket = false; |
99
|
|
|
while ( $counter < 300 && !is_resource($msgsocket) ) { |
100
|
|
|
$counter++; |
101
|
|
|
// wait for 0.1 secondes |
102
|
|
|
usleep(100000); |
103
|
|
|
$msgsocket=socket_accept($FTP->DC["socket"]); |
104
|
|
|
} |
105
|
|
|
debug("ftp::OpenDC socket accepted? (".$msgsocket.")"); |
106
|
|
|
if (!is_resource($msgsocket) ) { |
107
|
|
|
ftp_Tell(425, "Couldn't build data connection"); |
108
|
|
|
$result=false; |
109
|
|
|
} else { |
110
|
|
|
debug("ftp: accept_connect returned $msgsocket"); |
111
|
|
|
socket_set_blocking($msgsocket, true); |
112
|
|
|
debug("ftp: connected ($msgsocket)"); |
113
|
|
|
$FTP->DC["msgsocket"]=$msgsocket; |
114
|
|
|
$result=true; |
115
|
|
|
} |
116
|
|
|
socket_close($FTP->DC["socket"]); |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
if ($result) { |
120
|
|
|
if ($FTP->DC["ob_active"]) { |
121
|
|
|
debug("error: OOPS, dc ob not closed!!"); |
122
|
|
|
} else { |
123
|
|
|
$FTP->DC["ob_active"]=true; |
124
|
|
|
if (ob_start("ftp_WriteDC")) { |
125
|
|
|
debug("ftp_OpenDC:: opening ob"); |
126
|
|
|
} else { |
127
|
|
|
debug("ftp_OpendDC:: could not open ob"); |
128
|
|
|
} |
129
|
|
|
} |
130
|
|
|
} |
131
|
|
|
return $result; |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
function ftp_GetPasv() { |
135
|
|
|
global $FTP; |
136
|
|
|
// client issued 'pasv' command |
137
|
|
|
// so lets try to bind a socket to a port |
138
|
|
|
$result=false; |
139
|
|
|
if ($FTP->DC["socket_desc"]) { |
140
|
|
|
// we alread got a socket open.. let's use it |
141
|
|
|
$result = $FTP->DC["socket_desc"]; |
142
|
|
|
} else { |
143
|
|
|
$socket=socket_create(AF_INET, SOCK_STREAM, 0); |
144
|
|
|
if ($socket>=0) { |
145
|
|
|
debug("ftp: open socket ($socket) (pasv mode)"); |
146
|
|
|
|
147
|
|
|
// FIXME: make this configurable! |
|
|
|
|
148
|
|
|
$bound=0; |
149
|
|
|
$port=12000; |
150
|
|
|
while (!$bound && $port<=12100) { |
151
|
|
|
$bound=socket_bind($socket, $FTP->server_ip, $port); |
152
|
|
|
debug("ftp::pasv socket_bind port $port ($bound)"); |
153
|
|
|
if (!$bound) { |
154
|
|
|
$port++; |
155
|
|
|
} |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
if ($bound) { |
159
|
|
|
$ret=socket_listen($socket, 1); |
160
|
|
|
socket_set_nonblock($socket); |
161
|
|
|
if ($ret < 0) { |
162
|
|
|
ftp_Tell(425, "Couldn't build data connection (rm: socket error:".strerror($socket).")"); |
163
|
|
|
} else { |
164
|
|
|
$FTP->DC["mode"]="passive"; |
165
|
|
|
$FTP->DC["socket"]=$socket; |
166
|
|
|
debug("ftp: listening on port $port"); |
167
|
|
|
$result=str_replace(".", ",", $FTP->server_ip); |
168
|
|
|
$result.=",".(((int)$port) >> 8); |
169
|
|
|
$result.=",".($port & 0x00FF); |
170
|
|
|
//$FTP->DC["socket_desc"]=$result; |
|
|
|
|
171
|
|
|
} |
172
|
|
|
} else { |
173
|
|
|
ftp_Tell(425, "Couldn't build data connection: couldn't bind to a socket"); |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
} else { |
177
|
|
|
ftp_Tell(425, "Couldn't build data connection (rm: socket error:".strerror($socket).")"); |
178
|
|
|
} |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
return $result; |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
|
185
|
|
|
function ftp_WriteDC($bdata) { |
186
|
|
|
global $FTP; |
187
|
|
|
/* |
188
|
|
|
make a copy of $data otherwise we will crash php |
189
|
|
|
(you can't write to data from an output buffer) |
190
|
|
|
*/ |
191
|
|
|
if ($FTP->resume) { |
192
|
|
|
debug("ftp::WriteDC() truncating data"); |
193
|
|
|
$data = substr($bdata, $FTP->resume); |
194
|
|
|
} else { |
195
|
|
|
$data = $bdata; |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
/* free unused data */ |
199
|
|
|
unset($bdata); |
200
|
|
|
|
201
|
|
|
if (strlen($data)) { |
202
|
|
|
debug("ftp::WriteDC([data]) (".strlen($data).")"); |
203
|
|
|
if ($FTP->DC["type"]==="A") { |
204
|
|
|
$offset = 0; |
205
|
|
|
$chunk = substr($data, $offset, 4096); |
206
|
|
|
while ($chunk!==false) { |
207
|
|
|
$chunk=str_replace("\n", "\r\n", $chunk); |
208
|
|
|
$len = strlen($chunk); |
209
|
|
|
debug("ftp_WriteDC:: writing chunk([chunk], $offset, 4096) (".$len.")"); |
210
|
|
|
if (!socket_write($FTP->DC["msgsocket"], $chunk, $len)) { |
211
|
|
|
debug("ftp_WriteDC:: chunk ERROR write $len bytes!"); |
212
|
|
|
$chunk = false; |
213
|
|
|
} else { |
214
|
|
|
debug("ftp_WriteDC:: chunk success"); |
215
|
|
|
//$offset+=strlen($chunk); |
|
|
|
|
216
|
|
|
$offset += 4096; |
217
|
|
|
$FTP->DC["transfered"]+=strlen($data); |
218
|
|
|
$chunk = substr($data, $offset, 4096); |
219
|
|
|
} |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
} else { |
223
|
|
|
$len=strlen($data); |
224
|
|
|
debug("ftp_WriteDC:: writing len (".$len.")"); |
225
|
|
|
if (!socket_write($FTP->DC["msgsocket"], $data, $len)) { |
226
|
|
|
debug("ftp_WriteDC:: ERROR writing $len bytes!"); |
227
|
|
|
} else { |
228
|
|
|
debug("ftp_WriteDC:: success"); |
229
|
|
|
} |
230
|
|
|
$FTP->DC["transfered"]+=strlen($data); |
231
|
|
|
} |
232
|
|
|
} |
233
|
|
|
|
234
|
|
|
return ""; // empty string |
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
function ftp_ReadDC() { |
238
|
|
|
global $FTP; |
239
|
|
|
$data = socket_read($FTP->DC["msgsocket"], 3000, PHP_BINARY_READ); |
240
|
|
|
if (strlen($data) && ($FTP->DC["type"]==="A")) { |
241
|
|
|
if ($data[strlen($data)-1]==="\r") { |
242
|
|
|
$postdata = socket_read($FTP->DC["msgsocket"], 1, PHP_BINARY_READ); |
243
|
|
|
$data.=$postdata; |
244
|
|
|
} |
245
|
|
|
$data=str_replace("\r\n", "\n", $data); |
246
|
|
|
} |
247
|
|
|
debug("ftp::ReadDC() (".strlen($data).")"); |
248
|
|
|
$FTP->DC["transfered"]+=strlen($data); |
249
|
|
|
return $data; |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
function ftp_CloseDC() { |
253
|
|
|
global $FTP; |
254
|
|
|
if ($FTP->DC["ob_active"]) { |
255
|
|
|
debug("ftp::CloseDC:: closing output buffer"); |
256
|
|
|
ob_end_flush(); |
257
|
|
|
debug("ftp::CLoseDC:: ok, ob closed"); |
258
|
|
|
$FTP->DC["ob_active"]=false; |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
debug("ftp: closing connection"); |
262
|
|
|
$con=$FTP->DC["msgsocket"]; |
263
|
|
|
if ($con) { |
264
|
|
|
debug("ftp::CloseDC:: closing connection"); |
265
|
|
|
socket_close($con); |
266
|
|
|
debug("ftp::CloseDC:: connection closed"); |
267
|
|
|
} |
268
|
|
|
} |
269
|
|
|
|
270
|
|
|
function ftp_TranslatePath(&$path, &$listMode) { |
271
|
|
|
global $FTP; |
272
|
|
|
$listMode=""; |
273
|
|
|
$absolute = ($path[0] === '/') ? true : false; |
274
|
|
|
$path=$FTP->site.$FTP->store->make_path($FTP->cwd, $path); |
275
|
|
View Code Duplication |
while (preg_match('|/'.ESPCHL.'([^/]*)'.ESPCHR.'/|', $path, $regs) && $regs[1]) { |
276
|
|
|
$listMode=$regs[1]; |
277
|
|
|
$path=str_replace("/".SPCHL.$listMode.SPCHR."/", "/", $path); |
278
|
|
|
} |
279
|
|
|
if (!$listMode) { |
280
|
|
|
if (!$absolute && $FTP->listMode) { |
281
|
|
|
$listMode=$FTP->listMode; |
282
|
|
|
} else { |
283
|
|
|
$listMode=$FTP->defaultListMode; |
284
|
|
|
} |
285
|
|
|
} |
286
|
|
|
debug("ftp: Translate:: (FTP->listMode = '$FTP->listMode', listMode = '$listMode', path = '$path')"); |
287
|
|
|
} |
288
|
|
|
|
289
|
|
|
function ftp_TranslateTemplate(&$path, &$template) { |
290
|
|
|
global $FTP; |
291
|
|
|
$parent = $FTP->store->make_path($path, ".."); |
292
|
|
|
$template = substr($path, strlen($parent), -1); |
293
|
|
|
$path = $parent; |
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
function ftp_Run() { |
297
|
|
|
global $FTP, $ARCurrent, $ARBeenHere; |
298
|
|
|
|
299
|
|
|
while (ftp_FetchCMD($cmd, $args)) { |
300
|
|
|
$ARBeenHere=array(); |
301
|
|
|
$ARCurrent->arLoginSilent = 0; |
302
|
|
|
$ARCurrent->ftp_error = ""; |
303
|
|
|
|
304
|
|
|
if ($last_cmd != 'REST') { |
|
|
|
|
305
|
|
|
$FTP->resume = 0; |
306
|
|
|
} |
307
|
|
|
switch ($cmd) { |
308
|
|
|
case 'MDTM': |
309
|
|
|
$path = $args; |
310
|
|
|
ftp_TranslatePath($path, $listMode); |
311
|
|
|
switch ($listMode) { |
312
|
|
View Code Duplication |
case 'templates': |
313
|
|
|
ftp_TranslateTemplate($path, $template); |
314
|
|
|
|
315
|
|
|
$result = current( |
316
|
|
|
$FTP->store->call("ftp.template.exists.phtml", |
317
|
|
|
array("arRequestedTemplate" => $template), |
318
|
|
|
$FTP->store->get($path))); |
319
|
|
|
$file_date = $result["date"]; |
320
|
|
|
|
321
|
|
|
if ($file_date) { |
322
|
|
|
ftp_Tell(213, date("YmdHis", $file_date)); |
323
|
|
|
} else { |
324
|
|
|
ftp_Tell(550, "No such file or directory"); |
325
|
|
|
} |
326
|
|
|
break; |
327
|
|
|
default: |
328
|
|
|
if ($FTP->store->exists($path)) { |
329
|
|
|
$file_date = time(); // TODO fix |
330
|
|
|
ftp_Tell(213, date("YmdHis", $file_date)); |
331
|
|
|
} else { |
332
|
|
|
ftp_Tell(550, "No such file or directory"); |
333
|
|
|
} |
334
|
|
|
break; |
335
|
|
|
} |
336
|
|
|
break; |
337
|
|
|
|
338
|
|
|
case 'REST': |
339
|
|
|
$FTP->resume = (int)$args; |
340
|
|
|
ftp_Tell(350, 'Restarting at '.$FTP->resume.'.'); |
341
|
|
|
break; |
342
|
|
|
case 'QUIT': |
343
|
|
|
ftp_Tell(221, "Goodbye."); |
344
|
|
|
/* check if we have to close a 'passive' socket */ |
345
|
|
|
if ($FTP->DC["socket_desc"]) { |
346
|
|
|
socket_close($FTP->DC["socket"]); |
347
|
|
|
} |
348
|
|
|
return 0; |
349
|
|
|
break; |
350
|
|
|
case 'PWD': |
351
|
|
|
$dir=$FTP->cwd; |
352
|
|
|
if ($FTP->listMode) { |
353
|
|
|
$dir="/".SPCHL.$FTP->listMode.SPCHR.$dir; |
354
|
|
|
} |
355
|
|
|
if (strlen($dir)>1) { |
356
|
|
|
$dir=substr($dir,0,-1); |
357
|
|
|
} |
358
|
|
|
ftp_Tell(257, "\"$dir\" is current directory."); |
359
|
|
|
break; |
360
|
|
|
case 'HELP': |
361
|
|
|
ftp_Tell(214, "not implemented" ); |
362
|
|
|
break; |
363
|
|
|
case 'PORT': |
364
|
|
|
$FTP->DC["mode"]="active"; |
365
|
|
|
$host=explode(",",$args); |
366
|
|
|
$address=$host[0].".".$host[1].".".$host[2].".".$host[3]; |
367
|
|
|
$FTP->DC["address"]=$address; |
368
|
|
|
$port=((int)$host[4]) << 8; |
369
|
|
|
$port+=(int)$host[5]; |
370
|
|
|
$FTP->DC["port"]=$port; |
371
|
|
|
ftp_Tell(200, "ok, connecting to $address $port"); |
372
|
|
|
break; |
373
|
|
|
case 'PASV': |
374
|
|
|
$port=ftp_GetPasv(); |
375
|
|
|
if ($port) { |
376
|
|
|
ftp_Tell(227, "Entering Passive Mode ($port)"); |
377
|
|
|
} |
378
|
|
|
break; |
379
|
|
View Code Duplication |
case 'CDUP': |
380
|
|
|
$cwd=$FTP->store->make_path($FTP->cwd, ".."); |
381
|
|
|
if ($FTP->store->exists($FTP->site.$cwd)) { |
382
|
|
|
$FTP->cwd=$cwd; |
383
|
|
|
ftp_Tell(250, "CDUP succesfull"); |
384
|
|
|
} else { |
385
|
|
|
ftp_Tell(550, "CDUP not succesfull"); |
386
|
|
|
} |
387
|
|
|
break; |
388
|
|
|
case 'CWD': |
389
|
|
|
/* if CWD path is absolute then listmode is set to |
390
|
|
|
the default value */ |
391
|
|
|
|
392
|
|
|
$absolute = ($args[0]=="/") ? true : false; |
393
|
|
|
if ($absolute) { |
394
|
|
|
$FTP->listMode=$FTP->defaultListMode; |
395
|
|
|
} |
396
|
|
|
|
397
|
|
|
$path=$FTP->store->make_path($FTP->cwd, $args); |
398
|
|
|
debug("ftp: cwd absolute path is ($path)"); |
399
|
|
View Code Duplication |
while (preg_match('|/'.ESPCHL.'([^/]*)'.ESPCHR.'/|', $path, $regs) && $regs[1]) { |
400
|
|
|
$FTP->listMode=$regs[1]; |
401
|
|
|
$path=str_replace("/".SPCHL.$FTP->listMode.SPCHR."/", "/", $path); |
402
|
|
|
} |
403
|
|
|
$cwd=$FTP->store->make_path($FTP->cwd, $path); |
404
|
|
|
if ($FTP->store->exists($FTP->site.$cwd)) { |
405
|
|
|
$result=current($FTP->store->call("system.get.phtml", "", |
406
|
|
|
$FTP->store->get($FTP->site.$cwd))); |
407
|
|
|
if ($result->type==="pshortcut") { |
408
|
|
|
debug("ftp: shortcut: ".$result->data->path); |
409
|
|
|
$cwd=$FTP->store->make_path($cwd, $result->data->path); |
410
|
|
|
} |
411
|
|
|
|
412
|
|
|
$FTP->cwd=$cwd; |
413
|
|
|
debug("ftp: cwd ($cwd) listmode(".$FTP->listMode.")"); |
414
|
|
|
ftp_Tell(250, "CWD succesfull (listmode = ".$FTP->listMode.")"); |
415
|
|
|
} else { |
416
|
|
|
ftp_Tell(550, "'$cwd' no such file or directory"); |
417
|
|
|
} |
418
|
|
|
break; |
419
|
|
|
|
420
|
|
|
case 'TYPE': |
421
|
|
|
if (preg_match('/a|i/i', $args)) { |
422
|
|
|
$FTP->DC["type"]=strtoupper($args); |
423
|
|
|
ftp_Tell(200, "Type set to ".$args); |
424
|
|
|
} else { |
425
|
|
|
ftp_Tell(500, "Type $args not valid"); |
426
|
|
|
} |
427
|
|
|
break; |
428
|
|
|
|
429
|
|
|
case 'SIZE': |
430
|
|
|
$path = $args; |
431
|
|
|
ftp_TranslatePath($path, $listMode); |
432
|
|
|
switch ($listMode) { |
433
|
|
View Code Duplication |
case 'templates': |
434
|
|
|
ftp_TranslateTemplate($path, $template); |
435
|
|
|
|
436
|
|
|
$result = current( |
437
|
|
|
$FTP->store->call("ftp.template.exists.phtml", |
438
|
|
|
array("arRequestedTemplate" => $template), |
439
|
|
|
$FTP->store->get($path))); |
440
|
|
|
if (is_array($result)) { |
441
|
|
|
$file_size = $result["size"]; |
442
|
|
|
ftp_Tell(213, (int)$file_size); |
443
|
|
|
} else { |
444
|
|
|
ftp_Tell(550, "No such file or directory"); |
445
|
|
|
} |
446
|
|
|
|
447
|
|
|
break; |
448
|
|
View Code Duplication |
default: |
449
|
|
|
if ($FTP->store->exists($path)) { |
450
|
|
|
$size = $FTP->store->call( |
451
|
|
|
"ftp.$listMode.size.phtml", |
452
|
|
|
"", |
453
|
|
|
$FTP->store->get($path)); |
454
|
|
|
ftp_Tell(213, (int)$size[0]); |
455
|
|
|
} else { |
456
|
|
|
ftp_Tell(550, "No such file or directory"); |
457
|
|
|
} |
458
|
|
|
break; |
459
|
|
|
} |
460
|
|
|
break; |
461
|
|
|
|
462
|
|
|
case 'RNFR': |
463
|
|
|
$rename_src_path = $args; |
464
|
|
|
ftp_TranslatePath($rename_src_path, $rename_src_listMode); |
465
|
|
|
if ($listMode === "templates") { |
|
|
|
|
466
|
|
|
ftp_TranslateTemplate($rename_src_path, $rename_src_template); |
467
|
|
|
$result = $FTP->store->call( |
468
|
|
|
"ftp.template.exists.phtml", |
469
|
|
|
array( |
470
|
|
|
"arRequestedTemplate" => $rename_src_template |
471
|
|
|
), |
472
|
|
|
$FTP->store->get($path)); |
|
|
|
|
473
|
|
|
|
474
|
|
|
if (is_array($result) && current($result)) { |
475
|
|
|
ftp_Tell(350, "template exists, supply destination name."); |
476
|
|
|
} else { |
477
|
|
|
ftp_Tell(550, "template [".$rename_src_template."] does not exists."); |
478
|
|
|
$rename_src_path = ""; |
479
|
|
|
} |
480
|
|
|
|
481
|
|
|
} else if ($FTP->store->exists($rename_src_path)) { |
482
|
|
|
ftp_Tell(350, "Object exists, supply destination name."); |
483
|
|
|
} else { |
484
|
|
|
ftp_Tell(550, "Object [".$rename_src_path."] does not exists."); |
485
|
|
|
$rename_src_path = ""; |
486
|
|
|
} |
487
|
|
|
break; |
488
|
|
|
|
489
|
|
|
case 'RNTO': |
490
|
|
|
if ($rename_src_path) { |
491
|
|
|
$rename_dest_path = $args; |
492
|
|
|
ftp_TranslatePath($rename_dest_path, $rename_dest_listMode); |
493
|
|
|
if ($rename_dest_listMode === $rename_src_listMode) { |
494
|
|
|
if ($rename_dest_listMode === "templates") { |
495
|
|
|
$temp = $args; |
496
|
|
|
if ($temp[strlen($temp)-1] === "/") { |
497
|
|
|
$rename_dest_template = $rename_src_template; |
|
|
|
|
498
|
|
|
} else { |
499
|
|
|
ftp_TranslateTemplate($rename_dest_path, $rename_dest_template); |
500
|
|
|
} |
501
|
|
|
$do_move = $FTP->store->exists($rename_dest_path); |
502
|
|
|
} else { |
503
|
|
|
if ($FTP->store->exists($rename_dest_path)) { |
504
|
|
|
$parent = $FTP->store->make_path($rename_src_path, ".."); |
|
|
|
|
505
|
|
|
$file = substr($rename_src_path, strlen($parent)); |
506
|
|
|
$rename_dest_path.=$file; |
507
|
|
|
} |
508
|
|
|
$do_move = !$FTP->store->exists($rename_dest_path); |
509
|
|
|
} |
510
|
|
|
|
511
|
|
|
if ($do_move) { |
512
|
|
|
debug("ftp::RENAME ($rename_src_path, $rename_dest_path, ".$rename_src_listMode.", $rename_src_template, $rename_dest_template)"); |
|
|
|
|
513
|
|
|
$FTP->store->call("ftp.".$rename_src_listMode.".rename.phtml", |
514
|
|
|
array( |
515
|
|
|
"source" => $rename_src_path, |
516
|
|
|
"target" => $rename_dest_path, |
517
|
|
|
"source_template" => $rename_src_template, |
518
|
|
|
"target_template" => $rename_dest_template |
519
|
|
|
), |
520
|
|
|
$FTP->store->get($rename_src_path)); |
521
|
|
|
|
522
|
|
View Code Duplication |
if ($ARCurrent->ftp_error) { |
523
|
|
|
ftp_Tell(550, $ARCurrent->ftp_error); |
524
|
|
|
unset($ARCurrent->ftp_error); |
525
|
|
|
} else { |
526
|
|
|
ftp_Tell(250, "Rename successfull."); |
527
|
|
|
} |
528
|
|
|
$rename_src_path = ""; |
529
|
|
|
} else { |
530
|
|
|
ftp_Tell(550, "Object [".$args."] does already exist."); |
531
|
|
|
} |
532
|
|
|
} else { |
533
|
|
|
ftp_Tell(550, "Moving objects between different modeses is not supported (yet)."); |
534
|
|
|
} |
535
|
|
|
} else { |
536
|
|
|
ftp_Tell(550, "Expected RNFR"); |
537
|
|
|
} |
538
|
|
|
break; |
539
|
|
|
|
540
|
|
|
case 'RETR': |
541
|
|
|
$path=$args; |
542
|
|
|
ftp_TranslatePath($path, $listMode); |
543
|
|
|
switch ($listMode) { |
544
|
|
|
case "templates": |
545
|
|
|
ftp_TranslateTemplate($path, $template); |
546
|
|
|
$getmode = "templates"; |
547
|
|
|
|
548
|
|
|
$result = current( |
549
|
|
|
$FTP->store->call("ftp.template.exists.phtml", |
550
|
|
|
array("arRequestedTemplate" => $template), |
551
|
|
|
$FTP->store->get($path))); |
552
|
|
|
$file_size = $result["size"]; |
553
|
|
|
break; |
554
|
|
|
default: |
555
|
|
|
$file_size = current( |
556
|
|
|
$FTP->store->call("ftp.files.size.phtml", "", |
557
|
|
|
$FTP->store->get($path))); |
558
|
|
|
$getmode = "files"; |
559
|
|
|
break; |
560
|
|
|
} |
561
|
|
|
|
562
|
|
|
debug("ftp: opening $path / template $template"); |
|
|
|
|
563
|
|
|
|
564
|
|
|
if (ftp_OpenDC()!==false) { |
565
|
|
|
if ($FTP->store->exists($path)) { |
566
|
|
|
|
567
|
|
|
$file_size -= $FTP->resume; |
568
|
|
|
ftp_Tell(150, "Opening ".(($FTP->DC["type"]==="A") ? 'ASCII' : 'BINARY')." mode data connection for $args ($file_size bytes)"); |
569
|
|
|
$FTP->store->call("ftp.$getmode.get.phtml", array("arRequestedTemplate" => $template), |
570
|
|
|
$FTP->store->get($path)); |
571
|
|
|
debug("ftp::get::going to close dc"); |
572
|
|
|
ftp_CloseDC(); |
573
|
|
|
debug("ftp::get::dc closed"); |
574
|
|
|
ftp_Tell(226, "Transfer complete"); |
575
|
|
|
} else { |
576
|
|
|
ftp_CloseDC(); |
577
|
|
|
ftp_Tell(550, "$file does not exist"); |
|
|
|
|
578
|
|
|
} |
579
|
|
|
} |
580
|
|
|
break; |
581
|
|
|
|
582
|
|
|
case 'NLST': |
583
|
|
|
case 'LIST': |
584
|
|
|
$args = chop($args); |
585
|
|
|
// only use the last word (some clients issue LIST -l [filename]) |
586
|
|
|
$args=preg_replace('/(-[^[:space:]]+)?[[:space:]]*([^[:space:]]*)$/', '\2', $args); |
587
|
|
|
debug("LIST ARGS($args)"); |
588
|
|
|
$path = $args; |
589
|
|
|
ftp_TranslatePath($path, $listMode); |
590
|
|
|
debug("ftp: LIST path=$path, mode=$listMode"); |
591
|
|
|
if ($FTP->store->exists($path)) { |
592
|
|
|
|
593
|
|
|
ftp_Tell(150, "Opening ".(($FTP->DC["type"]==="A") ? 'ASCII' : 'BINARY')." mode data connection"); |
594
|
|
|
if (ftp_OpenDC()!==false) { |
595
|
|
|
$mode = array(); |
596
|
|
|
debug("ftp: listing ($path) ($listMode)"); |
597
|
|
|
|
598
|
|
|
if ($FTP->symlinkListModes) { |
599
|
|
View Code Duplication |
if ($listMode!=="files") { |
600
|
|
|
$mode["filename"]=SPCHL."files".SPCHR; |
601
|
|
|
$mode["date"]=time(); |
602
|
|
|
if ($FTP->cwd!=="/") { |
603
|
|
|
$mode["type"]="shortcut"; |
604
|
|
|
$mode["target"]=$FTP->cwd; |
605
|
|
|
if ($FTP->defaultListMode!="files") { |
606
|
|
|
$mode["target"]="/".SPCHL."files".SPCHR.$mode["target"]; |
607
|
|
|
} |
608
|
|
|
} else { |
609
|
|
|
$mode["type"]="dir"; |
610
|
|
|
} |
611
|
|
|
$mode["size"]=0; |
612
|
|
|
$mode["grants"]["read"]=true; |
613
|
|
|
|
614
|
|
|
if ($cmd!=="NLST") { |
615
|
|
|
$data=ftp_GenListEntry($mode); |
616
|
|
|
echo "$data"; |
617
|
|
|
} else { |
618
|
|
|
echo $mode["filename"]."\n"; |
619
|
|
|
} |
620
|
|
|
} |
621
|
|
|
|
622
|
|
View Code Duplication |
if ($listMode!=="templates") { |
623
|
|
|
$mode["filename"]=SPCHL."templates".SPCHR; |
624
|
|
|
$mode["date"]=time(); |
625
|
|
|
if ($FTP->cwd!=="/") { |
626
|
|
|
$mode["type"]="shortcut"; |
627
|
|
|
$mode["target"]=$FTP->cwd; |
628
|
|
|
if ($FTP->defaultListMode!="templates") { |
629
|
|
|
$mode["target"]="/".SPCHL."templates".SPCHR.$mode["target"]; |
630
|
|
|
} |
631
|
|
|
} else { |
632
|
|
|
$mode["type"]="dir"; |
633
|
|
|
} |
634
|
|
|
$mode["size"]=0; |
635
|
|
|
$mode["grants"]["read"]=true; |
636
|
|
|
if ($cmd!=="NLST") { |
637
|
|
|
$data=ftp_GenListEntry($mode); |
638
|
|
|
echo "$data"; |
639
|
|
|
} else { |
640
|
|
|
echo $mode["filename"]."\n"; |
641
|
|
|
} |
642
|
|
|
} |
643
|
|
|
|
644
|
|
View Code Duplication |
if ($listMode!=="objects") { |
645
|
|
|
$mode["filename"]=SPCHL."objects".SPCHR; |
646
|
|
|
$mode["date"]=time(); |
647
|
|
|
$mode["size"]=0; |
648
|
|
|
$mode["grants"]["read"]=true; |
649
|
|
|
if ($FTP->cwd!=="/") { |
650
|
|
|
$mode["type"]="shortcut"; |
651
|
|
|
$mode["target"]=$FTP->cwd; |
652
|
|
|
if ($FTP->defaultListMode!="objects") { |
653
|
|
|
$mode["target"]="/".SPCHL."objects".SPCHR.$mode["target"]; |
654
|
|
|
} |
655
|
|
|
} else { |
656
|
|
|
$mode["type"]="dir"; |
657
|
|
|
} |
658
|
|
|
if ($cmd!=="NLST") { |
659
|
|
|
$data=ftp_GenListEntry($mode); |
660
|
|
|
echo "$data"; |
661
|
|
|
} else { |
662
|
|
|
echo $mode["filename"]."\n"; |
663
|
|
|
} |
664
|
|
|
} |
665
|
|
|
} |
666
|
|
|
$template="ftp.".$listMode.".list.phtml"; |
667
|
|
|
$result=current($FTP->store->call($template, "", |
668
|
|
|
$FTP->store->get($path))); |
669
|
|
|
|
670
|
|
|
debug("ftp: results(".sizeof($result).")"); |
671
|
|
|
@reset($result); |
|
|
|
|
672
|
|
|
foreach ( $result as $entry ) { |
673
|
|
|
debug("ftp: file path = (".$entry["path"].")"); |
674
|
|
View Code Duplication |
if ($cmd!=="NLST") { |
675
|
|
|
$data=ftp_GenListEntry($entry); |
676
|
|
|
echo "$data"; |
677
|
|
|
} else { |
678
|
|
|
$parent = $FTP->store->make_path($entry["path"], ".."); |
679
|
|
|
$filename = $entry["path"] ? substr($entry["path"], strlen($parent), -1) : $entry["filename"]; |
680
|
|
|
debug("ftp::nlst ".$filename); |
681
|
|
|
echo $filename."\n"; |
682
|
|
|
} |
683
|
|
|
} |
684
|
|
|
|
685
|
|
|
ftp_CloseDC(); |
686
|
|
|
ftp_Tell(226, "Transfer complete"); |
687
|
|
|
} else { |
688
|
|
|
ftp_Tell(550, "Could not connect to client"); |
689
|
|
|
debug("ftp: could not connect"); |
690
|
|
|
} |
691
|
|
|
} else { |
692
|
|
|
ftp_TranslateTemplate($path, $template); |
693
|
|
|
debug("ftp::list maybe it's a template? ($path, $template)"); |
694
|
|
|
$result = current($FTP->store->call("ftp.template.exists.phtml", |
695
|
|
|
array("arRequestedTemplate" => $template), |
696
|
|
|
$FTP->store->get($path))); |
697
|
|
|
|
698
|
|
|
if (is_array($result)) { |
699
|
|
|
ftp_Tell(150, "Opening ".(($FTP->DC["type"]==="A") ? 'ASCII' : 'BINARY')." mode data connection"); |
700
|
|
|
if (ftp_OpenDC()!==false) { |
701
|
|
View Code Duplication |
if ($cmd!=="NLST") { |
702
|
|
|
echo ftp_GenListEntry($result); |
703
|
|
|
} else { |
704
|
|
|
$parent = $FTP->store->make_path($result["path"], ".."); |
705
|
|
|
$filename = $result["path"] ? substr($result["path"], strlen($parent), -1) : $result["filename"]; |
706
|
|
|
debug("ftp::nlst ".$filename); |
707
|
|
|
echo $filename."\n"; |
708
|
|
|
} |
709
|
|
|
ftp_CloseDC(); |
710
|
|
|
ftp_Tell(226, "Transfer complete"); |
711
|
|
|
} else { |
712
|
|
|
ftp_Tell(550, "Could not connect to client"); |
713
|
|
|
debug("ftp: could not connect"); |
714
|
|
|
} |
715
|
|
|
} else { |
716
|
|
|
ftp_Tell(550, "Directory not found"); |
717
|
|
|
} |
718
|
|
|
} |
719
|
|
|
break; |
720
|
|
|
|
721
|
|
|
case 'RMD': |
722
|
|
|
case 'RMDIR': |
723
|
|
|
case 'DELE': |
724
|
|
|
$target = $args; |
725
|
|
|
ftp_TranslatePath($target, $listMode); |
726
|
|
|
|
727
|
|
|
debug("ftp: removing $target"); |
728
|
|
|
if ($listMode==="templates") { |
729
|
|
|
$path = $FTP->store->make_path($target, ".."); |
730
|
|
|
$template = substr($target, strlen($path), -1); |
731
|
|
|
debug("ftp: removing template ($path) ($template)"); |
732
|
|
|
$FTP->store->call("ftp.templates.delete.phtml", array("template" => $template), |
733
|
|
|
$FTP->store->get($path)); |
734
|
|
|
|
735
|
|
|
ftp_Tell(250, "$template removed"); |
736
|
|
|
} else if ($FTP->store->exists($target)) { |
737
|
|
|
debug("ftp::delete ($target) ftp.$listMode.delete.phtml"); |
738
|
|
|
$FTP->store->call("ftp.$listMode.delete.phtml", "", |
739
|
|
|
$FTP->store->get($target)); |
740
|
|
|
|
741
|
|
View Code Duplication |
if ($ARCurrent->ftp_error) { |
742
|
|
|
ftp_Tell(550, $ARCurrent->ftp_error); |
743
|
|
|
unset($ARCurrent->ftp_error); |
744
|
|
|
} else { |
745
|
|
|
ftp_Tell(250, "$target removed"); |
746
|
|
|
} |
747
|
|
|
} else { |
748
|
|
|
ftp_Tell(550, "$target does not exist"); |
749
|
|
|
} |
750
|
|
|
break; |
751
|
|
|
|
752
|
|
|
case 'STOR': |
753
|
|
|
$target = $args; |
754
|
|
|
ftp_TranslatePath($target, $listMode); |
755
|
|
|
$path = $FTP->store->make_path($target, ".."); |
756
|
|
|
|
757
|
|
|
ftp_Tell(150, "Opening ".(($FTP->DC["type"]==="A") ? 'ASCII' : 'BINARY')." mode data connection"); |
758
|
|
|
debug("ftp: client wants to store file ($target)"); |
759
|
|
|
preg_match('|^/(.*/)?[^./]*[.]([^./]+)/$|i', $target, $regs); |
760
|
|
|
$ext = $regs[2]; |
761
|
|
|
if (ftp_OpenDC()) { |
762
|
|
|
$tempfile=tempnam($FTP->store->get_config('files')."temp/", "upload"); |
763
|
|
|
debug("tempfile: '$tempfile' ext: '$ext'"); |
764
|
|
|
$tempfile.=$ext; |
765
|
|
|
$fp=fopen($tempfile, "wb"); |
766
|
|
|
$fileinfo = array(); |
767
|
|
|
if ($fp) { |
768
|
|
|
$fileinfo["tmp_name"]=$tempfile; |
769
|
|
|
if ($listMode === "templates") { |
770
|
|
|
ftp_TranslateTemplate($target, $template); |
771
|
|
|
$fileinfo["name"]=preg_replace('/[^.a-z0-9_-]/i', '_', $template); |
772
|
|
|
|
773
|
|
|
debug("ftp: writing to $tempfile\n"); |
774
|
|
|
if ($FTP->resume) { |
775
|
|
|
debug("ftp::store resuming file at $FTP->resume"); |
776
|
|
|
ob_start(); |
777
|
|
|
$FTP->store->call("ftp.$listMode.get.phtml", array("arRequestedTemplate" => $template), |
778
|
|
|
$FTP->store->get($target)); |
779
|
|
|
$data=ob_get_contents(); |
780
|
|
|
fwrite($fp, substr($data, 0, $FTP->resume)); |
781
|
|
|
ob_end_clean(); |
782
|
|
|
} |
783
|
|
|
while (($data=ftp_ReadDC())) { |
784
|
|
|
fwrite($fp, $data); |
785
|
|
|
} |
786
|
|
|
fclose($fp); |
787
|
|
|
ftp_CloseDC(); |
788
|
|
|
$fileinfo["type"]=get_mime_type($tempfile); |
789
|
|
View Code Duplication |
if (!$fileinfo["type"]) { |
790
|
|
|
$fileinfo["type"]=get_mime_type($fileinfo["name"], MIME_EXT); |
791
|
|
|
} |
792
|
|
|
$fileinfo["size"]=filesize($tempfile); |
793
|
|
|
|
794
|
|
|
debug("ftp: writing template to ($target$template)"); |
795
|
|
|
$FTP->store->call("ftp.templates.save.phtml", array("file" => $fileinfo), |
796
|
|
|
$FTP->store->get($target)); |
797
|
|
|
} else { |
798
|
|
|
$file=substr($target, strlen($path), -1); |
799
|
|
|
$fileinfo["name"]=preg_replace('/[^.a-z0-9_-]/i', '_', $file); |
800
|
|
|
if ($FTP->store->exists($target)) { |
801
|
|
|
debug("ftp::store updating $target"); |
802
|
|
|
debug("ftp: writing to $tempfile\n"); |
803
|
|
|
if ($FTP->resume) { |
804
|
|
|
debug("ftp::store resuming file at $FTP->resume"); |
805
|
|
|
ob_start(); |
806
|
|
|
$FTP->store->call("ftp.$listMode.get.phtml", "", |
807
|
|
|
$FTP->store->get($target)); |
808
|
|
|
$data=ob_get_contents(); |
809
|
|
|
debug("ftp::store resume pre-read ".strlen($data)); |
810
|
|
|
fwrite($fp, substr($data, 0, $FTP->resume)); |
811
|
|
|
ob_end_clean(); |
812
|
|
|
} |
813
|
|
|
while (($data=ftp_ReadDC())) { |
814
|
|
|
fwrite($fp, $data); |
815
|
|
|
} |
816
|
|
|
fclose($fp); |
817
|
|
|
ftp_CloseDC(); |
818
|
|
|
|
819
|
|
|
$fileinfo["type"]=get_mime_type($tempfile); |
820
|
|
View Code Duplication |
if (!$fileinfo["type"]) { |
821
|
|
|
$fileinfo["type"]=get_mime_type($fileinfo["name"], MIME_EXT); |
822
|
|
|
} |
823
|
|
|
$fileinfo["size"]=filesize($tempfile); |
824
|
|
|
debug("ftp::store total size of fileupload is: ".$fileinfo["size"]); |
825
|
|
|
// if $target already exists |
826
|
|
|
$FTP->store->call("ftp.$listMode.save.phtml", array("file" => $fileinfo), |
827
|
|
|
$FTP->store->get($target)); |
828
|
|
|
} else { |
829
|
|
|
debug("ftp::store storing $target"); |
830
|
|
|
debug("ftp: writing to $tempfile\n"); |
831
|
|
|
while (($data=ftp_ReadDC())) { |
832
|
|
|
fwrite($fp, $data); |
833
|
|
|
} |
834
|
|
|
fclose($fp); |
835
|
|
|
ftp_CloseDC(); |
836
|
|
|
|
837
|
|
|
$fileinfo["type"]=get_mime_type($tempfile); |
838
|
|
View Code Duplication |
if (!$fileinfo["type"]) { |
839
|
|
|
$fileinfo["type"]=get_mime_type($fileinfo["name"], MIME_EXT); |
840
|
|
|
} |
841
|
|
|
$fileinfo["size"]=filesize($tempfile); |
842
|
|
|
|
843
|
|
|
$FTP->store->call("ftp.$listMode.save.new.phtml", array("file" => $fileinfo), |
844
|
|
|
$FTP->store->get($path)); |
845
|
|
|
} |
846
|
|
|
} |
847
|
|
|
if (file_exists($tempfile)) { |
848
|
|
|
@unlink($tempfile); |
|
|
|
|
849
|
|
|
} |
850
|
|
|
|
851
|
|
|
} else { |
852
|
|
|
debug("ftp: could not write to $filename\n"); |
|
|
|
|
853
|
|
|
} |
854
|
|
|
|
855
|
|
|
if ($ARCurrent->ftp_error) { |
856
|
|
|
ftp_Tell(550, $ARCurrent->ftp_error); |
857
|
|
|
unset($ARCurrent->ftp_error); |
858
|
|
|
} else { |
859
|
|
|
ftp_Tell(226, "Transfer complete (".$fileinfo["name"].")"); |
860
|
|
|
} |
861
|
|
|
} else { |
862
|
|
|
debug("ftp: error connecting to client"); |
863
|
|
|
ftp_Tell(550, "Could not establish a connection"); |
864
|
|
|
} |
865
|
|
|
break; |
866
|
|
|
|
867
|
|
|
case 'MKD': |
868
|
|
|
$path_requested = $args; |
869
|
|
|
$path=preg_replace("|/".ESPCHL.'[^/]*'.ESPCHR."/|", "/", $args); |
870
|
|
|
preg_match('|^(.*[/])?(.*)$|i', $path, $regs); |
871
|
|
|
$arNewFilename=preg_replace('/[^.a-z0-9_-]/i', '_', $regs[2]); |
872
|
|
|
|
873
|
|
|
$path=$FTP->site.$FTP->store->make_path($FTP->cwd, $path); |
874
|
|
|
$parent=$FTP->store->make_path($path, ".."); |
875
|
|
|
|
876
|
|
|
debug("ftp: mkdir: name = '$arNewFilename' path = '$path' parent = '$parent'"); |
877
|
|
|
|
878
|
|
|
if ($FTP->store->exists($parent)) { |
879
|
|
|
if (!$FTP->store->exists($path)) { |
880
|
|
|
$FTP->store->call("ftp.mkdir.phtml", array("arNewFilename" => $arNewFilename), |
881
|
|
|
$FTP->store->get($parent)); |
882
|
|
|
} else { |
883
|
|
|
$ARCurrent->ftp_error="Directory already exists"; |
884
|
|
|
} |
885
|
|
|
} else { |
886
|
|
|
$ARCurrent->ftp_error="Could not find path $parent"; |
887
|
|
|
} |
888
|
|
|
|
889
|
|
View Code Duplication |
if ($ARCurrent->ftp_error) { |
890
|
|
|
ftp_Tell(550, $ARCurrent->ftp_error); |
891
|
|
|
unset($ARCurrent->ftp_error); |
892
|
|
|
} else { |
893
|
|
|
ftp_Tell(257, "\"$path_requested\" - Directory successfully created."); |
894
|
|
|
} |
895
|
|
|
break; |
896
|
|
|
|
897
|
|
|
case 'SYST': |
898
|
|
|
ftp_Tell(215, "UNIX Type: L8"); |
899
|
|
|
break; |
900
|
|
|
|
901
|
|
|
case 'NOOP': |
902
|
|
|
ftp_Tell(200, "NOOP command successful"); |
903
|
|
|
break; |
904
|
|
|
|
905
|
|
|
case 'USER': |
906
|
|
|
case 'PASS': |
907
|
|
|
ftp_Tell(530, "User '$FTP->user' already logged in"); |
908
|
|
|
break; |
909
|
|
|
|
910
|
|
|
default: |
911
|
|
|
ftp_Tell(500, "Function $cmd not implemented (yet)."); |
912
|
|
|
break; |
913
|
|
|
} |
914
|
|
|
$last_cmd = $cmd; |
915
|
|
|
} |
916
|
|
|
} |
917
|
|
|
|
918
|
|
|
function ftp_CheckLogin() { |
919
|
|
|
global $FTP, $AR, $ARLogin, $ARPassword; |
920
|
|
|
|
921
|
|
|
while (!$AR->user) { |
922
|
|
|
ftp_FetchCMD($cmd, $args); |
923
|
|
|
if ($cmd==="USER") { |
924
|
|
|
$login=$args; |
925
|
|
|
ftp_Tell(331, "Password required for '$login'"); |
926
|
|
|
ftp_FetchCMD($cmd, $args); |
927
|
|
|
if ($cmd=="PASS") { |
928
|
|
|
$password=$args; |
929
|
|
|
debug("ftp: auth ($login, $password)"); |
930
|
|
|
|
931
|
|
|
$criteria="object.implements = 'puser'"; |
932
|
|
|
$criteria.=" and login.value = '".AddSlashes($login)."'"; |
933
|
|
|
$user=$FTP->store->call("system.get.phtml", "", |
934
|
|
|
$FTP->store->find("/system/users/", |
935
|
|
|
$criteria)); |
936
|
|
|
$user=$user[0]; |
937
|
|
|
|
938
|
|
|
if ($user) { |
939
|
|
|
debug("ftp: found user"); |
940
|
|
|
$ARLogin=$login; |
941
|
|
|
$ARPassword=$password; |
942
|
|
|
|
943
|
|
|
if ($user->CheckPassword($password)) { |
944
|
|
|
$AR->user=$user; |
945
|
|
|
if ($user->data->login!="admin") { |
946
|
|
|
$AR->user->grants[$AR->user->path]=$AR->user->GetValidGrants(); |
947
|
|
|
} |
948
|
|
|
|
949
|
|
|
$siteroot = current($FTP->store->call("system.get.phtml", "", $FTP->store->get($FTP->site."/"))); |
950
|
|
|
|
951
|
|
|
if ($AR->user->data->login==="admin" || $siteroot->CheckLogin("ftp")) { |
952
|
|
|
$FTP->cwd="/"; |
953
|
|
|
$FTP->user=$login; |
954
|
|
|
} else { |
955
|
|
|
ftp_Tell(530, "Login incorrect: (site) permission denied"); |
956
|
|
|
unset($user); |
957
|
|
|
unset($AR->user); |
958
|
|
|
} |
959
|
|
|
|
960
|
|
|
} else { |
961
|
|
|
ftp_Tell(530, "Login incorrect: password incorrect"); |
962
|
|
|
} |
963
|
|
|
} else { |
964
|
|
|
ftp_Tell(530, "Login incorrect: user '$login' not found "); |
965
|
|
|
} |
966
|
|
|
} else { |
967
|
|
|
ftp_Tell(530, "Please login with USER and PASS."); |
968
|
|
|
} |
969
|
|
|
} else { |
970
|
|
|
ftp_Tell(530, "Please login with USER and PASS."); |
971
|
|
|
} |
972
|
|
|
} |
973
|
|
|
ftp_Tell(230, "User '".$FTP->user."' logged in at $FTP->cwd "); |
974
|
|
|
} |
975
|
|
|
|
976
|
|
|
function ftp_FetchCMD(&$cmd, &$args) { |
977
|
|
|
global $FTP; |
978
|
|
|
$cmd = ""; |
979
|
|
|
do { |
980
|
|
|
$data=fgets($FTP->stdin, 2000); |
981
|
|
|
debug("ftp: client:: '$data'"); |
982
|
|
|
if (preg_match('/^([a-z]+)([[:space:]]+(.*))?/i', $data, $regs)) { |
983
|
|
|
$cmd=strtoupper($regs[1]); |
984
|
|
|
$args=chop($regs[3]); |
985
|
|
|
debug("ftp: cmd ($cmd) arg ($args)"); |
986
|
|
|
} |
987
|
|
|
} while (!$cmd); |
988
|
|
|
return $cmd; |
989
|
|
|
} |
990
|
|
|
|
991
|
|
|
function ftp_Tell($code, $msg) { |
992
|
|
|
global $FTP; |
993
|
|
|
if (is_array($msg)) { |
994
|
|
|
fputs($FTP->stdout, "$code-".$msg[0]."\n"); |
995
|
|
|
next($msg); |
996
|
|
|
while (list(,$line)=each($msg)) { |
997
|
|
|
fputs($FTP->stdout, $line."\r\n"); |
998
|
|
|
debug($line); |
999
|
|
|
} |
1000
|
|
|
} else { |
1001
|
|
|
fputs($FTP->stdout, "$code $msg\n"); |
1002
|
|
|
debug("$code $msg\n"); |
1003
|
|
|
} |
1004
|
|
|
fflush($FTP->stdout); |
1005
|
|
|
} |
1006
|
|
|
|
1007
|
|
|
function ftp_GenListEntry($entry) { |
1008
|
|
|
global $AR; |
1009
|
|
|
|
1010
|
|
|
$user=$AR->user->data->login; |
1011
|
|
|
$grants=$entry["grants"]; |
1012
|
|
|
|
1013
|
|
|
if ($entry["filename"]) { |
1014
|
|
|
$file=$entry["filename"]; |
1015
|
|
|
} else { |
1016
|
|
|
$file=substr($entry["path"], strrpos(substr($entry["path"], 0, -1), "/")+1); |
1017
|
|
|
} |
1018
|
|
|
|
1019
|
|
|
if ($entry["type"]==="dir") { |
1020
|
|
|
$data.="d"; |
|
|
|
|
1021
|
|
View Code Duplication |
if ($file[strlen($file)-1]==='/') { |
1022
|
|
|
$file=substr($file, 0, -1); |
1023
|
|
|
} |
1024
|
|
|
} else if ($entry["type"]==="shortcut") { |
1025
|
|
|
$data.="l"; |
1026
|
|
View Code Duplication |
if ($file[strlen($file)-1]==='/') { |
1027
|
|
|
$file=substr($file, 0, -1); |
1028
|
|
|
} |
1029
|
|
|
$file=$file." -> "; |
1030
|
|
|
$file.=$entry["target"]; |
1031
|
|
|
} else if ($entry["type"]==="template") { |
1032
|
|
|
$data.="-"; |
1033
|
|
|
} else { |
1034
|
|
|
$data.="-"; |
1035
|
|
|
$file=substr($file, 0, -1); |
1036
|
|
|
} |
1037
|
|
|
|
1038
|
|
|
if ($grants["read"]) { |
1039
|
|
|
$data.="r"; |
1040
|
|
|
} else { |
1041
|
|
|
$data.="-"; |
1042
|
|
|
} |
1043
|
|
|
if ($grants["write"]) { |
1044
|
|
|
|
1045
|
|
|
$data.="w"; |
1046
|
|
|
} else { |
1047
|
|
|
$data.="-"; |
1048
|
|
|
} |
1049
|
|
|
if (($entry["type"]==="dir" || $entry["type"]==="shortcut") && $grants["read"]) { |
1050
|
|
|
$data.="x"; |
1051
|
|
|
} else { |
1052
|
|
|
$data.="-"; |
1053
|
|
|
} |
1054
|
|
|
|
1055
|
|
|
// 'group' grants are identical to user grants |
1056
|
|
|
// and we don't give public any grants |
1057
|
|
|
$data.=substr($data, 1); |
1058
|
|
|
$data.="---"; |
1059
|
|
|
|
1060
|
|
|
$data.=" 1 "; // we just say this directory contains 1 child |
1061
|
|
|
|
1062
|
|
|
$user = substr($user, 0, 9); |
1063
|
|
|
$userentry = $user.substr(" ", strlen($user)); |
1064
|
|
|
$data.=$userentry.$userentry; |
1065
|
|
|
|
1066
|
|
|
$size = substr($entry["size"], 0, 8); |
1067
|
|
|
$sizeentry = substr(" ", strlen($size)).$size; |
1068
|
|
|
$data.=$sizeentry; |
1069
|
|
|
|
1070
|
|
|
$date=substr(date("M d h:i", $entry["date"]), 0, 12); |
1071
|
|
|
$dateentry = substr(" ", strlen($date)).$date; |
1072
|
|
|
$data.=" ".$dateentry; |
1073
|
|
|
|
1074
|
|
|
$data.=" ".$file; |
1075
|
|
|
|
1076
|
|
|
$data.="\n"; |
1077
|
|
|
debug($data); |
1078
|
|
|
return $data; |
1079
|
|
|
} |
1080
|
|
|
|
1081
|
|
|
|
1082
|
|
|
// debugon("pinp"); |
|
|
|
|
1083
|
|
|
|
1084
|
|
|
// set PHP error handling |
1085
|
|
|
error_reporting(1); |
1086
|
|
|
set_error_handler("ftp_ErrorHandler"); |
1087
|
|
|
error_reporting(1); |
1088
|
|
|
set_time_limit(0); |
1089
|
|
|
|
1090
|
|
|
$FTP = new object; |
1091
|
|
|
$inst_store = $store_config["dbms"]."store"; |
1092
|
|
|
$store=new $inst_store("", $store_config); |
1093
|
|
|
|
1094
|
|
|
// fill in your own server ip number: |
1095
|
|
|
$FTP->server_ip = $ftp_config["server_ip"]; |
|
|
|
|
1096
|
|
|
$FTP->host = $ftp_config["site"]; |
|
|
|
|
1097
|
|
|
$FTP->store = &$store; |
|
|
|
|
1098
|
|
|
// default listMode ( files, objects or templates ) |
1099
|
|
|
$listMode = $ftp_config["defaultListMode"]; |
1100
|
|
|
if (!$listMode) { |
1101
|
|
|
$listMode = "files"; |
1102
|
|
|
} |
1103
|
|
|
$FTP->defaultListMode = $listMode; |
|
|
|
|
1104
|
|
|
$FTP->symlinkListModes = $ftp_config["symlinkListModes"]; |
|
|
|
|
1105
|
|
|
|
1106
|
|
|
// default type is ASCII |
1107
|
|
|
$FTP->DC["type"] = "A"; |
|
|
|
|
1108
|
|
|
|
1109
|
|
|
ob_start("debug"); |
1110
|
|
|
$FTP->stdin=fopen("php://stdin", "r"); |
|
|
|
|
1111
|
|
|
if ($FTP->stdin) { |
1112
|
|
|
$FTP->stdout=fopen("php://stdout", "w"); |
|
|
|
|
1113
|
|
|
if ($FTP->stdout) { |
1114
|
|
|
|
1115
|
|
|
$FTP->site=substr($ftp_config["root"],0, -1); |
|
|
|
|
1116
|
|
|
$FTP->cwd="/"; |
|
|
|
|
1117
|
|
|
ftp_Tell(220, $ftp_config["greeting"]); |
1118
|
|
|
|
1119
|
|
|
ftp_CheckLogin(); |
1120
|
|
|
ftp_Run(); |
1121
|
|
|
|
1122
|
|
|
} else { |
1123
|
|
|
fclose($FTP->stdin); |
1124
|
|
|
$FTP->error="Could not open stdout"; |
|
|
|
|
1125
|
|
|
} |
1126
|
|
|
} else { |
1127
|
|
|
$FTP->error="Could not open stdin"; |
1128
|
|
|
} |
1129
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.