root/trunk/gui/include/class.vfs.php

Revision 1408, 9.8 kB (checked in by scitech, 4 days ago)

Add default user with password to statistics

  • Property svn:eol-style set to native
Line 
1 <?php
2 /**
3  * ispCP ω (OMEGA) a Virtual Hosting Control System
4  *
5  * @copyright     2006-2008 by ispCP | http://isp-control.net
6  * @version     SVN: $Id$
7  * @link         http://isp-control.net
8  * @author         ispCP Team
9  *
10  * @license
11  *   This program is free software; you can redistribute it and/or modify it under
12  *   the terms of the MPL General Public License as published by the Free Software
13  *   Foundation; either version 1.1 of the License, or (at your option) any later
14  *   version.
15  *   You should have received a copy of the MPL Mozilla Public License along with
16  *   this program; if not, write to the Open Source Initiative (OSI)
17  *   http://opensource.org | osi@opensource.org
18  */
19
20 /*
21  * This should be class constants, but we're php4 compatible
22  */
23
24 /*
25  * File types definition
26  */
27 define('VFS_TYPE_DIR', 'd');
28 define('VFS_TYPE_LINK', 'l');
29 define('VFS_TYPE_FILE', '-');
30
31 /*
32  * Possible VFS Transfer modes
33  */
34 define('VFS_ASCII', FTP_ASCII);
35 define('VFS_BINARY', FTP_BINARY);
36
37 /**
38  * Virtual File System main class
39  *
40  * This class allows the ispCP Control panel to browse and
41  * edit all of the user files
42  */
43 class vfs {
44     /**
45      * Domain name of this filesystem
46      *
47      * @var string
48      */
49     var $_domain = '';
50
51     /**
52      * FTP connection handle
53      *
54      * @var resource
55      */
56     var $_handle = null;
57
58     /**
59      * Database connection handle
60      *
61      * @var resource
62      */
63     var $_db = null;
64
65     /**
66      * FTP temporary user name
67      *
68      * @var string
69      */
70     var $_user = '';
71
72     /**
73      * FTP password
74      *
75      * @var string
76      */
77     var $_passwd = '';
78
79     /**
80      * Create a new Virtual File System
81      *
82      * Creates a new Virtual File System object for the
83      * specified domain.
84      *
85      * Warning! $domain parameter is not sanitized, so this is
86      * left as work for the caller.
87      *
88      * @param string $domain Domain name of the new VFS.
89      * @param resource $db Adodb database resource.
90      * @return vfs
91      */
92     function vfs($domain, &$db) {
93         // Sort of php4 destructor
94         register_shutdown_function(array(&$this, "__destruct"));
95         return $this->__construct($domain, $db);
96     }
97
98     /**
99      * PHP5 constructor
100      *
101      * @param string $domain Domain name of the new VFS.
102      * @param resource $db Adodb database resource.
103      * @return vfs
104      */
105     function __construct($domain, &$db) {
106         $this->_domain = $domain;
107         $this->_db = &$db;
108
109         if (!defined("VFS_TMP_DIR")) {
110             define("VFS_TMP_DIR", Config::get('GUI_ROOT_DIR') . '/phptmp');
111         }
112         $_ENV['PHP_TMPDIR'] = VFS_TMP_DIR;
113         $_ENV['TMPDIR'] = VFS_TMP_DIR;
114         putenv("PHP_TMPDIR=" . $_ENV['PHP_TMPDIR']);
115         putenv("TMPDIR=" . $_ENV['PHP_TMPDIR']);
116     }
117
118     /**
119      * Destructor, ensure that we logout and remove the
120      * temporary user
121      */
122     function __destruct() {
123         $this->close();
124     }
125
126     /**
127      * Set ispCP DB handler
128      *
129      * The system uses a "global" $sql variable to store the DB
130      * handler, but we're a "black box" ;).
131      *
132      * @param resource $db Adodb database resource.
133      */
134     function setDb(&$db) {
135         $this->_db = &$db;
136     }
137
138     /**
139      * Create a temporary FTP user
140      *
141      * @return boolean Returns TRUE on succes or FALSE on failure.
142      */
143     function _createTmpUser() {
144         // Get domain data
145         $query = 'select domain_uid, domain_gid
146                   from   domain
147                   where  domain_name = ?';
148         $rs = exec_query($this->_db, $query, array($this->_domain));
149         if (!$rs) {
150             return false;
151         }
152         // Generate a random userid and password
153         $user = uniqid('tmp_') . '@' . $this->_domain;
154         $this->_passwd = uniqid('tmp_', true);
155         $passwd = crypt_user_pass_with_salt($this->_passwd);
156         // Create the temporary user
157         $query = <<<SQL_QUERY
158             insert into ftp_users
159                 (userid, passwd, uid, gid, shell, homedir)
160             values
161                 (?, ?, ?, ?, ?, ?)
162 SQL_QUERY;
163         $rs = exec_query($this->_db, $query, array($user, $passwd, $rs->fields['domain_uid'], $rs->fields['domain_gid'],
164                 Config::get('CMD_SHELL'), Config::get('FTP_HOMEDIR') . '/' . $this->_domain
165                 ));
166         if (!$rs) {
167             return false;
168         }
169         // All ok
170         $this->_user = $user;
171         return true;
172     }
173
174     /**
175      * Removes the temporary FTP user
176      *
177      * @return Returns TRUE on succes or FALSE on failure.
178      */
179     function _removeTmpUser() {
180         $query = <<<SQL_QUERY
181             delete from ftp_users
182             where  userid = ?
183 SQL_QUERY;
184         $rs = exec_query($this->_db, $query, array($this->_user));
185
186         return $rs ? true : false;
187     }
188
189     /**
190      * Open the virtual file system
191      *
192      * @return boolean Returns TRUE on succes or FALSE on failure.
193      */
194     function open() {
195         // Check if we're already open
196         if (is_resource($this->_handle)) {
197             return true;
198         }
199         // Check if we have a valid ispcp database
200         if (!$this->_db) {
201             return false;
202         }
203         // Create the temporary ftp account
204         $result = $this->_createTmpUser();
205         if (!$result) {
206             return false;
207         }
208         // 'localhost' for testing purposes. I have to study if a better
209         // $this->_domain would work on all situations
210         $this->_handle = @ftp_connect('localhost');
211         if (!is_resource($this->_handle)) {
212             $this->close();
213             return false;
214         }
215         // Perform actual login
216         $response = @ftp_login($this->_handle, $this->_user, $this->_passwd);
217         if (!$response) {
218             $this->close();
219             return false;
220         }
221         // All went ok! :)
222         return true;
223     }
224
225     /**
226      * Closes the virtual file system
227      */
228     function close() {
229         // Close FTP connection
230         if ($this->_handle) {
231             ftp_close($this->_handle);
232             $this->_handle = null;
233         }
234         // Remove temporary user
235         if ($this->_user) {
236             $this->_removeTmpUser();
237         }
238     }
239
240     /**
241      * Get directory listing
242      *
243      * Get the directory listing of a specified dir,
244      * either in short (default) or long mode.
245      *
246      * @param string $dirname VFS directory path.
247      * @return array Returns an array of directory entries or FALSE on error.
248      */
249     function ls($dirname) {
250         // Ensure that we're open
251         if (!$this->open()) {
252             return false;
253         }
254         // Path is always relative to the root vfs
255         if (substr($dirname, 0, 1) != '/') {
256             $dirname = '/' . $dirname;
257         }
258         // No security implications, the FTP server handles
259         // this for us
260         $list = ftp_rawlist($this->_handle, '-a ' . $dirname, false);
261         if (!$list) {
262             return false;
263         }
264         $len = count($list);
265         for($i = 0; $i < $len; $i++) {
266             $parts = preg_split("/[\s]+/", $list[$i], 9);
267             $list[$i] = array('perms' => $parts[0],
268                 'number' => $parts[1],
269                 'owner' => $parts[2],
270                 'group' => $parts[3],
271                 'size' => $parts[4],
272                 'month' => $parts[5],
273                 'day' => $parts[6],
274                 'time' => $parts[7],
275                 'file' => $parts[8],
276                 'type' => substr($parts[0], 0, 1),
277                 );
278         }
279
280         return $list;
281     }
282
283     /**
284      * Checks for file existance
285      *
286      * @param string $file VFS file path.
287      * @param int $type Type of the file to match. Must be either VFS_TYPE_DIR,
288      *                     VFS_TYPE_LINK or VFS_TYPE_FILE.
289      * @return boolean Returns TRUE if file exists or FALSE if it doesn't exist.
290      */
291     function exists($file, $type = null) {
292         // Ensure that we're open
293         if (false === $this->open()) {
294             return false;
295         }
296         // Actually get the listing
297         $dirname = dirname($file);
298         $list = $this->ls($dirname);
299         if (!$list)
300             return false;
301         // We get filenames only from the listing
302         $file = basename($file);
303         // Try to match it
304         foreach($list as $entry) {
305             // Skip non-matching files
306             if ($entry['file'] != $file) {
307                 continue;
308             }
309             // Check type
310             if ($type !== null && $entry['type'] != $type)
311                 return false;
312             // Matched and same type (or no type specified)
313             return true;
314         }
315         return false;
316     }
317
318     /**
319      * Retrieves a file from the virtual file system
320      *
321      * @param string $file VFS file path.
322      * @param int $ VFS transfer mode. Must be either VFS_ASCII or VFS_BINARY.
323      * @return boolean Returns TRUE on succes or FALSE on failure.
324      */
325     function get($file, $mode = VFS_ASCII) {
326         // Ensure that we're open
327         if (!$this->open()) {
328             return false;
329         }
330         // Get a temporary file name
331         $tmp = tempnam(VFS_TMP_DIR, 'vfs_');
332         // Get the actual file
333         $res = ftp_get($this->_handle, $tmp, $file, $mode);
334         if (false === $res) {
335             return false;
336         }
337         // Retrieve file contents
338         $res = file_get_contents($tmp);
339         // Delete temporary file
340         unlink($tmp);
341
342         return $res;
343     }
344
345     /**
346      * Stores a file inside the virtual file system
347      *
348      * @param string $file VFS file path.
349      * @param string $content File contents.
350      * @param int $ VFS transfer mode. Must be either VFS_ASCII or VFS_BINARY.
351      * @return boolean Returns TRUE on success or FALSE on failure.
352      */
353     function put($file, $content, $mode = VFS_ASCII) {
354         // Ensure that we're open
355         if (!$this->open()) {
356             return false;
357         }
358         // Get a temporary file name
359         $tmp = tempnam(VFS_TMP_DIR, 'vfs_');
360         // Save temporary file
361         $res = file_put_contents($tmp, $content);
362         if (false === $res) {
363             return false;
364         }
365         // Upload it
366         $res = ftp_put($this->_handle, $file, $tmp, $mode);
367         if (!$res) {
368             return false;
369         }
370         // Remove temp file
371         unlink($tmp);
372
373         return true;
374     }
375 }
376
377 /**
378  * Make sure we have needed file_put_contents() functionality
379  */
380 if (!function_exists('file_put_contents')) {
381     function file_put_contents($filename, $content) {
382         // Make sure that we have a string to write
383         if (!is_scalar($content)) {
384             user_error('file_put_contents() The 2nd parameter should be a string',
385                 E_USER_WARNING);
386             return false;
387         }
388         // Get the data size
389         $length = strlen($content);
390         // Open the file for writing
391         if (($fh = @fopen($filename, 'wb')) === false) {
392             user_error('file_put_contents() failed to open stream: Permission denied',
393                 E_USER_WARNING);
394             return false;
395         }
396         // Write to the file
397         $bytes = 0;
398         if (($bytes = @fwrite($fh, $content)) === false) {
399             $errormsg = sprintf('file_put_contents() Failed to write %d bytes to %s',
400                 $length,
401                 $filename);
402             user_error($errormsg, E_USER_WARNING);
403             return false;
404         }
405         // Close the handle
406         @fclose($fh);
407         // Check all the data was written
408         if ($bytes != $length) {
409             $errormsg = sprintf('file_put_contents() Only %d of %d bytes written, possibly out of free disk space.',
410                 $bytes,
411                 $length);
412             user_error($errormsg, E_USER_WARNING);
413             return false;
414         }
415         // Return length
416         return $bytes;
417     }
418 }
419
420 ?>
Note: See TracBrowser for help on using the browser.