1<?php
2/** FTP class is designed to work with FTP Connections
3@author Edwin van Wijk, www.v-wijk.net
4@email info@vwijk.net
5*/
6
7class ftp {
8	/** FTP server */
9	var $server="";
10	/** FTP server port */
11	var $port=21;
12	/** FTP user */
13	var $user="";
14	/** User specific directory (for zip and download) */
15	var $userDir="";
16	/** password */
17	var $password = "";
18	/** FTP connection */
19	var $connection = "";
20	/** Passive FTP connection */
21	var $passive = false;
22	/** Type of FTP server (UNIX, Windows, ...) */
23	var $systype = "";
24	/** Binary (1) or ASCII (0) mode */
25	var $mode = 0;
26	/** Logon indicator */
27	var $loggedOn = false;
28	/** resume broken downloads */
29	var $resumeDownload = false;
30	/** temporary download directory on local server */
31	var $downloadDir = "";
32
33	/**	constructor
34	@param none
35	Set FTP settings and logon to the server
36	*/
37	function ftp($server, $port, $user, $password, $passive=false){
38		$this->server = $server;
39		$this->port = $port;
40		$this->user = $user;
41		$this->userDir = $user . "_tmp";
42		$this->password = $password;
43
44		// connect to server
45		$this->connect();
46
47		// switch to passivemode(?)
48		$this->setPassive($passive);
49	}
50
51	/** connect to a ftp server */
52	function connect() {
53		$this->connection = @ftp_connect($this->server, $this->port);
54		$this->loggedOn = @ftp_login($this->connection, $this->user, $this->password);
55		$this->systype = @ftp_systype($this->connection);
56		return;
57	}
58
59	/** set passive connection */
60	function setPassive($passive) {
61		$this->passive=$passive;
62		@ftp_pasv($this->connection, $this->passive);
63		return;
64	}
65
66	/** Set transfermode */
67	function setMode($mode=1) {
68		$this->mode = $mode;
69		return;
70	}
71
72	/** set and goto current directory on ftp server */
73	function setCurrentDir($dir=false) {
74		if ($dir==true)
75		{
76			ftp_chdir($this->connection, $dir);
77		}
78		$this->currentDir = ftp_pwd($this->connection);
79		return $this->currentDir;
80	}
81
82	function getCurrentDirectoryShort() {
83		$string = $this->currentDir;
84		$stringArray = split("/",$string);
85		$level = count($stringArray);
86		$returnString = $stringArray[$level-1];
87		if(trim($returnString)=="") {
88			$returnString = "/";
89		}
90		return $returnString;
91	}
92
93	function setDownloadDir($dir) {
94		$this->downloadDir = $dir;
95		return;
96	}
97
98	function setResumeDownload($resume) {
99		$this->resumeDownload = $resume;
100		return;
101	}
102
103	function chmod($permissions, $file) {
104		return @ftp_site($this->connection, "chmod $permissions $file");
105	}
106
107	function cd($directory) {
108		if ($directory=="..") {
109			@ftp_cdup($this->connection);
110		} else {
111			if(!@ftp_chdir($this->connection, $this->currentDir . $directory)) {
112				@ftp_chdir($this->connection, $directory); // Symbolic link directory
113			}
114		}
115		$this->currentDir=ftp_pwd($this->connection);;
116		return;
117	}
118
119	/* get file from ftp server */
120	function get($file,$destination) {
121		if($destination == ""){
122			$destination = $this->downloadDir;
123		}
124		$ok=true;
125		if($this->resumeDownload) {
126			$fp = fopen($destination . $file, "a+");
127			$ok = ftp_fget($this->connection,$fp,"$file",$this->mode, filesize($destination . $file));
128		} else {
129			$fp = fopen($destination . $file, "w");
130			$ok = ftp_fget($this->connection,$fp,"$file",$this->mode);
131		}
132		fclose($fp);
133		return $ok;
134	}
135
136	/* put file to ftp server */
137	function put($remoteFile,$localFile) {
138		$ok=false;
139		if(file_exists($localFile)) {
140			ftp_put($this->connection, $remoteFile, $localFile, $this->mode);
141			$ok=true;
142		}
143		return $ok;
144	}
145
146	/* Download file from server and send it to the browser */
147	function download($file) {
148		if($this->get($file)) {
149			//Send header to browser to receive a file
150			header("Content-disposition: attachment; filename=\"$file\"");
151			header("Content-type: application/octetstream");
152			header("Pragma: ");
153			header("Cache-Control: cache");
154			header("Expires: 0");
155			$data = readfile($this->downloadDir . $file);
156			$i=0;
157			while ($data[$i] != "")
158			{
159				$fileStream .= $data[$i];
160				$i++;
161			}
162			unlink($this->downloadDir . $file);
163			echo $fileStream;
164			exit;
165		} else {
166			return false;
167		}
168	}
169
170	function upload($uploadFile) {
171		$tempFileName = $uploadFile['tmp_name'];
172		$fileName = $uploadFile['name'];
173		return $this->put($this->currentDir . "/" . filePart(StripSlashes($fileName)), $tempFileName);
174	}
175
176	function deleteFile($file) {
177		return @ftp_delete($this->connection, "$file");
178	}
179
180
181	function deleteRecursive($baseDirectory,$file){
182		if ($fileList = @ftp_nlist($this->connection, "$baseDirectory/$file")){
183			for ($x=0;$x<count($fileList);$x++){
184				if ($fileList[$x] != '.' && $fileList[$x] != '..' && !@ftp_delete($this->connection, $fileList[$x]))
185					deleteRecursive($baseDirectory."/$file",$fileList[$x]);
186			}
187			@ftp_rmdir($this->connection, "$baseDirectory/$file");
188		 } else {
189			@ftp_rmdir($this->connection, "$baseDirectory/$file");
190		 }
191	}
192
193	function rename($old, $new) {
194		return @ftp_rename($this->connection, "$old", "$new");
195	}
196
197	function makeDir($directory) {
198		return @ftp_mkdir($this->connection, "$directory");
199	}
200
201	function getRecursive($baseDir,$file){
202		$files = $this->ftpRawList($baseDir . "/$file");
203
204		for ($x=0;$x<count($files);$x++){
205			if ($files[$x]["name"] != '.' or $files[$x]["name"] != '..') {
206				$downloadLocation = $this->downloadDir  . ereg_replace($this->currentDir."/",$this->userDir."/",$baseDir . "/$file/");
207				$downloadLocation = ereg_replace("//","/",$downloadLocation);
208				$ftpFileDir = ereg_replace($this->currentDir . "/","",$baseDir . "/$file/");
209				//print $downloadLocation . "(" . $baseDir . "/$file/" . ")<br>";
210				mkdir($downloadLocation);
211
212				if ($files[$x]["is_dir"]==1)
213				{
214					$this->getRecursive($baseDir . "/$file/",$files[$x]["name"]);
215				} else {
216					$localFile = $this->downloadDir . $this->userDir . "/" . ereg_replace($this->currentDir . "/","",$baseDir . "/$file/") . $files[$x]["name"];;
217					$remoteFile = $baseDir . "/" . $file . "/" . $files[$x]["name"];
218
219					if($this->resumeDownload) {
220						$fp = fopen($localFile, "a+");
221						$ok = ftp_fget($this->connection,$fp,"$remoteFile",$this->mode, filesize($localFile));
222					} else {
223						$fp = fopen($localFile, "w");
224						$ok = ftp_fget($this->connection,$fp,"$remoteFile",$this->mode);
225					}
226					fclose($fp);
227				}
228			}
229		}
230	}
231
232
233	function ftpRawList($directory) {
234		if($directory=="") {
235			$directory = $this->currentDir;
236		}
237		$list=Array();
238		$list = ftp_rawlist($this->connection, "-a " . $directory);
239		if ($this->systype == "UNIX")
240		{
241			//$regexp = "([-ldrwxs]{10})[ ]+([0-9]+)[ ]+([A-Z|0-9|-]+)[ ]+([A-Z|0-9|-]+)[ ]+([0-9]+)[ ]+([A-Z]{3}[ ]+[0-9]{1,2}[ ]+[0-9|:]{4,5})[ ]+(.*)";
242			//$regexp = "([-ldrwxs]{10})[ ]+([0-9]+)[ ]+([A-Z|0-9|-|_]+)[ ]+([A-Z|0-9|-|_]+)[ ]+([0-9]+)[ ]+([A-Z]{3}[ ]+[0-9]{1,2}[ ]+[0-9|:]{4,5})[ ]+(.*)";
243			$regexp = "([-ltdrwxs]{10})[ ]+([0-9]+)[ ]+([A-Z|0-9|-|_]+)[ ]+([A-Z|0-9|-|_]+)[ ]+([0-9]+)[ ]+([A-Z]{3}[ ]+[0-9]{1,2}[ ]+[0-9|:]{4,5})[ ]+(.*)";
244			$i=0;
245			foreach ($list as $line)
246			{
247				$is_dir = $is_link = FALSE;
248				$target = "";
249
250				if (eregi($regexp, $line, $regs))
251				{
252					if (!eregi("^[.]", $regs[7])) //hide hidden files
253					if (!eregi("^[.]{2}", $regs[7])) // don't hide hidden files
254					{
255						$i++;
256						if (eregi("^[d]", $regs[1]))
257						{
258							$is_dir = TRUE;
259						}
260						elseif (eregi("^[l]", $regs[1]))
261						{
262							$is_link = TRUE;
263							list($regs[7], $target) = split(" -> ", $regs[7]);
264						}
265
266						//Get extension from file name
267						$regs_ex = explode(".",$regs[7]);
268						if ((!$is_dir)&&(count($regs_ex) > 1))
269						   $extension = $regs_ex[count($regs_ex)-1];
270						else $extension = "";
271
272						$files[$i] = array (
273						"is_dir"	=> $is_dir,
274						"extension"	=> $extension,
275						"name"		=> $regs[7],
276						"perms"		=> $regs[1],
277						"num"		=> $regs[2],
278						"user"		=> $regs[3],
279						"group"		=> $regs[4],
280						"size"		=> $regs[5],
281						"date"		=> $regs[6],
282						"is_link"	=> $is_link,
283						"target"	=> $target );
284					}
285				}
286			}
287		}
288		else
289		{
290			$regexp = "([0-9\-]{8})[ ]+([0-9:]{5}[APM]{2})[ ]+([0-9|<DIR>]+)[ ]+(.*)";
291			foreach ($list as $line)
292			{
293				$is_dir = false;
294				if (eregi($regexp, $line, $regs))
295				{
296					if (!eregi("^[.]", $regs[4]))
297					{
298						if($regs[3] == "<DIR>")
299						{
300							$is_dir = true;
301							$regs[3] = '';
302						}
303						$i++;
304
305						// Get extension from filename
306						$regs_ex = explode(".",$regs[4]);
307						if ((!$is_dir)&&(count($regs_ex) > 1))
308						   $extension = $regs_ex[count($regs_ex)-1];
309						else $extension = "";
310
311						$files[$i] = array (
312							"is_dir"	=> $is_dir,
313							"extension"	=> $extension,
314							"name"		=> $regs[4],
315							"date"		=> $regs[1],
316							"time"		=> $regs[2],
317							"size"		=> $regs[3],
318							"is_link"	=> 0,
319							"target"	=> "",
320							"num"		=> "" );
321					}
322				}
323			}
324		}
325		if ( is_array($files)  AND count($files) > 0)
326		{
327			$files=array_sort_multi($files, 1, 3);
328		}
329		return $files;
330	}
331
332}
333?>