XCloner – Backup and Restore - Version 3.0.3

Version Description

  • added amazon ssl option box
  • moved the compress option to the System tab, don't use unless you know what you are doing!
Download this release

Release Info

Developer xcloner
Plugin Icon 128x128 XCloner – Backup and Restore
Version 3.0.3
Comparing to
See all releases

Code changes from version 3.0.2 to 3.0.3

cloner.cron.php CHANGED
@@ -313,7 +313,7 @@ if(!$_CONFIG['cron_amazon_ssl'])
313
  else
314
  $amazon_ssl = true;
315
 
316
- $s3 = new S3($_CONFIG['cron_amazon_awsAccessKey'], $_CONFIG['cron_amazon_awsSecretKey'], $amazon_ssl);
317
 
318
  logxx("AMAZON S3: Starting communication with the Amazon S3 server...ssl mode ".$amazon_ssl);
319
 
313
  else
314
  $amazon_ssl = true;
315
 
316
+ $s3 = new S3($_CONFIG['cron_amazon_awsAccessKey'], $_CONFIG['cron_amazon_awsSecretKey'], (int)$amazon_ssl);
317
 
318
  logxx("AMAZON S3: Starting communication with the Amazon S3 server...ssl mode ".$amazon_ssl);
319
 
language/english.php CHANGED
@@ -415,7 +415,7 @@ define("LM_LOGIN_TEXT","
415
  1. If you are on this screen for the first time, your default
416
  username is '<i>admin</i>' and password '<i>admin</i>', you should change them after login
417
 
418
- 2. if you forget your password, to reset it you need to add
419
  this code:
420
 
421
  <b>$"."_CONFIG[\"jcpass\"] = md5(\"my_new_pass\");</b>
@@ -423,6 +423,8 @@ define("LM_LOGIN_TEXT","
423
  at the end of the config file cloner.config.php just
424
  before line ?>
425
  Don't forget to replace my_new_pass with the actual password
 
 
426
  </pre>
427
  ");
428
  ?>
415
  1. If you are on this screen for the first time, your default
416
  username is '<i>admin</i>' and password '<i>admin</i>', you should change them after login
417
 
418
+ 2. If you've forgot your password, to reset it you need to add
419
  this code:
420
 
421
  <b>$"."_CONFIG[\"jcpass\"] = md5(\"my_new_pass\");</b>
423
  at the end of the config file cloner.config.php just
424
  before line ?>
425
  Don't forget to replace my_new_pass with the actual password
426
+
427
+ 3. The username and password are Case-Sensitive
428
  </pre>
429
  ");
430
  ?>
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: http://www.xcloner.com/
4
  Tags: backup, restore, admin, plugin, database, full backup, cloner, xcloner, theme, files, upload, wordpress backup, backup plugin, database backup, database restore, site move, transfer, blog transfer, BuddyPress
5
  Requires at least: 2.0.2
6
  Tested up to: 3.1
7
- Stable tag: 3.0.1
8
 
9
  XCloner is a full backup and restore plugin for Wordpress, it will backup and restore both files and database. www.xcloner.com
10
 
@@ -68,6 +68,10 @@ If the inside Clone option fails for some reason, you need to:
68
 
69
  == Changelog ==
70
 
 
 
 
 
71
  = 3.0.1 =
72
  * several important security and bug fixes
73
 
@@ -93,5 +97,5 @@ If the inside Clone option fails for some reason, you need to:
93
 
94
  == Upgrade Notice ==
95
 
96
- = 3.0.1 =
97
- Important security and bug fixes, upgrade is Highly recommended!
4
  Tags: backup, restore, admin, plugin, database, full backup, cloner, xcloner, theme, files, upload, wordpress backup, backup plugin, database backup, database restore, site move, transfer, blog transfer, BuddyPress
5
  Requires at least: 2.0.2
6
  Tested up to: 3.1
7
+ Stable tag: 3.0.3
8
 
9
  XCloner is a full backup and restore plugin for Wordpress, it will backup and restore both files and database. www.xcloner.com
10
 
68
 
69
  == Changelog ==
70
 
71
+ = 3.0.3 =
72
+ * added amazon ssl option box
73
+ * moved the compress option to the System tab, don't use unless you know what you are doing!
74
+
75
  = 3.0.1 =
76
  * several important security and bug fixes
77
 
97
 
98
  == Upgrade Notice ==
99
 
100
+ = 3.0.3 =
101
+ Please check changelog!
restore/TAR.php ADDED
@@ -0,0 +1,2084 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set ts=4 sw=4: */
3
+ // +----------------------------------------------------------------------+
4
+ // | PHP Version 4 |
5
+ // +----------------------------------------------------------------------+
6
+ // | Copyright (c) 1997-2003 The PHP Group |
7
+ // +----------------------------------------------------------------------+
8
+ // | This source file is subject to version 3.0 of the PHP license, |
9
+ // | that is bundled with this package in the file LICENSE, and is |
10
+ // | available through the world-wide-web at the following url: |
11
+ // | http://www.php.net/license/3_0.txt. |
12
+ // | If you did not receive a copy of the PHP license and are unable to |
13
+ // | obtain it through the world-wide-web, please send a note to |
14
+ // | license@php.net so we can mail you a copy immediately. |
15
+ // +----------------------------------------------------------------------+
16
+ // | Author: Vincent Blavet <vincent@phpconcept.net> |
17
+ // +----------------------------------------------------------------------+
18
+ //
19
+ // $Id: Tar.php,v 1.39 2006/12/22 19:20:08 cellog Exp $
20
+
21
+ #require_once 'PEAR.php';
22
+
23
+
24
+ define ('ARCHIVE_TAR_ATT_SEPARATOR', 90001);
25
+ define ('ARCHIVE_TAR_END_BLOCK', pack("a512", ''));
26
+
27
+ /**
28
+ * Creates a (compressed) Tar archive
29
+ *
30
+ * @author Vincent Blavet <vincent@phpconcept.net>
31
+ * @version $Revision: 1.39 $
32
+ * @package Archive
33
+ */
34
+ class archive_tar
35
+ {
36
+ /**
37
+ * @var string Name of the Tar
38
+ */
39
+ var $_tarname='';
40
+
41
+ /**
42
+ * @var boolean if true, the Tar file will be gzipped
43
+ */
44
+ var $_compress=false;
45
+
46
+ /**
47
+ * @var string Type of compression : 'none', 'gz' or 'bz2'
48
+ */
49
+ var $_compress_type='none';
50
+
51
+ /**
52
+ * @var string Explode separator
53
+ */
54
+ var $_separator=' ';
55
+
56
+ /**
57
+ * @var file descriptor
58
+ */
59
+ var $_file=0;
60
+
61
+ /**
62
+ * @var string Local Tar name of a remote Tar (http:// or ftp://)
63
+ */
64
+ var $_temp_tarname='';
65
+
66
+ function raiseError($message){
67
+
68
+ print "<b>TAR error: </b><font color='red'>".$message."</font><br />";return;
69
+
70
+ }
71
+
72
+ // {{{ constructor
73
+ /**
74
+ * Archive_Tar Class constructor. This flavour of the constructor only
75
+ * declare a new Archive_Tar object, identifying it by the name of the
76
+ * tar file.
77
+ * If the compress argument is set the tar will be read or created as a
78
+ * gzip or bz2 compressed TAR file.
79
+ *
80
+ * @param string $p_tarname The name of the tar archive to create
81
+ * @param string $p_compress can be null, 'gz' or 'bz2'. This
82
+ * parameter indicates if gzip or bz2 compression
83
+ * is required. For compatibility reason the
84
+ * boolean value 'true' means 'gz'.
85
+ * @access public
86
+ */
87
+ function Archive_Tar($p_tarname, $p_compress = null)
88
+ {
89
+ #$this->PEAR();
90
+ $this->_compress = false;
91
+ $this->_compress_type = 'none';
92
+ if (($p_compress === null) || ($p_compress == '')) {
93
+ if (@file_exists($p_tarname)) {
94
+ if ($fp = @fopen($p_tarname, "rb")) {
95
+ // look for gzip magic cookie
96
+ $data = fread($fp, 2);
97
+ fclose($fp);
98
+ if ($data == "\37\213") {
99
+ $this->_compress = true;
100
+ $this->_compress_type = 'gz';
101
+ // No sure it's enought for a magic code ....
102
+ } elseif ($data == "BZ") {
103
+ $this->_compress = true;
104
+ $this->_compress_type = 'bz2';
105
+ }
106
+ }
107
+ } else {
108
+ // probably a remote file or some file accessible
109
+ // through a stream interface
110
+ if (substr($p_tarname, -2) == 'gz') {
111
+ $this->_compress = true;
112
+ $this->_compress_type = 'gz';
113
+ } elseif ((substr($p_tarname, -3) == 'bz2') ||
114
+ (substr($p_tarname, -2) == 'bz')) {
115
+ $this->_compress = true;
116
+ $this->_compress_type = 'bz2';
117
+ }
118
+ }
119
+ } else {
120
+ if (($p_compress === true) || ($p_compress == 'gz')) {
121
+ $this->_compress = true;
122
+ $this->_compress_type = 'gz';
123
+ } else if ($p_compress == 'bz2') {
124
+ $this->_compress = true;
125
+ $this->_compress_type = 'bz2';
126
+ } else {
127
+ die("Unsupported compression type '$p_compress'\n".
128
+ "Supported types are 'gz' and 'bz2'.\n");
129
+ return false;
130
+ }
131
+ }
132
+ $this->_tarname = $p_tarname;
133
+ if ($this->_compress) { // assert zlib or bz2 extension support
134
+ if ($this->_compress_type == 'gz')
135
+ $extname = 'zlib';
136
+ else if ($this->_compress_type == 'bz2')
137
+ $extname = 'bz2';
138
+
139
+ #if (!extension_loaded($extname)) {
140
+ #PEAR::loadExtension($extname);
141
+ #}
142
+ if (!extension_loaded($extname)) {
143
+ die("The extension '$extname' couldn't be found.\n".
144
+ "Please make sure your version of PHP was built ".
145
+ "with '$extname' support.\n");
146
+ return false;
147
+ }
148
+ }
149
+ }
150
+ // }}}
151
+
152
+ // {{{ destructor
153
+ function _Archive_Tar()
154
+ {
155
+ $this->_close();
156
+ // ----- Look for a local copy to delete
157
+ if ($this->_temp_tarname != '')
158
+ @unlink($this->_temp_tarname);
159
+ #$this->_PEAR();
160
+ }
161
+ // }}}
162
+
163
+ // {{{ create()
164
+ /**
165
+ * This method creates the archive file and add the files / directories
166
+ * that are listed in $p_filelist.
167
+ * If a file with the same name exist and is writable, it is replaced
168
+ * by the new tar.
169
+ * The method return false and a PEAR error text.
170
+ * The $p_filelist parameter can be an array of string, each string
171
+ * representing a filename or a directory name with their path if
172
+ * needed. It can also be a single string with names separated by a
173
+ * single blank.
174
+ * For each directory added in the archive, the files and
175
+ * sub-directories are also added.
176
+ * See also createModify() method for more details.
177
+ *
178
+ * @param array $p_filelist An array of filenames and directory names, or a
179
+ * single string with names separated by a single
180
+ * blank space.
181
+ * @return true on success, false on error.
182
+ * @see createModify()
183
+ * @access public
184
+ */
185
+ function create($p_filelist)
186
+ {
187
+ return $this->createModify($p_filelist, '', '');
188
+ }
189
+ // }}}
190
+
191
+ // {{{ add()
192
+ /**
193
+ * This method add the files / directories that are listed in $p_filelist in
194
+ * the archive. If the archive does not exist it is created.
195
+ * The method return false and a PEAR error text.
196
+ * The files and directories listed are only added at the end of the archive,
197
+ * even if a file with the same name is already archived.
198
+ * See also createModify() method for more details.
199
+ *
200
+ * @param array $p_filelist An array of filenames and directory names, or a
201
+ * single string with names separated by a single
202
+ * blank space.
203
+ * @return true on success, false on error.
204
+ * @see createModify()
205
+ * @access public
206
+ */
207
+ function add($p_filelist)
208
+ {
209
+ return $this->addModify($p_filelist, '', '');
210
+ }
211
+ // }}}
212
+
213
+ // {{{ extract()
214
+ function extract($p_path='')
215
+ {
216
+ return $this->extractModify($p_path, '');
217
+ }
218
+ // }}}
219
+
220
+ // {{{ listContent()
221
+ function listContent()
222
+ {
223
+ $v_list_detail = array();
224
+
225
+ if ($this->_openRead()) {
226
+ if (!$this->_extractList('', $v_list_detail, "list", '', '')) {
227
+ unset($v_list_detail);
228
+ $v_list_detail = 0;
229
+ }
230
+ $this->_close();
231
+ }
232
+
233
+ return $v_list_detail;
234
+ }
235
+ // }}}
236
+
237
+ // {{{ createModify()
238
+ /**
239
+ * This method creates the archive file and add the files / directories
240
+ * that are listed in $p_filelist.
241
+ * If the file already exists and is writable, it is replaced by the
242
+ * new tar. It is a create and not an add. If the file exists and is
243
+ * read-only or is a directory it is not replaced. The method return
244
+ * false and a PEAR error text.
245
+ * The $p_filelist parameter can be an array of string, each string
246
+ * representing a filename or a directory name with their path if
247
+ * needed. It can also be a single string with names separated by a
248
+ * single blank.
249
+ * The path indicated in $p_remove_dir will be removed from the
250
+ * memorized path of each file / directory listed when this path
251
+ * exists. By default nothing is removed (empty path '')
252
+ * The path indicated in $p_add_dir will be added at the beginning of
253
+ * the memorized path of each file / directory listed. However it can
254
+ * be set to empty ''. The adding of a path is done after the removing
255
+ * of path.
256
+ * The path add/remove ability enables the user to prepare an archive
257
+ * for extraction in a different path than the origin files are.
258
+ * See also addModify() method for file adding properties.
259
+ *
260
+ * @param array $p_filelist An array of filenames and directory names,
261
+ * or a single string with names separated by
262
+ * a single blank space.
263
+ * @param string $p_add_dir A string which contains a path to be added
264
+ * to the memorized path of each element in
265
+ * the list.
266
+ * @param string $p_remove_dir A string which contains a path to be
267
+ * removed from the memorized path of each
268
+ * element in the list, when relevant.
269
+ * @return boolean true on success, false on error.
270
+ * @access public
271
+ * @see addModify()
272
+ */
273
+ function createModify($p_filelist, $p_add_dir, $p_remove_dir='')
274
+ {
275
+ $v_result = true;
276
+
277
+ if (!$this->_openWrite())
278
+ return false;
279
+
280
+ if ($p_filelist != '') {
281
+ if (is_array($p_filelist))
282
+ $v_list = $p_filelist;
283
+ elseif (is_string($p_filelist))
284
+ $v_list = explode($this->_separator, $p_filelist);
285
+ else {
286
+ $this->_cleanFile();
287
+ $this->_error('Invalid file list');
288
+ return false;
289
+ }
290
+
291
+ $v_result = $this->_addList($v_list, $p_add_dir, $p_remove_dir);
292
+ }
293
+
294
+ if ($v_result) {
295
+ $this->_writeFooter();
296
+ $this->_close();
297
+ } else
298
+ $this->_cleanFile();
299
+
300
+ return $v_result;
301
+ }
302
+ // }}}
303
+
304
+ // {{{ addModify()
305
+ /**
306
+ * This method add the files / directories listed in $p_filelist at the
307
+ * end of the existing archive. If the archive does not yet exists it
308
+ * is created.
309
+ * The $p_filelist parameter can be an array of string, each string
310
+ * representing a filename or a directory name with their path if
311
+ * needed. It can also be a single string with names separated by a
312
+ * single blank.
313
+ * The path indicated in $p_remove_dir will be removed from the
314
+ * memorized path of each file / directory listed when this path
315
+ * exists. By default nothing is removed (empty path '')
316
+ * The path indicated in $p_add_dir will be added at the beginning of
317
+ * the memorized path of each file / directory listed. However it can
318
+ * be set to empty ''. The adding of a path is done after the removing
319
+ * of path.
320
+ * The path add/remove ability enables the user to prepare an archive
321
+ * for extraction in a different path than the origin files are.
322
+ * If a file/dir is already in the archive it will only be added at the
323
+ * end of the archive. There is no update of the existing archived
324
+ * file/dir. However while extracting the archive, the last file will
325
+ * replace the first one. This results in a none optimization of the
326
+ * archive size.
327
+ * If a file/dir does not exist the file/dir is ignored. However an
328
+ * error text is send to PEAR error.
329
+ * If a file/dir is not readable the file/dir is ignored. However an
330
+ * error text is send to PEAR error.
331
+ *
332
+ * @param array $p_filelist An array of filenames and directory
333
+ * names, or a single string with names
334
+ * separated by a single blank space.
335
+ * @param string $p_add_dir A string which contains a path to be
336
+ * added to the memorized path of each
337
+ * element in the list.
338
+ * @param string $p_remove_dir A string which contains a path to be
339
+ * removed from the memorized path of
340
+ * each element in the list, when
341
+ * relevant.
342
+ * @return true on success, false on error.
343
+ * @access public
344
+ */
345
+ function addModify($p_filelist, $p_add_dir, $p_remove_dir='')
346
+ {
347
+ $v_result = true;
348
+
349
+ if (!$this->_isArchive())
350
+ $v_result = $this->createModify($p_filelist, $p_add_dir,
351
+ $p_remove_dir);
352
+ else {
353
+ if (is_array($p_filelist))
354
+ $v_list = $p_filelist;
355
+ elseif (is_string($p_filelist))
356
+ $v_list = explode($this->_separator, $p_filelist);
357
+ else {
358
+ $this->_error('Invalid file list');
359
+ return false;
360
+ }
361
+
362
+ $v_result = $this->_append($v_list, $p_add_dir, $p_remove_dir);
363
+ }
364
+
365
+ return $v_result;
366
+ }
367
+ // }}}
368
+
369
+ // {{{ addString()
370
+ /**
371
+ * This method add a single string as a file at the
372
+ * end of the existing archive. If the archive does not yet exists it
373
+ * is created.
374
+ *
375
+ * @param string $p_filename A string which contains the full
376
+ * filename path that will be associated
377
+ * with the string.
378
+ * @param string $p_string The content of the file added in
379
+ * the archive.
380
+ * @return true on success, false on error.
381
+ * @access public
382
+ */
383
+ function addString($p_filename, $p_string)
384
+ {
385
+ $v_result = true;
386
+
387
+ if (!$this->_isArchive()) {
388
+ if (!$this->_openWrite()) {
389
+ return false;
390
+ }
391
+ $this->_close();
392
+ }
393
+
394
+ if (!$this->_openAppend())
395
+ return false;
396
+
397
+ // Need to check the get back to the temporary file ? ....
398
+ $v_result = $this->_addString($p_filename, $p_string);
399
+
400
+ $this->_writeFooter();
401
+
402
+ $this->_close();
403
+
404
+ return $v_result;
405
+ }
406
+ // }}}
407
+
408
+ // {{{ extractModify()
409
+ /**
410
+ * This method extract all the content of the archive in the directory
411
+ * indicated by $p_path. When relevant the memorized path of the
412
+ * files/dir can be modified by removing the $p_remove_path path at the
413
+ * beginning of the file/dir path.
414
+ * While extracting a file, if the directory path does not exists it is
415
+ * created.
416
+ * While extracting a file, if the file already exists it is replaced
417
+ * without looking for last modification date.
418
+ * While extracting a file, if the file already exists and is write
419
+ * protected, the extraction is aborted.
420
+ * While extracting a file, if a directory with the same name already
421
+ * exists, the extraction is aborted.
422
+ * While extracting a directory, if a file with the same name already
423
+ * exists, the extraction is aborted.
424
+ * While extracting a file/directory if the destination directory exist
425
+ * and is write protected, or does not exist but can not be created,
426
+ * the extraction is aborted.
427
+ * If after extraction an extracted file does not show the correct
428
+ * stored file size, the extraction is aborted.
429
+ * When the extraction is aborted, a PEAR error text is set and false
430
+ * is returned. However the result can be a partial extraction that may
431
+ * need to be manually cleaned.
432
+ *
433
+ * @param string $p_path The path of the directory where the
434
+ * files/dir need to by extracted.
435
+ * @param string $p_remove_path Part of the memorized path that can be
436
+ * removed if present at the beginning of
437
+ * the file/dir path.
438
+ * @return boolean true on success, false on error.
439
+ * @access public
440
+ * @see extractList()
441
+ */
442
+ function extractModify($p_path, $p_remove_path)
443
+ {
444
+ $v_result = true;
445
+ $v_list_detail = array();
446
+
447
+ if ($v_result = $this->_openRead()) {
448
+ $v_result = $this->_extractList($p_path, $v_list_detail,
449
+ "complete", 0, $p_remove_path);
450
+ $this->_close();
451
+ }
452
+
453
+ return $v_result;
454
+ }
455
+ // }}}
456
+
457
+ // {{{ extractInString()
458
+ /**
459
+ * This method extract from the archive one file identified by $p_filename.
460
+ * The return value is a string with the file content, or NULL on error.
461
+ * @param string $p_filename The path of the file to extract in a string.
462
+ * @return a string with the file content or NULL.
463
+ * @access public
464
+ */
465
+ function extractInString($p_filename)
466
+ {
467
+ if ($this->_openRead()) {
468
+ $v_result = $this->_extractInString($p_filename);
469
+ $this->_close();
470
+ } else {
471
+ $v_result = NULL;
472
+ }
473
+
474
+ return $v_result;
475
+ }
476
+ // }}}
477
+
478
+ // {{{ extractList()
479
+ /**
480
+ * This method extract from the archive only the files indicated in the
481
+ * $p_filelist. These files are extracted in the current directory or
482
+ * in the directory indicated by the optional $p_path parameter.
483
+ * If indicated the $p_remove_path can be used in the same way as it is
484
+ * used in extractModify() method.
485
+ * @param array $p_filelist An array of filenames and directory names,
486
+ * or a single string with names separated
487
+ * by a single blank space.
488
+ * @param string $p_path The path of the directory where the
489
+ * files/dir need to by extracted.
490
+ * @param string $p_remove_path Part of the memorized path that can be
491
+ * removed if present at the beginning of
492
+ * the file/dir path.
493
+ * @return true on success, false on error.
494
+ * @access public
495
+ * @see extractModify()
496
+ */
497
+ function extractList($p_filelist, $p_path='', $p_remove_path='')
498
+ {
499
+ $v_result = true;
500
+ $v_list_detail = array();
501
+
502
+ if (is_array($p_filelist))
503
+ $v_list = $p_filelist;
504
+ elseif (is_string($p_filelist))
505
+ $v_list = explode($this->_separator, $p_filelist);
506
+ else {
507
+ $this->_error('Invalid string list');
508
+ return false;
509
+ }
510
+
511
+ if ($v_result = $this->_openRead()) {
512
+ $v_result = $this->_extractList($p_path, $v_list_detail, "partial",
513
+ $v_list, $p_remove_path);
514
+ $this->_close();
515
+ }
516
+
517
+ return $v_result;
518
+ }
519
+ // }}}
520
+
521
+ // {{{ setAttribute()
522
+ /**
523
+ * This method set specific attributes of the archive. It uses a variable
524
+ * list of parameters, in the format attribute code + attribute values :
525
+ * $arch->setAttribute(ARCHIVE_TAR_ATT_SEPARATOR, ',');
526
+ * @param mixed $argv variable list of attributes and values
527
+ * @return true on success, false on error.
528
+ * @access public
529
+ */
530
+ function setAttribute()
531
+ {
532
+ $v_result = true;
533
+
534
+ // ----- Get the number of variable list of arguments
535
+ if (($v_size = func_num_args()) == 0) {
536
+ return true;
537
+ }
538
+
539
+ // ----- Get the arguments
540
+ $v_att_list = &func_get_args();
541
+
542
+ // ----- Read the attributes
543
+ $i=0;
544
+ while ($i<$v_size) {
545
+
546
+ // ----- Look for next option
547
+ switch ($v_att_list[$i]) {
548
+ // ----- Look for options that request a string value
549
+ case ARCHIVE_TAR_ATT_SEPARATOR :
550
+ // ----- Check the number of parameters
551
+ if (($i+1) >= $v_size) {
552
+ $this->_error('Invalid number of parameters for '
553
+ .'attribute ARCHIVE_TAR_ATT_SEPARATOR');
554
+ return false;
555
+ }
556
+
557
+ // ----- Get the value
558
+ $this->_separator = $v_att_list[$i+1];
559
+ $i++;
560
+ break;
561
+
562
+ default :
563
+ $this->_error('Unknow attribute code '.$v_att_list[$i].'');
564
+ return false;
565
+ }
566
+
567
+ // ----- Next attribute
568
+ $i++;
569
+ }
570
+
571
+ return $v_result;
572
+ }
573
+ // }}}
574
+
575
+ // {{{ _error()
576
+ function _error($p_message)
577
+ {
578
+ // ----- To be completed
579
+ $this->raiseError($p_message);
580
+ }
581
+ // }}}
582
+
583
+ // {{{ _warning()
584
+ function _warning($p_message)
585
+ {
586
+ // ----- To be completed
587
+ $this->raiseError($p_message);
588
+ }
589
+ // }}}
590
+
591
+ // {{{ _isArchive()
592
+ function _isArchive($p_filename=NULL)
593
+ {
594
+ if ($p_filename == NULL) {
595
+ $p_filename = $this->_tarname;
596
+ }
597
+ clearstatcache();
598
+ return @is_file($p_filename);
599
+ }
600
+ // }}}
601
+
602
+ // {{{ _openWrite()
603
+ function _openWrite()
604
+ {
605
+ if ($this->_compress_type == 'gz')
606
+ $this->_file = @gzopen($this->_tarname, "wb9");
607
+ else if ($this->_compress_type == 'bz2')
608
+ $this->_file = @bzopen($this->_tarname, "wb");
609
+ else if ($this->_compress_type == 'none')
610
+ $this->_file = @fopen($this->_tarname, "wb");
611
+ else
612
+ $this->_error('Unknown or missing compression type ('
613
+ .$this->_compress_type.')');
614
+
615
+ if ($this->_file == 0) {
616
+ $this->_error('Unable to open in write mode \''
617
+ .$this->_tarname.'\'');
618
+ return false;
619
+ }
620
+
621
+ return true;
622
+ }
623
+ // }}}
624
+
625
+ // {{{ _openRead()
626
+ function _openRead()
627
+ {
628
+ if (strtolower(substr($this->_tarname, 0, 7)) == 'http://') {
629
+
630
+ // ----- Look if a local copy need to be done
631
+ if ($this->_temp_tarname == '') {
632
+ $this->_temp_tarname = uniqid('tar').'.tmp';
633
+ if (!$v_file_from = @fopen($this->_tarname, 'rb')) {
634
+ $this->_error('Unable to open in read mode \''
635
+ .$this->_tarname.'\'');
636
+ $this->_temp_tarname = '';
637
+ return false;
638
+ }
639
+ if (!$v_file_to = @fopen($this->_temp_tarname, 'wb')) {
640
+ $this->_error('Unable to open in write mode \''
641
+ .$this->_temp_tarname.'\'');
642
+ $this->_temp_tarname = '';
643
+ return false;
644
+ }
645
+ while ($v_data = @fread($v_file_from, 1024))
646
+ @fwrite($v_file_to, $v_data);
647
+ @fclose($v_file_from);
648
+ @fclose($v_file_to);
649
+ }
650
+
651
+ // ----- File to open if the local copy
652
+ $v_filename = $this->_temp_tarname;
653
+
654
+ } else
655
+ // ----- File to open if the normal Tar file
656
+ $v_filename = $this->_tarname;
657
+
658
+ if ($this->_compress_type == 'gz')
659
+ $this->_file = @gzopen($v_filename, "rb");
660
+ else if ($this->_compress_type == 'bz2')
661
+ $this->_file = @bzopen($v_filename, "rb");
662
+ else if ($this->_compress_type == 'none')
663
+ $this->_file = @fopen($v_filename, "rb");
664
+ else
665
+ $this->_error('Unknown or missing compression type ('
666
+ .$this->_compress_type.')');
667
+
668
+ if ($this->_file == 0) {
669
+ $this->_error('Unable to open in read mode \''.$v_filename.'\'');
670
+ return false;
671
+ }
672
+
673
+ return true;
674
+ }
675
+ // }}}
676
+
677
+ // {{{ _openReadWrite()
678
+ function _openReadWrite()
679
+ {
680
+ if ($this->_compress_type == 'gz')
681
+ $this->_file = @gzopen($this->_tarname, "r+b");
682
+ else if ($this->_compress_type == 'bz2')
683
+ $this->_file = @bzopen($this->_tarname, "r+b");
684
+ else if ($this->_compress_type == 'none')
685
+ $this->_file = @fopen($this->_tarname, "r+b");
686
+ else
687
+ $this->_error('Unknown or missing compression type ('
688
+ .$this->_compress_type.')');
689
+
690
+ if ($this->_file == 0) {
691
+ $this->_error('Unable to open in read/write mode \''
692
+ .$this->_tarname.'\'');
693
+ return false;
694
+ }
695
+
696
+ return true;
697
+ }
698
+ // }}}
699
+
700
+ // {{{ _close()
701
+ function _close()
702
+ {
703
+ //if (isset($this->_file)) {
704
+ if (is_resource($this->_file)) {
705
+ if ($this->_compress_type == 'gz')
706
+ @gzclose($this->_file);
707
+ else if ($this->_compress_type == 'bz2')
708
+ @bzclose($this->_file);
709
+ else if ($this->_compress_type == 'none')
710
+ @fclose($this->_file);
711
+ else
712
+ $this->_error('Unknown or missing compression type ('
713
+ .$this->_compress_type.')');
714
+
715
+ $this->_file = 0;
716
+ }
717
+
718
+ // ----- Look if a local copy need to be erase
719
+ // Note that it might be interesting to keep the url for a time : ToDo
720
+ if ($this->_temp_tarname != '') {
721
+ @unlink($this->_temp_tarname);
722
+ $this->_temp_tarname = '';
723
+ }
724
+
725
+ return true;
726
+ }
727
+ // }}}
728
+
729
+ // {{{ _cleanFile()
730
+ function _cleanFile()
731
+ {
732
+ $this->_close();
733
+
734
+ // ----- Look for a local copy
735
+ if ($this->_temp_tarname != '') {
736
+ // ----- Remove the local copy but not the remote tarname
737
+ @unlink($this->_temp_tarname);
738
+ $this->_temp_tarname = '';
739
+ } else {
740
+ // ----- Remove the local tarname file
741
+ @unlink($this->_tarname);
742
+ }
743
+ $this->_tarname = '';
744
+
745
+ return true;
746
+ }
747
+ // }}}
748
+
749
+ // {{{ _writeBlock()
750
+ function _writeBlock($p_binary_data, $p_len=null)
751
+ {
752
+ if (is_resource($this->_file)) {
753
+ if ($p_len === null) {
754
+ if ($this->_compress_type == 'gz')
755
+ @gzputs($this->_file, $p_binary_data);
756
+ else if ($this->_compress_type == 'bz2')
757
+ @bzwrite($this->_file, $p_binary_data);
758
+ else if ($this->_compress_type == 'none')
759
+ @fputs($this->_file, $p_binary_data);
760
+ else
761
+ $this->_error('Unknown or missing compression type ('
762
+ .$this->_compress_type.')');
763
+ } else {
764
+ if ($this->_compress_type == 'gz')
765
+ @gzputs($this->_file, $p_binary_data, $p_len);
766
+ else if ($this->_compress_type == 'bz2')
767
+ @bzwrite($this->_file, $p_binary_data, $p_len);
768
+ else if ($this->_compress_type == 'none')
769
+ @fputs($this->_file, $p_binary_data, $p_len);
770
+ else
771
+ $this->_error('Unknown or missing compression type ('
772
+ .$this->_compress_type.')');
773
+
774
+ }
775
+ }
776
+ return true;
777
+ }
778
+ // }}}
779
+
780
+ // {{{ _readBlock()
781
+ function _readBlock()
782
+ {
783
+ $v_block = null;
784
+ if (is_resource($this->_file)) {
785
+ if ($this->_compress_type == 'gz')
786
+ $v_block = @gzread($this->_file, 512);
787
+ else if ($this->_compress_type == 'bz2')
788
+ $v_block = @bzread($this->_file, 512);
789
+ else if ($this->_compress_type == 'none')
790
+ $v_block = @fread($this->_file, 512);
791
+ else
792
+ $this->_error('Unknown or missing compression type ('
793
+ .$this->_compress_type.')');
794
+ }
795
+ return $v_block;
796
+ }
797
+ // }}}
798
+
799
+ // {{{ _jumpBlock()
800
+ function _jumpBlock($p_len=null)
801
+ {
802
+ if (is_resource($this->_file)) {
803
+ if ($p_len === null)
804
+ $p_len = 1;
805
+
806
+ if ($this->_compress_type == 'gz') {
807
+ @gzseek($this->_file, gztell($this->_file)+($p_len*512));
808
+ }
809
+ else if ($this->_compress_type == 'bz2') {
810
+ // ----- Replace missing bztell() and bzseek()
811
+ for ($i=0; $i<$p_len; $i++)
812
+ $this->_readBlock();
813
+ } else if ($this->_compress_type == 'none')
814
+ @fseek($this->_file, ftell($this->_file)+($p_len*512));
815
+ else
816
+ $this->_error('Unknown or missing compression type ('
817
+ .$this->_compress_type.')');
818
+
819
+ }
820
+ return true;
821
+ }
822
+ // }}}
823
+
824
+ // {{{ _writeFooter()
825
+ function _writeFooter()
826
+ {
827
+ if (is_resource($this->_file)) {
828
+ // ----- Write the last 0 filled block for end of archive
829
+ $v_binary_data = pack('a1024', '');
830
+ $this->_writeBlock($v_binary_data);
831
+ }
832
+ return true;
833
+ }
834
+ // }}}
835
+
836
+ // {{{ _addList()
837
+ function _addList($p_list, $p_add_dir, $p_remove_dir)
838
+ {
839
+ $v_result=true;
840
+ $v_header = array();
841
+
842
+ // ----- Remove potential windows directory separator
843
+ $p_add_dir = $this->_translateWinPath($p_add_dir);
844
+ $p_remove_dir = $this->_translateWinPath($p_remove_dir, false);
845
+
846
+ if (!$this->_file) {
847
+ $this->_error('Invalid file descriptor');
848
+ return false;
849
+ }
850
+
851
+ if (sizeof($p_list) == 0)
852
+ return true;
853
+
854
+ foreach ($p_list as $v_filename) {
855
+ if (!$v_result) {
856
+ break;
857
+ }
858
+
859
+ // ----- Skip the current tar name
860
+ if ($v_filename == $this->_tarname)
861
+ continue;
862
+
863
+ if ($v_filename == '')
864
+ continue;
865
+
866
+ if (!file_exists($v_filename)) {
867
+ $this->_warning("File '$v_filename' does not exist");
868
+ continue;
869
+ }
870
+
871
+ // ----- Add the file or directory header
872
+ if (!$this->_addFile($v_filename, $v_header, $p_add_dir, $p_remove_dir))
873
+ return false;
874
+
875
+ if (@is_dir($v_filename)) {
876
+ if (!($p_hdir = opendir($v_filename))) {
877
+ $this->_warning("Directory '$v_filename' can not be read");
878
+ continue;
879
+ }
880
+ while (false !== ($p_hitem = readdir($p_hdir))) {
881
+ if (($p_hitem != '.') && ($p_hitem != '..')) {
882
+ if ($v_filename != ".")
883
+ $p_temp_list[0] = $v_filename.'/'.$p_hitem;
884
+ else
885
+ $p_temp_list[0] = $p_hitem;
886
+
887
+ $v_result = $this->_addList($p_temp_list,
888
+ $p_add_dir,
889
+ $p_remove_dir);
890
+ }
891
+ }
892
+
893
+ unset($p_temp_list);
894
+ unset($p_hdir);
895
+ unset($p_hitem);
896
+ }
897
+ }
898
+
899
+ return $v_result;
900
+ }
901
+ // }}}
902
+
903
+ // {{{ _addFile()
904
+ function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir)
905
+ {
906
+ if (!$this->_file) {
907
+ $this->_error('Invalid file descriptor');
908
+ return false;
909
+ }
910
+
911
+ if ($p_filename == '') {
912
+ $this->_error('Invalid file name');
913
+ return false;
914
+ }
915
+
916
+ // ----- Calculate the stored filename
917
+ $p_filename = $this->_translateWinPath($p_filename, false);;
918
+ $v_stored_filename = $p_filename;
919
+ if (strcmp($p_filename, $p_remove_dir) == 0) {
920
+ return true;
921
+ }
922
+ if ($p_remove_dir != '') {
923
+ if (substr($p_remove_dir, -1) != '/')
924
+ $p_remove_dir .= '/';
925
+
926
+ if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir)
927
+ $v_stored_filename = substr($p_filename, strlen($p_remove_dir));
928
+ }
929
+ $v_stored_filename = $this->_translateWinPath($v_stored_filename);
930
+ if ($p_add_dir != '') {
931
+ if (substr($p_add_dir, -1) == '/')
932
+ $v_stored_filename = $p_add_dir.$v_stored_filename;
933
+ else
934
+ $v_stored_filename = $p_add_dir.'/'.$v_stored_filename;
935
+ }
936
+
937
+ $v_stored_filename = $this->_pathReduction($v_stored_filename);
938
+
939
+ if ($this->_isArchive($p_filename)) {
940
+ if (($v_file = @fopen($p_filename, "rb")) == 0) {
941
+ $this->_warning("Unable to open file '".$p_filename
942
+ ."' in binary read mode");
943
+ return true;
944
+ }
945
+
946
+ if (!$this->_writeHeader($p_filename, $v_stored_filename))
947
+ return false;
948
+
949
+ while (($v_buffer = fread($v_file, 512)) != '') {
950
+ $v_binary_data = pack("a512", "$v_buffer");
951
+ $this->_writeBlock($v_binary_data);
952
+ }
953
+
954
+ fclose($v_file);
955
+
956
+ } else {
957
+ // ----- Only header for dir
958
+ if (!$this->_writeHeader($p_filename, $v_stored_filename))
959
+ return false;
960
+ }
961
+
962
+ return true;
963
+ }
964
+ // }}}
965
+
966
+ // {{{ _addString()
967
+ function _addString($p_filename, $p_string)
968
+ {
969
+ if (!$this->_file) {
970
+ $this->_error('Invalid file descriptor');
971
+ return false;
972
+ }
973
+
974
+ if ($p_filename == '') {
975
+ $this->_error('Invalid file name');
976
+ return false;
977
+ }
978
+
979
+ // ----- Calculate the stored filename
980
+ $p_filename = $this->_translateWinPath($p_filename, false);;
981
+
982
+ if (!$this->_writeHeaderBlock($p_filename, strlen($p_string),
983
+ time(), 384, "", 0, 0))
984
+ return false;
985
+
986
+ $i=0;
987
+ while (($v_buffer = substr($p_string, (($i++)*512), 512)) != '') {
988
+ $v_binary_data = pack("a512", $v_buffer);
989
+ $this->_writeBlock($v_binary_data);
990
+ }
991
+
992
+ return true;
993
+ }
994
+ // }}}
995
+
996
+ // {{{ _writeHeader()
997
+ function _writeHeader($p_filename, $p_stored_filename)
998
+ {
999
+ if ($p_stored_filename == '')
1000
+ $p_stored_filename = $p_filename;
1001
+ $v_reduce_filename = $this->_pathReduction($p_stored_filename);
1002
+
1003
+ if (strlen($v_reduce_filename) > 99) {
1004
+ if (!$this->_writeLongHeader($v_reduce_filename))
1005
+ return false;
1006
+ }
1007
+
1008
+ $v_info = stat($p_filename);
1009
+ $v_uid = sprintf("%6s ", DecOct($v_info[4]));
1010
+ $v_gid = sprintf("%6s ", DecOct($v_info[5]));
1011
+ $v_perms = sprintf("%6s ", DecOct(fileperms($p_filename)));
1012
+
1013
+ $v_mtime = sprintf("%11s", DecOct(filemtime($p_filename)));
1014
+
1015
+ if (@is_dir($p_filename)) {
1016
+ $v_typeflag = "5";
1017
+ $v_size = sprintf("%11s ", DecOct(0));
1018
+ } else {
1019
+ $v_typeflag = '';
1020
+ clearstatcache();
1021
+ $v_size = sprintf("%11s ", DecOct(filesize($p_filename)));
1022
+ }
1023
+
1024
+ $v_linkname = '';
1025
+
1026
+ $v_magic = '';
1027
+
1028
+ $v_version = '';
1029
+
1030
+ $v_uname = '';
1031
+
1032
+ $v_gname = '';
1033
+
1034
+ $v_devmajor = '';
1035
+
1036
+ $v_devminor = '';
1037
+
1038
+ $v_prefix = '';
1039
+
1040
+ $v_binary_data_first = pack("a100a8a8a8a12A12",
1041
+ $v_reduce_filename, $v_perms, $v_uid,
1042
+ $v_gid, $v_size, $v_mtime);
1043
+ $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12",
1044
+ $v_typeflag, $v_linkname, $v_magic,
1045
+ $v_version, $v_uname, $v_gname,
1046
+ $v_devmajor, $v_devminor, $v_prefix, '');
1047
+
1048
+ // ----- Calculate the checksum
1049
+ $v_checksum = 0;
1050
+ // ..... First part of the header
1051
+ for ($i=0; $i<148; $i++)
1052
+ $v_checksum += ord(substr($v_binary_data_first,$i,1));
1053
+ // ..... Ignore the checksum value and replace it by ' ' (space)
1054
+ for ($i=148; $i<156; $i++)
1055
+ $v_checksum += ord(' ');
1056
+ // ..... Last part of the header
1057
+ for ($i=156, $j=0; $i<512; $i++, $j++)
1058
+ $v_checksum += ord(substr($v_binary_data_last,$j,1));
1059
+
1060
+ // ----- Write the first 148 bytes of the header in the archive
1061
+ $this->_writeBlock($v_binary_data_first, 148);
1062
+
1063
+ // ----- Write the calculated checksum
1064
+ $v_checksum = sprintf("%6s ", DecOct($v_checksum));
1065
+ $v_binary_data = pack("a8", $v_checksum);
1066
+ $this->_writeBlock($v_binary_data, 8);
1067
+
1068
+ // ----- Write the last 356 bytes of the header in the archive
1069
+ $this->_writeBlock($v_binary_data_last, 356);
1070
+
1071
+ return true;
1072
+ }
1073
+ // }}}
1074
+
1075
+ // {{{ _writeHeaderBlock()
1076
+ function _writeHeaderBlock($p_filename, $p_size, $p_mtime=0, $p_perms=0,
1077
+ $p_type='', $p_uid=0, $p_gid=0)
1078
+ {
1079
+ $p_filename = $this->_pathReduction($p_filename);
1080
+
1081
+ if (strlen($p_filename) > 99) {
1082
+ if (!$this->_writeLongHeader($p_filename))
1083
+ return false;
1084
+ }
1085
+
1086
+ if ($p_type == "5") {
1087
+ $v_size = sprintf("%11s ", DecOct(0));
1088
+ } else {
1089
+ $v_size = sprintf("%11s ", DecOct($p_size));
1090
+ }
1091
+
1092
+ $v_uid = sprintf("%6s ", DecOct($p_uid));
1093
+ $v_gid = sprintf("%6s ", DecOct($p_gid));
1094
+ $v_perms = sprintf("%6s ", DecOct($p_perms));
1095
+
1096
+ $v_mtime = sprintf("%11s", DecOct($p_mtime));
1097
+
1098
+ $v_linkname = '';
1099
+
1100
+ $v_magic = '';
1101
+
1102
+ $v_version = '';
1103
+
1104
+ $v_uname = '';
1105
+
1106
+ $v_gname = '';
1107
+
1108
+ $v_devmajor = '';
1109
+
1110
+ $v_devminor = '';
1111
+
1112
+ $v_prefix = '';
1113
+
1114
+ $v_binary_data_first = pack("a100a8a8a8a12A12",
1115
+ $p_filename, $v_perms, $v_uid, $v_gid,
1116
+ $v_size, $v_mtime);
1117
+ $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12",
1118
+ $p_type, $v_linkname, $v_magic,
1119
+ $v_version, $v_uname, $v_gname,
1120
+ $v_devmajor, $v_devminor, $v_prefix, '');
1121
+
1122
+ // ----- Calculate the checksum
1123
+ $v_checksum = 0;
1124
+ // ..... First part of the header
1125
+ for ($i=0; $i<148; $i++)
1126
+ $v_checksum += ord(substr($v_binary_data_first,$i,1));
1127
+ // ..... Ignore the checksum value and replace it by ' ' (space)
1128
+ for ($i=148; $i<156; $i++)
1129
+ $v_checksum += ord(' ');
1130
+ // ..... Last part of the header
1131
+ for ($i=156, $j=0; $i<512; $i++, $j++)
1132
+ $v_checksum += ord(substr($v_binary_data_last,$j,1));
1133
+
1134
+ // ----- Write the first 148 bytes of the header in the archive
1135
+ $this->_writeBlock($v_binary_data_first, 148);
1136
+
1137
+ // ----- Write the calculated checksum
1138
+ $v_checksum = sprintf("%6s ", DecOct($v_checksum));
1139
+ $v_binary_data = pack("a8", $v_checksum);
1140
+ $this->_writeBlock($v_binary_data, 8);
1141
+
1142
+ // ----- Write the last 356 bytes of the header in the archive
1143
+ $this->_writeBlock($v_binary_data_last, 356);
1144
+
1145
+ return true;
1146
+ }
1147
+ // }}}
1148
+
1149
+ // {{{ _writeLongHeader()
1150
+ function _writeLongHeader($p_filename)
1151
+ {
1152
+ $v_size = sprintf("%11s ", DecOct(strlen($p_filename)));
1153
+
1154
+ $v_typeflag = 'L';
1155
+
1156
+ $v_linkname = '';
1157
+
1158
+ $v_magic = '';
1159
+
1160
+ $v_version = '';
1161
+
1162
+ $v_uname = '';
1163
+
1164
+ $v_gname = '';
1165
+
1166
+ $v_devmajor = '';
1167
+
1168
+ $v_devminor = '';
1169
+
1170
+ $v_prefix = '';
1171
+
1172
+ $v_binary_data_first = pack("a100a8a8a8a12A12",
1173
+ '././@LongLink', 0, 0, 0, $v_size, 0);
1174
+ $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12",
1175
+ $v_typeflag, $v_linkname, $v_magic,
1176
+ $v_version, $v_uname, $v_gname,
1177
+ $v_devmajor, $v_devminor, $v_prefix, '');
1178
+
1179
+ // ----- Calculate the checksum
1180
+ $v_checksum = 0;
1181
+ // ..... First part of the header
1182
+ for ($i=0; $i<148; $i++)
1183
+ $v_checksum += ord(substr($v_binary_data_first,$i,1));
1184
+ // ..... Ignore the checksum value and replace it by ' ' (space)
1185
+ for ($i=148; $i<156; $i++)
1186
+ $v_checksum += ord(' ');
1187
+ // ..... Last part of the header
1188
+ for ($i=156, $j=0; $i<512; $i++, $j++)
1189
+ $v_checksum += ord(substr($v_binary_data_last,$j,1));
1190
+
1191
+ // ----- Write the first 148 bytes of the header in the archive
1192
+ $this->_writeBlock($v_binary_data_first, 148);
1193
+
1194
+ // ----- Write the calculated checksum
1195
+ $v_checksum = sprintf("%6s ", DecOct($v_checksum));
1196
+ $v_binary_data = pack("a8", $v_checksum);
1197
+ $this->_writeBlock($v_binary_data, 8);
1198
+
1199
+ // ----- Write the last 356 bytes of the header in the archive
1200
+ $this->_writeBlock($v_binary_data_last, 356);
1201
+
1202
+ // ----- Write the filename as content of the block
1203
+ $i=0;
1204
+ while (($v_buffer = substr($p_filename, (($i++)*512), 512)) != '') {
1205
+ $v_binary_data = pack("a512", "$v_buffer");
1206
+ $this->_writeBlock($v_binary_data);
1207
+ }
1208
+
1209
+ return true;
1210
+ }
1211
+ // }}}
1212
+
1213
+ // {{{ _readHeader()
1214
+ function _readHeader($v_binary_data, &$v_header)
1215
+ {
1216
+ if (strlen($v_binary_data)==0) {
1217
+ $v_header['filename'] = '';
1218
+ return true;
1219
+ }
1220
+
1221
+ if (strlen($v_binary_data) != 512) {
1222
+ $v_header['filename'] = '';
1223
+ $this->_error('Invalid block size : '.strlen($v_binary_data));
1224
+ return false;
1225
+ }
1226
+
1227
+ if (!is_array($v_header)) {
1228
+ $v_header = array();
1229
+ }
1230
+ // ----- Calculate the checksum
1231
+ $v_checksum = 0;
1232
+ // ..... First part of the header
1233
+ for ($i=0; $i<148; $i++)
1234
+ $v_checksum+=ord(substr($v_binary_data,$i,1));
1235
+ // ..... Ignore the checksum value and replace it by ' ' (space)
1236
+ for ($i=148; $i<156; $i++)
1237
+ $v_checksum += ord(' ');
1238
+ // ..... Last part of the header
1239
+ for ($i=156; $i<512; $i++)
1240
+ $v_checksum+=ord(substr($v_binary_data,$i,1));
1241
+
1242
+ $v_data = unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/"
1243
+ ."a8checksum/a1typeflag/a100link/a6magic/a2version/"
1244
+ ."a32uname/a32gname/a8devmajor/a8devminor",
1245
+ $v_binary_data);
1246
+
1247
+ // ----- Extract the checksum
1248
+ $v_header['checksum'] = OctDec(trim($v_data['checksum']));
1249
+ if ($v_header['checksum'] != $v_checksum) {
1250
+ $v_header['filename'] = '';
1251
+
1252
+ // ----- Look for last block (empty block)
1253
+ if (($v_checksum == 256) && ($v_header['checksum'] == 0))
1254
+ return true;
1255
+
1256
+ $this->_error('Invalid checksum for file "'.$v_data['filename']
1257
+ .'" : '.$v_checksum.' calculated, '
1258
+ .$v_header['checksum'].' expected');
1259
+ return false;
1260
+ }
1261
+
1262
+ // ----- Extract the properties
1263
+ $v_header['filename'] = trim($v_data['filename']);
1264
+ if ($this->_maliciousFilename($v_header['filename'])) {
1265
+ $this->_error('Malicious .tar detected, file "' . $v_header['filename'] .
1266
+ '" will not install in desired directory tree');
1267
+ return false;
1268
+ }
1269
+ $v_header['mode'] = OctDec(trim($v_data['mode']));
1270
+ $v_header['uid'] = OctDec(trim($v_data['uid']));
1271
+ $v_header['gid'] = OctDec(trim($v_data['gid']));
1272
+ $v_header['size'] = OctDec(trim($v_data['size']));
1273
+ $v_header['mtime'] = OctDec(trim($v_data['mtime']));
1274
+ if (($v_header['typeflag'] = $v_data['typeflag']) == "5") {
1275
+ $v_header['size'] = 0;
1276
+ }
1277
+ $v_header['link'] = trim($v_data['link']);
1278
+ /* ----- All these fields are removed form the header because
1279
+ they do not carry interesting info
1280
+ $v_header[magic] = trim($v_data[magic]);
1281
+ $v_header[version] = trim($v_data[version]);
1282
+ $v_header[uname] = trim($v_data[uname]);
1283
+ $v_header[gname] = trim($v_data[gname]);
1284
+ $v_header[devmajor] = trim($v_data[devmajor]);
1285
+ $v_header[devminor] = trim($v_data[devminor]);
1286
+ */
1287
+
1288
+ return true;
1289
+ }
1290
+ // }}}
1291
+
1292
+ // {{{ _maliciousFilename()
1293
+ /**
1294
+ * Detect and report a malicious file name
1295
+ *
1296
+ * @param string $file
1297
+ * @return bool
1298
+ * @access private
1299
+ */
1300
+ function _maliciousFilename($file)
1301
+ {
1302
+ if (strpos($file, '/../') !== false) {
1303
+ return true;
1304
+ }
1305
+ if (strpos($file, '../') === 0) {
1306
+ return true;
1307
+ }
1308
+ return false;
1309
+ }
1310
+ // }}}
1311
+
1312
+ // {{{ _readLongHeader()
1313
+ function _readLongHeader(&$v_header)
1314
+ {
1315
+ $v_filename = '';
1316
+ $n = floor($v_header['size']/512);
1317
+ for ($i=0; $i<$n; $i++) {
1318
+ $v_content = $this->_readBlock();
1319
+ $v_filename .= $v_content;
1320
+ }
1321
+ if (($v_header['size'] % 512) != 0) {
1322
+ $v_content = $this->_readBlock();
1323
+ $v_filename .= $v_content;
1324
+ }
1325
+
1326
+ // ----- Read the next header
1327
+ $v_binary_data = $this->_readBlock();
1328
+
1329
+ if (!$this->_readHeader($v_binary_data, $v_header))
1330
+ return false;
1331
+
1332
+ $v_header['filename'] = $v_filename;
1333
+ if ($this->_maliciousFilename($v_filename)) {
1334
+ $this->_error('Malicious .tar detected, file "' . $v_filename .
1335
+ '" will not install in desired directory tree');
1336
+ return false;
1337
+ }
1338
+
1339
+ return true;
1340
+ }
1341
+ // }}}
1342
+
1343
+ // {{{ _extractInString()
1344
+ /**
1345
+ * This method extract from the archive one file identified by $p_filename.
1346
+ * The return value is a string with the file content, or NULL on error.
1347
+ * @param string $p_filename The path of the file to extract in a string.
1348
+ * @return a string with the file content or NULL.
1349
+ * @access private
1350
+ */
1351
+ function _extractInString($p_filename)
1352
+ {
1353
+ $v_result_str = "";
1354
+
1355
+ While (strlen($v_binary_data = $this->_readBlock()) != 0)
1356
+ {
1357
+ if (!$this->_readHeader($v_binary_data, $v_header))
1358
+ return NULL;
1359
+
1360
+ if ($v_header['filename'] == '')
1361
+ continue;
1362
+
1363
+ // ----- Look for long filename
1364
+ if ($v_header['typeflag'] == 'L') {
1365
+ if (!$this->_readLongHeader($v_header))
1366
+ return NULL;
1367
+ }
1368
+
1369
+ if ($v_header['filename'] == $p_filename) {
1370
+ if ($v_header['typeflag'] == "5") {
1371
+ $this->_error('Unable to extract in string a directory '
1372
+ .'entry {'.$v_header['filename'].'}');
1373
+ return NULL;
1374
+ } else {
1375
+ $n = floor($v_header['size']/512);
1376
+ for ($i=0; $i<$n; $i++) {
1377
+ $v_result_str .= $this->_readBlock();
1378
+ }
1379
+ if (($v_header['size'] % 512) != 0) {
1380
+ $v_content = $this->_readBlock();
1381
+ $v_result_str .= substr($v_content, 0,
1382
+ ($v_header['size'] % 512));
1383
+ }
1384
+ return $v_result_str;
1385
+ }
1386
+ } else {
1387
+ $this->_jumpBlock(ceil(($v_header['size']/512)));
1388
+ }
1389
+ }
1390
+
1391
+ return NULL;
1392
+ }
1393
+ // }}}
1394
+
1395
+ // {{{ _extractList()
1396
+ function _extractList_vbdata($p_path, &$p_list_detail, $p_mode,
1397
+ $p_file_list, $p_remove_path, $v_binary_data)
1398
+ {
1399
+ $v_result=true;
1400
+ $v_nb = 0;
1401
+ $v_extract_all = true;
1402
+ $v_listing = false;
1403
+
1404
+ $p_path = $this->_translateWinPath($p_path, false);
1405
+ if ($p_path == '' || (substr($p_path, 0, 1) != '/'
1406
+ && substr($p_path, 0, 3) != "../" && !strpos($p_path, ':'))) {
1407
+ $p_path = "./".$p_path;
1408
+ }
1409
+ $p_remove_path = $this->_translateWinPath($p_remove_path);
1410
+
1411
+ // ----- Look for path to remove format (should end by /)
1412
+ if (($p_remove_path != '') && (substr($p_remove_path, -1) != '/'))
1413
+ $p_remove_path .= '/';
1414
+ $p_remove_path_size = strlen($p_remove_path);
1415
+
1416
+ switch ($p_mode) {
1417
+ case "complete" :
1418
+ $v_extract_all = TRUE;
1419
+ $v_listing = FALSE;
1420
+ break;
1421
+ case "partial" :
1422
+ $v_extract_all = FALSE;
1423
+ $v_listing = FALSE;
1424
+ break;
1425
+ case "list" :
1426
+ $v_extract_all = FALSE;
1427
+ $v_listing = TRUE;
1428
+ break;
1429
+ default :
1430
+ $this->_error('Invalid extract mode ('.$p_mode.')');
1431
+ return false;
1432
+ }
1433
+
1434
+ clearstatcache();
1435
+
1436
+ //while (strlen($v_binary_data = $this->_readBlock()) != 0)
1437
+ {
1438
+ $v_extract_file = FALSE;
1439
+ $v_extraction_stopped = 0;
1440
+
1441
+ if (!$this->_readHeader($v_binary_data, $v_header))
1442
+ return false;
1443
+
1444
+ if ($v_header['filename'] == '') {
1445
+ continue;
1446
+ }
1447
+
1448
+ // ----- Look for long filename
1449
+ if ($v_header['typeflag'] == 'L') {
1450
+ if (!$this->_readLongHeader($v_header))
1451
+ return false;
1452
+ }
1453
+
1454
+ #if ((!$v_extract_all) && (is_array($p_file_list)))
1455
+ #{
1456
+ // ----- By default no unzip if the file is not found
1457
+ $v_extract_file = true;
1458
+
1459
+ /*for ($i=0; $i<sizeof($p_file_list); $i++) {
1460
+ // ----- Look if it is a directory
1461
+ if (substr($p_file_list[$i], -1) == '/') {
1462
+ // ----- Look if the directory is in the filename path
1463
+ if ((strlen($v_header['filename']) > strlen($p_file_list[$i]))
1464
+ && (substr($v_header['filename'], 0, strlen($p_file_list[$i]))
1465
+ == $p_file_list[$i])) {
1466
+ $v_extract_file = TRUE;
1467
+ break;
1468
+ }
1469
+ }
1470
+
1471
+ // ----- It is a file, so compare the file names
1472
+ elseif ($p_file_list[$i] == $v_header['filename']) {
1473
+ $v_extract_file = TRUE;
1474
+ break;
1475
+ }
1476
+ }
1477
+ } else {
1478
+ $v_extract_file = TRUE;
1479
+ }*/
1480
+
1481
+ // ----- Look if this file need to be extracted
1482
+ if (($v_extract_file) && (!$v_listing))
1483
+ {
1484
+ if (($p_remove_path != '')
1485
+ && (substr($v_header['filename'], 0, $p_remove_path_size)
1486
+ == $p_remove_path))
1487
+ $v_header['filename'] = substr($v_header['filename'],
1488
+ $p_remove_path_size);
1489
+ if (($p_path != './') && ($p_path != '/')) {
1490
+ while (substr($p_path, -1) == '/')
1491
+ $p_path = substr($p_path, 0, strlen($p_path)-1);
1492
+
1493
+ if (substr($v_header['filename'], 0, 1) == '/')
1494
+ $v_header['filename'] = $p_path.$v_header['filename'];
1495
+ else
1496
+ $v_header['filename'] = $p_path.'/'.$v_header['filename'];
1497
+ }
1498
+ if (file_exists($v_header['filename'])) {
1499
+ if ( (@is_dir($v_header['filename']))
1500
+ && ($v_header['typeflag'] == '')) {
1501
+ $this->_error('File '.$v_header['filename']
1502
+ .' already exists as a directory');
1503
+ return false;
1504
+ }
1505
+ if ( ($this->_isArchive($v_header['filename']))
1506
+ && ($v_header['typeflag'] == "5")) {
1507
+ $this->_error('Directory '.$v_header['filename']
1508
+ .' already exists as a file');
1509
+ return false;
1510
+ }
1511
+ if (!is_writeable($v_header['filename'])) {
1512
+ $this->_error('File '.$v_header['filename']
1513
+ .' already exists and is write protected');
1514
+ return false;
1515
+ }
1516
+ if (filemtime($v_header['filename']) > $v_header['mtime']) {
1517
+ // To be completed : An error or silent no replace ?
1518
+ }
1519
+ }
1520
+
1521
+ // ----- Check the directory availability and create it if necessary
1522
+ elseif (($v_result
1523
+ = $this->_dirCheck(($v_header['typeflag'] == "5"
1524
+ ?$v_header['filename']
1525
+ :dirname($v_header['filename'])))) != 1) {
1526
+ $this->_error('Unable to create path for '.$v_header['filename']);
1527
+ return false;
1528
+ }
1529
+
1530
+ if ($v_extract_file) {
1531
+ if ($v_header['typeflag'] == "5") {
1532
+ if (!@file_exists($v_header['filename'])) {
1533
+ if (!@mkdir($v_header['filename'], 0777)) {
1534
+ $this->_error('Unable to create directory {'
1535
+ .$v_header['filename'].'}');
1536
+ return false;
1537
+ }
1538
+ }
1539
+ } elseif ($v_header['typeflag'] == "2") {
1540
+ if (!@symlink($v_header['link'], $v_header['filename'])) {
1541
+ $this->_error('Unable to extract symbolic link {'
1542
+ .$v_header['filename'].'}');
1543
+ return false;
1544
+ }
1545
+ } else {
1546
+ if (($v_dest_file = @fopen($v_header['filename'], "wb")) == 0) {
1547
+ $this->_error('Error while opening {'.$v_header['filename']
1548
+ .'} in write binary mode');
1549
+ return false;
1550
+ } else {
1551
+ $n = floor($v_header['size']/512);
1552
+ for ($i=0; $i<$n; $i++) {
1553
+ $v_content = $this->_readBlock();
1554
+ fwrite($v_dest_file, $v_content, 512);
1555
+ }
1556
+ if (($v_header['size'] % 512) != 0) {
1557
+ $v_content = $this->_readBlock();
1558
+ fwrite($v_dest_file, $v_content, ($v_header['size'] % 512));
1559
+ }
1560
+
1561
+ @fclose($v_dest_file);
1562
+
1563
+ // ----- Change the file mode, mtime
1564
+ @touch($v_header['filename'], $v_header['mtime']);
1565
+ if ($v_header['mode'] & 0111) {
1566
+ // make file executable, obey umask
1567
+ $mode = fileperms($v_header['filename']) | (~umask() & 0111);
1568
+ @chmod($v_header['filename'], $mode);
1569
+ }
1570
+ }
1571
+
1572
+ // ----- Check the file size
1573
+ clearstatcache();
1574
+ if (filesize($v_header['filename']) != $v_header['size']) {
1575
+ $this->_error('Extracted file '.$v_header['filename']
1576
+ .' does not have the correct file size \''
1577
+ .filesize($v_header['filename'])
1578
+ .'\' ('.$v_header['size']
1579
+ .' expected). Archive may be corrupted.');
1580
+ return false;
1581
+ }
1582
+ }
1583
+ } else {
1584
+ $this->_jumpBlock(ceil(($v_header['size']/512)));
1585
+ }
1586
+ } else {
1587
+ $this->_jumpBlock(ceil(($v_header['size']/512)));
1588
+ }
1589
+
1590
+ /* TBC : Seems to be unused ...
1591
+ if ($this->_compress)
1592
+ $v_end_of_file = @gzeof($this->_file);
1593
+ else
1594
+ $v_end_of_file = @feof($this->_file);
1595
+ */
1596
+
1597
+ if ($v_listing || $v_extract_file || $v_extraction_stopped) {
1598
+ // ----- Log extracted files
1599
+ if (($v_file_dir = dirname($v_header['filename']))
1600
+ == $v_header['filename'])
1601
+ $v_file_dir = '';
1602
+ if ((substr($v_header['filename'], 0, 1) == '/') && ($v_file_dir == ''))
1603
+ $v_file_dir = '/';
1604
+
1605
+ $p_list_detail[$v_nb++] = $v_header;
1606
+ if (is_array($p_file_list) && (count($p_list_detail) == count($p_file_list))) {
1607
+ return true;
1608
+ }
1609
+ }
1610
+ }
1611
+
1612
+ return true;
1613
+ }
1614
+ // }}}
1615
+
1616
+
1617
+ // {{{ _extractList()
1618
+ function _extractList($p_path, &$p_list_detail, $p_mode,
1619
+ $p_file_list, $p_remove_path, $limit=0)
1620
+ {
1621
+ $v_result=true;
1622
+ $v_nb = 0;
1623
+ $v_extract_all = true;
1624
+ $v_listing = false;
1625
+ $inc = 0;
1626
+
1627
+ $p_path = $this->_translateWinPath($p_path, false);
1628
+ if ($p_path == '' || (substr($p_path, 0, 1) != '/'
1629
+ && substr($p_path, 0, 3) != "../" && !strpos($p_path, ':'))) {
1630
+ $p_path = "./".$p_path;
1631
+ }
1632
+ $p_remove_path = $this->_translateWinPath($p_remove_path);
1633
+
1634
+ // ----- Look for path to remove format (should end by /)
1635
+ if (($p_remove_path != '') && (substr($p_remove_path, -1) != '/'))
1636
+ $p_remove_path .= '/';
1637
+ $p_remove_path_size = strlen($p_remove_path);
1638
+
1639
+ switch ($p_mode) {
1640
+ case "complete" :
1641
+ $v_extract_all = TRUE;
1642
+ $v_listing = FALSE;
1643
+ break;
1644
+ case "partial" :
1645
+ $v_extract_all = FALSE;
1646
+ $v_listing = FALSE;
1647
+ break;
1648
+ case "list" :
1649
+ $v_extract_all = FALSE;
1650
+ $v_listing = TRUE;
1651
+ break;
1652
+ default :
1653
+ $this->_error('Invalid extract mode ('.$p_mode.')');
1654
+ return false;
1655
+ }
1656
+
1657
+ clearstatcache();
1658
+
1659
+ while (strlen($v_binary_data = $this->_readBlock()) != 0)
1660
+ {
1661
+
1662
+ $v_extract_file = FALSE;
1663
+ $v_extraction_stopped = 0;
1664
+
1665
+ if (!$this->_readHeader($v_binary_data, $v_header))
1666
+ return false;
1667
+
1668
+ if ($v_header['filename'] == '') {
1669
+ continue;
1670
+ }
1671
+
1672
+ //Ovi's code
1673
+ if(($inc >= $limit) and ($limit !=0))
1674
+ return ftell($this->_file);
1675
+ $inc++;
1676
+
1677
+ // ----- Look for long filename
1678
+ if ($v_header['typeflag'] == 'L') {
1679
+ if (!$this->_readLongHeader($v_header))
1680
+ return false;
1681
+ }
1682
+
1683
+ if ((!$v_extract_all) && (is_array($p_file_list))) {
1684
+ // ----- By default no unzip if the file is not found
1685
+ $v_extract_file = false;
1686
+
1687
+ for ($i=0; $i<sizeof($p_file_list); $i++) {
1688
+ // ----- Look if it is a directory
1689
+ if (substr($p_file_list[$i], -1) == '/') {
1690
+ // ----- Look if the directory is in the filename path
1691
+ if ((strlen($v_header['filename']) > strlen($p_file_list[$i]))
1692
+ && (substr($v_header['filename'], 0, strlen($p_file_list[$i]))
1693
+ == $p_file_list[$i])) {
1694
+ $v_extract_file = TRUE;
1695
+ break;
1696
+ }
1697
+ }
1698
+
1699
+ // ----- It is a file, so compare the file names
1700
+ elseif ($p_file_list[$i] == $v_header['filename']) {
1701
+ $v_extract_file = TRUE;
1702
+ break;
1703
+ }
1704
+ }
1705
+ } else {
1706
+ $v_extract_file = TRUE;
1707
+ }
1708
+
1709
+ // ----- Look if this file need to be extracted
1710
+ if (($v_extract_file) && (!$v_listing))
1711
+ {
1712
+ if (($p_remove_path != '')
1713
+ && (substr($v_header['filename'], 0, $p_remove_path_size)
1714
+ == $p_remove_path))
1715
+ $v_header['filename'] = substr($v_header['filename'],
1716
+ $p_remove_path_size);
1717
+ if (($p_path != './') && ($p_path != '/')) {
1718
+ while (substr($p_path, -1) == '/')
1719
+ $p_path = substr($p_path, 0, strlen($p_path)-1);
1720
+
1721
+ if (substr($v_header['filename'], 0, 1) == '/')
1722
+ $v_header['filename'] = $p_path.$v_header['filename'];
1723
+ else
1724
+ $v_header['filename'] = $p_path.'/'.$v_header['filename'];
1725
+ }
1726
+ if (file_exists($v_header['filename'])) {
1727
+ if ( (@is_dir($v_header['filename']))
1728
+ && ($v_header['typeflag'] == '')) {
1729
+ $this->_error('File '.$v_header['filename']
1730
+ .' already exists as a directory');
1731
+ return false;
1732
+ }
1733
+ if ( ($this->_isArchive($v_header['filename']))
1734
+ && ($v_header['typeflag'] == "5")) {
1735
+ $this->_error('Directory '.$v_header['filename']
1736
+ .' already exists as a file');
1737
+ return false;
1738
+ }
1739
+ if (!is_writeable($v_header['filename'])) {
1740
+ $this->_error('File '.$v_header['filename']
1741
+ .' already exists and is write protected');
1742
+ return false;
1743
+ }
1744
+ if (filemtime($v_header['filename']) > $v_header['mtime']) {
1745
+ // To be completed : An error or silent no replace ?
1746
+ }
1747
+ }
1748
+
1749
+ // ----- Check the directory availability and create it if necessary
1750
+ elseif (($v_result
1751
+ = $this->_dirCheck(($v_header['typeflag'] == "5"
1752
+ ?$v_header['filename']
1753
+ :dirname($v_header['filename'])))) != 1) {
1754
+ $this->_error('Unable to create path for '.$v_header['filename']);
1755
+ return false;
1756
+ }
1757
+
1758
+ if ($v_extract_file) {
1759
+ if ($v_header['typeflag'] == "5") {
1760
+ if (!@file_exists($v_header['filename'])) {
1761
+ if (!@mkdir($v_header['filename'], 0777)) {
1762
+ $this->_error('Unable to create directory {'
1763
+ .$v_header['filename'].'}');
1764
+ return false;
1765
+ }
1766
+ }
1767
+ } elseif ($v_header['typeflag'] == "2") {
1768
+ if (!@symlink($v_header['link'], $v_header['filename'])) {
1769
+ $this->_error('Unable to extract symbolic link {'
1770
+ .$v_header['filename'].'}');
1771
+ return false;
1772
+ }
1773
+ } else {
1774
+ if (($v_dest_file = @fopen($v_header['filename'], "wb")) == 0) {
1775
+ $this->_error('Error while opening {'.$v_header['filename']
1776
+ .'} in write binary mode');
1777
+ return false;
1778
+ } else {
1779
+ $n = floor($v_header['size']/512);
1780
+ for ($i=0; $i<$n; $i++) {
1781
+ $v_content = $this->_readBlock();
1782
+ fwrite($v_dest_file, $v_content, 512);
1783
+ }
1784
+ if (($v_header['size'] % 512) != 0) {
1785
+ $v_content = $this->_readBlock();
1786
+ fwrite($v_dest_file, $v_content, ($v_header['size'] % 512));
1787
+ }
1788
+
1789
+ @fclose($v_dest_file);
1790
+
1791
+ // ----- Change the file mode, mtime
1792
+ @touch($v_header['filename'], $v_header['mtime']);
1793
+ if ($v_header['mode'] & 0111) {
1794
+ // make file executable, obey umask
1795
+ $mode = fileperms($v_header['filename']) | (~umask() & 0111);
1796
+ @chmod($v_header['filename'], $mode);
1797
+ }
1798
+ }
1799
+
1800
+ // ----- Check the file size
1801
+ clearstatcache();
1802
+ if (filesize($v_header['filename']) != $v_header['size']) {
1803
+ $this->_error('Extracted file '.$v_header['filename']
1804
+ .' does not have the correct file size \''
1805
+ .filesize($v_header['filename'])
1806
+ .'\' ('.$v_header['size']
1807
+ .' expected). Archive may be corrupted.');
1808
+ return false;
1809
+ }
1810
+ }
1811
+ } else {
1812
+ $this->_jumpBlock(ceil(($v_header['size']/512)));
1813
+ }
1814
+ } else {
1815
+ $this->_jumpBlock(ceil(($v_header['size']/512)));
1816
+ }
1817
+
1818
+ /* TBC : Seems to be unused ...
1819
+ if ($this->_compress)
1820
+ $v_end_of_file = @gzeof($this->_file);
1821
+ else
1822
+ $v_end_of_file = @feof($this->_file);
1823
+ */
1824
+
1825
+ if ($v_listing || $v_extract_file || $v_extraction_stopped) {
1826
+ // ----- Log extracted files
1827
+ if (($v_file_dir = dirname($v_header['filename']))
1828
+ == $v_header['filename'])
1829
+ $v_file_dir = '';
1830
+ if ((substr($v_header['filename'], 0, 1) == '/') && ($v_file_dir == ''))
1831
+ $v_file_dir = '/';
1832
+
1833
+ $p_list_detail[$v_nb++] = $v_header;
1834
+ if (is_array($p_file_list) && (count($p_list_detail) == count($p_file_list))) {
1835
+ return true;
1836
+ }
1837
+ }
1838
+ }
1839
+
1840
+ return true;
1841
+ }
1842
+ // }}}
1843
+
1844
+ //extract file by sending v_header and setting seek position
1845
+ function extractFile($tar, &$v_header)
1846
+ {
1847
+ $v_result_str = "";
1848
+ $p_filename = $v_header['filename'];
1849
+
1850
+ // ----- Look for long filename
1851
+ if ($v_header['typeflag'] == 'L') {
1852
+ if (!$tar->_readLongHeader($v_header))
1853
+ return NULL;
1854
+ }
1855
+
1856
+ if ($v_header['typeflag'] == "5") {
1857
+ $tar->_error('Unable to extract in string a directory '
1858
+ .'entry {'.$v_header['filename'].'}');
1859
+ return NULL;
1860
+ } else {
1861
+ $n = floor($v_header['size']/512);
1862
+ for ($i=0; $i<$n; $i++) {
1863
+ $v_result_str .= $tar->_readBlock();
1864
+ }
1865
+ if (($v_header['size'] % 512) != 0) {
1866
+ $v_content = $tar->_readBlock();
1867
+ $v_result_str .= substr($v_content, 0,
1868
+ ($v_header['size'] % 512));
1869
+ }
1870
+ return $v_result_str;
1871
+ }
1872
+
1873
+
1874
+ return NULL;
1875
+ }
1876
+
1877
+
1878
+ // {{{ _openAppend()
1879
+ function _openAppend()
1880
+ {
1881
+ if (filesize($this->_tarname) == 0)
1882
+ return $this->_openWrite();
1883
+
1884
+ if ($this->_compress) {
1885
+ $this->_close();
1886
+
1887
+ if (!@rename($this->_tarname, $this->_tarname.".tmp")) {
1888
+ $this->_error('Error while renaming \''.$this->_tarname
1889
+ .'\' to temporary file \''.$this->_tarname
1890
+ .'.tmp\'');
1891
+ return false;
1892
+ }
1893
+
1894
+ if ($this->_compress_type == 'gz')
1895
+ $v_temp_tar = @gzopen($this->_tarname.".tmp", "rb");
1896
+ elseif ($this->_compress_type == 'bz2')
1897
+ $v_temp_tar = @bzopen($this->_tarname.".tmp", "rb");
1898
+
1899
+ if ($v_temp_tar == 0) {
1900
+ $this->_error('Unable to open file \''.$this->_tarname
1901
+ .'.tmp\' in binary read mode');
1902
+ @rename($this->_tarname.".tmp", $this->_tarname);
1903
+ return false;
1904
+ }
1905
+
1906
+ if (!$this->_openWrite()) {
1907
+ @rename($this->_tarname.".tmp", $this->_tarname);
1908
+ return false;
1909
+ }
1910
+
1911
+ if ($this->_compress_type == 'gz') {
1912
+ while (!@gzeof($v_temp_tar)) {
1913
+ $v_buffer = @gzread($v_temp_tar, 512);
1914
+ if ($v_buffer == ARCHIVE_TAR_END_BLOCK) {
1915
+ // do not copy end blocks, we will re-make them
1916
+ // after appending
1917
+ continue;
1918
+ }
1919
+ $v_binary_data = pack("a512", $v_buffer);
1920
+ $this->_writeBlock($v_binary_data);
1921
+ }
1922
+
1923
+ @gzclose($v_temp_tar);
1924
+ }
1925
+ elseif ($this->_compress_type == 'bz2') {
1926
+ while (strlen($v_buffer = @bzread($v_temp_tar, 512)) > 0) {
1927
+ if ($v_buffer == ARCHIVE_TAR_END_BLOCK) {
1928
+ continue;
1929
+ }
1930
+ $v_binary_data = pack("a512", $v_buffer);
1931
+ $this->_writeBlock($v_binary_data);
1932
+ }
1933
+
1934
+ @bzclose($v_temp_tar);
1935
+ }
1936
+
1937
+ if (!@unlink($this->_tarname.".tmp")) {
1938
+ $this->_error('Error while deleting temporary file \''
1939
+ .$this->_tarname.'.tmp\'');
1940
+ }
1941
+
1942
+ } else {
1943
+ // ----- For not compressed tar, just add files before the last
1944
+ // one or two 512 bytes block
1945
+ if (!$this->_openReadWrite())
1946
+ return false;
1947
+
1948
+ clearstatcache();
1949
+ $v_size = filesize($this->_tarname);
1950
+
1951
+ // We might have zero, one or two end blocks.
1952
+ // The standard is two, but we should try to handle
1953
+ // other cases.
1954
+ fseek($this->_file, $v_size - 1024);
1955
+ if (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) {
1956
+ fseek($this->_file, $v_size - 1024);
1957
+ }
1958
+ elseif (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) {
1959
+ fseek($this->_file, $v_size - 512);
1960
+ }
1961
+ }
1962
+
1963
+ return true;
1964
+ }
1965
+ // }}}
1966
+
1967
+ // {{{ _append()
1968
+ function _append($p_filelist, $p_add_dir='', $p_remove_dir='')
1969
+ {
1970
+ if (!$this->_openAppend())
1971
+ return false;
1972
+
1973
+ if ($this->_addList($p_filelist, $p_add_dir, $p_remove_dir))
1974
+ $this->_writeFooter();
1975
+
1976
+ $this->_close();
1977
+
1978
+ return true;
1979
+ }
1980
+ // }}}
1981
+
1982
+ // {{{ _dirCheck()
1983
+
1984
+ /**
1985
+ * Check if a directory exists and create it (including parent
1986
+ * dirs) if not.
1987
+ *
1988
+ * @param string $p_dir directory to check
1989
+ *
1990
+ * @return bool TRUE if the directory exists or was created
1991
+ */
1992
+ function _dirCheck($p_dir)
1993
+ {
1994
+ clearstatcache();
1995
+ if ((@is_dir($p_dir)) || ($p_dir == ''))
1996
+ return true;
1997
+
1998
+ $p_parent_dir = dirname($p_dir);
1999
+
2000
+ if (($p_parent_dir != $p_dir) &&
2001
+ ($p_parent_dir != '') &&
2002
+ (!$this->_dirCheck($p_parent_dir)))
2003
+ return false;
2004
+
2005
+ if (!@mkdir($p_dir, 0777)) {
2006
+ $this->_error("Unable to create directory '$p_dir'");
2007
+ return false;
2008
+ }
2009
+
2010
+ return true;
2011
+ }
2012
+
2013
+ // }}}
2014
+
2015
+ // {{{ _pathReduction()
2016
+
2017
+ /**
2018
+ * Compress path by changing for example "/dir/foo/../bar" to "/dir/bar",
2019
+ * rand emove double slashes.
2020
+ *
2021
+ * @param string $p_dir path to reduce
2022
+ *
2023
+ * @return string reduced path
2024
+ *
2025
+ * @access private
2026
+ *
2027
+ */
2028
+ function _pathReduction($p_dir)
2029
+ {
2030
+ $v_result = '';
2031
+
2032
+ // ----- Look for not empty path
2033
+ if ($p_dir != '') {
2034
+ // ----- Explode path by directory names
2035
+ $v_list = explode('/', $p_dir);
2036
+
2037
+ // ----- Study directories from last to first
2038
+ for ($i=sizeof($v_list)-1; $i>=0; $i--) {
2039
+ // ----- Look for current path
2040
+ if ($v_list[$i] == ".") {
2041
+ // ----- Ignore this directory
2042
+ // Should be the first $i=0, but no check is done
2043
+ }
2044
+ else if ($v_list[$i] == "..") {
2045
+ // ----- Ignore it and ignore the $i-1
2046
+ $i--;
2047
+ }
2048
+ else if ( ($v_list[$i] == '')
2049
+ && ($i!=(sizeof($v_list)-1))
2050
+ && ($i!=0)) {
2051
+ // ----- Ignore only the double '//' in path,
2052
+ // but not the first and last /
2053
+ } else {
2054
+ $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?'/'
2055
+ .$v_result:'');
2056
+ }
2057
+ }
2058
+ }
2059
+ $v_result = strtr($v_result, '\\', '/');
2060
+ return $v_result;
2061
+ }
2062
+
2063
+ // }}}
2064
+
2065
+ // {{{ _translateWinPath()
2066
+ function _translateWinPath($p_path, $p_remove_disk_letter=true)
2067
+ {
2068
+ if (defined('OS_WINDOWS') && OS_WINDOWS) {
2069
+ // ----- Look for potential disk letter
2070
+ if ( ($p_remove_disk_letter)
2071
+ && (($v_position = strpos($p_path, ':')) != false)) {
2072
+ $p_path = substr($p_path, $v_position+1);
2073
+ }
2074
+ // ----- Change potential windows directory separator
2075
+ if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
2076
+ $p_path = strtr($p_path, '\\', '/');
2077
+ }
2078
+ }
2079
+ return $p_path;
2080
+ }
2081
+ // }}}
2082
+
2083
+ }
2084
+ ?>
restore/XCloner.php ADDED
@@ -0,0 +1,1369 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * XCloner.php
4
+ *
5
+ * Copyright 2011 Ovidiu Liuta <info@thinkovi.com>
6
+ *
7
+ * This program is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License
18
+ * along with this program; if not, write to the Free Software
19
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
+ * MA 02110-1301, USA.
21
+ */
22
+
23
+ if(@is_file("../cloner.config.php")){
24
+
25
+ echo "<h3>Access denied, if you are trying to restore a backup, please move the restore script in another directory!</h3>";
26
+
27
+ exit;
28
+
29
+ }
30
+
31
+
32
+ @set_time_limit(3600);
33
+
34
+ @ini_set("error_reporting", E_ALL^E_NOTICE);
35
+
36
+ ###################### Do not edit Below #############################
37
+
38
+ $g_pcltar_lib_dir = "./";
39
+
40
+ require "TAR.php";
41
+
42
+ $_CONFIG['my_version'] = "3.0.1";
43
+ $_CONFIG['script_name'] = "XCloner.php";
44
+ $_CONFIG['sql_usefile'] = "";
45
+ $_CONFIG['filesLimit'] = 100;
46
+ $_CONFIG['seek'] = 0;
47
+
48
+
49
+ if(isset($_REQUEST['sql_setfile']))
50
+ $_CONFIG['sql_usefile'] = $_REQUEST['sql_setfile'];
51
+
52
+ if(trim($_CONFIG['sql_usefile']) == "")
53
+ $_CONFIG['sql_usefile'] = "database-sql.sql";
54
+
55
+ if(isset($_REQUEST['strrep'])){
56
+ setcookie ("strrep_c", "", time() - 3600);
57
+ setcookie("strrep_c", str_replace("\r\n","*-*",stripslashes($_REQUEST['strrep'])), time()+3600); /* expire in 1 hour */
58
+ }else{
59
+ $_REQUEST['strrep'] = str_replace("*-*", "\r\n", $_COOKIE['strrep_c']);
60
+ }
61
+
62
+
63
+ if ($handle = opendir('./')) {
64
+ /* This is the correct way to loop over the directory. */
65
+ while (false !== ($file = readdir($handle))){
66
+ $ext = substr($file,strlen($file)-4,strlen($file));
67
+ if(($file!='XCloner.php')&&($file!='..')&&($file!='.')&&(($ext=='.tgz')||($ext=='.tar'))){
68
+ $_CONFIG[versions][] = $file;
69
+ }
70
+ }
71
+ closedir($handle);
72
+ }else{
73
+ echo "Unable to open my directory for reading and listing!";exit;
74
+ }
75
+
76
+
77
+ ######################################################################
78
+
79
+
80
+ $_CONFIG['output_path'] = $_REQUEST['output_path'];
81
+ $_CONFIG['output_url'] = $_REQUEST['output_url_pref']."://".$_REQUEST['output_url'];
82
+ $_REQUEST['output_url'] = str_replace("/###","",$_REQUEST['output_url']."###");
83
+ $_REQUEST['output_url'] = str_replace("###","",$_REQUEST['output_url']);
84
+
85
+ if(function_exists('filter_var')){
86
+ $_CONFIG['output_url'] = filter_var($_CONFIG['output_url'], FILTER_SANITIZE_URL);
87
+ }
88
+ $_CONFIG['tmp'] = $_REQUEST['output_path'];
89
+
90
+
91
+ if($_REQUEST['files_skip'] == 1)
92
+ $_REQUEST['do_database'] = 1;
93
+ if($_REQUEST['fpos'])
94
+ $_CONFIG['seek'] = $_REQUEST['fpos'];
95
+
96
+ $filepath =$_SERVER["SCRIPT_FILENAME"];
97
+ $pathinfo = pathinfo($filepath);
98
+ $startscript = $pathinfo['dirname'];
99
+ $_CONFIG[group] = $groupinfo[name];
100
+ $_CONFIG[owner] =$ownerinfo[name];
101
+
102
+ ###################### FRONT AREA ###################################
103
+ //setCache();
104
+ ?>
105
+
106
+ <!DOCTYPE html>
107
+
108
+ <html>
109
+ <head>
110
+ <title>XCloner Restore - <?php echo $_SERVER['HTTP_HOST']?> - Backup and Restore Made Easy</title>
111
+ <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
112
+ <link REL="SHORTCUT ICON" HREF="http://www.xcloner.com/images/favicon.ico">
113
+ <style type="text/css" media="screen">
114
+ @import url( http://www.xcloner.com/downloads/style.css );
115
+ @import url( http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/themes/start/jquery-ui.css );
116
+ .error {
117
+ color: red;
118
+ font-size: 15px;
119
+ }
120
+ </style>
121
+
122
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" type="text/javascript"></script>
123
+ <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js" type="text/javascript"></script>
124
+ </head>
125
+
126
+ <body>
127
+
128
+ <script>
129
+ $(function() {
130
+ $( "#tabs-main" ).tabs();
131
+ });
132
+ </script>
133
+
134
+
135
+ <!-- section 1-->
136
+
137
+ <table align='center' width='700' bgcolor='#eeeeee' style='padding: 0 5px 0 5px;'>
138
+
139
+ <tr><td align='center'><h2><font color=red>XCloner</font> Automatic Restore! - <?php echo $_SERVER['HTTP_HOST']?></h2></td></tr>
140
+
141
+ <tr><td align='left'>
142
+
143
+ <form action='' method='GET' name='form'>
144
+
145
+ <?php
146
+
147
+
148
+
149
+ switch ($_REQUEST[task]) {
150
+ case 'step2':
151
+ step2();
152
+ break;
153
+ case 'step1':
154
+ step1();
155
+ break;
156
+ case 'getinfo':
157
+ getPHPINFO();
158
+ break;
159
+ case 'info':
160
+ echo phpinfo();
161
+ break;
162
+ default :
163
+ start();
164
+ break;
165
+ }
166
+
167
+ ?>
168
+
169
+ </form>
170
+ </td></tr>
171
+ <tr><td>
172
+ <hr />
173
+ <small>XCloner Automatic Restore(<b><?php echo $_CONFIG['my_version']?></b>) - <a href='http://www.xcloner.com' title='XCloner.com - Website Backup Application'>Website Backup and Restore</a>
174
+ </small>
175
+ </td></tr>
176
+ </table>
177
+
178
+ </body>
179
+
180
+ </html>
181
+
182
+
183
+
184
+
185
+
186
+ <?php
187
+
188
+ #####################################################################
189
+
190
+
191
+ ##################### FUNCTIONS #####################################
192
+
193
+ function step2($file=""){
194
+
195
+ global $_CONFIG,$filepath ;
196
+
197
+ $DBcreated = $_REQUEST[DBcreated];
198
+
199
+ if ($DBcreated=='on'){
200
+ $DBhostname = $_REQUEST['mysql_server'];
201
+ $DBuserName = $_REQUEST['mysql_username'];
202
+ $DBpassword = $_REQUEST['mysql_pass'];
203
+ $DBname = $_REQUEST['mysql_db'];
204
+
205
+ $db = @mysql_connect($DBhostname, $DBuserName, $DBpassword) or die("<br />The database details provided are incorrect and/or empty. Unable to connect to mysql server");
206
+ @mysql_query("CREATE database $DBname;");
207
+ if (!@mysql_select_db($DBname)) {
208
+ die("<br /><span class='error'>Could not connect to $DBname database! Please make sure the database exists and that you assigned the mysql user to it...</span>");
209
+ }
210
+ mysql_query("SET sql_mode='';");
211
+ if($_REQUEST['charset_of_file']!="")
212
+ mysql_query("SET NAMES ".$_REQUEST['charset_of_file']."");
213
+ else
214
+ mysql_query("SET NAMES utf8;");
215
+ }
216
+
217
+ if($_REQUEST['do_database'] != 1){
218
+
219
+ ############ DATABASE ONLY RESTRICTION##################################################
220
+
221
+ ########################### START FTP MODE #################################
222
+ if($_REQUEST[transfer_mode]==2){
223
+
224
+ $_CONFIG[output_path] = $_CONFIG[output_path]."/archive_tmp/";
225
+ @mkdir($_CONFIG[output_path]);
226
+
227
+ // set up basic connection
228
+ $conn_id = @ftp_connect($_REQUEST[ftp_server], $_REQUEST[ftp_port]) or die("<span class='error'>Could not connect to $_REQUEST[ftp_server] on port $_REQUEST[ftp_port]! Ftp connection has failed!</span>");
229
+
230
+ // login with username and password
231
+ $login_result = @ftp_login($conn_id, $_REQUEST[ftp_user], $_REQUEST[ftp_pass]) or die("<span class='error'>Could not login to ftp server for user $_REQUEST[ftp_user] and provided pass! Ftp connection has failed!</span>");
232
+
233
+ // check connection
234
+ if ((!$conn_id) || (!$login_result)) {
235
+ echo "<b style='color:red'>FTP connection has failed!</b>";
236
+ echo "<b style='color:red'>Attempted to connect to ".$_REQUEST[ftp_server].":".$_REQUEST[ftp_port]." for user ".$_REQUEST[ftp_user]."</b>";
237
+ return;
238
+ } else {
239
+ echo "<br />Connected to $_REQUEST[ftp_server], for user $_REQUEST[ftp_user], starting transfer...<br />";
240
+ }
241
+ $ftp_dir_original = ftp_pwd($conn_id);
242
+ @ftp_mkdir($conn_id,$_REQUEST[ftp_path]);
243
+
244
+ // try to change the directory to somedir
245
+ if (@ftp_chdir($conn_id, $_REQUEST[ftp_path])) {
246
+ echo "Current directory is now: <b>" . ftp_pwd($conn_id) . "</b>\n";
247
+ } else {
248
+ echo "<b style='color:red'>Couldn't change directory to <b>$_REQUEST[ftp_path]</b>, please verify that the ftp location exists or use the \"Install files directly\" option!</b><br />\n";
249
+ return;
250
+ }
251
+ @ftp_chdir($conn_id, $ftp_dir_original);
252
+
253
+ }
254
+
255
+ ########################## END FTP MODE ######################################
256
+
257
+
258
+ ##### START extract ######
259
+ if($_REQUEST['refresh'] < 1){
260
+
261
+ $ext = substr($file, strlen($file)-4, strlen($file));
262
+ if($_REQUEST['file_utilities'] != '1'){
263
+ $tar_object = new Archive_Tar($file);
264
+
265
+ if($_REQUEST['manual_ftp']){
266
+
267
+ $tar_object->_openRead();
268
+ fseek($tar_object->_file, $_CONFIG['seek']);
269
+ $seek = $tar_object->_extractList($_CONFIG['output_path'], $return, "partial", "", "", $_CONFIG['filesLimit']);
270
+ $seek = $seek - 512;//reverse 512 bytes
271
+ if($seek > 0){
272
+ $backupSize = filesize($file);
273
+ $rurl = rurl($seek, $backupSize);
274
+ $percent = sprintf("%.2f",($seek*100)/$backupSize);
275
+ echo "<h3>Processing files - ".$percent."%</h3>";
276
+ echo "<script> document.location='".$rurl."'</script>";
277
+ return;
278
+ }
279
+ $_REQUEST['fpos'] = 0;
280
+ $_REQUEST['chunk'] = 0;
281
+ }
282
+ else{
283
+ $tar_object->extract($_CONFIG['output_path']);
284
+ #$tar_object->extractList("backups/perm.txt", $_CONFIG['output_path']);
285
+ }
286
+
287
+ }else{
288
+ if($ext == '.tgz') $compress = 'z';
289
+ else $compress = '';
290
+ shell_exec("tar -x".$compress."pf $file -C $_CONFIG[output_path]");
291
+ }
292
+ }
293
+ ##### END extract ######
294
+
295
+
296
+ $new_arr = array();
297
+ #@chmod($_CONFIG[output_path], 0777);
298
+ $tran_file = $_CONFIG[output_path]."/transfer.txt";
299
+
300
+ if($_REQUEST[transfer_mode]==2){
301
+ # initialise list arrays, directories and files separately and array counters for them
302
+ $excludedFolders = array();
303
+ $d_arr = array(); $d = 0;
304
+ $ds_arr = array();
305
+ $f_arr = array(); $f = 0;
306
+ $s_arr = array(); $s = 0;
307
+ $d_arr[$d] = $_CONFIG[output_path];
308
+
309
+ if($_REQUEST['refresh'] < 1){
310
+ # obtain the list of files by recursing the mambo file store
311
+ recurseFiles($d_arr, $ds_arr, $f_arr, $s_arr, $d, $f, $s, $excludedFolders , '', $_CONFIG[output_path]);
312
+ recurseFiles($d_arr, $ds_arr, $f_arr, $s_arr, $d, $f, $s, $d_arr , '', $_CONFIG[output_path]);
313
+ sort($d_arr);
314
+ sort($f_arr);
315
+ $new_arr = array_merge($d_arr, $f_arr);
316
+
317
+ if($_REQUEST[transfer_mode]==2)
318
+ if($fp = fopen($tran_file, "w")){
319
+ foreach($new_arr as $file){
320
+ fwrite($fp, $file."\n");
321
+ }
322
+ fclose($fp);
323
+ }else{
324
+ echo "Unable to write to directory ".$_CONFIG[output_path]."! Please check that this directory is writeable!"; return;
325
+ }
326
+ else{};
327
+
328
+ }else{
329
+ $content = "";
330
+ $new_arr = file($tran_file);
331
+ }
332
+
333
+ if(sizeof($new_arr) != 0 )
334
+ $percn = sprintf("%.2f",($_REQUEST[next] * 100)/sizeof($new_arr));
335
+ if($percn > sizeof($new_arr))
336
+ $percn = sizeof($new_arr);
337
+
338
+ }
339
+
340
+
341
+ if($_REQUEST['refresh'] == 1){
342
+ echo "<h3>Transfering $percn% of ".sizeof($new_arr)." files through ftp</h3>";
343
+ echo "<textarea cols=70 rows=30 name='ftp_list'></textarea>";
344
+ }
345
+ elseif($_REQUEST['refresh'] == 2)
346
+ echo "Files transfer finished!";
347
+
348
+ $i = (int)$_REQUEST[next];
349
+ $j = 0;
350
+
351
+ ### MOVING THE FILES THROUGH FTP
352
+
353
+ #foreach($new_arr as $key=>$file)
354
+ for($key=$i;$key<=sizeof($new_arr);$key++){
355
+ $file = str_replace(array("\r","\n"), array("",""), $new_arr[$key]);
356
+ if($_REQUEST['manual_ftp'] == 1)
357
+ if($j == 100){
358
+ #echo "Transfering files from line: ". (int)$_REQUEST[next];
359
+ $qstr = explode("&refresh=1&next=",$_SERVER['QUERY_STRING']);
360
+ $rurl = "XCloner.php?".$qstr[0]."&refresh=1&next=".($_REQUEST[next]+100);
361
+ ftp_close($conn_id);
362
+ echo "<script> document.location='".$rurl."'</script>";
363
+ exit;
364
+ }
365
+
366
+ $j++;
367
+ $sfile = str_replace($_CONFIG[output_path],"",$file);
368
+ $fsource = $_CONFIG[output_path]."/".$sfile;
369
+ if(($sfile != "")&&($sfile!="/"))
370
+ if($_REQUEST[transfer_mode]==2){
371
+ $upload = 1;
372
+ $ftarget = $_REQUEST[ftp_path]."/".$sfile;
373
+ if(is_dir($fsource)){
374
+ $upload1 = @ftp_mkdir($conn_id,$ftarget);
375
+ }else{
376
+ $upload = ftp_put($conn_id, $ftarget, $fsource, FTP_BINARY);
377
+ }
378
+ #echo "$i <br >";
379
+
380
+ if(!$upload){
381
+ echo "<br /><font color=red>Transfer fail for $fsource to $ftarget</font> <br />File already exists and/or doesn't have writing permissions!<br/>";
382
+ }else{
383
+
384
+ if($_REQUEST['manual_ftp'] == 1){
385
+ $ftarget .= '\n';
386
+
387
+ echo "<script>document.form.ftp_list.value = document.form.ftp_list.value + '".$ftarget."'; </script>";
388
+ #echo "$ftarget <br />\n";
389
+ }
390
+ }
391
+ }
392
+ }
393
+
394
+
395
+ if($_REQUEST['refresh'] == 1){
396
+ $qstr = explode("&refresh=1&next=",$_SERVER['QUERY_STRING']);
397
+ $rurl = "XCloner.php?".$qstr[0]."&refresh=2&next=".($_REQUEST[next]+102);
398
+ echo "<script> document.location='".$rurl."'</script>";
399
+ exit;
400
+ }
401
+
402
+ ############### RESTORING HTACCESS AND CONFIGURATION PERM#####################################
403
+
404
+ if($_REQUEST[transfer_mode]==2){
405
+ $cmd = "CHMOD 0777 ".$_REQUEST[ftp_path]."/"."wp-config.php";
406
+ @ftp_site($conn_id, $cmd);
407
+ }else{
408
+ @chmod($_REQUEST[output_path]."/"."wp-config.php", 0777);
409
+ }
410
+
411
+
412
+ #### CUSTOM PERMISSIONS #####
413
+ if($_REQUEST['preserve_perm']){
414
+ $perm_data = "";
415
+ $perm_file = $_CONFIG[output_path]."/administrator/backups/perm.txt";
416
+ $per = 1;
417
+
418
+ @chmod($perm_file,0777);
419
+ $fp = @fopen($perm_file,'r');
420
+ if($fp){
421
+ while(!feof($fp))
422
+ $perm_data .= fread($fp, 1024);
423
+ fclose($fp);
424
+ }else{
425
+
426
+ echo "Could not set permissions! Permissions file $perm_file not found!<br />";
427
+ $per = 0;
428
+ }
429
+
430
+ $data = explode("\n",$perm_data);
431
+ foreach($data as $value){
432
+ $dir = explode("|", $value);
433
+ if($dir[1]=="")
434
+ $dir[1] = '0755';
435
+
436
+ if(strstr($dir[0],"wp-config.php"))
437
+ $dir[1] = '0777';
438
+
439
+ if($_REQUEST[transfer_mode]==2){
440
+ $cmd = "CHMOD ".$dir[1]." ".$_REQUEST[ftp_path]."/".$dir[0];
441
+
442
+ @ftp_site($conn_id, $cmd);
443
+
444
+ }else{
445
+
446
+ @chmod($_CONFIG[output_path]."/".$dir[0], octdec($dir[1]));
447
+
448
+ }
449
+
450
+ }
451
+
452
+ if($per){
453
+ echo "<h2>Permissions restored to their initial value...</h2>";
454
+ }
455
+
456
+ }
457
+ #### END CUSTOM PERMISSIONS #####
458
+
459
+ $_CONFIG[output_path] = str_replace("/archive_tmp/","",$_CONFIG[output_path]);
460
+
461
+ if($_REQUEST[transfer_mode]==2){
462
+
463
+ // close the FTP stream
464
+ @ftp_close($conn_id);
465
+ recursive_remove_directory($_CONFIG[output_path]."/archive_tmp/");
466
+ @unlink($_CONFIG[output_path]."/archive_tmp/");
467
+ echo "<h2>Files succesfully copied to ".$_REQUEST[ftp_path]." on $_REQUEST[ftp_server] using FTP</h2>";
468
+
469
+ }else{
470
+ echo "<h2>Files succesfully copied to ".$_CONFIG[output_path]."</h2>";
471
+ }
472
+
473
+ ######### END DATABASE ONLY RESTRICT #########################################
474
+
475
+ }
476
+
477
+
478
+ ##### RESTORE CONFIGURATION #####
479
+ $update_config = 1;
480
+
481
+ if(($_REQUEST['files_skip']) and (isset($_REQUEST['fpos']))){
482
+
483
+ $update_config = 0;
484
+
485
+ }
486
+
487
+ if(($_REQUEST['do_database'] != 1) || ($_REQUEST['files_skip'] == 1)){
488
+ $config_file = $_CONFIG[output_path]."/wp-config.php";
489
+ @chmod($config_file,0777);
490
+ @unlink($_CONFIG[output_path]."/administrator/backups/perm.txt");
491
+ if(($_CONFIG['sql_usefile'] == "database-sql.sql") and ($update_config))
492
+ if(write_config($config_file)){
493
+ echo "<H2>Configuration updated!</H2>";
494
+ }else{
495
+ echo "<span class='error'>Unable to write to configuration file $config_file... Aborting...</span>";return;
496
+ }
497
+ }
498
+
499
+
500
+ ############ ATTEMPT DATABASE INSERT #####################################
501
+
502
+ if($DBcreated!='on'){
503
+
504
+ echo "<h2>Database import skipped!</h2>";
505
+ echo "<a href='".$_CONFIG[output_url]."'><b>All should be done! Click here to continue...</b></a><br />";
506
+
507
+ return ;
508
+ }
509
+
510
+ if (($DBcreated=='on')&&($_REQUEST['do_database'] == 1)){
511
+
512
+ $sqlfile = $_CONFIG[output_path]."/administrator/backups/".$_CONFIG['sql_usefile'];
513
+
514
+ if(!file_exists($sqlfile)){
515
+ echo "<span class='error'>Unable to read the database backup file $sqlfile , database was not imported!</span>";
516
+ }else{
517
+
518
+ if($_REQUEST['manual_sql'])
519
+ $errors = populate_db_manual( $db, $sqlfile);
520
+ else
521
+ $errors = populate_db( $db, $sqlfile);
522
+
523
+ if(sizeof($errors)>0){
524
+
525
+ echo "There were some errors while importing the database:<br />";
526
+ echo "<textarea cols=60 rows=30>".implode("\n",$errors)."</textarea>";
527
+ exit;
528
+ }else{
529
+
530
+ @unlink($_CONFIG[output_path]."/administrator/backups/".$_CONFIG['sql_usefile']);
531
+
532
+ }
533
+
534
+ echo "<h2>Database populated...</h2>";
535
+
536
+ }
537
+ }
538
+
539
+ ###################################################################################
540
+
541
+ if($_REQUEST['do_database'] != 1) {
542
+
543
+ $vars = "";
544
+ foreach($_REQUEST as $key=>$value)
545
+ $vars .= $key.'='.@urlencode($value).'&';
546
+
547
+ #$href = "XCloner.php?".$vars."do_database=1";
548
+ $href = rurl()."&do_database=1";
549
+ echo "<br /><a href='$href'>Please click here to continue with database import...</a>";
550
+
551
+ return;
552
+
553
+ }else{
554
+
555
+ echo "<br /><a href='".$_CONFIG[output_url]."'><b>All should be done! Click here to continue...<br /></a><br />";
556
+ return ;
557
+ }
558
+
559
+ }
560
+
561
+ function write_config($file){
562
+
563
+ global $_CONFIG;
564
+
565
+ if(@$fp = fopen($file, "r")){
566
+ $config_data = "";
567
+ while(!feof($fp))
568
+ $config_data .= fread($fp, 1024);
569
+ fclose($fp);
570
+ }
571
+
572
+ if ($_REQUEST[DBcreated] == 'on'){
573
+
574
+ $config_data = str_replace("define('DB_HOST', '", "define('DB_HOST', '".$_REQUEST[mysql_server]."');#", $config_data);
575
+ $config_data = str_replace("define('DB_USER', '", "define('DB_USER', '".$_REQUEST[mysql_username]."');#", $config_data);
576
+ $config_data = str_replace("define('DB_PASSWORD', '", "define('DB_PASSWORD', '".$_REQUEST[mysql_pass]."');#", $config_data);
577
+ $config_data = str_replace("define('DB_NAME', '", "define('DB_NAME', '".$_REQUEST[mysql_db]."');#", $config_data);
578
+ $liveurl = $_CONFIG['output_url'];
579
+ $config_data = str_replace("define('DB_HOST", "define('WP_SITEURL','".$liveurl."');\ndefine('WP_HOME','".$liveurl."');\ndefine('RELOCATE',true);\ndefine('DB_HOST", $config_data);
580
+
581
+ $config_data = str_replace("define('WP_SITEURL', '", "define('WP_SITEURL', '".$liveurl."');#", $config_data);
582
+ $config_data = str_replace("define('WP_HOME', '", "define('WP_HOME', '".$liveurl."');#", $config_data);
583
+ }
584
+
585
+ if($_REQUEST['transfer_mode'] == 2){
586
+ $config_data = str_replace('$'.'ftp_host =',"$"."ftp_host ='".$_REQUEST[ftp_server]."';#", $config_data);
587
+ $config_data = str_replace('$'.'ftp_port =',"$"."ftp_port ='".$_REQUEST[ftp_port]."';#", $config_data);
588
+ $config_data = str_replace('$'.'ftp_user =',"$"."ftp_user ='".$_REQUEST[ftp_user]."';#", $config_data);
589
+ $config_data = str_replace('$'.'ftp_pass =',"$"."ftp_pass ='".$_REQUEST[ftp_pass]."';#", $config_data);
590
+ $config_data = str_replace('$'.'ftp_root =',"$"."ftp_root ='".$_REQUEST[ftp_path]."';#", $config_data);
591
+ }else{
592
+ $config_data = str_replace('$'.'ftp_enable =',"$"."ftp_enable ='0';#", $config_data);
593
+ }
594
+
595
+
596
+ $config_data = str_replace('$'.'live_site =',"$"."live_site ='".$_CONFIG['output_url']."';#", $config_data);
597
+ $config_data = str_replace('$'.'absolute_path =',"$"."absolute_path ='".$_CONFIG['output_path']."';#", $config_data);
598
+
599
+ if ($fp = fopen($file, "w")) {
600
+ fwrite( $fp, $config_data);
601
+ fclose( $fp );
602
+ } else {
603
+ return false;
604
+ } // if
605
+ return true;
606
+ }
607
+
608
+
609
+ function step1(){
610
+
611
+ global $_CONFIG;
612
+
613
+ $ftarget = $_CONFIG[output_path]."/".$_REQUEST[ver];
614
+
615
+ if($_REQUEST['refresh'] < 1)
616
+
617
+ if(!is_writable($_CONFIG[output_path])){
618
+
619
+ echo "<span class='error'>Directory ".$_CONFIG[output_path]." is not writeable or does not exists! Could not continue...</span>";
620
+
621
+ return ;
622
+
623
+ }
624
+
625
+
626
+
627
+ $ftarget = $_REQUEST[ver];
628
+
629
+
630
+ if((!file_exists($ftarget)) and (!$_REQUEST['files_skip'])){
631
+ echo "<span class='error'>Could not continue, unable to read the clone backup file! Please make sure you copied the backup in the same directory as XCloner.php </span>";
632
+ return;
633
+ }
634
+
635
+ step2($ftarget);
636
+
637
+ return;
638
+
639
+ }
640
+
641
+
642
+
643
+ function start() {
644
+
645
+ global $_CONFIG,$pathinfo;
646
+
647
+ $pdir = str_replace($_CONFIG['script_name'], "", $_SERVER["SCRIPT_FILENAME"]);
648
+
649
+ $purl = $_SERVER['HTTP_HOST'].str_replace("/".$_CONFIG['script_name'],"", $_SERVER['SCRIPT_NAME']);
650
+
651
+ ?>
652
+
653
+
654
+ <script>
655
+ $(function() {
656
+ $( "#DBcreated" ).button();
657
+ $( "#phpinfo").button();
658
+ $( "#manual_sql" ).button();
659
+ $( "#transfer_mode-ftp" ).button();
660
+ $( "#transfer_mode-direct" ).button();
661
+ $( "input:submit", ".form" ).button();
662
+ });
663
+ $(function() {
664
+ $( "#tabs" ).tabs();
665
+ $( "#tabs2" ).tabs();
666
+ });
667
+ </script>
668
+
669
+
670
+ <!-- section 1-->
671
+ <div id="tabs2">
672
+ <ul>
673
+ <li><a href="#tabs2-1">New Path & Url Configuration</a></li>
674
+ </ul>
675
+ <div id="tabs2-1">
676
+ <table class="adminForm">
677
+
678
+ <tr><td nowrap>
679
+ 1. Install directory: (server path where you want to restore your backup)<br />
680
+ <input type=text size=80 name='output_path' value='<?php echo str_replace("\\", "/", $pdir);?>'><br >
681
+
682
+ </td></tr>
683
+ <tr><td>
684
+ <br />2.Install Url: (the url correspondent of your Install directory:)<br />
685
+ <div style="display:inline">
686
+ <div style="float:left">
687
+ <select name='output_url_pref'>
688
+ <option selected value='http'>http://</option>
689
+ <option value='https'>https://</option>
690
+ </select>
691
+ </div>
692
+ <div style="float:left">
693
+ <input type=text size=65 name='output_url' value='<?php echo $purl?>'>
694
+ </div>
695
+ </div>
696
+
697
+ </td></tr>
698
+ <tr><td>
699
+ <br />3. Choose backup archive to restore:
700
+ <?php echo version_list('ver');?>
701
+ </td></tr>
702
+ </table>
703
+ </div>
704
+ </div>
705
+ <!-- end section 1-->
706
+
707
+ <div id="tabs">
708
+ <ul>
709
+ <li><a href="#tabs-1">New Mysql Configuration</a></li>
710
+ <li><a href="#tabs-2">File Restore Options</a></li>
711
+ </ul>
712
+
713
+ <div id="tabs-1">
714
+ <!--start tabs 1 -->
715
+ <table width="100%">
716
+ <tr><td>
717
+ <!--<h3><a href="#">Mysql configuration: </a></h3>-->
718
+ <input type=checkbox checked name='DBcreated' id="DBcreated"> <label for="DBcreated">Import mysql database</label>
719
+ <input type='checkbox' value='1' name='manual_sql' checked id="manual_sql"> <label for="manual_sql">Incremental sql import</label>
720
+ </td></tr>
721
+ <tr><td>
722
+ <!-- mysql details -->
723
+ <table width='100%'>
724
+ <tr>
725
+ <td nowrap>Mysql server:</td>
726
+ <td><input type=text size=40 name='mysql_server' value='localhost'></td>
727
+ <tr>
728
+ <td>Mysql username:</td>
729
+ <td><input type=text size=40 name='mysql_username' value=''></td>
730
+ </tr>
731
+ <tr>
732
+ <td>Mysql password:</td>
733
+ <td><input type=text size=40 name='mysql_pass' value=''></td>
734
+ </tr>
735
+ <tr>
736
+ <td>Mysql database:</td>
737
+ <td><input type=text size=40 name='mysql_db' value=''></td>
738
+ </tr>
739
+ <tr>
740
+ <td>Data encoding:</td>
741
+ <td>
742
+ <select name="charset_of_file">
743
+
744
+ <option value="" selected="selected">Default</option>
745
+ <option value="big5" title="Big5 Traditional Chinese">big5</option>
746
+ <option value="binary" title="Binary pseudo charset">binary</option>
747
+ <option value="cp1250" title="Windows Central European">cp1250</option>
748
+ <option value="cp932" title="SJIS for Windows Japanese">cp932</option>
749
+ <option value="euckr" title="EUC-KR Korean">euckr</option>
750
+
751
+ <option value="gb2312" title="GB2312 Simplified Chinese">gb2312</option>
752
+ <option value="gbk" title="GBK Simplified Chinese">gbk</option>
753
+ <option value="latin1" title="cp1252 West European">latin1</option>
754
+ <option value="latin2" title="ISO 8859-2 Central European">latin2</option>
755
+ <option value="sjis" title="Shift-JIS Japanese">sjis</option>
756
+ <option value="tis620" title="TIS620 Thai">tis620</option>
757
+
758
+ <option value="ucs2" title="UCS-2 Unicode">ucs2</option>
759
+ <option value="ujis" title="EUC-JP Japanese">ujis</option>
760
+ <option value="utf8" title="UTF-8 Unicode" >utf8</option>
761
+ </select>
762
+ </td>
763
+ </tr>
764
+
765
+ <?php
766
+ $dir = "administrator/backups/";
767
+ $sql_files =array();
768
+ if(@is_dir($dir)){
769
+ if ($handle = @opendir($dir)) {
770
+ /* This is the correct way to loop over the directory. */
771
+ while (false !== ($file = @readdir($handle))) {
772
+ if(strstr($file, ".sql"))
773
+ $sql_files[] = $file;
774
+ }
775
+ @closedir($handle);
776
+ }
777
+
778
+ if(sizeof($sql_files) > 0) {
779
+ $list = "";
780
+ for($i=0;$i<sizeof($sql_files);$i++){
781
+ $list .= "<option value='$sql_files[$i]'>$sql_files[$i]</option>";
782
+ }
783
+
784
+ echo "<tr><td>Import Mysql file:</td>
785
+ <td><select name='sql_setfile'><option value='database-sql.sql'>Default</option>$list</select></td> </tr>";
786
+ }
787
+ }
788
+ ?>
789
+ </table>
790
+ </tr></td>
791
+ <!-- end mysql details -->
792
+ </table>
793
+ <!--end tabs 1 -->
794
+ </div>
795
+
796
+ <div id="tabs-2">
797
+ <!-- start tabs 2 -->
798
+ <table width="100%">
799
+ <tr bgcolor='#dddddd'><td>
800
+ <!--<h3><a href="#">Files transfer and configuration:</a></h3>-->
801
+ <input type=checkbox name='files_skip' value='1' > <font color='red'>Skip files restore</font><br />
802
+ <input type=checkbox name='preserve_perm' value='1'> Restore files permissions<br />
803
+ <input type=checkbox name='file_utilities' value='1' > Restore by using the server utilities(tar) <br />
804
+ <input type='checkbox' value='1' name='manual_ftp' checked> Incremental transfer
805
+ </td></tr>
806
+
807
+ <tr><td colspan=2>
808
+
809
+ <table width='100%'>
810
+ <tr><td colspan='2'>
811
+ <label for="transfer_mode-ftp">Install files throught ftp:</label>
812
+ <input type=radio name=transfer_mode value=2 id="transfer_mode-ftp">
813
+ <!--<small>this will attempt to transfer all files through ftp, so the owner keep it's permissions, can be used to send files to other hosts also, <font color=red>*recommended</font></small>-->
814
+ <label for="transfer_mode-direct">Install files directly</label>
815
+ <input type=radio name=transfer_mode value=1 checked id="transfer_mode-direct"><br />
816
+ <!--<small>transfering the files directly will cause some permissions problems in some cases, but it's faster than the other option </small>-->
817
+ </td></tr>
818
+ <tr>
819
+ <td valign="top" nowrap>Ftp server:</td>
820
+ <td><input type=text size=30 name='ftp_server' value='localhost'> : <input type=text size=3 name='ftp_port' value='21'></td>
821
+ </tr>
822
+ <tr>
823
+ <td valign="top">Ftp username:</td>
824
+ <td><input type=text size=30 name='ftp_user'></td>
825
+ </tr>
826
+ <tr>
827
+ <td valign="top">Ftp password:</td>
828
+ <td><input type=text size=30 name='ftp_pass'></td>
829
+ </tr>
830
+ <tr>
831
+ <td valign="top">Ftp upload path:</td>
832
+ <td><input type=text size=30 name='ftp_path'>
833
+ <br><small>ftp root path of where the backup will be restored</small>
834
+ </td>
835
+ </tr>
836
+ </table>
837
+
838
+ </td></tr>
839
+ </table>
840
+ <!--end tabs 2-->
841
+ </div>
842
+ </div>
843
+
844
+ <br />
845
+ <div class="form">
846
+ <input type=hidden name='task' value='step1'>
847
+ <input type=submit name=submit value='Start install' >
848
+ <button onclick="window.open('XCloner.php?task=getinfo', 'getInfo', 'toolbar,width=750,height=400'); return false;" id="phpinfo">phpinfo()</button>
849
+ </div>
850
+ <small>*after hitting submit please wait for the package to get unarchived and transfered through ftp if it is the case!</small>
851
+
852
+ <br />
853
+ <span class="ui-state-highlight">
854
+ <span style='color:red'>Security Note:</span> After restore <b>delete the XCloner.php</b> script from your server</span>
855
+ </span>
856
+
857
+ <?php
858
+
859
+ }
860
+
861
+ function getPHPINFO(){
862
+
863
+ ?>
864
+
865
+ <table width='100%'>
866
+ <tr bgcolor='#dddddd'><td>
867
+ <b>PHP Configuration: <a target='_blank' href='XCloner.php?task=info'> phpinfo()</a></b>
868
+ </td></tr>
869
+
870
+ <tr><td>
871
+ <table bgcolor='#dddddd' width='65%' style='text-align:center;' border='1'>
872
+ <tr>
873
+ <td><b style='color:red'>PHP Setting</b></td>
874
+ <td><b style='color:orange'>Current Value</b></td>
875
+ <td><b style='color:green'>Recomemnded</b></td>
876
+ </tr>
877
+ <tr>
878
+ <td><b>Open_Basedir:</b> </td>
879
+ <td>
880
+ <?php echo (@ini_get('open_basedir') ? @ini_get('open_basedir') : 'No value')?>
881
+ </td>
882
+ <td><b>No Value</b></td>
883
+ </tr>
884
+ <tr>
885
+ <td><b>Max Execution Time:</b> </td>
886
+ <td>
887
+ <?php echo (@ini_get('max_execution_time') ? @ini_get('max_execution_time') : 'No value')?>
888
+ </td>
889
+ <td><b>>30</b></td>
890
+ </tr>
891
+ <tr>
892
+ <td><b>Safe mode:</b> </td>
893
+ <td>
894
+ <?php echo (@ini_get('safe_mode') ? @ini_get('safe_mode') : 'Off')?>
895
+ </td>
896
+ <td><b>Off</b></td>
897
+ </tr>
898
+ </table>
899
+ </td></tr>
900
+ </table>
901
+
902
+ <?php
903
+ }
904
+
905
+
906
+ ###END
907
+
908
+
909
+ ###Starting the manual sql backup
910
+
911
+ function populate_db_manual( $db, $sqlfile='administrator/backups/database-sql.sql'){
912
+
913
+ global $qstr;
914
+
915
+ $extra_que = $qstr[0];
916
+
917
+ $file = $sqlfile;
918
+
919
+ define ('DATA_CHUNK_LENGTH',16384); // How many chars are read per time
920
+
921
+ define ('MAX_QUERY_LINES',300); // How many lines may be considered to be one query (except text lines)
922
+
923
+ $lines = "";
924
+
925
+ $error = "";
926
+
927
+ $error_status = 0;
928
+
929
+ if((isset($_REQUEST['chunk']))&&((int)$_REQUEST['chunk'] != 0))
930
+
931
+ $chunk = $_REQUEST['chunk'];
932
+
933
+ else
934
+
935
+ $chunk = DATA_CHUNK_LENGTH;
936
+
937
+ if($_REQUEST['correct_query'] != 1){
938
+
939
+ $start_pos = (int)$_REQUEST['fpos'];
940
+
941
+ $fpos = read_file($file, MAX_QUERY_LINES, $start_pos, $chunk, $lines);
942
+
943
+ }else{
944
+
945
+ $lines[0] = stripslashes($_REQUEST['error_msg']);
946
+
947
+ $fpos = $_REQUEST['start_posf'] ;
948
+
949
+ }
950
+
951
+ foreach($lines as $line)
952
+
953
+ if(trim($line) != ''){
954
+
955
+ $query = $line;
956
+
957
+ $line = $line .";\n";
958
+
959
+ #$tmp = explode("DEFAULT CHARSET",$line);
960
+
961
+ $line_tmp = $line;
962
+
963
+ $start_pos = $start_pos + strlen($line);
964
+
965
+ if(isset($_REQUEST['strrep']))
966
+
967
+ {
968
+
969
+ $strrep = explode("\r\n", stripslashes($_REQUEST['strrep']));
970
+
971
+ foreach($strrep as $value)
972
+
973
+ if(trim($value)!= ""){
974
+
975
+
976
+ $tmp = explode("|", $value);
977
+
978
+
979
+ $line_tmp = str_replace(trim($tmp[0]),trim($tmp[1]),$line_tmp);
980
+
981
+ $query = str_replace(trim($tmp[0]),trim($tmp[1]),$query);
982
+
983
+ }
984
+
985
+ }
986
+
987
+ if(!mysql_query($line_tmp)){
988
+
989
+ if($_REQUEST['correct_query'] != 1)
990
+
991
+ $fpos = $start_pos ;
992
+
993
+ $form_url = rurl($fpos, $chunk);
994
+
995
+ echo "</form><form name='' action='".$form_url."' method='POST'>
996
+
997
+ <input type='hidden' name='correct_query' value = '1'>
998
+
999
+ <input type='hidden' name='start_pos' value='".$start_pos."'>
1000
+
1001
+ <input type='hidden' name='start_posf' value='".$fpos."'>
1002
+
1003
+ <input type='hidden' name='glen' value='".$qlen."'>
1004
+
1005
+ <center>";
1006
+
1007
+ echo sprintf("<b>###MYSQL error</b>\n<br /><font color='red'>".mysql_error()."</font><br />\n<b>###On Query:</b><br />\n<br /><textarea cols=70 rows=15 name='error_msg'>%s</textarea><br />", $query);
1008
+
1009
+ echo "<b>Search and replace in query:</b><br /><textarea cols=70 rows=5 name='strrep'>".stripslashes($_REQUEST[strrep])."</textarea><br />
1010
+
1011
+ <small>
1012
+
1013
+ enter a string, one per line, which you would like to replace in the query above, example <i>string_to_search|text_to_replace_with</i>
1014
+
1015
+ </small>";
1016
+
1017
+ echo "<br /> <input type=submit name=submit value='Correct Query &gt;&gt;'>";
1018
+
1019
+ echo "</center></form>";
1020
+
1021
+ $error_status = 1;
1022
+
1023
+ break;
1024
+
1025
+ }
1026
+
1027
+ }
1028
+
1029
+
1030
+ $percent = sprintf("%.2f", (100*$fpos)/ filesize($file));
1031
+
1032
+ if($fpos!='-1'){
1033
+
1034
+ echo "<h3>Processed $percent% from sql backup!</h3>";
1035
+
1036
+ $red_url = rurl($fpos, $chunk);
1037
+
1038
+ if($error_status == 1 ){
1039
+
1040
+ echo "<h3><a href='".$red_url."'>To skip this query, click here to Continue</a></h3>";
1041
+
1042
+ exit;
1043
+
1044
+ }else{
1045
+
1046
+ echo "<h3><a href='".$red_url."'>Continue here</a></h3>";
1047
+
1048
+ echo "<script>window.location='".$red_url."'</script>";
1049
+
1050
+ exit;
1051
+
1052
+ }
1053
+
1054
+ } else {
1055
+
1056
+ echo "<h3>The sql import is finished!</h3>";
1057
+
1058
+ }
1059
+
1060
+ return;
1061
+
1062
+ }
1063
+
1064
+ ########END
1065
+
1066
+
1067
+
1068
+ ### STARTING THE AUTOMATIC BACKUP
1069
+
1070
+ function populate_db( $db, $sqlfile='administrator/backups/database-sql.sql') {
1071
+
1072
+ global $errors, $_CONFIG;
1073
+
1074
+ if($_REQUEST['use_mysqldump'] == 1){
1075
+ echo shell_exec($_REQUEST['mysqldump_path']." -u ".$_REQUEST[mysql_username]." -p".$_REQUEST[mysql_pass]." -h ".$_REQUEST[mysql_server]." ".$_REQUEST[mysql_db]." < ".$sqlfile);
1076
+ return;
1077
+ }
1078
+
1079
+ $mqr = @get_magic_quotes_runtime();
1080
+
1081
+ @set_magic_quotes_runtime(0);
1082
+
1083
+ @chmod($sqlfile,0777);
1084
+
1085
+ $query = fread( fopen( $sqlfile, 'r' ), filesize( $sqlfile ) );
1086
+
1087
+ @set_magic_quotes_runtime($mqr);
1088
+
1089
+ $pieces = split_sql($query);
1090
+
1091
+
1092
+
1093
+ for ($i=0; $i<count($pieces); $i++) {
1094
+
1095
+ $pieces[$i] = trim($pieces[$i]);
1096
+
1097
+ $tmp = explode("DEFAULT CHARSET",$pieces[$i]);
1098
+
1099
+ $pieces[$i] = $tmp[0].";";
1100
+
1101
+ if(!empty($pieces[$i]) && $pieces[$i] != "#") {
1102
+
1103
+ if (!mysql_query($pieces[$i], $db)) {
1104
+
1105
+ $errors[] = "\n\n##Mysql Query: \n########\n".
1106
+
1107
+ $pieces[$i].
1108
+
1109
+ "\n########\n##Error message: ".
1110
+
1111
+ mysql_error();
1112
+
1113
+
1114
+
1115
+ }
1116
+
1117
+ }
1118
+
1119
+
1120
+
1121
+ }
1122
+
1123
+ return $errors;
1124
+
1125
+ }
1126
+
1127
+
1128
+ function rurl($fpos = 0, $chunk = 0){
1129
+
1130
+ $get_query = "&";
1131
+
1132
+ foreach($_REQUEST as $key=>$value){
1133
+ if(($key != 'fpos')&&($key != 'chunk')&&($key != 'strrep_c')&&($key != 'strrep'))
1134
+ $get_query .= $key."=".$value."&";
1135
+ }
1136
+ $url = $_SERVER['PHP_SELF']."?fpos=".$fpos."&chunk=".$chunk.$get_query;
1137
+
1138
+ return $url;
1139
+ }
1140
+
1141
+ function read_file($file, $lines, $start_pos, &$chunk, &$text){
1142
+
1143
+ $cline = 0;
1144
+
1145
+ $fp = fopen($file, "r");
1146
+ fseek($fp, $start_pos);
1147
+ while((!feof($fp)) &&($cline <= $lines)){
1148
+ $btemp = fgets($fp, $chunk);
1149
+ $buffer .= $btemp;
1150
+ if(strstr($btemp, ";\n"))
1151
+ $cline++;
1152
+ $fpos = ftell($fp);
1153
+ }
1154
+
1155
+ $buffer = str_replace(";\r", ";\n", $buffer);
1156
+ $text = explode(";\n", $buffer);
1157
+ $fpos = $fpos - strlen($text[sizeof($text)-1]);
1158
+ if(sizeof($text) == 1)
1159
+ $chunk = DATA_CHUNK_LENGTH+$chunk;
1160
+ else
1161
+ $chunk = DATA_CHUNK_LENGTH;
1162
+
1163
+ if(feof($fp))
1164
+ $fpos = '-1';
1165
+ fclose ($fp);
1166
+
1167
+ return $fpos; // array_reverse is optional: you can also just return the $text array which consists of the file's lines.
1168
+
1169
+ }
1170
+
1171
+
1172
+
1173
+ /**
1174
+
1175
+ * @param string
1176
+
1177
+ */
1178
+
1179
+ function split_sql($sql) {
1180
+
1181
+ $ret = array();
1182
+ $sql = str_replace("\n) ", "\n) ;\n#\n#", $sql);
1183
+ $sql = str_replace("\n--\n","\n#\n",$sql);
1184
+ $sql = str_replace("\n-- ","\n# ",$sql);
1185
+ $sql = str_replace("\n/*","\n#/*",$sql);
1186
+ $sql = str_replace("#\n", "#;\n", $sql);
1187
+
1188
+ // Processing the SQL file content
1189
+
1190
+ $file_content = explode("\n",$sql);
1191
+ $query = "";
1192
+ // Parsing the SQL file content
1193
+ foreach($file_content as $key=>$sql_line) {
1194
+
1195
+ if(substr($sql_line, 0, 2) == "--")
1196
+ $sql_line = "#".substr($sql_line, 2, strlen($sql_line));
1197
+
1198
+ if(trim($sql_line) != "" ){
1199
+
1200
+ $query .= $sql_line;
1201
+
1202
+ // Checking whether the line is a valid statement
1203
+ if(preg_match("/(.*);/", $sql_line)){
1204
+
1205
+ $query = substr($query, 0, strlen($query)-1);
1206
+
1207
+ //Executing the parsed string, returns the error code in failure
1208
+ $ret[] = $query;
1209
+ $query = "";
1210
+ }
1211
+ }
1212
+ } //End of foreach
1213
+
1214
+ return($ret);
1215
+ }
1216
+
1217
+
1218
+
1219
+ function recurseFiles(&$d_arr, &$ds_arr, &$f_arr, &$s_arr, &$d, &$f, &$s, &$includedFolders, $path, $mosConfig_absolute_path) {
1220
+
1221
+ $currentfullpath = $mosConfig_absolute_path.$path;
1222
+
1223
+ # Open possibly available directory
1224
+
1225
+ if( is_dir( $currentfullpath ) ) {
1226
+
1227
+ if( $handle = opendir( $currentfullpath ) ) {
1228
+
1229
+ while( false !== ( $file = readdir( $handle ) ) ) {
1230
+
1231
+ # Make sure we don't push parental directories or dotfiles (unix) into the arrays
1232
+
1233
+ if( $file != "." && $file != ".." ) {
1234
+
1235
+ if( is_dir( $currentfullpath . "/" . $file ) ) {
1236
+
1237
+ # Create array for directories
1238
+
1239
+ $d_arr[++$d] = $currentfullpath . "/" . $file;
1240
+
1241
+ recurseFiles($d_arr, $ds_arr, $f_arr, $s_arr, $d, $f, $s, $includedFolders, $path . "/" . $file, $mosConfig_absolute_path);
1242
+
1243
+ } else {
1244
+
1245
+ if ( in_array($currentfullpath, $includedFolders) ) {
1246
+
1247
+ # Create array for files
1248
+
1249
+ $s_arr[$f] = filesize($currentfullpath.'/'.$file);
1250
+
1251
+ $f_arr[$f++] = str_replace($mosConfig_absolute_path.'/', '', $currentfullpath.'/').$file;
1252
+
1253
+ $s += filesize($currentfullpath.'/'.$file);
1254
+
1255
+ }
1256
+
1257
+ }
1258
+
1259
+ }
1260
+
1261
+ }
1262
+
1263
+ }
1264
+
1265
+ # Wrap things up if we're in a directory
1266
+
1267
+ if( is_dir( $handle ) )
1268
+
1269
+ closedir( $handle );
1270
+
1271
+ }
1272
+
1273
+ }
1274
+
1275
+
1276
+
1277
+
1278
+
1279
+ function version_list($fname) {
1280
+
1281
+ global $_CONFIG;
1282
+
1283
+ $return = "<select name='$fname'><option value=''>Choose local clone archive</option>";
1284
+
1285
+ if(is_array($_CONFIG[versions])){
1286
+
1287
+ foreach($_CONFIG[versions] as $key=>$value){
1288
+
1289
+ $size = sprintf("%.2fM", filesize($value)/(1024*1024));
1290
+
1291
+ $return .= "<option selected value='$value'>$value($size)</option>";
1292
+
1293
+ }
1294
+
1295
+ }
1296
+
1297
+ $return .= "</select>";
1298
+
1299
+ return $return;
1300
+
1301
+ }
1302
+
1303
+
1304
+ function recursive_remove_directory($directory, $empty=FALSE){
1305
+
1306
+ // if the path has a slash at the end we remove it here
1307
+ if(substr($directory,-1) == '/'){
1308
+ $directory = substr($directory,0,-1);
1309
+ }
1310
+
1311
+ // if the path is not valid or is not a directory ...
1312
+ if(!file_exists($directory) || !is_dir($directory)){
1313
+ // ... we return false and exit the function
1314
+ return FALSE;
1315
+
1316
+ // ... if the path is not readable
1317
+ }elseif(!is_readable($directory)){
1318
+ // ... we return false and exit the function
1319
+ return FALSE;
1320
+ // ... else if the path is readable
1321
+ }else{
1322
+ // we open the directory
1323
+ $handle = opendir($directory);
1324
+ // and scan through the items inside
1325
+ while (FALSE !== ($item = readdir($handle))){
1326
+ // if the filepointer is not the current directory
1327
+ // or the parent directory
1328
+ if($item != '.' && $item != '..'){
1329
+ // we build the new path to delete
1330
+ $path = $directory.'/'.$item;
1331
+ // if the new path is a directory
1332
+ if(is_dir($path)){
1333
+ // we call this function with the new path
1334
+ recursive_remove_directory($path);
1335
+ // if the new path is a file
1336
+ }else{
1337
+ // we remove the file
1338
+ unlink($path);
1339
+ }
1340
+ }
1341
+ }
1342
+ // close the directory
1343
+ closedir($handle);
1344
+
1345
+ // if the option to empty is not set to true
1346
+ if($empty == FALSE){
1347
+ // try to delete the now empty directory
1348
+ if(!@rmdir($directory)){
1349
+ // return false if not possible
1350
+ return FALSE;
1351
+ }
1352
+ }
1353
+ // return success
1354
+ return TRUE;
1355
+ }
1356
+ }
1357
+
1358
+
1359
+ function setCache($time = 3600){
1360
+
1361
+ $seconds_to_cache = $time;
1362
+ $ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";
1363
+ @header("Expires: $ts");
1364
+ @header("Pragma: cache");
1365
+ @header("Cache-Control: maxage=$seconds_to_cache");
1366
+
1367
+ }
1368
+
1369
+ ?>
screenshot-1.png ADDED
Binary file
screenshot-2.png ADDED
Binary file
screenshot-3.png ADDED
Binary file
screenshot-4.png ADDED
Binary file
screenshot-5.png ADDED
Binary file
screenshot-6.png ADDED
Binary file
screenshot-7.png ADDED
Binary file
screenshot-8.png ADDED
Binary file
toolbar.cloner.html.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * XCloner
4
+ * Oficial website: http://www.joomlaplug.com/
5
+ * -------------------------------------------
6
+ * Creator: Liuta Romulus Ovidiu
7
+ * License: GNU/GPL
8
+ * Email: admin@joomlaplug.com
9
+ * Revision: 1.0
10
+ * Date: July 2007
11
+ **/
12
+
13
+
14
+ /** ensure this file is being included by a parent file */
15
+ defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
16
+
17
+ function button($action, $text='', $js=''){
18
+ if($action == "cancel")
19
+ $icon = "ui-icon-cancel";
20
+ elseif($action == "generate")
21
+ $icon = "ui-icon-arrowthick-1-e";
22
+ elseif($action == "config")
23
+ $icon = "ui-icon-circle-check";
24
+ else
25
+ $icon = "ui-icon-arrowreturnthick-1-e";
26
+ ?>
27
+ <script>
28
+ $(function() {
29
+ $( "#<?php echo $text?>" ).button({
30
+ icons:{
31
+ primary: '<?php echo $icon;?>'
32
+ }
33
+ })
34
+ .click(function(){
35
+ document.adminForm.task.value='<?php echo $action?>';document.adminForm.submit();
36
+ })
37
+ .css({ 'text-transform':'uppercase', width: '110px', 'padding-top': '10px', 'padding-bottom': '10px' });
38
+ });
39
+ </script>
40
+
41
+ <button id="<?php echo $text?>"><?php echo $text?></button>
42
+
43
+ <?php
44
+
45
+ }
46
+
47
+ class TOOLBAR_cloner {
48
+
49
+ function _LOGIN() {
50
+ button('dologin','Login',false);
51
+ button('cancel','Cancel',false);
52
+ }
53
+ function _GENERATE() {
54
+ button('clone','Clone',false);
55
+ button('move','Move',false);
56
+ button('view','Back',false);
57
+ }
58
+ function _CONFIRM() {
59
+ button('generate','Continue',false);
60
+ button('cancel','Cancel',false);
61
+ }
62
+ function _CLONE() {
63
+ button('continue','Continue',false);
64
+ button('view','Cancel',false);
65
+ }
66
+ function _CONFIG() {
67
+ button('config', 'Save');
68
+ button('cancel', 'Cancel');
69
+ }
70
+
71
+ function _LANG_EDIT() {
72
+ button('save_lang_apply','Apply');
73
+ button('save_lang', 'Save');
74
+ button('cancel_lang', 'Cancel');
75
+ }
76
+
77
+ function _LANG_ADD() {
78
+ button('add_lang_new', 'New');
79
+ button('cancel_lang', 'Cancel');
80
+ }
81
+
82
+ function _LANG() {
83
+ button('add_lang','New');
84
+ button('edit_lang', 'Edit');
85
+ button('del_lang', 'Delete');
86
+ button('cancel','Cancel');
87
+ }
88
+
89
+ function _RENAME() {
90
+ button('rename_save', 'Save');
91
+ button('rename_cancel', 'Cancel');
92
+ }
93
+ function _VIEW() {
94
+ button('clone','Clone',true);
95
+ button('move','Move',true);
96
+ button('rename','Rename',true);
97
+ button('remove','Delete');
98
+ button('cancel','Cancel');
99
+ }
100
+ function _DEFAULT() {
101
+
102
+ button('logout','Logout');
103
+ button('cancel','Cancel');
104
+
105
+ }
106
+ }
107
+ ?>
toolbar.cloner.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * XCloner
4
+ * Oficial website: http://www.joomlaplug.com/
5
+ * -------------------------------------------
6
+ * Creator: Liuta Romulus Ovidiu
7
+ * License: GNU/GPL
8
+ * Email: admin@joomlaplug.com
9
+ * Revision: 1.0
10
+ * Date: July 2007
11
+ **/
12
+
13
+
14
+ /** ensure this file is being included by a parent file */
15
+ defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
16
+
17
+ require_once('toolbar.cloner.html.php' );
18
+
19
+ switch ( $task ) {
20
+ case 'help':
21
+ case 'credits':
22
+ case 'refresh':
23
+ case 'generate':
24
+ TOOLBAR_cloner::_GENERATE();
25
+ break;
26
+
27
+ case 'rename_save':
28
+ case 'rename':
29
+ TOOLBAR_cloner::_RENAME();
30
+ break;
31
+ case 'confirm':
32
+ TOOLBAR_cloner::_CONFIRM();
33
+ break;
34
+ case 'continue':
35
+ case 'move':
36
+ case 'clone':
37
+ TOOLBAR_cloner::_CLONE();
38
+ break;
39
+ case 'config':
40
+ TOOLBAR_cloner::_CONFIG();
41
+ break;
42
+ case 'show':
43
+ case 'view':
44
+ TOOLBAR_cloner::_VIEW();
45
+ break;
46
+
47
+
48
+ case 'add_lang':
49
+ TOOLBAR_cloner::_LANG_ADD();
50
+ break;
51
+ case 'save_lang_apply':
52
+ case 'edit_lang':
53
+ TOOLBAR_cloner::_LANG_EDIT();
54
+ break;
55
+
56
+ case 'del_lang':
57
+ case 'lang':
58
+ TOOLBAR_cloner::_LANG();
59
+ break;
60
+
61
+ case 'login':
62
+ TOOLBAR_cloner::_LOGIN();
63
+ break;
64
+
65
+ default:
66
+ TOOLBAR_cloner::_DEFAULT();
67
+ break;
68
+ }
69
+
70
+ ?>
xcloner.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: XCloner
4
+ Plugin URI: http://www.xcloner.com
5
+ Description: XCloner is a tool that will help you manage your website backups, generate/restore/move so your website will be always secured! With XCloner you will be able to clone your site to any other location with just a few clicks. Don't forget to create the 'administrator/backups' directory in your Wordpress root and make it fully writeable. <a href="plugins.php?page=xcloner_show">Open XCloner</a> | <a href="http://www.xcloner.com/support/premium-support/">Get Premium Support</a> | <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=info%40xcloner%2ecom&lc=US&item_name=XCloner%20Support&no_note=0&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHostedGuest">Donate</a>
6
+ Version: 3.0.3
7
+ Author: Liuta Ovidiu
8
+ Author URI: http://www.xcloner.com
9
+ Plugin URI: http://www.xcloner.com
10
+ */
11
+
12
+
13
+ // no direct access
14
+ #defined( '_JEXEC' ) or die( 'Restricted access' );
15
+
16
+ function xcloner_show(){
17
+
18
+ print "<iframe src='../wp-content/plugins/xcloner-backup-and-restore/index.php' width='100%' height='900' frameborder=0 marginWidth=0 frameSpacing=0 marginHeight=110 ></iframe>";
19
+
20
+ }
21
+ function xcloner_install(){
22
+
23
+ }
24
+
25
+ function xcloner_page(){
26
+
27
+ if ( function_exists('add_submenu_page') )
28
+ add_submenu_page('plugins.php', XCloner, XCloner, 'manage_options', 'xcloner_show', 'xcloner_show');
29
+
30
+
31
+
32
+ }
33
+
34
+ #add_action('admin_head', 'xcloner');
35
+ add_action('admin_menu', 'xcloner_page');
36
+
37
+ #add_options_page('XCloner Options', 'XCloner', 9, 'index.php', 'xcloner_options');
38
+
39
+ if (isset($_GET['activate']) && $_GET['activate'] == 'true')
40
+ {
41
+ add_action('init', 'xcloner_install');
42
+ }
43
+
44
+ ?>
xcloner_j1.5.xml ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <install type="component" version="1.5.0" method="upgrade">
2
+ <name>XCloner-BackupandRestore</name>
3
+ <version>2.2.1</version>
4
+ <license>GNU/GPL</license>
5
+ <author>XCloner.com</author>
6
+ <authoremail>info@xcloner.com</authoremail>
7
+ <authorurl>http://www.xcloner.com</authorurl>
8
+ <creationDate>February 2011</creationDate>
9
+ <copyright>XCloner.com</copyright>
10
+ <description><![CDATA[
11
+ <h2>XCloner Backup&Restore Utility</h2>
12
+ <pre>XCloner is a tool that will help you manage your website backups, generate/restore/move so your website will be always secured!
13
+ <a href="http://www.xcloner.com"><img src="http://www.xcloner.com/xcloner_p.jpg" border=0 style="float:left; padding-right:10px;padding-bottom: 100px;padding-top:20px;"></a>
14
+ Features:
15
+ -cron script to generate backup
16
+ -multiple backup options
17
+ -restore tool to move the website rapidly to other locations
18
+ -multiple locations of where you could store the backup safelly
19
+ -comnpatible with both Joomla 1.5.x and 1.6.x
20
+
21
+ For reports and suggestions please contact us at info@xcloner.com or visit us on <a href='http://www.xcloner.com'>http://www.xcloner.com</a>
22
+ </pre>
23
+ <br/>
24
+
25
+ XCloner.com &copy; 2006-2011 | <a href="http://www.xcloner.com">www.xcloner.com</a>
26
+ <br/><p/><br/>
27
+ ]]>
28
+ </description>
29
+ <installfile>install.xcloner.php</installfile>
30
+ <administration>
31
+ <menu img="components/com_xcloner-backupandrestore/images/xcloner.png" alias="XCloner">.XCloner-Backup and Restore</menu>
32
+ <files>
33
+ <filename>admin.xcloner.php</filename>
34
+ <filename>admin.xcloner-backupandrestore.php</filename>
35
+ <filename>xcloner.php</filename>
36
+ <filename>classes/S3.php</filename>
37
+ <filename>classes/fileRecursion.php</filename>
38
+ <filename>classes/index.html</filename>
39
+ <filename>classes/main.class.php</filename>
40
+ <filename>classes/mysqlBackup.class.php</filename>
41
+ <filename>administrator/index.html</filename>
42
+ <filename>administrator/backups/index.html</filename>
43
+ <filename>browser/file.gif</filename>
44
+ <filename>browser/filebrowser.css</filename>
45
+ <filename>browser/files_inpage.php</filename>
46
+ <filename>browser/files_xml.php</filename>
47
+ <filename>browser/folder.gif</filename>
48
+ <filename>browser/timer.gif</filename>
49
+ <filename>browser/xmlhttp.js</filename>
50
+ <filename>configs/index.html</filename>
51
+ <filename>css/dtree.css</filename>
52
+ <filename>css/main.css</filename>
53
+ <filename>css/start/jquery-ui-1.8.9.custom.css</filename>
54
+ <filename>css/start/images/ui-bg_flat_55_999999_40x100.png</filename>
55
+ <filename>css/start/images/ui-bg_flat_75_aaaaaa_40x100.png</filename>
56
+ <filename>css/start/images/ui-bg_glass_75_79c9ec_1x400.png</filename>
57
+ <filename>css/start/images/ui-icons_056b93_256x240.png</filename>
58
+ <filename>css/start/images/ui-icons_d8e7f3_256x240.png</filename>
59
+ <filename>css/start/images/ui-icons_fcd113_256x240.png</filename>
60
+ <filename>css/start/images/ui-bg_glass_45_0078ae_1x400.png</filename>
61
+ <filename>css/start/images/ui-icons_f7a50d_256x240.png</filename>
62
+ <filename>css/start/images/ui-bg_gloss-wave_45_e14f1c_500x100.png</filename>
63
+ <filename>css/start/images/ui-icons_0078ae_256x240.png</filename>
64
+ <filename>css/start/images/ui-bg_glass_55_f8da4e_1x400.png</filename>
65
+ <filename>css/start/images/ui-icons_e0fdff_256x240.png</filename>
66
+ <filename>css/start/images/ui-bg_inset-hard_100_fcfdfd_1x100.png</filename>
67
+ <filename>css/start/images/ui-icons_f5e175_256x240.png</filename>
68
+ <filename>css/start/images/ui-bg_gloss-wave_50_6eac2c_500x100.png</filename>
69
+ <filename>css/start/images/ui-bg_gloss-wave_75_2191c0_500x100.png</filename>
70
+
71
+ <filename>images/about.png</filename>
72
+ <filename>images/actions.gif</filename>
73
+ <filename>images/actions.png</filename>
74
+ <filename>images/backup.png</filename>
75
+ <filename>images/css.png</filename>
76
+ <filename>images/editions.png</filename>
77
+ <filename>images/editionssm.png</filename>
78
+ <filename>images/empty.gif</filename>
79
+ <filename>images/filesave.png</filename>
80
+ <filename>images/folder.png</filename>
81
+ <filename>images/forum.png</filename>
82
+ <filename>images/gen_settings.png</filename>
83
+ <filename>images/help.png</filename>
84
+ <filename>images/helpsm.png</filename>
85
+ <filename>images/join.gif</filename>
86
+ <filename>images/joinbottom.gif</filename>
87
+ <filename>images/keep_icon.gif</filename>
88
+ <filename>images/lang.png</filename>
89
+ <filename>images/lhelp.png</filename>
90
+ <filename>images/line.gif</filename>
91
+ <filename>images/logo.gif</filename>
92
+ <filename>images/logo.png</filename>
93
+ <filename>images/xcloner.png</filename>
94
+ <filename>images/minus.gif</filename>
95
+ <filename>images/minusbottom.gif</filename>
96
+ <filename>images/nolines_minus.gif</filename>
97
+ <filename>images/nolines_plus.gif</filename>
98
+ <filename>images/page.gif</filename>
99
+ <filename>images/plus.gif</filename>
100
+ <filename>images/plusbottom.gif</filename>
101
+ <filename>images/publish_x.png</filename>
102
+ <filename>images/settings.png</filename>
103
+ <filename>images/support.png</filename>
104
+ <filename>images/templatessm.png</filename>
105
+ <filename>images/website.png</filename>
106
+ <filename>images/wizard.png</filename>
107
+ <filename>images/wizardsm.png</filename>
108
+ <filename>images/wizardsm_restore.gif</filename>
109
+ <filename>images/wizardsm_restore.png</filename>
110
+ <filename>javascript/dtree.js</filename>
111
+ <filename>javascript/main.js</filename>
112
+ <filename>javascript/jquery-1.4.4.min.js</filename>
113
+ <filename>javascript/jquery-ui-1.8.9.custom.min.js</filename>
114
+ <filename>language/english.php</filename>
115
+ <filename>language/spanish.php</filename>
116
+ <filename>language/dutch.php</filename>
117
+ <filename>language/deutsch.php</filename>
118
+ <filename>language/index.html</filename>
119
+ <filename>restore/TAR.php</filename>
120
+ <filename>restore/XCloner.php</filename>
121
+ <filename>admin.cloner.html.php</filename>
122
+ <filename>admin.cloner.php</filename>
123
+ <filename>cloner.config.php</filename>
124
+ <filename>cloner.cron.php</filename>
125
+ <filename>cloner.functions.php</filename>
126
+ <filename>common.php</filename>
127
+ <filename>index.php</filename>
128
+ <filename>index2.php</filename>
129
+ <filename>install.xcloner.php</filename>
130
+ <filename>license.txt</filename>
131
+ <filename>readme.txt</filename>
132
+ <filename>toolbar.cloner.html.php</filename>
133
+ <filename>toolbar.cloner.php</filename>
134
+ </files>
135
+ </administration>
136
+ </install>
137
+
138
+