]> git.p6c8.net - jirafeau.git/blob - lib/functions.php
10e98685c60f48a9ecd56caa27c6b5257f6c2ae1
[jirafeau.git] / lib / functions.php
1 <?php
2 /*
3 * Jirafeau, your web file repository
4 * Copyright (C) 2008 Julien "axolotl" BERNARD <axolotl@magieeternelle.org>
5 * Copyright (C) 2012 Jerome Jutteau <j.jutteau@gmail.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (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 Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20 /**
21 * transforms a php.ini string representing a value in an integer
22 * @param $value the value from php.ini
23 * @returns an integer for this value
24 */
25 function jirafeau_ini_to_bytes ($value)
26 {
27 $modifier = substr ($value, -1);
28 $bytes = substr ($value, 0, -1);
29 switch (strtoupper ($modifier))
30 {
31 case 'P':
32 $bytes *= 1024;
33 case 'T':
34 $bytes *= 1024;
35 case 'G':
36 $bytes *= 1024;
37 case 'M':
38 $bytes *= 1024;
39 case 'K':
40 $bytes *= 1024;
41 default:
42 break;
43 }
44 return $bytes;
45 }
46
47 /**
48 * gets the maximum upload size according to php.ini
49 * @returns the maximum upload size
50 */
51 function
52 jirafeau_get_max_upload_size ()
53 {
54 return min (jirafeau_ini_to_bytes (ini_get ('post_max_size')),
55 jirafeau_ini_to_bytes (ini_get ('upload_max_filesize')));
56 }
57
58 /**
59 * gets a string explaining the error
60 * @param $code the error code
61 * @returns a string explaining the error
62 */
63 function
64 jirafeau_upload_errstr ($code)
65 {
66 switch ($code)
67 {
68 case UPLOAD_ERR_INI_SIZE:
69 case UPLOAD_ERR_FORM_SIZE:
70 return _('Your file exceeds the maximum authorized file size. ');
71 break;
72
73 case UPLOAD_ERR_PARTIAL:
74 case UPLOAD_ERR_NO_FILE:
75 return
76 _
77 ('Your file was not uploaded correctly. You may succeed in retrying. ');
78 break;
79
80 case UPLOAD_ERR_NO_TMP_DIR:
81 case UPLOAD_ERR_CANT_WRITE:
82 case UPLOAD_ERR_EXTENSION:
83 return _('Internal error. You may not succeed in retrying. ');
84 break;
85
86 default:
87 break;
88 }
89 return _('Unknown error. ');
90 }
91
92 /** Remove link and it's file
93 * @param $link the link's name (hash)
94 */
95
96 function
97 jirafeau_delete ($link)
98 {
99 if (!file_exists ( VAR_LINKS . $link))
100 return;
101
102 $content = file (VAR_LINKS . $link);
103 $md5 = trim ($content[5]);
104 unlink (VAR_LINKS . $link);
105
106 $counter = 1;
107 if (file_exists ( VAR_FILES . $md5. '_count'))
108 {
109 $content = file ( VAR_FILES . $md5. '_count');
110 $counter = trim ($content[0]);
111 }
112 $counter--;
113
114 if ($counter >= 1)
115 {
116 $handle = fopen ( VAR_FILES . $md5. '_count', 'w');
117 fwrite ($handle, $counter);
118 fclose ($handle);
119 }
120
121 if ($counter == 0 && file_exists ( VAR_FILES . $md5))
122 {
123 unlink ( VAR_FILES . $md5);
124 unlink ( VAR_FILES . $md5. '_count');
125 }
126 }
127
128 /**
129 * Delete a file and it's links.
130 */
131 function
132 jirafeau_delete_file ($md5)
133 {
134 $count = 0;
135 $links_dir = scandir (VAR_LINKS);
136
137 foreach ($links_dir as $link)
138 {
139 if (strcmp ($link, '.') == 0 || strcmp ($link, '..') == 0)
140 continue;
141 /* Read link informations. */
142 $l = jirafeau_get_link ($link);
143 if ($l['md5'] == $md5)
144 {
145 $count++;
146 jirafeau_delete ($link);
147 }
148 }
149
150 if (file_exists (VAR_FILES . $md5 . '_count'))
151 unlink (VAR_FILES . $md5. '_count');
152 if (file_exists (VAR_FILES . $md5))
153 unlink (VAR_FILES . $md5);
154
155 return $count;
156 }
157
158 /**
159 * handles an uploaded file
160 * @param $file the file struct given by $_FILE[]
161 * @param $one_time_download is the file a one time download ?
162 * @param $key if not empty, protect the file with this key
163 * @param $time the time of validity of the file
164 * @param $cfg the current configuration
165 * @param $ip uploader's ip
166 * @returns an array containing some information
167 * 'error' => information on possible errors
168 * 'link' => the link name of the uploaded file
169 * 'delete_link' => the link code to delete file
170 */
171 function
172 jirafeau_upload ($file, $one_time_download, $key, $time, $cfg, $ip)
173 {
174 if (empty ($file['tmp_name']) || !is_uploaded_file ($file['tmp_name']))
175 {
176 return (array(
177 'error' =>
178 array ('has_error' => true,
179 'why' => jirafeau_upload_errstr ($file['error'])),
180 'link' => '',
181 'delete_link' => ''));
182 }
183
184 /* array representing no error */
185 $noerr = array ('has_error' => false, 'why' => '');
186
187 /* file informations */
188 $md5 = md5_file ($file['tmp_name']);
189 $name = trim ($file['name']);
190 $mime_type = $file['type'];
191 $size = $file['size'];
192
193 /* does file already exist ? */
194 $rc = false;
195 if (file_exists ( VAR_FILES . $md5))
196 {
197 $rc = unlink ($file['tmp_name']);
198 }
199 elseif (move_uploaded_file ($file['tmp_name'], VAR_FILES . $md5))
200 {
201 $rc = true;
202 }
203 if (!$rc)
204 {
205 return (array(
206 'error' =>
207 array ('has_error' => true,
208 'why' => _('Internal error during file creation. ')),
209 'link' =>'',
210 'delete_link' => ''));
211 }
212
213 /* increment or create count file */
214 $counter = 0;
215 if (file_exists (VAR_FILES . $md5 . '_count'))
216 {
217 $content = file ( VAR_FILES . $md5. '_count');
218 $counter = trim ($content[0]);
219 }
220 $counter++;
221 $handle = fopen ( VAR_FILES . $md5. '_count', 'w');
222 fwrite ($handle, $counter);
223 fclose ($handle);
224
225 /* Create delete code. */
226 $delete_link_code = 0;
227 for ($i = 0; $i < 8; $i++)
228 $delete_link_code .= dechex (rand (0, 16));
229
230 /* md5 password or empty */
231 $password = '';
232 if (!empty ($key))
233 $password = md5 ($key);
234
235 /* create link file */
236 $link_tmp_name = VAR_LINKS . $md5.rand (0, 10000) . ' .tmp';
237 $handle = fopen ($link_tmp_name, 'w');
238 fwrite ($handle,
239 $name . NL. $mime_type . NL. $size . NL. $password . NL. $time . NL . $md5.
240 NL.($one_time_download ? 'O' : 'R') . NL.date ('U') . NL. $ip . NL.
241 $delete_link_code . NL);
242 fclose ($handle);
243 $md5_link = md5_file ($link_tmp_name);
244 if (!rename ($link_tmp_name, VAR_LINKS . $md5_link))
245 {
246 unlink ($link_tmp_name);
247 $counter--;
248 if ($counter >= 1)
249 {
250 $handle = fopen ( VAR_FILES . $md5. '_count', 'w');
251 fwrite ($handle, $counter);
252 fclose ($handle);
253 }
254 else
255 {
256 unlink ( VAR_FILES . $md5. '_count');
257 unlink ( VAR_FILES . $md5);
258 }
259 return (array(
260 'error' =>
261 array ('has_error' => true,
262 'why' => _('Internal error during file creation. ')),
263 'link' =>'',
264 'delete_link' => ''));
265 }
266 return (array ('error' => $noerr,
267 'link' => $md5_link,
268 'delete_link' => $delete_link_code));
269 }
270
271 /**
272 * tells if a mime-type is viewable in a browser
273 * @param $mime the mime type
274 * @returns a boolean telling if a mime type is viewable
275 */
276 function
277 jirafeau_is_viewable ($mime)
278 {
279 if (!empty ($mime))
280 {
281 /* Actually, verify if mime-type is an image or a text. */
282 $viewable = array ('image', 'text');
283 $decomposed = explode ('/', $mime);
284 return in_array ($decomposed[0], $viewable);
285 }
286 return false;
287 }
288
289
290 // Error handling functions.
291 //! Global array that contains all registered errors.
292 $error_list = array ();
293
294 /**
295 * Adds an error to the list of errors.
296 * @param $title the error's title
297 * @param $description is a human-friendly description of the problem.
298 */
299 function
300 add_error ($title, $description)
301 {
302 global $error_list;
303 $error_list[] = '<p>' . $title. '<br />' . $description. '</p>';
304 }
305
306 /**
307 * Informs whether any error has been registered yet.
308 * @return true if there are errors.
309 */
310 function
311 has_error ()
312 {
313 global $error_list;
314 return !empty ($error_list);
315 }
316
317 /**
318 * Displays all the errors.
319 */
320 function
321 show_errors ()
322 {
323 if (has_error ())
324 {
325 global $error_list;
326 echo '<div class="error">';
327 foreach ($error_list as $error)
328 {
329 echo $error;
330 }
331 echo '</div>';
332 }
333 }
334
335 /**
336 * Read link informations
337 * @return array containing informations.
338 */
339 function
340 jirafeau_get_link ($hash)
341 {
342 $out = array ();
343 $link = VAR_LINKS . $hash;
344
345 if (!file_exists ($link))
346 return $out;
347
348 $c = file ($link);
349 $out['file_name'] = trim ($c[0]);
350 $out['mime_type'] = trim ($c[1]);
351 $out['file_size'] = trim ($c[2]);
352 $out['key'] = trim ($c[3], NL);
353 $out['time'] = trim ($c[4]);
354 $out['md5'] = trim ($c[5]);
355 $out['onetime'] = trim ($c[6]);
356 $out['upload_date'] = trim ($c[7]);
357 $out['ip'] = trim ($c[8]);
358 $out['link_code'] = trim ($c[9]);
359
360 return $out;
361 }
362
363 function
364 jirafeau_human_size ($octets)
365 {
366 $u = array ('B', 'KB', 'MB', 'GB', 'TB');
367 $o = max ($octets, 0);
368 $p = min (floor (($o ? log ($o) : 0) / log (1024)), count ($u) - 1);
369 $o /= pow (1024, $p);
370 return round ($o, 1) . $u[$p];
371 }
372
373 /**
374 * List files in admin interface.
375 */
376 function
377 jirafeau_admin_list ($name, $file_hash, $link_hash)
378 {
379 $links_dir = scandir (VAR_LINKS);
380 echo '<fieldset><legend>';
381 if (!empty ($name))
382 echo $name . ' ';
383 if (!empty ($file_hash))
384 echo $file_hash . ' ';
385 if (!empty ($link_hash))
386 echo $link_hash . ' ';
387 if (empty ($name) && empty ($file_hash) && empty ($link_hash))
388 echo _('List all files');
389 echo '</legend>';
390 echo '<table>';
391 echo '<tr>';
392 echo '<td>' . _('Filename') . '</td>';
393 echo '<td>' . _('Type') . '</td>';
394 echo '<td>' . _('Size') . '</td>';
395 echo '<td>' . _('Expire') . '</td>';
396 echo '<td>' . _('Onetime') . '</td>';
397 echo '<td>' . _('Upload date') . '</td>';
398 echo '<td>' . _('Origin') . '</td>';
399 echo '<td>' . _('Action') . '</td>';
400 echo '</tr>';
401 foreach ($links_dir as $link)
402 {
403 if (strcmp ($link, '.') == 0 || strcmp ($link, '..') == 0)
404 continue;
405 /* Read link informations. */
406 $l = jirafeau_get_link ($link);
407
408 /* Filter. */
409 if (!empty ($name) && $name != $l['file_name'])
410 continue;
411 if (!empty ($file_hash) && $file_hash != $l['md5'])
412 continue;
413 if (!empty ($link_hash) && $link_hash != $link)
414 continue;
415
416 /* Print link informations. */
417 echo '<tr>';
418 echo '<td>' . $l['file_name'] . '</td>';
419 echo '<td>' . $l['mime_type'] . '</td>';
420 echo '<td>' . jirafeau_human_size ($l['file_size']) . '</td>';
421 echo '<td>' . ($l['time'] == -1 ? '' : strftime ('%c', $l['time'])) .
422 '</td>';
423 echo '<td>' . $l['onetime'] . '</td>';
424 echo '<td>' . strftime ('%c', $l['upload_date']) . '</td>';
425 echo '<td>' . $l['ip'] . '</td>';
426 echo '<td>' .
427 '<form action = "admin.php" method = "post">' .
428 '<input type = "hidden" name = "action" value = "delete_link"/>' .
429 '<input type = "hidden" name = "link" value = "' . $link . '"/>' .
430 '<input type = "submit" value = "' . _('Del link') . '" />' .
431 '</form>' .
432 '<form action = "admin.php" method = "post">' .
433 '<input type = "hidden" name = "action" value = "delete_file"/>' .
434 '<input type = "hidden" name = "md5" value = "' . $l['md5'] . '"/>' .
435 '<input type = "submit" value = "' . _('Del file and links') . '" />' .
436 '</form>' .
437 '</td>';
438 echo '</tr>';
439 }
440 echo '</table></fieldset>';
441 }
442
443 /**
444 * Clean expired files.
445 * @return number of cleaned files.
446 */
447 function
448 jirafeau_admin_clean ()
449 {
450 $c = 0;
451 $links_dir = scandir (VAR_LINKS);
452
453 foreach ($links_dir as $link)
454 {
455 if (strcmp ($link, '.') == 0 || strcmp ($link, '..') == 0)
456 continue;
457 /* Read link informations. */
458 $l = jirafeau_get_link ($link);
459 if ($l['time'] > 0 && $l['time'] < time ())
460 {
461 echo 'HAAAA' . $l['time'] . '-->' . time ();
462 jirafeau_delete ($link);
463 $c++;
464 }
465 }
466 return $c;
467 }
468 ?>

patrick-canterino.de