Moved php files in webroot/
[squasher.git] / webroot / squasher.class.php
1 <?php
2 require_once("config.php");
3
4 function zfill($n, $a) {
5         return str_repeat("0", max(0,$a-strlen($n))) . $n;
6 }
7
8 function named_records_sort($named_recs, $order_by, $reverse=false, $flags=0) {
9         $named_hash = array();
10         foreach ($named_recs as $key => $fields)
11                 $named_hash[$key] = $fields[$order_by];
12
13         if ($reverse)
14                 arsort($named_hash,$flags=0) ;
15         else
16                 asort($named_hash, $flags=0);
17
18         $sorted_records = array();
19         foreach($named_hash as $key => $val)$sorted_records[$key] = $named_recs[$key];
20
21         return $sorted_records;
22 }
23
24 function validate_user($username, $password, $salt) {
25         $creds['validated'] = false;
26         $query="SELECT * FROM users WHERE user_name = '".mysql_escape_string($username)."'";
27         $q_result = mysql_query($query);
28         while ($fetched_object = mysql_fetch_object($q_result)) {
29                 if (md5($fetched_object->user_pass.$salt) == $password) {
30                         //validated
31                         $creds['user_id'] = $fetched_object->user_id;
32                         $creds['user_name'] = $fetched_object->user_name;
33                         $creds['user_level'] = $fetched_object->user_level;
34                         $creds['validated'] = true;
35                         $log_hash=str_repeat("0",32); // File ID is always empty on login
36                         $q="INSERT INTO log (hash,action,user_id,user_name,ip,date) VALUES ('".mysql_escape_string($log_hash)."','login',".$creds['user_id'].",'".mysql_escape_string($creds['user_name'])."','".mysql_escape_string($_SERVER['REMOTE_ADDR'])."',NOW())";
37                         mysql_query($q);
38                 }
39         }
40         $_SESSION['creds'] = $creds;
41         return $creds['validated'];
42 }
43
44
45 function get_smarty() {
46         require_once(SQUASHER_SMARTY_SOURCE); // See config.php
47
48         $smarty = new Smarty;
49         $smarty->setTemplateDir(SQUASHER_SMARTY_TEMPLATES)
50                ->setCompileDir(SQUASHER_SMARTY_TEMPLATES_C)
51                ->setCacheDir(SQUASHER_SMARTY_CACHE);
52
53         return $smarty;
54 }
55
56
57 class squashweb {
58
59 var $basepath;
60 var $configs = array();
61 var $files = array();
62 var $subfolders = array();
63 var $folderrights;
64 var $userrights;
65 var $history = array();
66
67 function set_root($root) {
68         $this->basepath = $root;
69 }
70
71 function get_configs() {
72         return $this->configs;
73 }
74
75 function subfolders() {
76         return $this->subfolders;
77 }
78
79 function get_config($h) {
80
81         return $this->configs[$h];
82 }
83
84 function folderrights() {
85         return $this->folderrights;
86 }
87
88 function userrights() {
89         return $this->userrights;
90 }
91
92 function update_history() {
93         $q="SELECT md5_hash,file,completed,checked FROM file_hash";
94         $r=mysql_query($q);
95         while($o=mysql_fetch_object($r)) {
96                 $this->history[$o->md5_hash]['file']=$o->file;
97                 $this->history[$o->md5_hash]['completed']=$o->completed;
98                 $this->history[$o->md5_hash]['checked']=$o->checked;
99         }
100 }
101
102 function get_users($user_level) {
103         $q = "SELECT * FROM users WHERE user_level < ".$user_level." ORDER BY user_name ASC";
104         $r = mysql_query($q);
105
106         while ($o = mysql_fetch_object($r)) {
107                 $return[$o->user_id]['id']              = $o->user_id;
108                 $return[$o->user_id]['name']    = $o->user_name;
109                 $return[$o->user_id]['level']   = $o->user_level;
110                 $return[$o->user_id]['enabled'] = ($o->user_pass == '') ? false : true ;
111         }
112
113         return $return;
114 }
115
116 function get_logs($type='all') {
117         $q="SELECT log.* FROM log WHERE log.user_id != '1' and ip != '87.233.211.2' ";
118         if ($_SESSION['creds']['user_id'] == 1)
119                 $q="SELECT log.* FROM log WHERE log.user_id != 'x' ";
120         switch($type) {
121         case "delete":
122                 $q.= " AND log.action = 'delete'";
123                 break;
124         case "download":
125                 $q.= " AND log.action = 'download'";
126                 break;
127         case "login":
128                 $q.= " AND log.action = 'login'";
129                 break;
130         case "debug":
131                 $q.= " AND log.action = 'debug'";
132                 break;
133         default:
134                 $q.= "";
135                 break;
136         }
137
138         $today     =" AND date > date(date_add(now(), interval -0 day)) ";
139         $yesterday =" AND date < date(date_add(now(), interval -0 day)) AND date > date(date_add(now(), interval -1 day)) ";
140         $lastweek  =" AND date < date(date_add(now(), interval -1 day)) AND date > date(date_add(now(), interval -6 day)) ";
141         $older     =" AND date < date(date_add(now(), interval -7 day)) AND date > date(date_add(now(), interval -30 day)) ";
142
143         $order=" ORDER BY log.log_id desc ";
144         $r = mysql_query($q.$today.$order);
145         $return = array();
146         while($a = mysql_fetch_array($r)) {
147                 $qu="SELECT users.user_name FROM users LEFT JOIN log ON users.user_id = log.user_id WHERE log.ip='".mysql_escape_string($a['ip'])."' GROUP BY users.user_name";
148                 $ru = mysql_query($qu);
149                 $a['users_from_ip'] = " | ";
150                 while($au = mysql_fetch_array($ru))
151                         $a['users_from_ip'] .= $au['user_name']." | ";
152                 $return['today'][$a['log_id']] = $a;
153         }
154         $r = mysql_query($q.$yesterday.$order);
155         while($a = mysql_fetch_array($r)) {
156                 $qu="SELECT users.user_name FROM users LEFT JOIN log ON users.user_id = log.user_id WHERE log.ip='".mysql_escape_string($a['ip'])."' GROUP BY users.user_name";
157                 $ru = mysql_query($qu);
158                 $a['users_from_ip'] = " | ";
159                 while($au = mysql_fetch_array($ru))
160                         $a['users_from_ip'] .= $au['user_name']." | ";
161                 $return['yesterday'][$a['log_id']] = $a;
162         }
163         $r = mysql_query($q.$lastweek.$order);
164         while($a = mysql_fetch_array($r)) {
165                 $qu="SELECT users.user_name FROM users LEFT JOIN log ON users.user_id = log.user_id WHERE log.ip='".mysql_escape_string($a['ip'])."' GROUP BY users.user_name";
166                 $ru = mysql_query($qu);
167                 $a['users_from_ip'] = " | ";
168                 while($au = mysql_fetch_array($ru))
169                         $a['users_from_ip'] .= $au['user_name']." | ";
170                 $return['lastweek'][$a['log_id']] = $a;
171         }
172         $r = mysql_query($q.$older.$order);
173         while($a = mysql_fetch_array($r)) {
174                 $qu="SELECT users.user_name FROM users LEFT JOIN log ON users.user_id = log.user_id WHERE log.ip='".mysql_escape_string($a['ip'])."' GROUP BY users.user_name";
175                 $ru = mysql_query($qu);
176                 $a['users_from_ip'] = " | ";
177                 while($au = mysql_fetch_array($ru))
178                         $a['users_from_ip'] .= $au['user_name']." | ";
179                 $return['older'][$a['log_id']] = $a;
180         }
181
182         return $return;
183 }
184
185 function insert_users($u, $admin_level) {
186         $user_name = $u['user_name'];
187         $user_pass = $u['user_pass'];
188         $user_level = (int)$u['user_level'];
189
190         $q = "INSERT INTO users (user_name,user_pass,user_level) VALUES ('".mysql_escape_string($user_name)."', '".mysql_escape_string(md5($user_pass))."', ".$user_level.")";
191         $r = mysql_query($q);
192 }
193
194 function update_users($u) {
195         $user_id = (int)$u['user_id'];
196         $user_name = @$u['user_name'];
197         $user_pass = @$u['user_pass'];
198         $user_level = (int)@$u['user_level'];
199         if ($user_name) {
200                 $q = "UPDATE users SET user_name = '".mysql_escape_string($user_name)."' WHERE user_id = ".$user_id;
201                 $r = mysql_query($q);
202         }
203         if ($user_pass) {
204                 $q = "UPDATE users SET user_pass = '".mysql_escape_string(md5($user_pass))."' WHERE user_id = ".$user_id;
205                 $r = mysql_query($q);
206         }
207         if ($user_level) {
208                 $q = "UPDATE users SET user_level = ".$user_level." WHERE user_id = ".$user_id;
209                 $r = mysql_query($q);
210         }
211 }
212
213 function disable_users($u) {
214         $user_id = (int)$u['user_id'];
215         $user_name = @$u['user_name'];
216         $user_level = (int)@$u['user_level'];
217         if ($user_name) {
218                 $q = "UPDATE users SET user_name = '".mysql_escape_string($user_name)."' WHERE user_id = ".$user_id;
219                 $r = mysql_query($q);
220         }
221         $q = "UPDATE users SET user_pass = '' WHERE user_id = ".$user_id;
222         $r = mysql_query($q);
223         if ($user_level) {
224                 $q = "UPDATE users SET user_level = ".$user_level." WHERE user_id = ".$user_id;
225                 $r = mysql_query($q);
226         }
227         $r = mysql_query($q);
228 }
229
230 function remove_users($u) {
231         $user_id = (int)$u['user_id'];
232         $q = "DELETE FROM users WHERE user_id = ".$user_id;
233         $r = mysql_query($q);
234 }
235
236 function get_rights($user_id) {
237         $result = array();
238
239         $q = "SELECT folder_path, access FROM user_rights WHERE user_id = ".(int)$user_id;
240         $r = mysql_query($q);
241         while ($o = mysql_fetch_object($r)) {
242
243                 //clean vars
244                 $arr_string = '$result';
245
246                 //get foldernames from path
247                 if ($o->folder_path != '/') {
248                         $path = $o->folder_path;
249                         if ($path{0}=='/')
250                                 $path=substr($path,1);
251                         $folder_arr = explode('/',$path);
252
253                         //create folder structure array
254                         foreach ($folder_arr AS $key => $value) {
255                                 $value_escaped = str_replace("'", "\\'", $value);
256                                 $arr_string .= "['".$value_escaped."']";
257                         }
258                 }
259                 $arr_string .= "['__access__']";
260
261                 eval($arr_string." = '".$o->access."';");
262         }
263         return $result;
264 }
265
266 function give_rights($user_id, $type='folderrights') {
267         if ($type=='folderrights')
268                 $this->folderrights = $this->get_rights($user_id);
269         else // $type=='userrights'
270                 $this->userrights = $this->get_rights($user_id);
271 }
272
273 function update_rights($edited_user, $m, $admin_level) {
274         $q = "SELECT count(*) result FROM users WHERE user_id = ".(int)$edited_user." AND user_level < ".(int)$admin_level;
275         $r = mysql_query($q);
276         $o = mysql_fetch_object($r);
277
278         if ($o->result) {
279                 foreach ($m AS $path => $access) {
280                         $p_q = "SELECT count(*) result FROM user_rights WHERE user_id = ".(int)$edited_user." AND folder_path = '".mysql_escape_string($path)."'";
281                         $p_r = mysql_query($p_q);
282                         $p_o = mysql_fetch_object($p_r);
283                         if ($p_o->result == 1)
284                                 mysql_query("UPDATE user_rights SET access = ".(int)$access." WHERE folder_path = '".mysql_escape_string($path)."' AND user_id = ".(int)$edited_user);
285                         if ($p_o->result == 0)
286                                 mysql_query("INSERT INTO user_rights (user_id,folder_path,access) values (".(int)$edited_user.",'".mysql_escape_string($path)."',".(int)$access.") ");
287                 }
288         }
289 }
290
291
292 function show_rights_tree($path, $depth=0, $userid=0) {
293
294         if ($userid==0)
295                 return false;
296         if ($depth==0)
297                 $this->give_rights($userid, 'userrights');
298
299         // access = 0 --deny-all
300         // access = 1 --allow-dir-only
301         // access = 2 --allow-inc-subs
302
303         $layout = '';
304         $style = '';
305
306         for ($i=0; $i<$depth; $i++)
307                 $layout .= " ";
308         if ($dir = opendir($path)) {
309                 $layout .= "<div style='clear:both;' >\n";
310                 $f = 0;
311                 while (false !== ($file = readdir($dir))) {
312                         $files_array[] = $file;
313                 }
314                 asort($files_array);
315                 foreach ($files_array as $f_index => $file) {
316                         if (($file{0} !== ".") && ($file !== ".."))
317                         {
318                                 $filename = $path."/".$file;
319                                 if (!is_file($filename) && $this->got_rights_array($filename) > 0) {
320                                         $f++;
321                                         if (substr($filename,0,strlen($this->basepath))==$this->basepath)
322                                                 $name = substr($filename,strlen($this->basepath));
323                                         $check = $this->got_rights_array_admin($filename, $this->userrights);
324                                         $check_all = '';
325                                         $check_allow = '';
326                                         $check_deny = '';
327                                         switch($check) {
328                                                 case 2:
329                                                         $check_all = 'checked';
330                                                         break;
331                                                 case 1:
332                                                         $check_allow = 'checked';
333                                                         break;
334                                                 case 0:
335                                                 default:
336                                                         $check_deny = 'checked';
337                                                         break;
338                                         }
339
340                                         if ($f==1)
341                                                 $style[$depth] = ".depth".$depth."{float:right;width:".(600-($depth*10))."px;border-left:2px solid #FFFFFF;border-top:1px solid #FFFFFF;background:#".dechex(14-$depth).dechex(14-$depth).dechex(14-$depth).dechex(14-$depth).dechex(14-$depth).dechex(14-$depth).";}";
342                                         if ($f==1)
343                                                 $layout .= "<div class='depth".$depth."'>";
344                                         $layout .= "<div class='white_border' >".htmlspecialchars($file)."</div>\n";
345                                         $name_escaped = htmlspecialchars($name);
346                                         $layout .= '<div class="check_deny"><input name="m['.$name_escaped.']" value=0 type=radio '.$check_deny."></div>\n";
347                                         $layout .= '<div class="check_allow"><input name="m['.$name_escaped.']" value=1 type=radio '.$check_allow."></div>\n";
348                                         $layout .= '<div class="check_all"><input name="m['.$name_escaped.']" value=2 type=radio '.$check_all."></div>\n";
349                                         $sub_return = $this->show_rights_tree($filename,$depth+1,$userid);
350                                         if (is_array($style) && is_array($sub_return['style']))
351                                                 $style = $style + $sub_return['style'];
352                                         $layout .= $sub_return['layout'];
353                                 }
354                         }
355                 }
356                 if ($f!=0)
357                         $layout .= "</div>";
358                 $layout .= "</div>\n";
359         }
360
361         $return['style'] = $style;
362         $return['layout'] = $layout;
363
364         return $return;
365 }
366
367 function got_rights_array($needle, $haystack='', $c=0) {
368         // used by:
369         // - read_single_file
370         // - read_directory
371         // - show_rights_tree
372
373         if (!is_array($haystack))
374                 $haystack = $this->folderrights;
375         if (substr($needle, 0, strlen($this->basepath)) == $this->basepath)
376                 $needle=substr($needle,strlen($this->basepath));
377
378         // check root rights
379         if ($needle{0} == '/' && @$haystack['__access__'] == 2 )
380                 return 2;
381
382         // remove leading /
383         if ($needle{0}=='/')
384                 $needle = substr($needle, 1);
385
386         $needle_arr = explode('/', $needle);
387         $n = count($needle_arr);
388         $d = $c + 1;
389
390         foreach ($haystack as $k => $v) {
391                 if ($needle_arr[$c] == $k) {
392                         if (!is_array(@$v['__access__'])) {
393                                 if ($v['__access__'] == 2             ) return 2;
394                                 if ($v['__access__'] == 1 && $d == $n ) return 1;
395                                 if ($v['__access__'] == 0 && $d == $n ) return 0;
396                         } else {
397                                 $return = $this->got_rights_array($needle, $v, $d);
398                         }
399                 }
400         }
401         return $return;
402 }
403
404 function got_rights_array_admin($needle, $haystack='', $c=0) {
405         // used by:
406         // - show_rights_tree
407
408         if (!is_array($haystack))
409                 $haystack = $this->folderrights;
410         if (substr($needle, 0, strlen($this->basepath)) == $this->basepath)
411                 $needle = substr($needle, strlen($this->basepath));
412
413         // check root rights
414         if ($needle{0} == '/' && @$haystack['__access__'] == 2 )
415                 return 2;
416
417         // remove leading /
418         if ($needle{0} == '/')
419                 $needle = substr($needle, 1);
420
421         $needle_arr = explode('/', $needle);
422         $n = count($needle_arr);
423         $d = $c + 1;
424         $return = 0;
425
426         if ($c < $n) {
427                 if (@$haystack['__access__'] == 2)
428                         return $haystack['__access__'];
429                 if (is_array($haystack[$needle_arr[$c]]))
430                         $return = $this->got_rights_array_admin($needle, $haystack[$needle_arr[$c]], $d);
431         } else {
432                 if (@$haystack['__access__'] > 0)
433                         $return = $haystack['__access__'];
434         }
435
436         return $return;
437 }
438
439 function got_rights_array_recursive($needle, $haystack='', $c=0) {
440         // used by:
441         // - read_directory, for subfolders
442
443         if (!is_array($haystack))
444                 $haystack = $this->folderrights;
445         if (substr($needle, 0, strlen($this->basepath)) == $this->basepath)
446                 $needle=substr($needle, strlen($this->basepath));
447
448         // check root rights
449         if($needle{0}=='/' && @$haystack['__access__'] == 2 )
450                 return 2;
451
452         // check folder rights
453         if($needle{0}=='/')
454                 $needle=substr($needle,1);
455
456         $needle_arr = explode('/', $needle);
457         $n = count($needle_arr);
458         $d = $c + 1;
459         $return = 0;
460
461         foreach($haystack as $k => $v) {
462                 if ($c < sizeof($needle_arr) && $needle_arr[$c] == $k) {
463                         if ($c < $n) {
464                                 if ($v['__access__'] == 2)
465                                         $return = $return + $v['__access__'];
466                                 $return = $return + $this->got_rights_array_recursive($needle, $v, $d);
467                         } else {
468                                 $return = $return + $this->in_array_recursive($v);
469                         }
470                 } elseif ($c == $n) {
471                         $return = $return + $v['__access__'];
472                         if($k != '__access__')$return = $return + $this->in_array_recursive($v);
473                 }
474         }
475
476         return $return;
477 }
478
479 function in_array_recursive($haystack) {
480         $return = 0;
481         if (is_array($haystack)) {
482                 foreach ($haystack as $key1 => $value1) {
483                         if (is_array($value1)) {
484                                 $return = $return + $this->in_array_recursive($value1);
485                         }
486                         elseif ($value1 > 0) {
487                                 return $value1;
488                         }
489                 }
490         }
491         return $return;
492 }
493
494 function read_single_file($path, $file) {
495         $filename = $path."/".$file;
496         $i = 0;
497         if ($this->got_rights_array($path) > 0) {
498                 if (is_file($filename.'.Completed'))
499                         $file.='.Completed';
500                 if (is_file($filename.'.InProgress'))
501                         $file.='.InProgress';
502                 if (is_file($filename.'.Starting'))
503                         $file.='.Starting';
504                 if (is_file($filename.'.Processed'))
505                         $file.='.Processed';
506                 $filename = $path . "/" . $file;
507                 $handle = @fopen($filename, "rb");
508                 if (strpos($file,'.Completed'))
509                         $ext='.Completed';
510                 if (strpos($file,'.InProgress'))
511                         $ext='.InProgress';
512                 if (strpos($file,'.Starting'))
513                         $ext='.Starting';
514                 if (strpos($file,'.Processed'))
515                         $ext='.Processed';
516                 $sub_pos = strpos($file, $ext);
517                 $base_name = substr($file, 0, $sub_pos);
518                 $filecontent = @fread($handle, @filesize($filename));
519                 $config[$i] = explode("\r\n", $filecontent);
520                 /***
521                 *       $config:: array
522                 *       [0]     ->      versioncode
523                 *       [1]     ->      date&time
524                 *       [2]     ->      filename
525                 *       [3]     ->      filesize
526                 *       [4]     ->      chunksize
527                 *       [5]     ->      chunkcount
528                 *       [6]     ->      CRC32 checksum
529                 ***/
530                 if (@filesize($filename) > 0) {
531                         $h = md5($path."/".$config[$i][2]);
532                         $this->configs[$h] = $config[$i];
533                         $this->configs[$h]['squashed'] = true;
534                         $this->configs[$h]['path'] = $path;
535                         $this->configs[$h]['status'] = substr($ext, 1);
536                         $this->configs[$h]['mime'] = $this->set_mime($this->configs[$h][2]);
537                         $this->configs[$h]['hidden'] = (is_file($path.'/'.$base_name.'.hidden')) ? true : false ;
538                         //to prevent dates of 1-1-1970 we set te dates of the config file
539                         $this->configs[$h]['added'] = filectime($filename);
540                         $this->configs[$h]['lastchange'] = filemtime($filename);
541                         fclose($handle);
542                         $this->populate_stats($path, $h);
543                         //insert hash in db
544                         #$this->update_hash($h,$path."/".$config[$i][2]);
545                         //check stats
546                         $this->check_stats($h);
547                 }
548         }
549 }
550
551
552 function read_directory($path, $getsubs=false, $getfirstfiles=true, $getdeepfiles=true, $populate=true) {
553
554         if ($dir = @opendir($path)) {
555                 $i = 0;
556                 $last = 1;
557                 while (false !== ($file = readdir($dir))) {
558                         if (($file{0} !== ".") && substr($file,0,1) !== "SQ") {
559                                 $filename = $path."/".$file;
560                                 if (!is_file($filename) && strpos($filename, './uploads/recieving')===false) {
561                                         if ($getsubs) {
562                                                 if ($this->got_rights_array_recursive($filename) > 0) {
563                                                         $key = substr($path, strlen($this->basepath)) . '/' . $file;
564                                                         $this->subfolders[$key] = $file;
565                                                 }
566                                         }
567                                         if ($getdeepfiles)
568                                                 $this->read_directory($filename, false, $getdeepfiles, $getdeepfiles, $populate);
569                                 } elseif (strpos($filename,'./uploads/ftp')) { //ftp files
570                                         if ($this->got_rights_array($path) > 0 && !strpos($filename, '.hidden') ) {
571                                                 $h = md5($filename);
572                                                 $name_only = substr($filename, strlen($path)+1);
573                                                 $file_structure = explode('.', $name_only);
574                                                 $ext = array_pop($file_structure);
575                                                 $base_name = array_pop($file_structure);
576                                                 $this->configs[$h]['path'] = $path;
577                                                 $this->configs[$h][0] = 'manual ftp';
578                                                 $this->configs[$h][2] = $name_only;
579                                                 $this->configs[$h][3] = filesize($filename);
580                                                 $this->configs[$h]['added'] = filectime($filename);
581                                                 $this->configs[$h]['lastchange'] = filemtime($filename);
582                                                 $this->configs[$h]['status'] = 'unknown';
583                                                 $this->configs[$h]['squashed'] = false;
584                                                 $this->configs[$h]['mime'] = $this->set_mime($name_only);
585                                                 $this->configs[$h]['hidden'] = (is_file($path.'/'.$base_name.'.hidden')) ? true : false ;
586                                         }
587                                 } elseif ($getfirstfiles) {
588                                         //squashed files
589                                         if ($this->got_rights_array($path) > 0) {
590                                                 if (strpos($filename, '.Completed') || strpos($filename, '.InProgress') || strpos($filename, '.Starting') || strpos($filename, '.Processed')) {
591                                                         $i++;
592                                                         $handle = @fopen($filename, "rb");
593                                                         if (strpos($file,'.Completed'))
594                                                                 $ext='.Completed';
595                                                         if (strpos($file,'.InProgress'))
596                                                                 $ext='.InProgress';
597                                                         if (strpos($file,'.Starting'))
598                                                                 $ext='.Starting';
599                                                         if (strpos($file,'.Processed'))
600                                                                 $ext='.Processed';
601                                                         $sub_pos = strpos($file, $ext);
602                                                         $base_name = substr($file, 0, $sub_pos);
603                                                         $filecontent = @fread($handle, @filesize($filename));
604                                                         $config[$i] = explode("\r\n", $filecontent);
605
606                                                         /***
607                                                         *       $config:: array
608                                                         *       [0]     ->      versioncode
609                                                         *       [1]     ->      date&time
610                                                         *       [2]     ->      filename
611                                                         *       [3]     ->      filesize
612                                                         *       [4]     ->      chunksize
613                                                         *       [5]     ->      chunkcount
614                                                         *       [6]     ->      CRC32 checksum
615                                                         ***/
616
617                                                         if (@filesize($filename) > 0) {
618                                                                 $h = md5($path."/".$config[$i][2]);
619                                                                 $this->configs[$h] = $config[$i];
620                                                                 $this->configs[$h]['squashed'] = true;
621                                                                 $this->configs[$h]['path'] = $path;
622                                                                 $this->configs[$h]['status'] = substr($ext, 1);
623                                                                 $this->configs[$h]['mime'] = $this->set_mime($this->configs[$h][2]);
624                                                                 $this->configs[$h]['hidden'] = (is_file($path.'/'.$base_name.'.hidden')) ? true : false ;
625                                                                 //to prevent dates of 1-1-1970 we set te dates of the config file
626                                                                 $this->configs[$h]['added'] = filectime($filename);
627                                                                 $this->configs[$h]['lastchange'] = filemtime($filename);
628                                                                 fclose($handle);
629                                                                 $this->populate_stats($path, $h);
630                                                                 //insert hash in db
631                                                                 $this->update_hash($h, $path."/".$config[$i][2]);
632                                                                 //check stats
633                                                                 $this->check_stats($h);
634                                                         }
635                                                 }
636                                         }
637                                 }
638                         }
639                 }
640         }
641 }
642
643 function check_stats($h) {
644         $config = $this->get_config($h);
645         $count = @array_sum($config['stats']);
646         if ($config['status']=='Completed' && $count != $config[5]) {
647                 $filepath=$config['path'].'/'.$config[2];
648                 if ($this->history[$h]['completed']=="1") {
649                         //don't display broken file, remove it instead
650                         unlink($config['path'].'/'.$config[2].'.Completed');
651                         unset($this->configs[$h]);
652
653                         if (!$count)
654                                 $count = 0;
655                         $m_subject = "Squasher Debug: File Removed";
656                         $m_body = "Upload removed: \n File: ".$config['path']."/".$config[2]." \n Status: ".$config['status']." \n Chunks: ".$count." out of ".$config[5];
657                         mail('jasper@netformatie.nl', $m_subject, $m_body, "From: support@netformatie.nl");
658                         $qlog = "INSERT INTO log (hash,file,action,user_id,user_name,ip,date) VALUES ('".mysql_escape_string($h)."','".mysql_escape_string($filepath)."','debug',-1,'squasher-web','cleanup',NOW())";
659                         mysql_query($qlog);
660                 } else {
661                         //do move
662                         rename($config['path'].'/'.$config[2].'.Completed', $config['path'].'/'.$config[2].'.InProgress');
663                         $this->configs[$h]['status'] = 'InProgress';
664
665                         //mail n4m
666                         if (!$count)
667                                 $count = 0;
668                         $m_subject = "Squasher Debug: Upload Error";
669                         $m_body = "Upload error: \n File: ".$config['path']."/".$config[2]." \n Status: ".$config['status']." \n Chunks: ".$count." out of ".$config[5];
670                         mail('support@netformatie.nl', $m_subject, $m_body, "From: squasher@netformatie.nl");
671                         mail('jan@netformatie.nl', $m_subject, $m_body, "From: support@netformatie.nl");
672                         mail('joop@netformatie.nl', $m_subject, $m_body, "From: support@netformatie.nl");
673                         mail('jasper@netformatie.nl', $m_subject, $m_body, "From: support@netformatie.nl");
674
675                         //do sms
676                         //wget -o/dev/null "http://www.mollie.nl/xml/sms/?username=netformatie&password=SMSdolsi&originator=Netformatie&recipients=${ENGINEER}&message=${CALLERID}";
677
678                         //mail RO
679                         $ship = explode('/',$config['path']);
680                         if ($ship[2] == 'myas' || $ship[2] == 'myez' || $ship[2] == 'myrw')
681                                 mail('ro1@'.$ship[2].'.greenpeace.org','Squasher: '.$config[2].' resume request','The squasher server has detected an upload error. Please resume the squasher transmission for '.$config[2].' to correct this problem.',"From: support@netformatie.nl\nX-Priority: 1");
682
683                         $qlog = "INSERT INTO log (hash,file,action,user_id,user_name,ip,date) VALUES ('".mysql_escape_string($h)."','".mysql_escape_string($filepath)."','debug',-1,'squasher-web','retry',NOW())";
684                         mysql_query($qlog);
685
686                 }
687         } elseif ($config['status']=='Completed' && $count == $config[5]) {
688                 if ($this->history[$h]['completed']==0)
689                         mysql_query("UPDATE file_hash SET completed = 1 WHERE md5_hash = '".mysql_escape_string($h)."'");
690         }
691 }
692
693 function update_hash($hash, $path) {
694         $check_hash_query = "select * from file_hash where md5_hash = '".$hash."'";
695         $check_hash_result = mysql_query($check_hash_query);
696         if(mysql_num_rows($check_hash_result) == 0) {
697                 $insert_hash_query = "INSERT INTO file_hash (md5_hash,file) values ('".mysql_escape_string($hash)."','".mysql_escape_string($path)."')";
698                 mysql_query($insert_hash_query);
699         }
700 }
701
702 function path_to_arraystring($path, $arrayname) {
703         $path_values = explode('/', $path);
704         $return = $arrayname;
705         foreach ($path_values AS $key => $value) {
706                 if ($value != '.' && $value != '')
707                         $return.= "['".$value."']";
708         }
709         return $return;
710 }
711
712 function populate_stats($path, $h) {
713         /***
714         *       $config:: array
715         *       [0]     ->      versioncode
716         *       [1]     ->      date&time
717         *       [2]     ->      filename
718         *       [3]     ->      filesize
719         *       [4]     ->      chunksize
720         *       [5]     ->      chunkcount
721         *       [6]     ->      CRC32 checksum
722         ***/
723         $config = $this->configs[$h];
724
725         $q = "SELECT * FROM file_hash WHERE md5_hash = '".mysql_escape_string($h)."'";
726         $r = mysql_query($q);
727         $o = mysql_fetch_object($r);
728         $validated_chunks = $o->validated_chunks;
729
730         if ($this->history[$h]['completed']=="1") {
731                 $file_part = $path."/SQ".zfill(1,6)."-".$config[2];
732                 if (!is_file($file_part))
733                         $file_part = $path."/SQ".zfill(1,3)."-".$config[2];
734                 if (is_file($file_part)) {
735                         $this->configs[$h]['added'] = filectime($file_part);
736                         $file_part = $path."/SQ".zfill($config[5],6)."-".$config[2];
737                         if (!is_file($file_part))
738                                 $file_part = $path."/SQ".zfill($config[5],3)."-".$config[2];
739                         if (is_file($file_part))
740                                 $this->configs[$h]['lastchange'] = filemtime($file_part);
741                         for ($i=1; $i<=$config[5]; $i++)
742                                 $this->configs[$h]['stats'][$i] = "1.00";
743                 } else {
744                         //failsafe voor verwijderde bestanden
745                         mysql_query("UPDATE file_hash SET completed = 0 WHERE md5_hash = '".mysql_escape_string($h)."'");
746                 }
747         } else {
748                 $keep_validating = true;
749                 for ($i=1; $i<=$config[5]; $i++) {
750                         if ($validated_chunks > $i) {
751                                 $this->configs[$h]['stats'][$i]="1.00";
752                         } else {
753                                 $file_part = $path."/SQ".zfill($i,6)."-".$config[2];
754                                 if (!is_file($file_part))
755                                         $file_part = $path."/SQ".zfill($i,3)."-".$config[2];
756                                 if (is_file($file_part)) {
757                                         $handle = fopen($file_part, "rb");
758                                         $size_this = filesize($file_part);
759                                         $added = filectime($file_part);
760                                         $last_changed = filemtime($file_part);
761                                         if ($this->configs[$h]['added'] > $added || !is_numeric($this->configs[$h]['added']))
762                                                 $this->configs[$h]['added'] = $added;
763                                         if ($this->configs[$h]['lastchange'] < $last_changed)
764                                                 $this->configs[$h]['lastchange'] = $last_changed;
765                                         if ($i != $config[5]) {
766                                                 $this->configs[$h]['stats'][$i] = number_format((1/$config[4])*$size_this, 2, '.', '');
767                                         //number_format((100/$config[4])*$size_this, 2, '.', '')."%";
768                                         }else{
769                                                 $this->configs[$h]['stats'][$i] = number_format((1/($config[3]-($config[4]*($config[5]-1))))*$size_this, 2, '.', '');
770                                                 //number_format((100/($config[3]-($config[4]*($config[5]-1))))*$size_this, 2, '.', '')."%";
771                                         }
772                                         fclose($handle);
773                                         if ($config[4] == $size_this && $keep_validating) {
774                                                 $validated_chunks = $i;
775                                         } else {
776                                                 $keep_validating = false;
777                                         }
778                                 } else {
779                                         $this->configs[$h]['stats'][$i] = "0.00";
780                                         //$this->configs[$h]['stats'][$i]="0.00%";
781
782                                 }
783                         }
784                 }
785                 mysql_query("UPDATE file_hash SET validated_chunks = '".mysql_escape_string($validated_chunks)."' WHERE md5_hash = '".mysql_escape_string($h)."'");
786         }
787 }
788
789 function read_config($path, $filename) {
790         if (is_file($path."/".$filename.".InProgress")) {
791                 $config_handle = fopen($path."/".$filename.".InProgress", "r");
792                 $conf_path=$path."/".$filename.".InProgress";
793         } elseif (is_file($path."/".$filename.".Completed" )) {
794                 $config_handle = fopen($path."/".$filename.".Completed", "r");
795                 $conf_path=$path."/".$filename.".Completed";
796         } elseif (is_file($path."/".$filename.".Starting" )) {
797                 $config_handle = fopen($path."/".$filename.".Starting", "r");
798                 $conf_path=$path."/".$filename.".Starting";
799         } elseif (is_file($path."/".$filename.".Processed" )) {
800                 $config_handle = fopen($path."/".$filename.".Processed", "r");
801                 $conf_path=$path."/".$filename.".Processed";
802         } else {
803                 return "Not Found";
804         }
805         $config_content = fread($config_handle, filesize($conf_path));
806         fclose($config_handle);
807         $config = explode("\n", $config_content);
808
809         return $config;
810 //              print_r($config);
811 /*              $file_count = $config[5];
812                 $last=1;
813     for ($i=1; $i<=$file_count; $i++)
814     {
815         $file_part = $path."/SQ".zfill($i,6)."-".$filename;
816         if (is_file($file_part))
817        {
818
819         $handle = fopen($file_part, "rb");
820         $size_this = filesize($file_part);
821                                 //$stats[$i]=round((100/$config[4])*$size_this)."%";
822                                 if ((($size_this==$config[4] && ($last+1)==$i) )|| $i == $config[5]) {
823                                         $merged_file.=fread($handle, filesize($file_part));
824                                         $last = $i;
825                                 }
826         fclose($handle);
827        }
828      }
829      return $merged_file;
830      */
831 }
832
833 function print_files($path, $filename, $tovar=false) {
834         if (strpos($path, './uploads/ftp')) {
835                 $filestring = $path.'/'.$filename;
836                 if (is_file($filestring)) {
837                         $handle = fopen($filestring, "rb");
838                         while (!feof($handle))
839                         {
840                                 print(fread($handle, 1024));
841                                 ob_flush();
842                                 flush();
843                         }
844                 }
845         } else {
846                 if (is_file($path."/".$filename.".InProgress")) {
847                         $config_handle = fopen($path."/".$filename.".InProgress", "r");
848                         $conf_path=$path."/".$filename.".InProgress";
849                 } elseif (is_file($path."/".$filename.".Completed" )) {
850                         $config_handle = fopen($path."/".$filename.".Completed", "r");
851                         $conf_path=$path."/".$filename.".Completed";
852                 } elseif (is_file($path."/".$filename.".Starting" )) {
853                         $config_handle = fopen($path."/".$filename.".Starting", "r");
854                         $conf_path=$path."/".$filename.".Starting";
855                 } elseif (is_file($path."/".$filename.".Processed" )) {
856                         $config_handle = fopen($path."/".$filename.".Processed", "r");
857                         $conf_path=$path."/".$filename.".Processed";
858                 } else{
859                         return "Not Found";
860                 }
861                 $config_content = fread($config_handle, filesize($conf_path));
862                 fclose($config_handle);
863                 $config = explode("\n",$config_content);
864 //              print_r($config);
865                 $file_count = $config[5];
866                 $last = 0;
867                 $last_part_size = ( $config[3] - ( ( $config[5] -1 ) * $config[4] ) );
868                 for ($i=0;$i<=$file_count;$i++)
869                 {
870                         $file_part = $path."/SQ".zfill($i,6)."-".$filename;
871                         if (!is_file($file_part))
872                                 $file_part = $path."/SQ".zfill($i,3)."-".$filename;
873                         if (is_file($file_part))
874                         {
875                                 $handle = fopen($file_part, "rb");
876                                 $size_this = filesize($file_part);
877                                 if ( ( ( $size_this==$config[4] ) && ( ($last+1)==$i ) ) || ( ( $i == $config[5] ) && ( $size_this==$last_part_size ) && ( ($last+1)==$i ) ) ) {
878                                         if ($tovar) {
879                                                 $merged_file.=fread($handle, $size_this);
880                                                 $last = $i;
881                                         } else {
882                                                 while (!feof($handle))
883                                                 {
884                                                         print(fread($handle, 4096));
885                                                 #       @ob_flush();
886                                                 #       @flush();
887                                                 }
888                                                 $last = $i;
889                                         }
890                                 }
891                                 fclose($handle);
892                         }
893                 }
894                 if ($tovar)
895                         return $merged_file;
896         }
897 }
898
899 function check_md5($h) {
900         $return = false;
901         $config = $this->configs[$h];
902         $var = $this->print_files($config['path'], $config[2], true);
903         $hash = md5($var);
904         if ($hash==$config[6])
905                 $return=true;
906
907         return $return;
908 }
909
910 function file_crc($file_string) {
911         //$file_string = file_get_contents($file);
912
913         $crc = crc32($file_string);
914         return sprintf("%u\n", $crc);
915 }
916
917 function file_crc_debug($file) {
918         $file_string = file_get_contents($file);
919
920         $crc = crc32($file_string);
921         return sprintf("%u\n", $crc);
922 }
923
924 function delete_file($h, $s) {
925         $request = $this->get_config($h);
926         $filepath=$request['path'].'/'.$request[2];
927         if (strpos($request['path'], './uploads/ftp')) {
928                 #remove file
929                 if (is_file($filepath))
930                         @unlink($filepath);
931                 if (is_file($filepath.'.hidden'))
932                         @unlink($filepath.'.hidden');
933         } else {
934                 #remove fileparts
935                 for ($i=0;$i<=$request[5];$i++) {
936                         $part_six   = $request['path']."/SQ".zfill($i,6)."-".$request[2];
937                         $part_three = $request['path']."/SQ".zfill($i,3)."-".$request[2];
938                         if (is_file($part_six))
939                                 @unlink($part_six);
940                         if (is_file($part_three))
941                                 @unlink($part_six);
942                 }
943                 #remove config file
944                 if (is_file($request['path'].'/'.$request[2].'.hidden'))        @unlink($request['path'].'/'.$request[2].'.hidden');
945                 if (is_file($request['path'].'/'.$request[2].'.Completed'))     @unlink($request['path'].'/'.$request[2].'.Completed');
946                 if (is_file($request['path'].'/'.$request[2].'.InProgress'))@unlink($request['path'].'/'.$request[2].'.InProgress');
947                 if (is_file($request['path'].'/'.$request[2].'.Processed'))     @unlink($request['path'].'/'.$request[2].'.Processed');
948                 if (is_file($request['path'].'/'.$request[2].'.Starting'))      @unlink($request['path'].'/'.$request[2].'.Starting');
949         }
950
951         #Update DB
952         $q = "DELETE FROM file_hash WHERE file_hash = '".mysql_escape_string($h)."'";
953         mysql_query($q);
954         $q = "INSERT INTO log (hash,file,action,user_id,user_name,ip,date) VALUES ('".mysql_escape_string($h)."','".mysql_escape_string($filepath)."','delete',".(int)$s['user_id'].",'".mysql_escape_string($s['user_name'])."','".mysql_escape_string($_SERVER['REMOTE_ADDR'])."',NOW())";
955         mysql_query($q);
956
957         #Send debug mail
958         $m_name = $s['user_name'];
959         $m_subject = "Squasher Debug: File Deleted by {$m_name}";
960         $m_body = "File Deleted: \n Requested by: {$m_name} \n File: {$filepath}";
961         mail('jasper@netformatie.nl', $m_subject, $m_body, "From: support@netformatie.nl");
962 }
963
964 function show_files() {
965
966         $path = "./uploads/";
967
968         if ($dir = opendir($path)) {
969                 $i = 1;
970                 $last = 1;
971                 $files = array();
972                 $files_merged = array();
973                 while (false !== ($file = readdir($dir)))
974                 {
975                         if (($file !== ".") && ($file !== ".."))
976                         {
977                                 $filename = $path.$file;
978                                 $handle = fopen($filename, "rb");
979                                 $size_this = filesize($filename);
980                                 if ($i==1)
981                                         $size_first = $size_this;
982                                 $filecontent = fread($handle, filesize($filename));
983                                 $files[$i++] = $filename;
984                                 $files_merged[$file_base][]=$filename;
985                                 fclose($handle);
986                         }
987                 }
988         }
989         echo "<pre>";
990         print_r($files);
991         print_r($files_merged);
992         echo "</pre>";
993 }
994
995 function set_mime($filename) {
996         $ext_arr = explode('.', $filename);
997         $ext = strtolower(array_pop($ext_arr));
998         switch($ext) {
999                 case 'avi':
1000                         $mime = 'video/avi';
1001                         break;
1002                 case 'mpeg':
1003                 case 'mpg':
1004                         $mime = 'video/mpeg';                                   //MPEG Video
1005                         break;
1006                 case 'exe':
1007                 case 'bat':
1008                 case 'doc':
1009                 case 'xls':
1010                         $mime = 'application/octet-stream';
1011                         break;
1012                 case 'gif':
1013                         $mime = 'image/gif';                                    //GIF Image
1014                         break;
1015                 case 'jpg':
1016                 case 'jpeg':
1017                         $mime = 'image/jpeg';                                   //JPEG Image
1018                         break;
1019                 case 'png':
1020                         $mime = 'image/png';                                    //PNG Image
1021                         break;
1022                 case 'wav':
1023                 case 'wave':
1024                         $mime = 'audio/wav';                                    //WAV Audio
1025                         break;
1026                 case 'mp3':
1027                         $mime = 'audio/mpeg';                                   //MP3 Audio
1028                         break;
1029                 case 'mov':
1030                         $mime = 'video/mov';                                    //Quicktime Video
1031                         break;
1032                 case 'wmv':
1033                         $mime = 'video/x-ms-wmv';                       //Windows WMV video
1034                         break;
1035                 case 'wma':
1036                         $mime = 'audio/x-ms-wma';                       //Windows WMA audio
1037                         break;
1038                 case 'rm':
1039                         $mime = 'audio/x-realaudio';    //RealPlayer Audio/Video (.rm)
1040                         break;
1041                 case 'ram':
1042                         $mime = 'audio/x-pn-realaudio'; //RealPlayer Audio/Video (.ram)
1043                         break;
1044                 case 'pdf':
1045                         $mime = 'application/pdf';              //PDF Document
1046                         break;
1047                 case 'doc':
1048                         $mime = 'application/msword';   //MS Word .doc file
1049                         break;
1050                 case 'zip':
1051                         $mime = 'application/zip';              //Zip File
1052                         break;
1053                 default:
1054                         $mime = 'application/octet-stream';
1055                         break;
1056         }
1057         //$return['mime']=$mime;
1058         //$return['ext']=$ext;
1059
1060         return $mime;
1061 }
1062
1063 }
1064 // vim: syntax=php ts=4 sw=4 sts=4 sr noet
1065 ?>