root / nephthys.class.php

View | Annotate | Download (84 KB)

1
<?php
2
3
/***************************************************************************
4
 *
5
 * Nephthys - file sharing management
6
 * Copyright (c) by Andreas Unterkircher, unki@netshadow.at
7
 *
8
 *  This file is part of Nephthys.
9
 *
10
 *  Nephthys is free software: you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation, either version 3 of the License, or
13
 *  (at your option) any later version.
14
 *
15
 *  Nephthys is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU General Public License
21
 *  along with Nephthys. If not, see <http://www.gnu.org/licenses/>.
22
 *
23
 ***************************************************************************/
24
25
require_once "nephthys_db.php";
26
require_once "nephthys_buckets.php";
27
require_once "nephthys_addressbook.php";
28
require_once "nephthys_users.php";
29
require_once "nephthys_profile.php";
30
require_once "nephthys_upload.php";
31
32
class NEPHTHYS {
33
34
   public $cfg;
35
   public $db;
36
   public $tmpl;
37
   public $current_user;
38
   public $browser_info;
39
   public $sort_order;
40
41
   private $runtime_error = false;
42
   private $_translationTable;        // currently loaded translation table
43
   private $_loadedTranslationTables; // array of all loaded translation tables
44
45
   /**
46
    * class constructor
47
    *
48
    * this function will be called on class construct
49
    * and will check requirements, loads configuration,
50
    * open databases and start the user session
51
    */
52
   public function __construct()
53
   {
54
      $GLOBALS['nephthys'] =& $this;
55
56
      /* load config, exit if it fails */
57
      if(!$this->load_config()) {
58
         $this->_error("Error during load_config()");
59
         exit(1);
60
      }
61
62
      // if servername has not been set in the configuration
63
      // get it from the webserver. Only necessary if not
64
      // called from command line.
65
      if(!isset($this->cfg->servername) && !$this->is_cmdline()) {
66
         if(!isset($_SERVER['SERVER_NAME']))
67
            die("Can't get server name out of \$_SERVER['SERVER_NAME']");
68
         $this->cfg->servername = $_SERVER['SERVER_NAME'];
69
      }
70
71
      /* Check necessary requirements */
72
      if(!$this->checkRequirements()) {
73
         exit(1);
74
      }
75
76
      $this->browser_info = new Net_UserAgent_Detect();
77
78
      /* verify if browser supports javascript
79
           ... if not called from command line
80
           ... if not called via RPC handler
81
           ... and ignore Javascript check is not set
82
      */
83
      if(!$this->is_cmdline() && !defined('RPC_CALL') && (!isset($this->cfg->ignore_js) || empty($this->cfg->ignore_js))) {
84
85
         if(!$this->browser_info->hasFeature('javascript')) {
86
            $this->_error("It seems your browser is not capable of supporting JavaScript or it has been disabled.");
87
            $this->_error("Nephthys will not work without JavaScript!");
88
            exit;
89
         }
90
      }
91
92
      /* if database type is set to sqlite, database exists
93
         but is not readable ...
94
      */
95
      if($this->cfg->db_type == "sqlite" &&
96
         file_exists($this->cfg->sqlite_path) &&
97
         !is_readable($this->cfg->sqlite_path)) {
98
         $this->_error("[". $this->cfg->sqlite_path ."] SQLite database is not readable for user ". $this->getuid());
99
         exit(1);
100
      }
101
102
      /* if database type is set to sqlite, database exists
103
         but is not writeable ...
104
      */
105
      if($this->cfg->db_type == "sqlite" &&
106
         file_exists($this->cfg->sqlite_path) &&
107
         !is_writable($this->cfg->sqlite_path)) {
108
         $this->_error("[". $this->cfg->sqlite_path ."] SQLite database is not writeable for user ". $this->getuid());
109
         exit(1);
110
      }
111
112
      /* if database type is set to sqlite, database does not exist
113
         yet and directory to store database is not writeable...
114
      */
115
      if($this->cfg->db_type == "sqlite" &&
116
         !file_exists($this->cfg->sqlite_path) &&
117
         !is_writable(dirname($this->cfg->sqlite_path))) {
118
         $this->_error("[". $this->cfg->sqlite_path ."] SQLite database can not be created in directory by user ". $this->getuid());
119
         exit(1);
120
      }
121
122
      $this->db  = new NEPHTHYS_DB();
123
124
      $this->check_db_tables();
125
126
      if(!is_writable($this->cfg->tmpl_path ."/templates_c")) {
127
         $this->_error("[". $this->cfg->tmpl_path ."/templates_c] directory is not writeable for user ". $this->getuid());
128
         exit(1);
129
      }
130
131
      /* check if the bucket root directory ($data_path) exists */
132
      if(!file_exists($this->cfg->data_path)) {
133
         $this->_error("[". $this->cfg->data_path ."] directory does not exist");
134
         exit(1);
135
      }
136
      /* check if the webservers user is allowed to modify the bucket
137
         root directory ($data_path). This is necessary to create &
138
         delete bucket directories.
139
      */
140
      if(!is_writeable($this->cfg->data_path)) {
141
         $this->_error("[". $this->cfg->data_path ."] directory is not writeable for user ". $this->getuid());
142
         exit(1);
143
      }
144
145
      /* if session is not yet started, do it now */
146
      if(session_id() == "")
147
         session_start();
148
149
      /*if(!isset($_SERVER['REMOTE_USER']) || empty($_SERVER['REMOTE_USER'])) {
150
         $this->parent->_error("It seems you are not authenticated through the server");
151
         exit(1);
152
      }
153
      */
154
155
      if(!$this->is_cmdline() &&
156
         isset($this->cfg->allow_server_auth) && $this->cfg->allow_server_auth == true
157
         && (!isset($_SERVER['REMOTE_USER']) || empty($_SERVER['REMOTE_USER']))) {
158
         $this->_error("Server authentication is enabled in Nephthys config but server does not "
159
            ."provide details in REMOTE_USER variable.");
160
161
         exit(1);
162
      }
163
164
      /* if server-authentication is allowed... */
165
      if(isset($this->cfg->allow_server_auth) &&
166
         $this->cfg->allow_server_auth == true) {
167
168
         /* if the user exists in Nephthys user table ... */
169
         if(isset($_SERVER['REMOTE_USER']) && $user = $this->get_user_details_by_name($_SERVER['REMOTE_USER'])) {
170
            /* if user is active, register informations to session */
171
            if($user->user_active == 'Y') {
172
               $_SESSION['login_name'] = $user->user_name;
173
               $_SESSION['login_idx'] = $user->user_idx;
174
               /* update the last login time of this user */
175
               $this->update_last_login($user->user_idx);
176
            }
177
         }
178
         /* otherwise, if auto-creation is enabled, create it... */
179
         else {
180
181
            /* is user-auto-creation enabled? */
182
            if(isset($this->cfg->user_auto_create) &&
183
               $this->cfg->user_auto_create == true) {
184
185
               if(isset($_SERVER['REMOTE_USER']) &&
186
                  $idx = $this->create_user($_SERVER['REMOTE_USER'])) {
187
                  if($user = $this->get_user_details_by_idx($idx)) {
188
                     $_SESSION['login_name'] = $user->user_name;
189
                     $_SESSION['login_idx'] = $user->user_idx;
190
                     /* update the last login time of this user */
191
                     $this->update_last_login($user->user_idx);
192
                  }
193
               }
194
            }
195
         }
196
      }
197
      else {
198
         /* local authentication, if login data is already available */
199
         if(isset($_SESSION['login_idx']) && is_numeric($_SESSION['login_idx']))
200
            $user = $this->get_user_details_by_idx($_SESSION['login_idx']);
201
      }
202
203
      /* if the user-object was found in database (or has been auto-created)
204
         and the user has selected its own prefered language...
205
      */
206
      if(isset($user) &&
207
         isset($user->user_language) &&
208
         !empty($user->user_language) &&
209
         in_array($user->user_language, array_keys($this->cfg->avail_langs))) {
210
211
         $this->cfg->language = $user->user_language;
212
213
      }
214
215
      /* load translation table for the current language */
216
      $this->load_translation_table();
217
218
      /* overload Smarty class if our own template handler */
219
      require_once "nephthys_tmpl.php";
220
      $this->tmpl = new NEPHTHYS_TMPL();
221
222
      if(isset($user->user_email) && !empty($user->user_email))
223
         $this->tmpl->assign('login_email', $user->user_email);
224
225
      /* if browser is type Internet Explorer set a template variable to
226
         inidicate to templates that browser is IE.
227
      */
228
      if(isset($this->browser_info) && $this->browser_info->isIE())
229
         $this->tmpl->assign('is_ie', true);
230
231
      if($this->browser_info->getOS(array("vista", "win7"))) {
232
         $this->tmpl->assign('is_vista', true);
233
      }
234
235
      $this->tmpl->assign('hide_logout', $this->cfg->hide_logout);
236
      $this->tmpl->assign('disk_used', $this->get_unit($this->get_used_diskspace()));
237
      $this->tmpl->assign('disk_free', $this->get_unit($this->get_free_diskspace()));
238
239
      /* pre-define default sort order, if not set yet */
240
      if(!isset($_SESSION['sort_order']) || !is_array($_SESSION['sort_order'])) {
241
242
         $_SESSION['sort_order'] = Array(
243
            'buckets' => Array(
244
               'column' => 'bucket_name',
245
               'order' => 'asc'),
246
            'addressbook' => Array(
247
               'column' => 'contact_name',
248
               'order' => 'asc'),
249
            'users' => Array(
250
               'column' => 'user_name',
251
               'order' => 'asc'),
252
         );
253
254
      }
255
256
   } // __construct()
257
258
   public function __destruct()
259
   {
260
261
   } // __destruct()
262
263
   /**
264
    * init - generate html output
265
    *
266
    * this function can be called after the constructor has prepared
267
    * everyhing. it will load the index.tpl Smarty template and exit
268
    * successfully.
269
    */
270
   public function init()
271
   {
272
      print $this->tmpl->fetch("index.tpl");
273
      exit(0);
274
275
   } // init()
276
277
   /**
278
    * outputs the main content template
279
    */
280
   public function show()
281
   {
282
      return $this->tmpl->fetch("main.tpl");
283
284
   } // show()
285
286
   /**
287
    * outputs the menu template()
288
    */
289
   public function get_menu()
290
   {
291
      return $this->tmpl->fetch("menu.tpl");
292
293
   } // get_menu()
294
295
   /**
296
    * return main content
297
    */
298
   public function get_content()
299
   {
300
      /* if no user-login yet, show the login box */
301
      if(!$this->is_logged_in()) {
302
         return $this->tmpl->fetch("login_box.tpl");
303
      }
304
      else {
305
         /* if the user has been auto-created, but its email address has not
306
            been set yet - and the nephthys config option
307
               $force_profile_update
308
            is set to true, forward the user to the profile page instead of
309
            everything else.
310
         */
311
         if(isset($this->cfg->force_profile_update) &&
312
            !empty($this->cfg->force_profile_update) &&
313
            $this->is_auto_created($_SESSION['login_idx']) &&
314
            !$this->get_user_email($_SESSION['login_idx'])) {
315
316
            $request = "profile";
317
318
         }
319
      }
320
321
      /* if the requests has not been overruled yet */
322
      if(!isset($request)) {
323
         /* page-id via HTTP GET */
324
         if(isset($_GET['id']) && is_string($_GET['id']))
325
            $request = $_GET['id'];
326
         /* page-id via HTTP POST */
327
         if(isset($_POST['id']) && is_string($_POST['id']))
328
            $request = $_POST['id'];
329
      }
330
331
      switch($request) {
332
         case 'main':
333
            $obj = $this;
334
            break;
335
         case 'users':
336
            $obj = new NEPHTHYS_USERS();
337
            break;
338
         case 'buckets':
339
            $obj = new NEPHTHYS_BUCKETS();
340
            break;
341
         case 'profile':
342
            $obj = new NEPHTHYS_PROFILE();
343
            break;
344
         case 'addressbook':
345
            $obj = new NEPHTHYS_ADDRESSBOOK();
346
            break;
347
         case 'about':
348
            return $this->tmpl->fetch("about.tpl");
349
            break;
350
         case 'help':
351
            return $this->tmpl->fetch("help.tpl");
352
            break;
353
         case 'savedbucket':
354
            $obj = new NEPHTHYS_BUCKETS();
355
            return $obj->showBucket();
356
            break;
357
      }
358
359
      if(isset($obj))
360
         return $obj->show();
361
362
   } // get_content()
363
364
   public function store()
365
   {
366
      if(!$this->is_logged_in()) {
367
         return "login first";
368
      }
369
370
      if(isset($_POST['module'])) {
371
         switch($_POST['module']) {
372
            case 'users':
373
               $obj = new NEPHTHYS_USERS;
374
               break;
375
            case 'buckets':
376
               $obj = new NEPHTHYS_BUCKETS;
377
               break;
378
            case 'profile':
379
               $obj = new NEPHTHYS_PROFILE;
380
               break;
381
            case 'addressbook':
382
               $obj = new NEPHTHYS_ADDRESSBOOK;
383
               break;
384
            default:
385
               return "unkown module";
386
               break;
387
         }
388
389
         if(isset($obj)) {
390
            switch($_POST['mode']) {
391
               case 'modify': return $obj->store(); break;
392
               case 'delete': return $obj->delete(); break;
393
               case 'toggle': return $obj->toggleStatus(); break;
394
            }
395
         }
396
      }
397
398
   } // store()
399
400
   /**
401
    * check if all requirements are met
402
    */
403
   private function checkRequirements()
404
   {
405
      /* Check for HTML_AJAX PEAR package, lent from Horde project */
406
      ini_set('track_errors', 1);
407
      @include_once 'HTML/AJAX/Server.php';
408
      if(isset($php_errormsg) && preg_match('/Failed opening.*for inclusion/i', $php_errormsg)) {
409
         $this->_error("PEAR HTML_AJAX package is missing");
410
         $missing = true;
411
      }
412
      @include_once 'MDB2.php';
413
      if(isset($php_errormsg) && preg_match('/Failed opening.*for inclusion/i', $php_errormsg)) {
414
         $this->_error("PEAR MDB2 package is missing");
415
         $missing = true;
416
         unset($php_errormsg);
417
      }
418
      // If database type is set to MySQL
419
      if($this->cfg->db_type == "mysql") {
420
         @include_once 'MDB2/Driver/mysqli.php';
421
         if(isset($php_errormsg) && preg_match('/Failed opening.*for inclusion/i', $php_errormsg)) {
422
            $this->_error("PEAR MDB2-mysqli package is missing");
423
            $missing = true;
424
            unset($php_errormsg);
425
         }
426
      }
427
      // If database type is set to SQLite
428
      if($this->cfg->db_type == "sqlite") {
429
          @include_once 'MDB2/Driver/sqlite.php';
430
         if(isset($php_errormsg) && preg_match('/Failed opening.*for inclusion/i', $php_errormsg)) {
431
            $this->_error("PEAR MDB2-sqlite package is missing");
432
            $missing = true;
433
            unset($php_errormsg);
434
         }
435
      }
436
      @include_once 'Mail.php';
437
      if(isset($php_errormsg) && preg_match('/Failed opening.*for inclusion/i', $php_errormsg)) {
438
         $this->_error("PEAR Mail package is missing");
439
         $missing = true;
440
         unset($php_errormsg);
441
      }
442
      @include_once 'Net/UserAgent/Detect.php';
443
      if(isset($php_errormsg) && preg_match('/Failed opening.*for inclusion/i', $php_errormsg)) {
444
         $this->_error("PEAR Net_UserAgent_Detect package is missing");
445
         $missing = true;
446
         unset($php_errormsg);
447
      }
448
      @include_once 'Console/Getopt.php';
449
      if(isset($php_errormsg) && preg_match('/Failed opening.*for inclusion/i', $php_errormsg)) {
450
         $this->_error("PEAR Console_Getopt package is missing");
451
         $missing = true;
452
         unset($php_errormsg);
453
      }
454
      @include_once $this->cfg->smarty_path .'/libs/Smarty.class.php';
455
      if(isset($php_errormsg) && preg_match('/Failed opening.*for inclusion/i', $php_errormsg)) {
456
         $this->_error("Smarty template engine can not be found in ". $this->cfg->smarty_path ."/libs/Smarty.class.php");
457
         $missing = true;
458
         unset($php_errormsg);
459
      }
460
      ini_restore('track_errors');
461
462
      if(isset($missing))
463
         return false;
464
465
      return true;
466
467
   } // checkRequirements()
468
469
   /**
470
    * return the type of protocol used
471
    *
472
    * this function returns wether HTTP or HTTPS
473
    * is used for the client connection.
474
    *
475
    * @return string
476
    */
477
   private function get_web_protocol()
478
   {
479
      if(!isset($_SERVER['HTTPS']))
480
         return "http";
481
      else
482
         return "https";
483
484
   } // get_web_protocol()
485
486
   /**
487
    * return url to this installation
488
    *
489
    * @return string
490
    */
491
   private function get_nephthys_url()
492
   {
493
      return $this->get_web_protocol() ."://". $this->get_server_name() . $this->cfg->web_path;
494
495
   } // get_nephthys_url()
496
   
497
   /**
498
    * check file exists and is readable
499
    *
500
    * returns true, if everything is ok, otherwise false
501
    * if $silent is not set, this function will output and
502
    * error message
503
    */
504
   private function check_readable($file, $silent = null)
505
   {
506
      if(!file_exists($file)) {
507
         if(!isset($silent))
508
            print "File \"". $file ."\" does not exist.\n";
509
         return false;
510
      }
511
512
      if(!is_readable($file)) {
513
         if(!isset($silent))
514
            print "File \"". $file ."\" is not reachable for user ". $this->getuid() ."\n";
515
         return false;
516
      }
517
518
      return true;
519
520
   } // check_readable()
521
522
   /**
523
    * validate config options
524
    *
525
    * this function checks if all necessary configuration options are
526
    * specified and set.
527
    */
528
   private function check_config_options()
529
   {
530
      if(!isset($this->cfg->page_title) || $this->cfg->page_title == "")
531
         $this->_error("Please set \$page_title in nephthys_cfg");
532
533
      if(!isset($this->cfg->base_path) || $this->cfg->base_path == "")
534
         $this->_error("Please set \$base_path in nephthys_cfg");
535
536
      if(!isset($this->cfg->web_path) || $this->cfg->web_path == "")
537
         $this->_error("Please set \$web_path in nephthys_cfg");
538
539
      if(!isset($this->cfg->smarty_path) || $this->cfg->smarty_path == "")
540
         $this->_error("Please set \$smarty_path in nephthys_cfg");
541
542
      if(!isset($this->cfg->theme_name))
543
         $this->_error("Please set \$theme_name in nephthys_cfg");
544
545
      if(!isset($this->cfg->mysql_host))
546
         $this->_error("Please set \$mysql_host in nephthys_cfg");
547
548
      if(!isset($this->cfg->mysql_db))
549
         $this->_error("Please set \$mysql_db in nephthys_cfg");
550
551
      if(!isset($this->cfg->mysql_user))
552
         $this->_error("Please set \$mysql_user in nephthys_cfg");
553
554
      if(!isset($this->cfg->mysql_pass))
555
         $this->_error("Please set \$mysql_pas in nephthys_cfg");
556
557
      if(!isset($this->cfg->logging))
558
         $this->_error("Please set \$logging in nephthys_cfg");
559
560
      if(isset($this->cfg->logging) && $this->cfg->logging == 'logfile') {
561
562
         if(!isset($this->cfg->log_file))
563
            $this->_error("Please set \$log_file because you set logging = log_file in nephthys_cfg");
564
565
         if(!is_writable($this->cfg->log_file))
566
            $this->_error("The specified \$log_file ". $log_file ." is not writeable!");
567
568
      }
569
570
      /* check for pending slash on web_path */
571
      if(!preg_match("/\/$/", $this->cfg->web_path))
572
         $this->cfg->web_path.= "/";
573
574
      return $this->runtime_error;
575
576
   } // check_config_options()
577
578
   /**
579
    * return the current process-user
580
    */
581
   private function getuid()
582
   {
583
      if($uid = posix_getuid()) {
584
         if($user = posix_getpwuid($uid)) {
585
            return $user['name'];
586
         }
587
      }
588
589
      return 'n/a';
590
591
   } // getuid()
592
593
   /**
594
    * returns the email address of the provided user id
595
    * @param int $user_idx
596
    * @return string
597
    */
598
   public function get_user_email($user_idx)
599
   {
600
      $row = $this->db->db_fetchSingleRow("
601
         SELECT
602
            user_email
603
         FROM
604
            nephthys_users
605
         WHERE
606
            user_idx='". $user_idx ."'
607
      ");
608
609
      if(isset($row->user_email)) {
610
         return $row->user_email;
611
      }
612
613
      return NULL;
614
615
   } // get_user_email()
616
617
   /**
618
    * return current users email address
619
    *
620
    * this function returns the email address of the
621
    * currently logged in user.
622
    * @return string
623
    */
624
   public function get_my_email()
625
   {
626
      /* if no user is logged in yet, return */
627
      if(!isset($_SESSION['login_name']))
628
         return NULL;
629
630
      $row = $this->db->db_fetchSingleRow("
631
         SELECT user_email
632
         FROM nephthys_users
633
         WHERE user_name LIKE '". $_SESSION['login_name'] ."'
634
      ");
635
636
      if(isset($row->user_email)) {
637
         return $row->user_email;
638
      }
639
640
      return NULL;
641
642
   } // get_my_email()
643
644
   /**
645
    * return all user details for the provided user_name
646
    */
647
   private function get_user_details_by_name($user_name)
648
   {
649
      if($user = $this->db->db_fetchSingleRow("
650
         SELECT *
651
         FROM nephthys_users
652
         WHERE
653
            user_name LIKE '". $user_name ."'")) {
654
655
         return $user;
656
      }
657
658
      return NULL;
659
660
   } // get_user_detail_by_name()
661
662
   /**
663
    * return all user details for the provided user_idx
664
    */
665
   private function get_user_details_by_idx($user_idx)
666
   {
667
      if($user = $this->db->db_fetchSingleRow("
668
         SELECT *
669
         FROM nephthys_users
670
         WHERE
671
            user_idx LIKE '". $user_idx ."'")) {
672
673
         return $user;
674
      }
675
676
      return NULL;
677
678
   } // get_user_details()
679
680
   /**
681
    * returns user name
682
    *
683
    * @return string
684
    */
685
   public function get_user_name($user_idx)
686
   {
687
      if($user = $this->get_user_details_by_idx($user_idx)) {
688
         return $user->user_name;
689
      }
690
691
      return NULL;
692
693
   } // get_user_name()
694
695
   /**
696
    * return the specified users full name
697
    *
698
    * @return string
699
    */
700
   public function get_user_fullname($user_idx)
701
   {
702
      if($user = $this->get_user_details_by_idx($user_idx)) {
703
         return $user->user_full_name;
704
      }
705
706
      return NULL;
707
708
   } // get_user_fullname()
709
710
   /**
711
    * returns user privilege
712
    */
713
   public function get_user_priv($user_idx)
714
   {
715
      if($user = $this->get_user_details_by_idx($user_idx)) {
716
         return $user->user_priv;
717
      }
718
719
      return NULL;
720
721
   } // get_user_priv()
722
723
   /**
724
    * returns users default expiration time
725
    */
726
   public function get_user_expire($user_idx)
727
   {
728
      if($user = $this->get_user_details_by_idx($user_idx)) {
729
         return $user->user_default_expire;
730
      }
731
732
      return NULL;
733
734
   } // get_user_expire()
735
736
   /**
737
    * returns true if a user is logged in, otherwise false
738
    */
739
   public function is_logged_in()
740
   {
741
      if(isset($_SESSION['login_name']) && !empty($_SESSION['login_name']) &&
742
         $this->is_valid_user($_SESSION['login_name'])) {
743
744
         return true;
745
746
      }
747
748
      return false;
749
750
   } // is_logged_in()
751
752
   /**
753
    * return true if the user exists
754
    */
755
   private function is_valid_user($user_name)
756
   {
757
      if($this->db->db_fetchSingleRow("
758
            SELECT user_idx
759
            FROM nephthys_users
760
            WHERE user_name LIKE '". $user_name ."'
761
         ")) {
762
763
         return true;
764
765
      }
766
767
      return false;
768
769
   } // is_valid_user()
770
771
   /***
772
    * validates all provided email addresses.
773
    * multiple email addresses are seperated by comma
774
    *
775
    * @param string $email
776
    * @return boolean
777
    */
778
   public function is_valid_email($email)
779
   {
780
      /* only one email address? */
781
      if(strstr($email, ',') === false)
782
         return $this->validate_email($email);
783
784
      /* multiple email addresses */
785
      $emails = preg_split("/,/", $email);
786
787
      if(!is_array($emails) || empty($emails))
788
         return false;
789
790
      foreach($emails as $email_addr) {
791
792
         $email_addr = trim($email_addr);
793
         /* return as soon as an invalid address has been found */
794
         if(!$this->validate_email($email_addr))
795
            return false;
796
      }
797
      return true;
798
799
   } // is_valid_email()
800
801
   /***
802
    * verify email address
803
    *
804
    * found on: http://www.ilovejackdaniels.com/php/email-address-validation/
805
   */
806
   public function validate_email($email)
807
   {
808
      /* if email has been entered in the format
809
            fullname <email-address>
810
         then we need to extract the address first
811
      */
812
      if(preg_match('/^(.+)\s\<(.+)\>/', $email, $matches)) {
813
         $email = $matches[2];
814
      }
815
816
      //if php version < 5.2
817
      if ( version_compare( phpversion(), "5.2","<" ) ) {
818
         // First, we check that there's one @ symbol, and that the lengths are right
819
         if (!preg_match("/^[^@]{1,64}@[^@]{1,255}$/", $email)) {
820
            // Email invalid because wrong number of characters in one section, or wrong number of @ symbols.
821
            return false;
822
         }
823
         // Split it into sections to make life easier
824
         $email_array = explode("@", $email);
825
         $local_array = explode(".", $email_array[0]);
826
         for ($i = 0; $i < sizeof($local_array); $i++) {
827
            if (!preg_match("/^(([A-Za-z0-9!#$%&'*+/=?^_`{|}~-][A-Za-z0-9!#$%&'*+/=?^_`{|}~\.-]{0,63})|(\"[^(\\|\")]{0,62}\"))$/", $local_array[$i])) {
828
               return false;
829
            }
830
         }
831
         if (!preg_match("/^\[?[0-9\.]+\]?$/", $email_array[1])) { // Check if domain is IP. If not, it should be valid domain name
832
            $domain_array = explode(".", trim($email_array[1]));
833
            if (sizeof($domain_array) < 2) {
834
               return false; // Not enough parts to domain
835
            }
836
            for ($i = 0; $i < sizeof($domain_array); $i++) {
837
               if (!preg_match("/^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]+))$/", $domain_array[$i])) {
838
                  return false;
839
               }
840
            }
841
         } else {
842
            //regular expression verifies that each component is a number from 1 to 3 characters in length
843
            if (!preg_match("/^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/", $email_array[1])){
844
               return false;
845
            }
846
         }
847
      } else if ( filter_var( $email, FILTER_VALIDATE_EMAIL ) === false ){
848
         return false;
849
      }
850
      return true;
851
852
   } // validate_email() 
853
854
   /**
855
    * generates a SHA-1 hash from the provided parameters
856
    * and some random stuff
857
    */
858
   public function get_sha_hash($sender, $receiver = false)
859
   {
860
      if(!$receiver)
861
         $receiver = mktime();
862
863
      return sha1($sender . $receiver . rand(0, 32768));
864
865
   } // get_sha_hash()
866
867
   public function notifybucket()
868
   {
869
      if(isset($_POST['id']) && is_numeric($_POST['id'])) {
870
         $bucket = new NEPHTHYS_BUCKETS($_POST['id']);
871
         return $bucket->notify();
872
      }
873
874
      return "unkown bucket";
875
876
   } // notifybucket()
877
878
   /**
879
    * load Nephthys configuration file
880
    */
881
   private function load_config()
882
   {
883
      ini_set('track_errors', 1);
884
      @include_once "nephthys_cfg.php";
885
      if(isset($php_errormsg) && preg_match('/Failed opening.*for inclusion/i', $php_errormsg)) {
886
         $this->_error("Can't read nephthys_cfg.php or have no permission to do it. Follow the documentation");
887
         $this->_error("create nephthys_cfg.php from nephthys_cfg.php.dist");
888
         return false;
889
      }
890
      ini_restore('track_errors');
891
892
      $this->cfg = new NEPHTHYS_CFG;
893
894
      /* verify config settings */
895
      if($this->check_config_options()) {
896
         return false;
897
      }
898
899
      /* set application name and version information */
900
      $this->cfg->product = "Nephthys";
901
      $this->cfg->version = "1.6";
902
      $this->cfg->db_version = 7;
903
904
      return true;
905
906
   } // load_config()
907
908
   /**
909
    * check login
910
    *
911
    * this function gets called via RPC to verify users entered
912
    * credential informations and permit or deny finally login.
913
    * @return string
914
    */
915
   public function login()
916
   {
917
      if(isset($_POST['login_name']) && !empty($_POST['login_name']) &&
918
         isset($_POST['login_pass']) && !empty($_POST['login_pass'])) {
919
920
         /* get user details */
921
         if($user = $this->get_user_details_by_name($_POST['login_name'])) {
922
923
            /* reject inactive users */
924
            if($user->user_active != 'Y')
925
               return $this->_("##FAILURE_USER_LOGON##");
926
927
            /* do not allow auto-created users to login (they have no password set...) */
928
            if($user->user_auto_created != 'Y' &&
929
               $user->user_pass == sha1($_POST['login_pass'])) {
930
931
               $_SESSION['login_name'] = $_POST['login_name'];
932
               $_SESSION['login_idx'] = $user->user_idx;
933
934
               /* update the last login time of this user */
935
               $this->update_last_login($user->user_idx);
936
937
               return "ok";
938
            }
939
            else {
940
               return $this->_("##FAILURE_PASSWORD##");
941
            }
942
         }
943
         else {
944
            return $this->_("##FAILURE_USER_LOGON##");
945
         }
946
      }
947
      else {
948
         return $this->_("##FAILURE_USER_PASS##");
949
      }
950
951
   } // check_login()
952
953
   /**
954
    * destroy the current user session to force logout
955
    */
956
   public function logout()
957
   {
958
      foreach($_SESSION as $k => $v) {
959
         unset($_SESSION[$k]);
960
      }
961
962
      session_destroy();
963
964
      return "ok";
965
966
   } // destroySession()
967
968
   /**
969
    * returns true if the requests user privilege is matching
970
    * with the actually user privileges
971
    */
972
   public function check_privileges($priv)
973
   {
974
      if(!isset($_SESSION['login_idx']))
975
         return false;
976
977
      if($user = $this->get_user_details_by_idx($_SESSION['login_idx'])) {
978
         if($user->user_priv == $priv)
979
            return true;
980
      }
981
      return false;
982
983
   } // check_privileges()
984
985
   /**
986
    * user has permission for long-time buckets
987
    *
988
    * this function returns true, if the user is allowed to
989
    * create long-time buckets while he has only "user" privileges.
990
    */
991
   public function has_bucket_privileges()
992
   {
993
      if($user = $this->get_user_details_by_idx($_SESSION['login_idx'])) {
994
         if($user->user_priv_expire == 'Y')
995
            return true;
996
      }
997
998
      return false;
999
1000
   } // has_bucket_privileges()
1001
1002
   /**
1003
    * returns true, if user is owner of the supplied bucket
1004
    */
1005
   public function is_bucket_owner($bucket_idx)
1006
   {
1007
      if($this->get_user_priv($_SESSION['login_idx']) == "admin")
1008
         return true;
1009
1010
      if($this->get_user_priv($_SESSION['login_idx']) == "manager")
1011
         return true;
1012
1013
      if($bucket = $this->db->db_fetchSingleRow("
1014
            SELECT *
1015
            FROM nephthys_buckets
1016
            WHERE bucket_idx LIKE '". $bucket_idx ."'
1017
         ")) {
1018
1019
         if($bucket->bucket_owner == $_SESSION['login_idx'])
1020
            return true;
1021
      }
1022
1023
      return false;
1024
1025
   } // is_bucket_owner()
1026
1027
   /**
1028
    * check if current user is owner of contact
1029
    *
1030
    * this function returns true, if the current user is owner
1031
    * of the supplied address-book contact. Otherwise it will
1032
    * return false
1033
    *
1034
    * @param int $bucket_idx
1035
    * @return bool
1036
    */
1037
   public function is_contact_owner($contact_idx)
1038
   {
1039
      if($contact = $this->db->db_fetchSingleRow("
1040
            SELECT *
1041
            FROM nephthys_addressbook
1042
            WHERE contact_idx LIKE '". $contact_idx ."'
1043
         ")) {
1044
1045
         if($contact->contact_owner == $_SESSION['login_idx'])
1046
            return true;
1047
      }
1048
1049
      return false;
1050
1051
   } // is_contact_owner()
1052
1053
   /**
1054
    * returns true if the requested user exists
1055
    */
1056
   public function check_user_exists($user_name)
1057
   {
1058
      switch($this->cfg->db_type) {
1059
         default:
1060
         case 'mysql':
1061
            /* MySQL does case-censetive search by adding BINARY... */
1062
            if($this->db->db_fetchSingleRow("
1063
               SELECT user_idx
1064
               FROM nephthys_users
1065
               WHERE
1066
                  user_name LIKE BINARY '". $user_name ."'
1067
               ")) {
1068
               return true;
1069
            }
1070
            break;
1071
         case 'sqlite':
1072
            if($this->db->db_fetchSingleRow("
1073
               SELECT user_idx
1074
               FROM nephthys_users
1075
               WHERE
1076
                  user_name LIKE '". $user_name ."'
1077
               ")) {
1078
               return true;
1079
            }
1080
            break;
1081
      }
1082
1083
      return false;
1084
1085
   } // check_user_exists()
1086
1087
   public function _error($text)
1088
   {
1089
      switch($this->cfg->logging) {
1090
         default:
1091
         case 'display':
1092
            print $text;
1093
            if(!$this->is_cmdline())
1094
               print "<br />";
1095
            print "\n";
1096
            break;
1097
         case 'errorlog':
1098
            error_log($text);
1099
            break;
1100
         case 'logfile':
1101
            error_log($text, 3, $his->cfg->log_file);
1102
            break;
1103
      }
1104
1105
      $this->runtime_error = true;
1106
1107
   } // _error()
1108
1109
   /**
1110
    * generate complete bucket URL
1111
    *
1112
    * This function generates a complete URL to a specified
1113
    * bucket provided via its hash value. It will either
1114
    * return a WebDAV or FTP URL (specified by type).
1115
    *
1116
    * @param string $type
1117
    * @param string $hash
1118
    * @return string
1119
    */
1120
   public function get_url($type, $hash)
1121
   {
1122
      switch($type) {
1123
         case 'ftp':
1124
            $url = "ftp://". $this->cfg->servername;
1125
            break;
1126
         case 'dav':
1127
            /* should a HTTPS URL be generated? */
1128
            if(isset($this->cfg->use_https) && !empty($this->cfg->use_https))
1129
               $url = "https://";
1130
            else
1131
               $url = "http://";
1132
            $url.= $this->cfg->servername;
1133
            break;
1134
         case 'dav_vista':
1135
             /* should a HTTPS URL be generated? */
1136
            if(isset($this->cfg->use_https) && !empty($this->cfg->use_https))
1137
               $url = "\\\\". $this->cfg->servername ."@SSL\DavWWWRoot";
1138
            else
1139
               $url = "\\\\". $this->cfg->servername ."\DavWWWRoot";
1140
            break;
1141
      }
1142
1143
      switch($type) {
1144
         case 'ftp':
1145
            $url.= $this->cfg->ftp_path ."/". $hash ."/";
1146
            break;
1147
         case 'dav':
1148
            $url.= $this->cfg->dav_path ."/". $hash ."/";
1149
            break;
1150
         case 'dav_vista';
1151
            $url = str_replace("/", "\\", $url);
1152
            $url.= "\\". $hash ."\\";
1153
            break;
1154
      }
1155
1156
      return $url;
1157
1158
   } // get_url()
1159
1160
   /**
1161
    * create user
1162
    * @param string $username
1163
    * @return object
1164
    */
1165
   private function create_user($username)
1166
   {
1167
      $sth = $this->db->db_prepare("
1168
         INSERT INTO nephthys_users (
1169
            user_idx, user_name, user_priv,
1170
            user_active, user_auto_created,
1171
            user_deny_chpwd
1172
         ) VALUES (
1173
            NULL, ?, 'user', 'Y', 'Y', 'Y'
1174
         )
1175
      ");
1176
1177
      $this->db->db_execute($sth, array($username));
1178
1179
      return $this->db->db_getid();
1180
1181
   } // create_user()
1182
1183
   /**
1184
    * return true if user is auto-created
1185
    * @param integer $idx
1186
    * @return boolean
1187
    */
1188
   public function is_auto_created($user_idx)
1189
   {
1190
      if($user = $this->db->db_fetchSingleRow("
1191
         SELECT user_auto_created
1192
         FROM nephthys_users
1193
         WHERE
1194
            user_idx LIKE '". $user_idx ."'
1195
         ")) {
1196
1197
         if(isset($user->user_auto_created) && $user->user_auto_created == 'Y')
1198
            return true;
1199
1200
      }
1201
1202
      return false;
1203
1204
   } // is_auto_created()
1205
1206
   /**
1207
    * return true if user is _not_ allowed to change its password
1208
    * @param integer $idx
1209
    * @return boolean
1210
    */
1211
   public function is_deny_chpwd($user_idx)
1212
   {
1213
      if($user = $this->db->db_fetchSingleRow("
1214
         SELECT user_deny_chpwd
1215
         FROM nephthys_users
1216
         WHERE
1217
            user_idx LIKE '". $user_idx ."'
1218
         ")) {
1219
1220
         if(isset($user->user_deny_chpwd) && $user->user_deny_chpwd == 'Y')
1221
            return true;
1222
1223
      }
1224
1225
      return false;
1226
1227
   } // is_deny_chpwd()
1228
1229
   /**
1230
    * check if called from command line
1231
    *
1232
    * this function will return true, if called from command line
1233
    * otherwise false.
1234
    * @return boolean
1235
    */
1236
   private function is_cmdline()
1237
   {
1238
      if(isset($_ENV['SHELL']) && !empty($_ENV['SHELL']))
1239
         return true;
1240
1241
      return false;
1242
1243
   } // is_cmdline()
1244
1245
   /**
1246
    * check Nephthys database
1247
    *
1248
    * this function checks the Nephthys database, if all
1249
    * tables are in place or if an database upgrade has
1250
    * to be done.
1251
    */
1252
   private function check_db_tables()
1253
   {
1254
      /* The following section checks if the necessary tables exist
1255
         in the database. If not (usually on the first Nephthys run),
1256
         they will be created and filled automatically.
1257
      */
1258
1259
      if(!$this->db->db_check_table_exists("nephthys_buckets")) {
1260
         switch($this->cfg->db_type) {
1261
            default:
1262
            case 'mysql':
1263
               $db_create = "CREATE TABLE `nephthys_buckets` (
1264
                  `bucket_idx` int(11) NOT NULL auto_increment,
1265
                  `bucket_name` varchar(255) default NULL,
1266
                  `bucket_sender` varchar(255) default NULL,
1267
                  `bucket_receiver` varchar(255) default NULL,
1268
                  `bucket_hash` varchar(64) default NULL,
1269
                  `bucket_created` int(11) default NULL,
1270
                  `bucket_expire` int(11) default NULL,
1271
                  `bucket_note` text,
1272
                  `bucket_owner` int(11) default NULL,
1273
                  `bucket_active` varchar(1) default NULL,
1274
                  `bucket_notified` varchar(1) default NULL,
1275
                  `bucket_notify_on_expire` varchar(1) default NULL,
1276
                  PRIMARY KEY  (`bucket_idx`)
1277
                  ) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
1278
               ";
1279
               break;
1280
            case 'sqlite':
1281
               $db_create = "CREATE TABLE nephthys_buckets (
1282
                  bucket_idx INTEGER PRIMARY KEY,
1283
                  bucket_name varchar(255),
1284
                  bucket_sender varchar(255),
1285
                  bucket_receiver varchar(255),
1286
                  bucket_hash varchar(64),
1287
                  bucket_created int,
1288
                  bucket_expire int,
1289
                  bucket_note text,
1290
                  bucket_owner int,
1291
                  bucket_active varchar(1),
1292
                  bucket_notified varchar(1),
1293
                  bucket_notify_on_expire varchar(1)
1294
               )";
1295
               break;
1296
         }
1297
1298
         if(!$this->db->db_exec($db_create)) {
1299
            die("Can't create table nephthys_buckets");
1300
         }
1301
      }
1302
1303
      if(!$this->db->db_check_table_exists("nephthys_users")) {
1304
         switch($this->cfg->db_type) {
1305
            default:
1306
            case 'mysql':
1307
               $db_create = "CREATE TABLE `nephthys_users` (
1308
                  `user_idx` int(11) NOT NULL auto_increment,
1309
                  `user_name` varchar(255) default NULL,
1310
                  `user_full_name` varchar(255) default NULL,
1311
                  `user_pass` varchar(255) default NULL,
1312
                  `user_email` varchar(255) default NULL,
1313
                  `user_priv` varchar(16) default NULL,
1314
                  `user_active` varchar(1) default NULL,
1315
                  `user_last_login` int(11) default NULL,
1316
                  `user_default_expire` int(11) default NULL,
1317
                  `user_priv_expire` varchar(1) default NULL,
1318
                  `user_auto_created` varchar(1) default NULL,
1319
                  `user_deny_chpwd` varchar(1) default NULL,
1320
                  `user_language` varchar(6) default NULL,
1321
                  PRIMARY KEY  (`user_idx`)
1322
                  ) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
1323
               ";
1324
               break;
1325
            case 'sqlite':
1326
               $db_create = "CREATE TABLE nephthys_users (
1327
                  user_idx INTEGER PRIMARY KEY,
1328
                  user_name varchar(255),
1329
                  user_full_name varchar(255),
1330
                  user_pass varchar(255),
1331
                  user_email varchar(255),
1332
                  user_priv varchar(16),
1333
                  user_active varchar(1),
1334
                  user_last_login int,
1335
                  user_default_expire int,
1336
                  user_priv_expire varchar(1),
1337
                  user_auto_created varchar(1),
1338
                  user_deny_chpwd varchar(1),
1339
                  user_language varchar(6)
1340
                  )
1341
               ";
1342
               break;
1343
         }
1344
1345
         if(!$this->db->db_exec($db_create)) {
1346
            die("Can't create table nephthys_users");
1347
         }
1348
1349
         $this->db->db_exec("
1350
            INSERT INTO nephthys_users
1351
            VALUES (
1352
               NULL,
1353
               'admin',
1354
               '',
1355
               'd033e22ae348aeb5660fc2140aec35850c4da997',
1356
               '',
1357
               'admin',
1358
               'Y',
1359
               NULL,
1360
               7,
1361
               'N',
1362
               'N',
1363
               'N',
1364
               'en')
1365
         ");
1366
1367
      }
1368
1369
      if(!$this->db->db_check_table_exists("nephthys_meta")) {
1370
         switch($this->cfg->db_type) {
1371
            default:
1372
            case 'mysql':
1373
               $db_create = "CREATE TABLE `nephthys_meta` (
1374
                  `meta_idx` int(11) NOT NULL auto_increment,
1375
                  `meta_key` varchar(255) default NULL,
1376
                  `meta_value` varchar(255) default NULL,
1377
                  PRIMARY KEY  (`meta_idx`)
1378
                  ) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
1379
               ";
1380
               break;
1381
            case 'sqlite':
1382
               $db_create = "CREATE TABLE nephthys_meta (
1383
                  meta_idx INTEGER PRIMARY KEY,
1384
                  meta_key varchar(255),
1385
                  meta_value varchar(255)
1386
               )";
1387
               break;
1388
         }
1389
1390
         if(!$this->db->db_exec($db_create)) {
1391
            die("Can't create table nephthys_meta");
1392
         }
1393
1394
         $this->db->db_exec("
1395
            INSERT INTO nephthys_meta
1396
            VALUES (
1397
               NULL,
1398
               'Nephthys Database Version',
1399
               '". $this->cfg->db_version ."'
1400
            )
1401
         ");
1402
      }
1403
1404
      if(!$this->db->db_check_table_exists("nephthys_addressbook")) {
1405
         switch($this->cfg->db_type) {
1406
            default:
1407
            case 'mysql':
1408
               $db_create = "CREATE TABLE `nephthys_addressbook` (
1409
                  `contact_idx` int(11) NOT NULL auto_increment,
1410
                  `contact_name` varchar(255) default NULL,
1411
                  `contact_email` varchar(255) default NULL,
1412
                  `contact_owner` int(11) default NULL,
1413
                  PRIMARY KEY  (`contact_idx`)
1414
                  ) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
1415
               ";
1416
               break;
1417
            case 'sqlite':
1418
               $db_create = "CREATE TABLE nephthys_addressbook (
1419
                  contact_idx INTEGER PRIMARY KEY,
1420
                  contact_name varchar(255),
1421
                  contact_email varchar(255),
1422
                  contact_owner INTEGER
1423
               )";
1424
               break;
1425
         }
1426
1427
         if(!$this->db->db_exec($db_create)) {
1428
            die("Can't create table nephthys_meta");
1429
         }
1430
      }
1431
1432
1433
      /* The following section keeps track of database upgrades. Nephthys
1434
         notes the database revision in a own table called nephthys_meta.
1435
      */
1436
1437
      /* db version 3 */
1438
      if($this->get_db_version() < 3) {
1439
1440
         /* add bucket-never-expire column to nephthys_users */
1441
         switch($this->cfg->db_type) {
1442
            default:
1443
            case 'mysql':
1444
               $this->db->db_alter_table(
1445
                  "nephthys_users",
1446
                  "add",
1447
                  "user_priv_expire",
1448
                  "varchar(1)
1449
                   AFTER
1450
                   user_default_expire"
1451
               );
1452
               break;
1453
            case 'sqlite':
1454
1455
               /* SQlite v2 does not support ALTER TABLE, so we need
1456
                  to take the help of a temporary table.
1457
               */
1458
               if(!$this->db->db_start_transaction())
1459
                  die("Can not start database transaction");
1460
1461
               $result = $this->db->db_exec("
1462
                  CREATE TEMPORARY TABLE nephthys_users_tmp (
1463
                     user_idx INTEGER PRIMARY KEY,
1464
                     user_name varchar(255),
1465
                     user_full_name varchar(255),
1466
                     user_pass varchar(255),
1467
                     user_email varchar(255),
1468
                     user_priv varchar(16),
1469
                     user_active varchar(1),
1470
                     user_last_login int,
1471
                     user_default_expire int,
1472
                     user_priv_expire varchar(1),
1473
                     user_auto_created varchar(1)
1474
                  );
1475
               ");
1476
1477
               if(!$result) {
1478
                  $this->db->db_rollback_transaction();
1479
                  die("Upgrade failover - tranaction rollback");
1480
               }
1481
1482
               $result = $this->db->db_exec("
1483
                  INSERT INTO nephthys_users_tmp
1484
                     SELECT
1485
                        user_idx,
1486
                        user_name,
1487
                        user_full_name,
1488
                        user_pass,
1489
                        user_email,
1490
                        user_priv,
1491
                        user_active,
1492
                        user_last_login,
1493
                        user_default_expire,
1494
                        NULL,
1495
                        user_auto_created
1496
                     FROM nephthys_users;
1497
               ");
1498
1499
               if(!$result) {
1500
                  $this->db->db_rollback_transaction();
1501
                  die("Upgrade failover - tranaction rollback");
1502
               }
1503
1504
               $result = $this->db->db_exec("
1505
                  DROP TABLE nephthys_users;
1506
               ");
1507
1508
               if(!$result) {
1509
                  $this->db->db_rollback_transaction();
1510
                  die("Upgrade failover - tranaction rollback");
1511
               }
1512
1513
               $result = $this->db->db_exec("
1514
                  CREATE TABLE nephthys_users (
1515
                     user_idx INTEGER PRIMARY KEY,
1516
                     user_name varchar(255),
1517
                     user_full_name varchar(255),
1518
                     user_pass varchar(255),
1519
                     user_email varchar(255),
1520
                     user_priv varchar(16),
1521
                     user_active varchar(1),
1522
                     user_last_login int,
1523
                     user_default_expire int,
1524
                     user_priv_expire varchar(1),
1525
                     user_auto_created varchar(1)
1526
                  );
1527
               ");
1528
1529
               if(!$result) {
1530
                  $this->db->db_rollback_transaction();
1531
                  die("Upgrade failover - tranaction rollback");
1532
               }
1533
1534
               $result = $this->db->db_exec("
1535
                  INSERT INTO nephthys_users
1536
                     SELECT *
1537
                     FROM nephthys_users_tmp;
1538
               ");
1539
1540
               if(!$result) {
1541
                  $this->db->db_rollback_transaction();
1542
                  die("Upgrade failover - tranaction rollback");
1543
               }
1544
1545
               $result = $this->db->db_exec("
1546
                  DROP TABLE nephthys_users_tmp;
1547
               ");
1548
1549
               if(!$result) {
1550
                  $this->db->db_rollback_transaction();
1551
                  die("Upgrade failover - tranaction rollback");
1552
               }
1553
1554
               if(!$this->db->db_commit_transaction())
1555
                  die("Can not commit database transaction");
1556
1557
               break;
1558
         }
1559
1560
         $this->set_db_version(3);
1561
1562
      } /* // db version 3 */
1563
1564
      /* db version 4 */
1565
      if($this->get_db_version() < 4) {
1566
1567
         /* add column user_language to nephthys_users */
1568
1569
         switch($this->cfg->db_type) {
1570
            default:
1571
            case 'mysql':
1572
               $this->db->db_alter_table(
1573
                  "nephthys_users",
1574
                  "add",
1575
                  "user_language",
1576
                  "varchar(6)"
1577
               );
1578
               break;
1579
1580
            case 'sqlite':
1581
1582
               /* SQlite v2 does not support ALTER TABLE, so we need
1583
                  to take the help of a temporary table.
1584
               */
1585
               if(!$this->db->db_start_transaction())
1586
                  die("Can not start database transaction");
1587
1588
               $result = $this->db->db_exec("
1589
                  CREATE TEMPORARY TABLE nephthys_users_tmp (
1590
                     user_idx INTEGER PRIMARY KEY,
1591
                     user_name varchar(255),
1592
                     user_full_name varchar(255),
1593
                     user_pass varchar(255),
1594
                     user_email varchar(255),
1595
                     user_priv varchar(16),
1596
                     user_active varchar(1),
1597
                     user_last_login int,
1598
                     user_default_expire int,
1599
                     user_priv_expire varchar(1),
1600
                     user_auto_created varchar(1),
1601
                     user_language varchar(6)
1602
                  );
1603
               ");
1604
1605
               if(!$result) {
1606
                  $this->db->db_rollback_transaction();
1607
                  die("Upgrade failover - tranaction rollback");
1608
               }
1609
1610
               $result = $this->db->db_exec("
1611
                  INSERT INTO nephthys_users_tmp
1612
                     SELECT
1613
                        user_idx,
1614
                        user_name,
1615
                        user_full_name,
1616
                        user_pass,
1617
                        user_email,
1618
                        user_priv,
1619
                        user_active,
1620
                        user_last_login,
1621
                        user_default_expire,
1622
                        user_priv_expire,
1623
                        user_auto_created,
1624
                        NULL
1625
                     FROM nephthys_users;
1626
               ");
1627
1628
               if(!$result) {
1629
                  $this->db->db_rollback_transaction();
1630
                  die("Upgrade failover - tranaction rollback");
1631
               }
1632
1633
               $result = $this->db->db_exec("
1634
                  DROP TABLE nephthys_users;
1635
               ");
1636
1637
               if(!$result) {
1638
                  $this->db->db_rollback_transaction();
1639
                  die("Upgrade failover - tranaction rollback");
1640
               }
1641
1642
               $result = $this->db->db_exec("
1643
                  CREATE TABLE nephthys_users (
1644
                     user_idx INTEGER PRIMARY KEY,
1645
                     user_name varchar(255),
1646
                     user_full_name varchar(255),
1647
                     user_pass varchar(255),
1648
                     user_email varchar(255),
1649
                     user_priv varchar(16),
1650
                     user_active varchar(1),
1651
                     user_last_login int,
1652
                     user_default_expire int,
1653
                     user_priv_expire varchar(1),
1654
                     user_auto_created varchar(1),
1655
                     user_language varchar(6)
1656
                  );
1657
               ");
1658
1659
               if(!$result) {
1660
                  $this->db->db_rollback_transaction();
1661
                  die("Upgrade failover - tranaction rollback");
1662
               }
1663
1664
               $result = $this->db->db_exec("
1665
                  INSERT INTO nephthys_users
1666
                     SELECT *
1667
                     FROM nephthys_users_tmp;
1668
               ");
1669
1670
               if(!$result) {
1671
                  $this->db->db_rollback_transaction();
1672
                  die("Upgrade failover - tranaction rollback");
1673
               }
1674
1675
               $result = $this->db->db_exec("
1676
                  DROP TABLE nephthys_users_tmp;
1677
               ");
1678
1679
               if(!$result) {
1680
                  $this->db->db_rollback_transaction();
1681
                  die("Upgrade failover - tranaction rollback");
1682
               }
1683
1684
               if(!$this->db->db_commit_transaction())
1685
                  die("Can not commit database transaction");
1686
1687
               break;
1688
         }
1689
1690
         $this->set_db_version(4);
1691
1692
      } /* // db version 4 */
1693
1694
      /* db version 5 */
1695
      if($this->get_db_version() < 5) {
1696
1697
         /* add column contact_name to nephthys_addressbook */
1698
1699
         switch($this->cfg->db_type) {
1700
            default:
1701
            case 'mysql':
1702
               $this->db->db_alter_table(
1703
                  "nephthys_addressbook",
1704
                  "add",
1705
                  "contact_name",
1706
                  "varchar(255) default NULL"
1707
               );
1708
               break;
1709
1710
            case 'sqlite':
1711
1712
               /* SQlite v2 does not support ALTER TABLE, so we need
1713
                  to take the help of a temporary table.
1714
               */
1715
               if(!$this->db->db_start_transaction())
1716
                  die("Can not start database transaction");
1717
1718
               $result = $this->db->db_exec("
1719
                  CREATE TEMPORARY TABLE nephthys_addressbook_tmp (
1720
                     contact_idx INTEGER PRIMARY KEY,
1721
                     contact_name varchar(255),
1722
                     contact_email varchar(255),
1723
                     contact_owner int
1724
                  );
1725
               ");
1726
1727
               if(!$result) {
1728
                  $this->db->db_rollback_transaction();
1729
                  die("Upgrade failover - tranaction rollback");
1730
               }
1731
1732
               $result = $this->db->db_exec("
1733
                  INSERT INTO nephthys_addressbook_tmp
1734
                     SELECT
1735
                        contact_idx,
1736
                        NULL,
1737
                        contact_email,
1738
                        contact_owner
1739
                     FROM nephthys_addressbook;
1740
               ");
1741
1742
               if(!$result) {
1743
                  $this->db->db_rollback_transaction();
1744
                  die("Upgrade failover - tranaction rollback");
1745
               }
1746
1747
               $result = $this->db->db_exec("
1748
                  DROP TABLE nephthys_addressbook;
1749
               ");
1750
1751
               if(!$result) {
1752
                  $this->db->db_rollback_transaction();
1753
                  die("Upgrade failover - tranaction rollback");
1754
               }
1755
1756
               $result = $this->db->db_exec("
1757
                  CREATE TABLE nephthys_addressbook (
1758
                     contact_idx INTEGER PRIMARY KEY,
1759
                     contact_name varchar(255),
1760
                     contact_email varchar(255),
1761
                     contact_owner int
1762
                  );
1763
               ");
1764
1765
               if(!$result) {
1766
                  $this->db->db_rollback_transaction();
1767
                  die("Upgrade failover - tranaction rollback");
1768
               }
1769
1770
               $result = $this->db->db_exec("
1771
                  INSERT INTO nephthys_addressbook
1772
                     SELECT *
1773
                     FROM nephthys_addressbook_tmp;
1774
               ");
1775
1776
               if(!$result) {
1777
                  $this->db->db_rollback_transaction();
1778
                  die("Upgrade failover - tranaction rollback");
1779
               }
1780
1781
               $result = $this->db->db_exec("
1782
                  DROP TABLE nephthys_addressbook_tmp;
1783
               ");
1784
1785
               if(!$result) {
1786
                  $this->db->db_rollback_transaction();
1787
                  die("Upgrade failover - tranaction rollback");
1788
               }
1789
1790
               if(!$this->db->db_commit_transaction())
1791
                  die("Can not commit database transaction");
1792
1793
               break;
1794
         }
1795
1796
         $this->set_db_version(5);
1797
1798
      } /* // db version 5 */
1799
1800
      /* db version 6 */
1801
      if($this->get_db_version() < 6) {
1802
1803
         /* add column user_deny_chpwd to nephthys_users */
1804
1805
         switch($this->cfg->db_type) {
1806
            default:
1807
            case 'mysql':
1808
               $this->db->db_alter_table(
1809
                  "nephthys_users",
1810
                  "add",
1811
                  "user_deny_chpwd",
1812
                  "varchar(1) default NULL"
1813
               );
1814
               break;
1815
1816
            case 'sqlite':
1817
1818
               /* SQlite v2 does not support ALTER TABLE, so we need
1819
                  to take the help of a temporary table.
1820
               */
1821
               if(!$this->db->db_start_transaction())
1822
                  die("Can not start database transaction");
1823
1824
               $result = $this->db->db_exec("
1825
                  CREATE TEMPORARY TABLE nephthys_users_tmp (
1826
                     user_idx INTEGER PRIMARY KEY,
1827
                     user_name varchar(255),
1828
                     user_full_name varchar(255),
1829
                     user_pass varchar(255),
1830
                     user_email varchar(255),
1831
                     user_priv varchar(16),
1832
                     user_active varchar(1),
1833
                     user_last_login int,
1834
                     user_default_expire int,
1835
                     user_priv_expire varchar(1),
1836
                     user_auto_created varchar(1),
1837
                     user_deny_chpwd varchar(1),
1838
                     user_language varchar(6)
1839
                  )
1840
               ");
1841
1842
               if(!$result) {
1843
                  $this->db->db_rollback_transaction();
1844
                  die("Upgrade failover - tranaction rollback");
1845
               }
1846
1847
               $result = $this->db->db_exec("
1848
                  INSERT INTO nephthys_users_tmp
1849
                     SELECT
1850
                        user_idx,
1851
                        user_name,
1852
                        user_full_name,
1853
                        user_pass,
1854
                        user_email,
1855
                        user_priv,
1856
                        user_active,
1857
                        user_last_login,
1858
                        user_default_expire,
1859
                        user_priv_expire,
1860
                        user_auto_created,
1861
                        NULL,
1862
                        user_language
1863
                     FROM nephthys_users;
1864
               ");
1865
1866
               if(!$result) {
1867
                  $this->db->db_rollback_transaction();
1868
                  die("Upgrade failover - tranaction rollback");
1869
               }
1870
1871
               $result = $this->db->db_exec("
1872
                  DROP TABLE nephthys_users;
1873
               ");
1874
1875
               if(!$result) {
1876
                  $this->db->db_rollback_transaction();
1877
                  die("Upgrade failover - tranaction rollback");
1878
               }
1879
1880
               $result = $this->db->db_exec("
1881
                  CREATE TABLE nephthys_users (
1882
                     user_idx INTEGER PRIMARY KEY,
1883
                     user_name varchar(255),
1884
                     user_full_name varchar(255),
1885
                     user_pass varchar(255),
1886
                     user_email varchar(255),
1887
                     user_priv varchar(16),
1888
                     user_active varchar(1),
1889
                     user_last_login int,
1890
                     user_default_expire int,
1891
                     user_priv_expire varchar(1),
1892
                     user_auto_created varchar(1),
1893
                     user_deny_chpwd varchar(1),
1894
                     user_language varchar(6)
1895
                  )
1896
               ");
1897
1898
               if(!$result) {
1899
                  $this->db->db_rollback_transaction();
1900
                  die("Upgrade failover - tranaction rollback");
1901
               }
1902
1903
               $result = $this->db->db_exec("
1904
                  INSERT INTO nephthys_users
1905
                     SELECT *
1906
                     FROM nephthys_users_tmp;
1907
               ");
1908
1909
               if(!$result) {
1910
                  $this->db->db_rollback_transaction();
1911
                  die("Upgrade failover - tranaction rollback");
1912
               }
1913
1914
               $result = $this->db->db_exec("
1915
                  DROP TABLE nephthys_users_tmp;
1916
               ");
1917
1918
               if(!$result) {
1919
                  $this->db->db_rollback_transaction();
1920
                  die("Upgrade failover - tranaction rollback");
1921
               }
1922
1923
               if(!$this->db->db_commit_transaction())
1924
                  die("Can not commit database transaction");
1925
1926
               break;
1927
         }
1928
1929
         /* per default we deny every auto-created user
1930
            to change his password.
1931
         */
1932
         $this->db->db_query("
1933
            UPDATE
1934
               nephthys_users
1935
            SET
1936
               user_deny_chpwd='Y'
1937
            WHERE
1938
               user_auto_created LIKE 'Y'
1939
         ");
1940
         /* per default we allowe every non auto-created user
1941
            to change his password.
1942
         */
1943
          $this->db->db_query("
1944
            UPDATE
1945
               nephthys_users
1946
            SET
1947
               user_deny_chpwd='N'
1948
            WHERE
1949
               user_auto_created NOT LIKE 'Y'
1950
         ");
1951
1952
         $this->set_db_version(6);
1953
1954
      } /* // db version 6 */
1955
1956
      /* db version 7 */
1957
      if($this->get_db_version() < 7) {
1958
1959
         /* add column user_deny_chpwd to nephthys_users */
1960
1961
         switch($this->cfg->db_type) {
1962
            default:
1963
            case 'mysql':
1964
               $this->db->db_alter_table(
1965
                  "nephthys_buckets",
1966
                  "add",
1967
                  "bucket_notify_on_expire",
1968
                  "varchar(1) default NULL"
1969
               );
1970
               break;
1971
1972
            case 'sqlite':
1973
1974
               /* SQlite v2 does not support ALTER TABLE, so we need
1975
                  to take the help of a temporary table.
1976
               */
1977
               if(!$this->db->db_start_transaction())
1978
                  die("Can not start database transaction");
1979
1980
               $result = $this->db->db_exec("
1981
                  CREATE TEMPORARY TABLE nephthys_buckets_tmp (
1982
                     bucket_idx INTEGER PRIMARY KEY,
1983
                     bucket_name varchar(255),
1984
                     bucket_sender varchar(255),
1985
                     bucket_receiver varchar(255),
1986
                     bucket_hash varchar(64),
1987
                     bucket_created int,
1988
                     bucket_expire int,
1989
                     bucket_note text,
1990
                     bucket_owner int,
1991
                     bucket_active varchar(1),
1992
                     bucket_notified varchar(1),
1993
                     bucket_notify_on_expire varchar(1)
1994
                  )
1995
               ");
1996
1997
               if(!$result) {
1998
                  $this->db->db_rollback_transaction();
1999
                  die("Upgrade failover - tranaction rollback");
2000
               }
2001
2002
               $result = $this->db->db_exec("
2003
                  INSERT INTO nephthys_buckets_tmp
2004
                     SELECT
2005
                        bucket_idx,
2006
                        bucket_name,
2007
                        bucket_sender,
2008
                        bucket_receiver,
2009
                        bucket_hash,
2010
                        bucket_created,
2011
                        bucket_expire,
2012
                        bucket_note,
2013
                        bucket_owner,
2014
                        bucket_active,
2015
                        bucket_notified,
2016
                        NULL
2017
                     FROM nephthys_buckets;
2018
               ");
2019
2020
               if(!$result) {
2021
                  $this->db->db_rollback_transaction();
2022
                  die("Upgrade failover - tranaction rollback");
2023
               }
2024
2025
               $result = $this->db->db_exec("
2026
                  DROP TABLE nephthys_buckets;
2027
               ");
2028
2029
               if(!$result) {
2030
                  $this->db->db_rollback_transaction();
2031
                  die("Upgrade failover - tranaction rollback");
2032
               }
2033
2034
               $result = $this->db->db_exec("
2035
                  CREATE TABLE nephthys_buckets (
2036
                     bucket_idx INTEGER PRIMARY KEY,
2037
                     bucket_name varchar(255),
2038
                     bucket_sender varchar(255),
2039
                     bucket_receiver varchar(255),
2040
                     bucket_hash varchar(64),
2041
                     bucket_created int,
2042
                     bucket_expire int,
2043
                     bucket_note text,
2044
                     bucket_owner int,
2045
                     bucket_active varchar(1),
2046
                     bucket_notified varchar(1),
2047
                     bucket_notify_on_expire varchar(1)
2048
                  )
2049
               ");
2050
2051
               if(!$result) {
2052
                  $this->db->db_rollback_transaction();
2053
                  die("Upgrade failover - tranaction rollback");
2054
               }
2055
2056
               $result = $this->db->db_exec("
2057
                  INSERT INTO nephthys_buckets
2058
                     SELECT *
2059
                     FROM nephthys_buckets_tmp;
2060
               ");
2061
2062
               if(!$result) {
2063
                  $this->db->db_rollback_transaction();
2064
                  die("Upgrade failover - tranaction rollback");
2065
               }
2066
2067
               $result = $this->db->db_exec("
2068
                  DROP TABLE nephthys_buckets_tmp;
2069
               ");
2070
2071
               if(!$result) {
2072
                  $this->db->db_rollback_transaction();
2073
                  die("Upgrade failover - tranaction rollback");
2074
               }
2075
2076
               if(!$this->db->db_commit_transaction())
2077
                  die("Can not commit database transaction");
2078
2079
               break;
2080
         }
2081
2082
         /* per default do not notify an expired bucket */
2083
         $this->db->db_query("
2084
            UPDATE
2085
               nephthys_buckets
2086
            SET
2087
               bucket_notify_on_expire='N'
2088
         ");
2089
2090
         $this->set_db_version(7);
2091
2092
      } /* // db version 7 */
2093
2094
   } // check_db_tables()
2095
2096
   /**
2097
    * add a email address to user's address book
2098
    *
2099
    * @param string $email
2100
    */
2101
   public function add_to_addressbook($email)
2102
   {
2103
      $to_ab = Array();
2104
2105
      /* only one email address? */
2106
      if(strstr($email, ',') === false)
2107
         array_push($to_ab, $email);
2108
2109
      /* multiple email addresses */
2110
      $emails = preg_split("/,/", $email);
2111
2112
      foreach($emails as $email_addr) {
2113
         $email_addr = trim($email_addr);
2114
         array_push($to_ab, $email_addr);
2115
      }
2116
2117
      /* loop over all contacts */
2118
      foreach($to_ab as $address) {
2119
2120
         $fullname = '';
2121
2122
         /* when entered in the format
2123
               fullname <email-address>
2124
            we need to extract the parts of that string first
2125
         */
2126
         if(preg_match('/^(.+)\s\<(.+)\>/', $address, $matches)) {
2127
            $fullname = $matches[1];
2128
            $address = $matches[2];
2129
         }
2130
2131
         /* do nothing if such a contact already exists */
2132
         if($this->db->db_fetchSingleRow("
2133
            SELECT *
2134
            FROM nephthys_addressbook
2135
            WHERE
2136
               contact_email LIKE '". $address ."'
2137
            ")) {
2138
            continue;
2139
         }
2140
2141
         $sth = $this->db->db_prepare("
2142
            INSERT INTO nephthys_addressbook (
2143
               contact_idx,
2144
               contact_email,
2145
               contact_owner,
2146
               contact_name
2147
            ) VALUES (
2148
               NULL,
2149
               ?,
2150
               ?,
2151
               ?
2152
            )
2153
         ");
2154
2155
         $this->db->db_execute($sth, array(
2156
            $address,
2157
            $_SESSION['login_idx'],
2158
            $fullname,
2159
         ));
2160
2161
      }
2162
2163
   } // add_to_addressbook()
2164
2165
   /**
2166
    * get bucket information & details
2167
    *
2168
    * this function just invokes get_bucket_info() of the
2169
    * NEPHTHYS_BUCKETS class. See that one for more info.
2170
    *
2171
    * @return string
2172
    */
2173
   public function get_bucket_info()
2174
   {
2175
      if(isset($_POST['id']) && is_numeric($_POST['id'])) {
2176
         $bucket = new NEPHTHYS_BUCKETS($_POST['id']);
2177
         return $bucket->get_bucket_info();
2178
      }
2179
2180
      return "unkown bucket";
2181
2182
   } // get_bucket_info()
2183
2184
   /**
2185
    * returns the value for the autocomplete tag-search
2186
    * @return string
2187
    */
2188
   public function get_xml_list()
2189
   {
2190
      if(!isset($_GET['search']) || !is_string($_GET['search']))
2191
         $_GET['search'] = '';
2192
2193
      /* strip leading or pending whitespaces */
2194
      $_GET['search'] = trim($_GET['search']);
2195
2196
      /* if string contains multiple receivers separated by
2197
         a comma character, just handle the last one entered.
2198
      */
2199
      if($matches = explode(',', $_GET['search'])) {
2200
         $_GET['search'] = trim($matches[count($matches)-1]);
2201
      }
2202
2203
      $length = 15;
2204
      $i = 1;
2205
2206
      $matched_contacts = Array();
2207
2208
      header("Content-Type: text/xml");
2209
2210
      $string = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n";
2211
      $string.= "<results>\n";
2212
2213
      $contacts = $this->db->db_query("
2214
         SELECT
2215
            contact_idx,
2216
            contact_name,
2217
            contact_email
2218
         FROM
2219
            nephthys_addressbook
2220
         WHERE
2221
            contact_owner LIKE '". $_SESSION['login_idx'] ."'
2222
      ");
2223
2224
      while($contact = $contacts->fetchRow()) {
2225
2226
         /* ignore empty searches */
2227
         if(empty($_GET['search']))
2228
            break;
2229
2230
         if((
2231
               preg_match("/". $_GET['search'] ."/i", $contact->contact_email) ||
2232
               preg_match("/". $_GET['search'] ."/i", $contact->contact_name)
2233
            )&&
2234
            count($matched_contacts) < $length) {
2235
2236
            $string.= " <rs id=\"". $i ."\" ";
2237
2238
            /* if a contact-name is available, add it as info for autosuggest */
2239
            if(isset($contact->contact_name) && !empty($contact->contact_name))
2240
               $string.= " info=\"". $this->unescape($contact->contact_name, false) ."\">";
2241
            else
2242
               $string.= " info=\"\">";
2243
2244
            $string.= $this->unescape($contact->contact_email, false);
2245
            $string.= "</rs>\n";
2246
2247
            $i++;
2248
         }
2249
2250
         /* if we have collected enough items, break out */
2251
         if(count($matched_contacts) >= $length)
2252
            break;
2253
      }
2254
2255
      $string.= "</results>\n";
2256
2257
      return $string;
2258
2259
   } // get_xml_list()
2260
2261
   /**
2262
    * return available disk space
2263
    *
2264
    * this function returns the available disk space of that
2265
    * disk where $data_path resists.
2266
    *
2267
    * @return string
2268
    */
2269
   private function get_free_diskspace()
2270
   {
2271
      $bytes = disk_free_space($this->cfg->data_path);
2272
      return $bytes;
2273
2274
   } // get_free_diskspace()
2275
2276
2277
   /**
2278
    * return used disk space
2279
    *
2280
    * this functions returns the used disk space of that
2281
    * disk where $data_path resists.
2282
    *
2283
    * @param string $path
2284
    * @return string
2285
    */
2286
   public function get_used_diskspace($path = NULL)
2287
   {
2288
      /* this function will be called recursive. if no path is
2289
         provided as parameter, use $data_path to start from.
2290
      */
2291
      if(!isset($path))
2292
         $path = $this->cfg->data_path;
2293
2294
      $bytes = 0;
2295
2296
      $dirhandle = opendir($path);
2297
      while($file = readdir($dirhandle)) {
2298
2299
         if(!$this->is_valid_file($path, $file))
2300
            continue;
2301
2302
         if(is_dir($path."/".$file)) {
2303
            $bytes = $bytes + $this->get_used_diskspace($path."/".$file);
2304
         }
2305
         else {
2306
            /* On 32bit plattforms filesize() can returns unexptected
2307
               and negative results when files are larger then 2GB.
2308
               Let's try to caputre this here and get the filesize by
2309
               invoking stat on the command line instead.
2310
            */
2311
            if(($size = @filesize($path."/".$file)) === false)
2312
               $size = exec ('stat -c %s '. escapeshellarg ($path."/".$file));
2313
2314
            if($size > 0)
2315
               $bytes+= $size;
2316
         }
2317
      }
2318
2319
      closedir($dirhandle);
2320
2321
      return $bytes;
2322
2323
   } // get_used_diskspace()
2324
2325
   /**
2326
    * return size of unit
2327
    *
2328
    * this function returns the suitable unit for the
2329
    * provided amount of bytes.
2330
    *
2331
    * @param int $bytes
2332
    * @return string
2333
    */
2334
   public function get_unit($bytes)
2335
   {
2336
      $symbols = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
2337
2338
      /* if $bytes = 0, return 0b */
2339
      if(empty($bytes))
2340
         return '0'. $symbols[0];
2341
2342
      /* if a non-numeric value has been provided, return */
2343
      if(!is_numeric($bytes))
2344
         return "n/a";
2345
2346
      $exp = floor(log($bytes)/log(1024));
2347
2348
      /* if $bytes was to small, return 0b */
2349
      if($exp == -INF)
2350
         return '0'. $symbols[0];
2351
2352
      return sprintf('%.2f '.$symbols[$exp], ($bytes/pow(1024, floor($exp))));
2353
2354
   } // get_unit()
2355
2356
   /**
2357
    * get database version
2358
    *
2359
    * this function queries the nephthys_meta table
2360
    * and returns the current database version.
2361
    *
2362
    * @return integer
2363
    */
2364
   public function get_db_version()
2365
   {
2366
      if($row = $this->db->db_fetchSingleRow("
2367
         SELECT meta_value
2368
         FROM
2369
            nephthys_meta
2370
         WHERE
2371
            meta_key LIKE 'Nephthys Database Version'
2372
         ")) {
2373
2374
         return $row->meta_value;
2375
2376
      }
2377
2378
      return 0;
2379
2380
   } // get_db_version()
2381
2382
   /**
2383
    * set database version
2384
    *
2385
    * this function updates the nephthys_meta table
2386
    * with the version number provided as the first
2387
    * parameter.
2388
    *
2389
    * @param int $version
2390
    */
2391
   public function set_db_version($version)
2392
   {
2393
      if(isset($version) && $version > 0) {
2394
2395
         $this->db->db_exec("
2396
            UPDATE
2397
               nephthys_meta
2398
            SET
2399
               meta_value='". $version ."'
2400
            WHERE
2401
               meta_key LIKE 'Nephthys Database Version'
2402
         ");
2403
2404
      }
2405
2406
   } // set_db_version()
2407
2408
   public function _($text)
2409
   {
2410
      return $this->get_translation($text);
2411
   }
2412
2413
   function get_language()
2414
   {
2415
      return $this->cfg->language;
2416
2417
   } // get_language()
2418
2419
   function load_translation_table()
2420
   {
2421
      $locale = $this->get_language();
2422
2423
      $path = $this->cfg->base_path
2424
         . '/themes/'
2425
         . $this->cfg->theme_name
2426
         . '/lang/'
2427
         . $locale
2428
         . '.lang';
2429
2430
      if (isset($this->_loadedTranslationTables[$locale])) {
2431
         if (in_array($path, $this->_loadedTranslationTables[$locale])) {
2432
            // Translation table was already loaded
2433
            return true;
2434
         }
2435
      }
2436
2437
      /* if the language file is not available, stop execution. */
2438
      if(!file_exists($path) || !is_readable($path)) {
2439
         die("Can not open language file $path");
2440
      }
2441
2442
      $entries = file($path);
2443
      $this->_translationTable[$locale][$path] = Array();
2444
      $this->_loadedTranslationTables[$locale][] = $path;
2445
2446
      foreach ($entries as $row) {
2447
2448
         $row = trim($row);
2449
2450
         // ignore empty lines
2451
         if(empty($row))
2452
            continue;
2453
2454
         // ignore lines with comments
2455
         if (substr(ltrim($row),0,2) == '//') // ignore comments
2456
            continue;
2457
2458
         $keyValuePair = explode('=',$row);
2459
2460
         // multiline values: the first line with an equal sign '=' will start a new key=value pair
2461
         if(sizeof($keyValuePair) == 1) {
2462
            if(isset($key) && !empty($key)) {
2463
               $this->_translationTable[$locale][$key] .= ' ' . chop($keyValuePair[0]);
2464
            }
2465
            continue;
2466
         }
2467
2468
         $key = trim($keyValuePair[0]);
2469
         $value = $keyValuePair[1];
2470
         if (!empty($key)) {
2471
            $this->_translationTable[$locale][$key] = chop($value);
2472
         }
2473
      }
2474
2475
      return true;
2476
2477
   } // load_translation_table()
2478
2479
   function get_translation($key)
2480
   {
2481
      $locale = $this->get_language();
2482
2483
      // if get_tranlation() get called via RPC (indirect), the translation
2484
      // table may not be loaded yet.
2485
      if (!isset($this->_loadedTranslationTables[$locale]))
2486
         $this->load_translation_table($locale);
2487
2488
      $trans = $this->_translationTable[$locale];
2489
2490
      /* get the real translation key */
2491
      $key = preg_replace('/##(.+?)##/', '${1}', $key);
2492
2493
      if (is_array($trans)) {
2494
         if (isset($trans[$key])) {
2495
            return $trans[$key];
2496
         }
2497
      }
2498
2499
      return "Can not find translation for key $key";
2500
   }
2501
2502
   /**
2503
    * unescape string and translate some characters to HTML
2504
    *
2505
    * this function gets used on strings previously modified
2506
    * by escape(). It will strip of slashes and translate
2507
    * some special characters (quotes for example) to HTML
2508
    * entities (if $encode_html == true).
2509
    *
2510
    * @param string $text
2511
    * @param boolean $encode_html
2512
    * @return string
2513
    */
2514
   public function unescape($text, $encode_html = true)
2515
   {
2516
      /* if text has already been escaped, we need to strip
2517
         slashes before
2518
      */
2519
2520
      $text = stripslashes($text);
2521
2522
      if($encode_html)
2523
         return htmlspecialchars($text);
2524
2525
      return $text;
2526
2527
   } // unescape()
2528
2529
   /**
2530
    * update users last login time
2531
    *
2532
    * this function updates the users last login time
2533
    * in the database table nephthys_users.
2534
    * @param int $user_idx
2535
    */
2536
   private function update_last_login($user_idx)
2537
   {
2538
      $this->db->db_query("
2539
         UPDATE
2540
            nephthys_users
2541
         SET
2542
            user_last_login='". mktime() ."'
2543
         WHERE
2544
            user_idx LIKE '". $user_idx ."'
2545
      ");
2546
2547
   } // update_last_login()
2548
2549
   /**
2550
    * get privilege name
2551
    *
2552
    * this function returns the real privilege name for the
2553
    * requests permission in the used language.
2554
    * @param string $user_priv
2555
    * @return string
2556
    */
2557
   public function get_priv_name($user_priv)
2558
   {
2559
      if(isset($this->cfg->privileges[$user_priv])) {
2560
         return $this->_($this->cfg->privileges[$user_priv]);
2561
      }
2562
2563
      /* return what we got, if we found no matching privilege */
2564
      return $user_priv;
2565
2566
   } // get_priv_name()
2567
2568
   /**
2569
    * update column sort order
2570
    *
2571
    * this function checks the provided information in the $_POST
2572
    * variable for the new requested sort options. it validates
2573
    * and then stores it in the $_SESSION['sort_order'] variable.
2574
    * @return string
2575
    */
2576
   public function update_sort_order()
2577
   {
2578
      /* define columns in each module which can be used for sorting.
2579
       * this array is used to validate the information provided by
2580
       * HTTP POST.
2581
       */
2582
      $modules = Array(
2583
         'buckets' => Array(
2584
            'bucket_name',
2585
            'bucket_owner',
2586
            'bucket_created',
2587
            'bucket_expire',
2588
            'bucket_notified',
2589
         ),
2590
         'addressbook' => Array(
2591
            'contact_name',
2592
            'contact_owner',
2593
         ),
2594
         'users' => Array(
2595
            'user_name',
2596
            'user_full_name',
2597
            'user_priv',
2598
            'user_last_login',
2599
         ),
2600
      );
2601
2602
      /* check if all parameters are available */
2603
      if(!isset($_POST['module']) || empty($_POST['module']) ||
2604
         !isset($_POST['column']) || empty($_POST['column']) ||
2605
         !isset($_POST['order']) || empty($_POST['order'])) {
2606
2607
         return "update_sort_order(): some parameters are missing!";
2608
      }
2609
2610
      /* make it a bit easier to handle... */
2611
      $module = $_POST['module'];
2612
      $column = $_POST['column'];
2613
      $order = $_POST['order'];
2614
2615
      /* check if the requested sort-order is valid */
2616
      if($order != 'asc' && $order != 'desc') {
2617
         return "update_sort_order(): incorrect sort order specified!";
2618
      }
2619
2620
      /* check if the requested module is valid */
2621
      if(in_array($module, array_keys($modules))) {
2622
         /* check if the requested column is valid */
2623
         if(in_array($column, $modules[$module])) {
2624
            /* update sort-order in session variable */
2625
            $_SESSION['sort_order'][$module]['column'] = $column;
2626
            $_SESSION['sort_order'][$module]['order']  = $order;
2627
            return "ok";
2628
         }
2629
      }
2630
2631
      return "update_sort_order(): incorrect order options specified!";
2632
2633
   } // update_sort_order()
2634
2635
   /**
2636
    * return column to be used to sort module results
2637
    *
2638
    * this function returns the column-name to be used in the
2639
    * SQL queries to sort the results.
2640
    * @param string $module
2641
    * @return string
2642
    */
2643
   public function get_sort_column($module)
2644
   {
2645
      if(isset($_SESSION['sort_order'][$module]))
2646
         return $_SESSION['sort_order'][$module]['column'];
2647
2648
      return NULL;
2649
2650
   } // get_sort_column()
2651
2652
   /**
2653
    * return sort-order to be used to sort module results
2654
    *
2655
    * this function returns the sort-order to be used in the
2656
    * SQL queries to sort the results.
2657
    * @param string $module
2658
    * @return string
2659
    */
2660
   public function get_sort_order($module)
2661
   {
2662
      if(isset($_SESSION['sort_order'][$module]))
2663
         return $_SESSION['sort_order'][$module]['order'];
2664
2665
      return NULL;
2666
2667
   } // get_sort_order()
2668
2669
   /**
2670
    * get directory information
2671
    *
2672
    * this function collect some directory information like
2673
    * amount of directories and files, last modification
2674
    * time, ... and returns them as array.
2675
    *
2676
    * @param string $path
2677
    * @return mixed
2678
    */
2679
   public function get_dir_info($path)
2680
   {
2681
      $info = Array();
2682
2683
      $info['files']    = 0;
2684
      $info['dirs']     = 0;
2685
      $info['last_mod'] = 0;
2686
2687
      if(!file_exists($path))
2688
         return __METHOD__ ." directory $path does not exist";
2689
2690
      if(!is_dir($path))
2691
         return __METHOD__ ." $path is not a directory";
2692
2693
      if(!is_readable($path) && !is_executable($path))
2694
         return __METHOD__ ." $path is either not readable or executable";
2695
2696
      $dirhandle = opendir($path);
2697
2698
      while($file = readdir($dirhandle)) {
2699
2700
         if(!$this->is_valid_file($path, $file))
2701
            continue;
2702
2703
         if(is_dir($path."/".$file)) {
2704
2705
            $info['dirs']++;
2706
2707
            $sub_info = $this->get_dir_info($path."/".$file);
2708
2709
            $info['dirs']    += $sub_info['dirs'];
2710
            $info['files']   += $sub_info['files'];
2711
            $info['last_mod'] = $info['last_mod'] > $sub_info['last_mod'] ? $info['last_mod'] : $sub_info['last_mod'];
2712
2713
         }
2714
         else {
2715
2716
            $info['files']++;
2717
2718
            $last_mod = filemtime($path ."/". $files);
2719
            $info['last_mod'] = $info['last_mod'] > $last_mod ? $info['last_mod'] : $last_mod;
2720
2721
         }
2722
      }
2723
2724
      closedir($dirhandle);
2725
2726
      return $info;
2727
2728
   } // get_dir_info()
2729
2730
   /**
2731
    * validate a file
2732
    *
2733
    * this function returns true, if the inspect file is
2734
    * valid in Nephthys point of view
2735
    *
2736
    * @param string $path
2737
    * @param string $file
2738
    * @return boolean
2739
    */
2740
   private function is_valid_file($path, $file)
2741
   {
2742
      if(!file_exists($path."/".$file))
2743
         return false;
2744
2745
      if(is_link($path."/".$file))
2746
         return false;
2747
2748
      if($file == "." || $file == "..")
2749
         return false;
2750
2751
      if($file == "webdav.html")
2752
         return false;
2753
2754
      return true;
2755
2756
   } // is_valid_file()
2757
2758
   public function load_filemgr()
2759
   {
2760
      $upload = new NEPHTHYS_UPLOAD;
2761
      return $upload->filemgr();
2762
2763
   } // load_filemgr()
2764
2765
   /**
2766
    * deltree similar function
2767
    *
2768
    * this function deletes the given $directory recursivley
2769
    * @param string $directory
2770
    * @return bool
2771
    */
2772
   public function deltree($directory)
2773
   {  
2774
      /* verify that $directory is really a directory */
2775
      if (!is_dir($directory))
2776
         return false;
2777
2778
      if(!is_readable($directory))
2779
         return false;
2780
2781
      /* open the directory and start reading all entries within */
2782
      $handle = opendir($directory);
2783
      while (false !== ($obj = readdir($handle))) {
2784
2785
         if ($obj == "." || $obj == "..")
2786
            continue;
2787
2788
         $fq_obj = $directory ."/". $obj;
2789
2790
         /* if object is a directory, call deltree for this directory. */
2791
         if (is_dir($fq_obj) && !is_link($fq_obj)) {
2792
            $this->deltree($fq_obj);
2793
         } else {
2794
            /* ordinary file will be deleted here */
2795
            if(!unlink($fq_obj))
2796
               return false;
2797
         }
2798
      }
2799
2800
      closedir($handle);
2801
2802
      /* now remove the - hopefully empty - directory */
2803
      if(!rmdir($directory))
2804
         return false;
2805
2806
      return true;
2807
2808
   } // deltree()
2809
2810
} // class NEPHTHYS
2811
2812
/***************************************************************************
2813
 *
2814
 * NEPHTHYS_DEFAULTS class, inherited by nephthys_cfg.php
2815
 *
2816
 ***************************************************************************/
2817
2818
class NEPHTHYS_DEFAULT_CFG {
2819
2820
   var $page_title  = "Nephthys - file sharing";
2821
   var $base_path   = "/srv/www/htdocs/nephthys";
2822
   var $data_path   = "/srv/www/nephthys_data";
2823
   var $web_path    = "/nephthys";
2824
   var $ftp_path    = "";
2825
   var $dav_path    = "/transfer";
2826
2827
   var $theme_name  = "default";
2828
   var $db_type     = "mysql";
2829
   var $mysql_host  = "localhost";
2830
   var $mysql_db    = "nephthys";
2831
   var $mysql_user  = "user";
2832
   var $mysql_pass  = "password";
2833
   var $sqlite_path = "/srv/www/nephthys_db/nephthys.db";
2834
   var $smarty_path = "/usr/share/php/smarty";
2835
   var $logging     = "display";
2836
   var $log_file    = "nephthys_err.log";
2837
   var $ignore_js   = false;
2838
   var $hide_logout = false;
2839
   var $use_https   = false;
2840
2841
   var $bucket_via_dav = true;
2842
   var $bucket_via_ftp = true;
2843
   var $bucket_via_http_upload = true;
2844
2845
   var $allow_server_auth = false;
2846
   var $user_auto_create  = false;
2847
2848
   var $force_profile_update = true;
2849
2850
   var $expirations = Array(
2851
      "1;1 ##DAY##;user",
2852
      "3;3 ##DAYS##;user",
2853
      "7;1 ##WEEK##;user",
2854
      "30;1 ##MONTH##;user",
2855
      "186;6 ##MONTHS##;manager",
2856
      "365;1 ##YEAR##; manager",
2857
      "-1;##NEVER##; manager",
2858
   );
2859
   var $privileges = Array(
2860
      "user" => "##USER##",
2861
      "manager" => "##MANAGER##",
2862
      "admin" => "##ADMIN##",
2863
   );
2864
2865
   var $language    = "en";
2866
   var $avail_langs = Array(
2867
      "en" => "English",
2868
      "de" => "German",
2869
      "ru" => "Russian",
2870
      "it" => "Italian",
2871
      "es" => "Spanish",
2872
      "nl" => "Dutch",
2873
   );
2874
2875
   public function __construct()
2876
   {
2877
      if(!isset($this->tmpl_path)) {
2878
         $this->tmpl_path = $this->base_path;
2879
      }
2880
2881
   } // __construct()
2882
2883
} // class NEPHTHYS_DEFAULT_CFG
2884
2885
/***************************************************************************
2886
 *
2887
 * NEPHTHYS_EXCEPTION class, inherits PHP's Exception class
2888
 *
2889
 ***************************************************************************/
2890
2891
class NEPHTHYS_EXCEPTION extends Exception {
2892
2893
   // custom string representation of object
2894
   public function __toString() {
2895
      return "Backtrace:<br />\n". str_replace("\n", "<br />\n", parent::getTraceAsString());
2896
   }
2897
2898
} // class NEPHTHYS_EXCEPTION
2899
2900
// vim: set filetype=php expandtab softtabstop=3 tabstop=3 shiftwidth=3 autoindent smartindent:
2901
?>
2902