| 1 |
lars |
1 |
<?php
|
|
|
2 |
/**
|
|
|
3 |
* Write data to a file and save as an ar
|
|
|
4 |
*
|
|
|
5 |
* PHP versions 4 and 5
|
|
|
6 |
*
|
|
|
7 |
* This library is free software; you can redistribute it and/or
|
|
|
8 |
* modify it under the terms of the GNU Lesser General Public
|
|
|
9 |
* License as published by the Free Software Foundation; either
|
|
|
10 |
* version 2.1 of the License, or (at your option) any later version.
|
|
|
11 |
*
|
|
|
12 |
* This library 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 GNU
|
|
|
15 |
* Lesser General Public License for more details.
|
|
|
16 |
*
|
|
|
17 |
* You should have received a copy of the GNU Lesser General Public
|
|
|
18 |
* License along with this library; if not, write to the Free Software
|
|
|
19 |
* Foundation, Inc., 59 Temple Place, Suite 330,Boston,MA 02111-1307 USA
|
|
|
20 |
*
|
|
|
21 |
* @category File Formats
|
|
|
22 |
* @package File_Archive
|
|
|
23 |
* @author Pablo Fischer <pablo@pablo.com.mx>
|
|
|
24 |
* @copyright 1997-2005 The PHP Group
|
|
|
25 |
* @license http://www.gnu.org/copyleft/lesser.html LGPL
|
|
|
26 |
* @version CVS: $Id:
|
|
|
27 |
* @link http://pear.php.net/package/File_Archive
|
|
|
28 |
*/
|
|
|
29 |
|
|
|
30 |
require_once "File/Archive/Writer/Archive.php";
|
|
|
31 |
|
|
|
32 |
/**
|
|
|
33 |
* Write the files as an AR archive
|
|
|
34 |
*/
|
|
|
35 |
class File_Archive_Writer_Ar extends File_Archive_Writer_Archive
|
|
|
36 |
{
|
|
|
37 |
|
|
|
38 |
/**
|
|
|
39 |
* @var string Current data of the file.
|
|
|
40 |
* @access private
|
|
|
41 |
*/
|
|
|
42 |
var $_buffer = "";
|
|
|
43 |
|
|
|
44 |
/**
|
|
|
45 |
* @var string Filename of the current filename
|
|
|
46 |
* @access private
|
|
|
47 |
*/
|
|
|
48 |
var $_currentFilename = null;
|
|
|
49 |
|
|
|
50 |
/**
|
|
|
51 |
* @var boolean Flag: use buffer or not.
|
|
|
52 |
* @access private
|
|
|
53 |
*/
|
|
|
54 |
var $_useBuffer;
|
|
|
55 |
|
|
|
56 |
/**
|
|
|
57 |
* @var array Stats of the current filename
|
|
|
58 |
* @access private
|
|
|
59 |
*/
|
|
|
60 |
var $_currentStat = array ();
|
|
|
61 |
|
|
|
62 |
/**
|
|
|
63 |
* @var boolean Flag: beginning of the archive or not
|
|
|
64 |
* @access private
|
|
|
65 |
*/
|
|
|
66 |
var $_atStart = true;
|
|
|
67 |
|
|
|
68 |
/**
|
|
|
69 |
* Returns the header of the current file.
|
|
|
70 |
*
|
|
|
71 |
* More Info:
|
|
|
72 |
* http://publibn.boulder.ibm.com/doc_link/en_US/a_doc_lib/files/aixfiles/ar_IA64.htm
|
|
|
73 |
*
|
|
|
74 |
* @access private
|
|
|
75 |
* @param string $filename Name of the current file
|
|
|
76 |
* @param array $stat Stat array of the current file
|
|
|
77 |
* @return string The built header struct
|
|
|
78 |
*/
|
|
|
79 |
function arHeader ($filename, $stat)
|
|
|
80 |
{
|
|
|
81 |
$mode = isset($stat[2]) ? $stat[2] : 0x8000;
|
|
|
82 |
$uid = isset($stat[4]) ? $stat[4] : 0;
|
|
|
83 |
$gid = isset($stat[5]) ? $stat[5] : 0;
|
|
|
84 |
$size = $stat[7];
|
|
|
85 |
$time = isset($stat[9]) ? $stat[9] : time();
|
|
|
86 |
|
|
|
87 |
$struct = "";
|
|
|
88 |
$currentSize = $size;
|
|
|
89 |
//if file length is > than 16..
|
|
|
90 |
if (strlen($filename) > 16) {
|
|
|
91 |
$currentSize += strlen($filename);
|
|
|
92 |
$struct .= sprintf("#1/%-13d", strlen($filename));
|
|
|
93 |
$struct .= sprintf("%-12d%-6d%-6d%-8s%-10d",
|
|
|
94 |
$time, $uid, $gid, $mode, $currentSize);
|
|
|
95 |
$struct .= "`\n".$filename;
|
|
|
96 |
} else {
|
|
|
97 |
$struct .= sprintf("%-16s", $filename);
|
|
|
98 |
$struct .= sprintf("%-12d%-6d%-6d%-8s%-10d`\n",
|
|
|
99 |
$time, $uid, $gid, $mode, $size);
|
|
|
100 |
}
|
|
|
101 |
return $struct;
|
|
|
102 |
}
|
|
|
103 |
|
|
|
104 |
/**
|
|
|
105 |
* Returns the footer of the current file, the footer depends
|
|
|
106 |
* of the size of the file
|
|
|
107 |
*
|
|
|
108 |
* @access private
|
|
|
109 |
* @param string $filename Name of the file, the footer depends on its length
|
|
|
110 |
* @param int $size Size of the current file, here the size does matters!
|
|
|
111 |
* @return string The footer struct
|
|
|
112 |
*/
|
|
|
113 |
function arFooter($filename, $size)
|
|
|
114 |
{
|
|
|
115 |
$size = (strlen ($filename) > 16) ? $size + strlen($filename) : $size;
|
|
|
116 |
|
|
|
117 |
return ($size % 2 == 1) ? "\n" : "";
|
|
|
118 |
}
|
|
|
119 |
|
|
|
120 |
|
|
|
121 |
/**
|
|
|
122 |
* Flush the memory we have in the ar.
|
|
|
123 |
*
|
|
|
124 |
* Build the buffer if its called at the end or initialize
|
|
|
125 |
* it if we are just creating it from the start.
|
|
|
126 |
*/
|
|
|
127 |
function flush()
|
|
|
128 |
{
|
|
|
129 |
if ($this->_atStart) {
|
|
|
130 |
$this->innerWriter->writeData("!<arch>\n");
|
|
|
131 |
$this->_atStart = false;
|
|
|
132 |
}
|
|
|
133 |
if ($this->_currentFilename !== null) {
|
|
|
134 |
$this->_currentStat[7] = strlen($this->_buffer);
|
|
|
135 |
if ($this->_useBuffer) {
|
|
|
136 |
$this->innerWriter->writeData(
|
|
|
137 |
$this->arHeader($this->_currentFilename, $this->_currentStat)
|
|
|
138 |
);
|
|
|
139 |
$this->innerWriter->writeData($this->_buffer);
|
|
|
140 |
}
|
|
|
141 |
$this->innerWriter->writeData($this->arFooter($this->_currentFilename, $this->_currentStat[7]));
|
|
|
142 |
}
|
|
|
143 |
$this->_buffer = "";
|
|
|
144 |
}
|
|
|
145 |
|
|
|
146 |
/**
|
|
|
147 |
* @see File_Archive_Writer::newFile()
|
|
|
148 |
*
|
|
|
149 |
*/
|
|
|
150 |
function newFile($filename, $stat = array (),
|
|
|
151 |
$mime = "application/octet-stream")
|
|
|
152 |
{
|
|
|
153 |
// ar file format doesn't support folders
|
|
|
154 |
if (substr($filename, -1) == '/') {
|
|
|
155 |
return;
|
|
|
156 |
}
|
|
|
157 |
|
|
|
158 |
$this->flush();
|
|
|
159 |
/*
|
|
|
160 |
* If the file is empty, there's no reason to have a buffer
|
|
|
161 |
* or use memory
|
|
|
162 |
*/
|
|
|
163 |
$this->_useBuffer = !isset($stats[7]);
|
|
|
164 |
/*
|
|
|
165 |
* Becaue ar fileformats doesn't support files in directories,
|
|
|
166 |
* then we need to just save with the filename an ommit the
|
|
|
167 |
* directory
|
|
|
168 |
*/
|
|
|
169 |
$this->_currentFilename = basename($filename);
|
|
|
170 |
$this->_currentStat = $stat;
|
|
|
171 |
|
|
|
172 |
if(!$this->_useBuffer) {
|
|
|
173 |
return $this->innerWriter->writeData($this->arHeader($filename, $stat));
|
|
|
174 |
}
|
|
|
175 |
}
|
|
|
176 |
|
|
|
177 |
/**
|
|
|
178 |
* @see File_Archive_Writer::close()
|
|
|
179 |
*/
|
|
|
180 |
function close()
|
|
|
181 |
{
|
|
|
182 |
$this->flush();
|
|
|
183 |
parent::close();
|
|
|
184 |
}
|
|
|
185 |
|
|
|
186 |
/**
|
|
|
187 |
* @see File_Archive_Writer::writeData()
|
|
|
188 |
*/
|
|
|
189 |
function writeData($data)
|
|
|
190 |
{
|
|
|
191 |
if ($this->_useBuffer) {
|
|
|
192 |
$this->_buffer .= $data;
|
|
|
193 |
} else {
|
|
|
194 |
$this->innerWriter->writeData($data);
|
|
|
195 |
}
|
|
|
196 |
|
|
|
197 |
}
|
|
|
198 |
/**
|
|
|
199 |
* @see File_Archive_Writer::writeFile()
|
|
|
200 |
*/
|
|
|
201 |
function writeFile($filename)
|
|
|
202 |
{
|
|
|
203 |
if ($this->_useBuffer) {
|
|
|
204 |
$this->_buffer .= file_get_contents($filename);
|
|
|
205 |
} else {
|
|
|
206 |
$this->innerWriter->writeFile($filename);
|
|
|
207 |
}
|
|
|
208 |
}
|
|
|
209 |
}
|