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