]>
git.p6c8.net - jirafeau_project.git/blob - lib/functions.php
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>
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.
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.
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/>.
22 * Transform a string in a path by seperating each letters by a '/'.
23 * @return path finishing with a '/'
29 for ($i = 0; $i < strlen ($s); $i++
)
35 * Convert base 16 to base 64
36 * @returns A string based on 64 characters (0-9, a-z, A-Z, "-" and "_")
41 $m = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_';
42 $hex2bin = ['0000', # 0
61 # Convert long hex string to bin.
62 $size = strlen ($num);
63 for ($i = 0; $i < $size; $i++
)
64 $b .= $hex2bin{hexdec ($num{$i})};
65 # Convert long bin to base 64.
67 for ($i = $size - 6; $i >= 0; $i -= 6)
68 $o = $m{bindec (substr ($b, $i, 6))} . $o;
69 # Some few bits remaining ?
70 if ($i < 0 && $i > -6)
71 $o = $m{bindec (substr ($b, 0, $i +
6))} . $o;
76 jirafeau_human_size ($octets)
78 $u = array ('B', 'KB', 'MB', 'GB', 'TB');
79 $o = max ($octets, 0);
80 $p = min (floor (($o ?
log ($o) : 0) / log (1024)), count ($u) - 1);
82 return round ($o, 1) . $u[$p];
86 jirafeau_clean_rm_link ($link)
89 if (file_exists (VAR_LINKS
. $p . $link))
90 unlink (VAR_LINKS
. $p . $link);
91 $parse = VAR_LINKS
. $p;
93 while (file_exists ($parse)
94 && ($scan = scandir ($parse))
95 && count ($scan) == 2 // '.' and '..' folders => empty.
96 && basename ($parse) != basename (VAR_LINKS
))
99 $parse = substr ($parse, 0, strlen($parse) - strlen(basename ($parse)) - 1);
104 jirafeau_clean_rm_file ($md5)
107 if (file_exists (VAR_FILES
. $p . $md5))
108 unlink (VAR_FILES
. $p . $md5);
109 if (file_exists (VAR_FILES
. $p . $md5 . '_count'))
110 unlink (VAR_FILES
. $p . $md5 . '_count');
111 $parse = VAR_FILES
. $p;
113 while (file_exists ($parse)
114 && ($scan = scandir ($parse))
115 && count ($scan) == 2 // '.' and '..' folders => empty.
116 && basename ($parse) != basename (VAR_FILES
))
119 $parse = substr ($parse, 0, strlen($parse) - strlen(basename ($parse)) - 1);
124 * transforms a php.ini string representing a value in an integer
125 * @param $value the value from php.ini
126 * @returns an integer for this value
128 function jirafeau_ini_to_bytes ($value)
130 $modifier = substr ($value, -1);
131 $bytes = substr ($value, 0, -1);
132 switch (strtoupper ($modifier))
151 * gets the maximum upload size according to php.ini
152 * @returns the maximum upload size string
155 jirafeau_get_max_upload_size ()
157 return jirafeau_human_size(
158 min (jirafeau_ini_to_bytes (ini_get ('post_max_size')),
159 jirafeau_ini_to_bytes (ini_get ('upload_max_filesize'))));
163 * gets a string explaining the error
164 * @param $code the error code
165 * @returns a string explaining the error
168 jirafeau_upload_errstr ($code)
172 case UPLOAD_ERR_INI_SIZE
:
173 case UPLOAD_ERR_FORM_SIZE
:
174 return t('Your file exceeds the maximum authorized file size. ');
177 case UPLOAD_ERR_PARTIAL
:
178 case UPLOAD_ERR_NO_FILE
:
181 ('Your file was not uploaded correctly. You may succeed in retrying. ');
184 case UPLOAD_ERR_NO_TMP_DIR
:
185 case UPLOAD_ERR_CANT_WRITE
:
186 case UPLOAD_ERR_EXTENSION
:
187 return t('Internal error. You may not succeed in retrying. ');
193 return t('Unknown error. ');
196 /** Remove link and it's file
197 * @param $link the link's name (hash)
201 jirafeau_delete_link ($link)
203 $l = jirafeau_get_link ($link);
207 jirafeau_clean_rm_link ($link);
213 if (file_exists (VAR_FILES
. $p . $md5. '_count'))
215 $content = file (VAR_FILES
. $p . $md5. '_count');
216 $counter = trim ($content[0]);
222 $handle = fopen (VAR_FILES
. $p . $md5. '_count', 'w');
223 fwrite ($handle, $counter);
228 jirafeau_clean_rm_file ($md5);
232 * Delete a file and it's links.
235 jirafeau_delete_file ($md5)
238 /* Get all links files. */
239 $stack = array (VAR_LINKS
);
240 while (($d = array_shift ($stack)) && $d != NULL)
244 foreach ($dir as $node)
246 if (strcmp ($node, '.') == 0 ||
strcmp ($node, '..') == 0 ||
247 preg_match ('/\.tmp/i', "$node"))
250 if (is_dir ($d . $node))
252 /* Push new found directory. */
253 $stack[] = $d . $node . '/';
255 elseif (is_file ($d . $node))
257 /* Read link informations. */
258 $l = jirafeau_get_link (basename ($node));
261 if ($l['md5'] == $md5)
264 jirafeau_delete_link ($node);
269 jirafeau_clean_rm_file ($md5);
274 * handles an uploaded file
275 * @param $file the file struct given by $_FILE[]
276 * @param $one_time_download is the file a one time download ?
277 * @param $key if not empty, protect the file with this key
278 * @param $time the time of validity of the file
279 * @param $ip uploader's ip
280 * @returns an array containing some information
281 * 'error' => information on possible errors
282 * 'link' => the link name of the uploaded file
283 * 'delete_link' => the link code to delete file
286 jirafeau_upload ($file, $one_time_download, $key, $time, $ip)
288 if (empty ($file['tmp_name']) ||
!is_uploaded_file ($file['tmp_name']))
292 array ('has_error' => true,
293 'why' => jirafeau_upload_errstr ($file['error'])),
295 'delete_link' => ''));
298 /* array representing no error */
299 $noerr = array ('has_error' => false, 'why' => '');
301 /* file informations */
302 $md5 = md5_file ($file['tmp_name']);
303 $name = trim ($file['name']);
304 $mime_type = $file['type'];
305 $size = $file['size'];
307 /* does file already exist ? */
310 if (file_exists (VAR_FILES
. $p . $md5))
312 $rc = unlink ($file['tmp_name']);
314 elseif ((file_exists (VAR_FILES
. $p) || @mkdir
(VAR_FILES
. $p, 0755, true))
315 && move_uploaded_file ($file['tmp_name'], VAR_FILES
. $p . $md5))
323 array ('has_error' => true,
324 'why' => t('Internal error during file creation.')),
326 'delete_link' => ''));
329 /* increment or create count file */
331 if (file_exists (VAR_FILES
. $p . $md5 . '_count'))
333 $content = file (VAR_FILES
. $p . $md5. '_count');
334 $counter = trim ($content[0]);
337 $handle = fopen (VAR_FILES
. $p . $md5. '_count', 'w');
338 fwrite ($handle, $counter);
341 /* Create delete code. */
342 $delete_link_code = 0;
343 for ($i = 0; $i < 8; $i++
)
344 $delete_link_code .= dechex (rand (0, 16));
346 /* md5 password or empty */
349 $password = md5 ($key);
351 /* create link file */
352 $link_tmp_name = VAR_LINKS
. $md5 . rand (0, 10000) . ' .tmp';
353 $handle = fopen ($link_tmp_name, 'w');
355 $name . NL
. $mime_type . NL
. $size . NL
. $password . NL
. $time .
356 NL
. $md5. NL
. ($one_time_download ?
'O' : 'R') . NL
.date ('U') .
357 NL
. $ip . NL
. $delete_link_code . NL
);
359 $md5_link = base_16_to_64 (md5_file ($link_tmp_name));
360 $l = s2p ("$md5_link");
361 if (!@mkdir
(VAR_LINKS
. $l, 0755, true) ||
362 !rename ($link_tmp_name, VAR_LINKS
. $l . $md5_link))
364 if (file_exists ($link_tmp_name))
365 unlink ($link_tmp_name);
370 $handle = fopen (VAR_FILES
. $p . $md5. '_count', 'w');
371 fwrite ($handle, $counter);
376 jirafeau_clean_rm_file ($md5_link);
380 array ('has_error' => true,
381 'why' => t('Internal error during file creation. ')),
383 'delete_link' => ''));
385 return (array ('error' => $noerr,
387 'delete_link' => $delete_link_code));
391 * tells if a mime-type is viewable in a browser
392 * @param $mime the mime type
393 * @returns a boolean telling if a mime type is viewable
396 jirafeau_is_viewable ($mime)
400 /* Actually, verify if mime-type is an image or a text. */
401 $viewable = array ('image', 'text');
402 $decomposed = explode ('/', $mime);
403 return in_array ($decomposed[0], $viewable);
409 // Error handling functions.
410 //! Global array that contains all registered errors.
411 $error_list = array ();
414 * Adds an error to the list of errors.
415 * @param $title the error's title
416 * @param $description is a human-friendly description of the problem.
419 add_error ($title, $description)
422 $error_list[] = '<p>' . $title. '<br />' . $description. '</p>';
426 * Informs whether any error has been registered yet.
427 * @return true if there are errors.
433 return !empty ($error_list);
437 * Displays all the errors.
445 echo '<div class="error">';
446 foreach ($error_list as $error)
455 * Read link informations
456 * @return array containing informations.
459 jirafeau_get_link ($hash)
462 $link = VAR_LINKS
. s2p ("$hash") . $hash;
464 if (!file_exists ($link))
468 $out['file_name'] = trim ($c[0]);
469 $out['mime_type'] = trim ($c[1]);
470 $out['file_size'] = trim ($c[2]);
471 $out['key'] = trim ($c[3], NL
);
472 $out['time'] = trim ($c[4]);
473 $out['md5'] = trim ($c[5]);
474 $out['onetime'] = trim ($c[6]);
475 $out['upload_date'] = trim ($c[7]);
476 $out['ip'] = trim ($c[8]);
477 $out['link_code'] = trim ($c[9]);
483 * List files in admin interface.
486 jirafeau_admin_list ($name, $file_hash, $link_hash)
488 echo '<fieldset><legend>';
490 echo t('Filename') . ": $name ";
491 if (!empty ($file_hash))
492 echo t('file') . ": $file_hash ";
493 if (!empty ($link_hash))
494 echo t('link') . ": $link_hash ";
495 if (empty ($name) && empty ($file_hash) && empty ($link_hash))
496 echo t('List all files');
500 echo '<td>' . t('Filename') . '</td>';
501 echo '<td>' . t('Type') . '</td>';
502 echo '<td>' . t('Size') . '</td>';
503 echo '<td>' . t('Expire') . '</td>';
504 echo '<td>' . t('Onetime') . '</td>';
505 echo '<td>' . t('Upload date') . '</td>';
506 echo '<td>' . t('Origin') . '</td>';
507 echo '<td>' . t('Action') . '</td>';
510 /* Get all links files. */
511 $stack = array (VAR_LINKS
);
512 while (($d = array_shift ($stack)) && $d != NULL)
515 foreach ($dir as $node)
517 if (strcmp ($node, '.') == 0 ||
strcmp ($node, '..') == 0 ||
518 preg_match ('/\.tmp/i', "$node"))
520 if (is_dir ($d . $node))
522 /* Push new found directory. */
523 $stack[] = $d . $node . '/';
525 elseif (is_file ($d . $node))
527 /* Read link informations. */
528 $l = jirafeau_get_link ($node);
533 if (!empty ($name) && !preg_match ("/$name/i", $l['file_name']))
535 if (!empty ($file_hash) && $file_hash != $l['md5'])
537 if (!empty ($link_hash) && $link_hash != $node)
539 /* Print link informations. */
542 '<form action = "admin.php" method = "post">' .
543 '<input type = "hidden" name = "action" value = "download"/>' .
544 '<input type = "hidden" name = "link" value = "' . $node . '"/>' .
545 '<input type = "submit" value = "' . $l['file_name'] . '" />' .
548 echo '<td>' . $l['mime_type'] . '</td>';
549 echo '<td>' . jirafeau_human_size ($l['file_size']) . '</td>';
550 echo '<td>' . ($l['time'] == -1 ?
'' : strftime ('%c', $l['time'])) .
552 echo '<td>' . $l['onetime'] . '</td>';
553 echo '<td>' . strftime ('%c', $l['upload_date']) . '</td>';
554 echo '<td>' . $l['ip'] . '</td>';
556 '<form action = "admin.php" method = "post">' .
557 '<input type = "hidden" name = "action" value = "delete_link"/>' .
558 '<input type = "hidden" name = "link" value = "' . $node . '"/>' .
559 '<input type = "submit" value = "' . t('Del link') . '" />' .
561 '<form action = "admin.php" method = "post">' .
562 '<input type = "hidden" name = "action" value = "delete_file"/>' .
563 '<input type = "hidden" name = "md5" value = "' . $l['md5'] . '"/>' .
564 '<input type = "submit" value = "' . t('Del file and links') . '" />' .
571 echo '</table></fieldset>';
575 * Clean expired files.
576 * @return number of cleaned files.
579 jirafeau_admin_clean ()
582 /* Get all links files. */
583 $stack = array (VAR_LINKS
);
584 while (($d = array_shift ($stack)) && $d != NULL)
588 foreach ($dir as $node)
590 if (strcmp ($node, '.') == 0 ||
strcmp ($node, '..') == 0 ||
591 preg_match ('/\.tmp/i', "$node"))
594 if (is_dir ($d . $node))
596 /* Push new found directory. */
597 $stack[] = $d . $node . '/';
599 elseif (is_file ($d . $node))
601 /* Read link informations. */
602 $l = jirafeau_get_link (basename ($node));
605 $p = s2p ($l['md5']);
606 if ($l['time'] > 0 && $l['time'] < time () ||
// expired
607 !file_exists (VAR_FILES
. $p . $l['md5']) ||
// invalid
608 !file_exists (VAR_FILES
. $p . $l['md5'] . '_count')) // invalid
610 jirafeau_delete_link ($node);
patrick-canterino.de