PageFlush added, log_legal without remote address
[brisk.git] / web / Obj / brisk.phh
index 50bc009..9051a75 100644 (file)
  */
 
 
-define(BRISK_CONF, "brisk.conf.pho");
-define(FTOK_PATH, "/var/lib/brisk");
-define(LEGAL_PATH, "/tmp/legal_brisk");
-define(PROXY_PATH, "/var/lib/brisk_proxy");
-define(TABLES_N, 36);
-define(TABLES_AUTH_N, 4);
-define(PLAYERS_N, 3);
-define(MAX_POINTS, 5);
-define(MAX_PLAYERS, (20 + (PLAYERS_N * TABLES_N)));
-define(SHM_DIMS_MIN, (50000 + 10000 * TABLES_N + 15000 * MAX_PLAYERS));
-define(SHM_DIMS_MAX, SHM_DIMS_MIN + 1048576);
-define(SHM_DIMS_DLT, 65536);
-
-define(SHM_DIMS_U_MIN, 4096);
-define(SHM_DIMS_U_MAX, 65536);
-define(SHM_DIMS_U_DLT, 4096);
-
-define(COMM_N, 18);
-define(COMM_GEN_N, 50);
-
-define(CHAT_N, 3);
-define(CHAT_ILL_TIME, 6);
-
-define(SESS_LEN, 13);
-define(STREAM_TIMEOUT, 20);
-define(EXPIRE_TIME_RD, 180);
-define(EXPIRE_TIME_SMAMMA, 360); 
-define(EXPIRE_TIME_WAG, 10);
-define(WAKEUP_TIME, 12); 
+define('BRISK_CONF', "brisk.conf.pho");
+define('FTOK_PATH', "/var/lib/brisk");
+define('LEGAL_PATH', "/tmp/legal_brisk");
+define('PROXY_PATH', "/var/lib/brisk_proxy");
+define('TABLES_N', 36);
+define('TABLES_AUTH_N', 4);
+define('PLAYERS_N', 3);
+define('MAX_POINTS', 5);
+define('MAX_PLAYERS', (20 + (PLAYERS_N * TABLES_N)));
+define('SHM_DIMS_MIN', (50000 + 10000 * TABLES_N + 15000 * MAX_PLAYERS));
+define('SHM_DIMS_MAX', SHM_DIMS_MIN + 1048576);
+define('SHM_DIMS_DLT', 65536);
+
+define('SHM_DIMS_U_MIN', 4096);
+define('SHM_DIMS_U_MAX', 65536);
+define('SHM_DIMS_U_DLT', 4096);
+
+define('COMM_N', 18);
+define('COMM_GEN_N', 50);
+
+define('CHAT_N', 3);
+define('CHAT_ILL_TIME', 6);
+
+define('SESS_LEN', 13);
+define('STREAM_TIMEOUT', 60);
+define('EXPIRE_TIME_RD', 180);
+define('EXPIRE_TIME_SMAMMA', 360);
+define('EXPIRE_TIME_WAG', 10);
+define('WAKEUP_TIME', 12);
 // BAN_TIME da allineare anche in commons.js
-define(BAN_TIME, 3600); 
-define(GARBAGE_TIMEOUT, 10);
-define(NICKSERV, "<i>BriskServ</i>");
-
-
-define(DBG_ONL2, 0x0001);
-define(DBG_ONLY, 0x0002);
-define(DBG_MAIN, 0x0004);
-define(DBG_READ, 0x0008);
-define(DBG_REA2, 0x0010);
-define(DBG_SEND, 0x0020);
-define(DBG_LOCK, 0x0040);
-define(DBG_WRIT, 0x0080);
-define(DBG_LOAD, 0x0100);
-define(DBG_AUTH, 0x0200);
-define(DBG_CRIT, 0x0400);
-define(DBG_LMOP, 0x0800);
-define(DBG_TRAC, 0x1000);
+define('BAN_TIME', 3600);
+define('GARBAGE_TIMEOUT', 10);
+define('NICKSERV', "<i>BriskServ</i>");
+
+define('LOCK_SHARE_MAX', 10000);
+
+define('DBG_ONL2', 0x0001);
+define('DBG_ONLY', 0x0002);
+define('DBG_MAIN', 0x0004);
+define('DBG_READ', 0x0008);
+define('DBG_REA2', 0x0010);
+define('DBG_SEND', 0x0020);
+define('DBG_LOCK', 0x0040);
+define('DBG_WRIT', 0x0080);
+define('DBG_LOAD', 0x0100);
+define('DBG_AUTH', 0x0200);
+define('DBG_CRIT', 0x0400);
+define('DBG_LMOP', 0x0800);
+define('DBG_TRAC', 0x1000);
+define('DBG_SHME', 0x2000);
 // NOTE: BRISK DEBUG must be a numerical constant, not the result of operations on symbols 
-define(BRISK_DEBUG, 0xffffffbf);
+define('BRISK_DEBUG', 0x0800);
 
-define(BRISK_SINGLE_DEBUG,0);
-define(BRISK_SINGLE_SESS, "");
-// define(DEBUGGING, "local");
+define('BRISK_SINGLE_DEBUG',0);
+define('BRISK_SINGLE_SESS', "");
+define('DEBUGGING', "no-debugging");
 
 require_once("$DOCUMENT_ROOT/Etc/".BRISK_CONF);
 
@@ -134,12 +136,12 @@ $mlang_brisk = array( 'btn_backstand'=> array( 'it' => 'torna in piedi',
 $G_lng = langtolng($G_lang);
 
 $G_all_points = array( 11,10,4,3,2, 0,0,0,0,0 );
-$G_brisk_version = "3.5.3";
+$G_brisk_version = "3.6.3";
 
 /* MLANG: ALL THE INFO STRINGS IN brisk.phh */
-$root_wellarr = array( 'it' => array ( 'Brisk (Ver. '.$G_brisk_version.'), <b>NOVITA\'</b>: terza versione di test per la nuova gestione dei dati volatili, rivista gestione del ticker.',
+$root_wellarr = array( 'it' => array ( 'Brisk (Ver. '.$G_brisk_version.'), <b>NOVITA\'</b>: nuovo sistema di evidenziazione degli utenti registrati.',
                                        'Se vuoi iscriverti alla <a target="_blank" href="mailto:ml-briscola+subscribe@milug.org">Mailing List</a>, cliccala!' ),
-                       'en' => array ( 'Brisk (Ver. '.$G_brisk_version.'), <b>NEWS</b>: third test version for the new volatile data management, ticker management refactored.',
+                       'en' => array ( 'Brisk (Ver. '.$G_brisk_version.'), <b>NEWS</b>: usage of reader/writer locking instead of generic exclusive locking.',
                                        'If you want to subscribe our <a target="_blank" href="ml-briscola+subscribe@milug.org">Mailing List</a>, click it!' ) );
 
 $G_room_help = array( 'it' => '
@@ -273,7 +275,7 @@ $G_room_about = array( 'it' => '<br>
   briscola chiamata in salsa ajax
 </div>
 <br><b>version '.$G_brisk_version.'</b><br><br>
-Copyright 2006-2009 <a href=\\"mailto:brisk@alternativeoutput.it\\">Matteo Nastasi</a> (aka mop)<br><br>',
+Copyright 2006-2012 <a href=\\"mailto:brisk@alternativeoutput.it\\">Matteo Nastasi</a> (aka mop)<br><br>',
                       'en' => '<br>
 <div id=\\"header\\" class=\\"header\\">
   <img class=\\"nobo\\" src=\\"img/brisk_logo64.png\\">
@@ -282,6 +284,79 @@ Copyright 2006-2009 <a href=\\"mailto:brisk@alternativeoutput.it\\">Matteo Nasta
 <br><b>version '.$G_brisk_version.'</b><br><br>
 Copyright 2006-2009 <a href=\\"mailto:brisk@alternativeoutput.it\\">Matteo Nastasi</a> (aka mop)<br><br>');
 
+function mop_flush()
+{
+    ob_flush();
+    flush();
+}
+
+function file_lock($fname, $is_exclusive)
+{
+    if (($res = @fopen($fname, "r+")) == FALSE) {
+        return (FALSE);
+    }
+        
+    if (flock($res, ($is_exclusive ? LOCK_EX : LOCK_SH)) == FALSE) {
+        fclose($res);
+        return (FALSE);
+    }
+
+    return ($res);
+}
+
+function file_unlock($res)
+{
+    if ($res != FALSE) {
+        flock($res, LOCK_UN);
+        fclose($res);
+    }
+}
+
+function webservers_exceeded()
+{
+    return(file_exists(PROXY_PATH."/webservers_exceded.flag"));
+}
+
+function webservers_check()
+{
+    GLOBAL $G_webserver_max;
+
+    /* FIXME: check all procs expirations */
+    return (10);
+
+    $ct = 0;
+
+    $dh = opendir('/proc');
+    while (($file = readdir($dh)) !== false) {
+        if (preg_match('/[0-9]+/', $file)) {
+            $cmdline = explode("\0", file_get_contents('/proc/'.$file.'/cmdline'));
+            // echo "xxx".$cmdline[0].$n;
+            if (strstr('/usr/sbin/apache2', $cmdline[0]) != FALSE) {
+                // echo "yyy".$cmdline[0].$n;
+                $ct++;
+            }
+        }
+    }
+    closedir($dh);
+
+    if ($ct >= $G_webserver_max) {
+        touch(PROXY_PATH."/webservers_exceded.flag");
+    }
+    else {
+        unlink(PROXY_PATH."/webservers_exceded.flag");
+    }
+    return ($ct);
+}
+
+$escpush_from = array("\\", "\"");
+$escpush_to   = array("\\\\", "\\\"");
+function escpush($s)
+{
+    GLOBAL $escpush_from, $escpush_to;
+
+    return str_replace($escpush_from, $escpush_to, $s);
+}
+
 $escinp_from = array( "\""     );
 $escinp_to = array(   "&quot;" );
 
@@ -583,37 +658,41 @@ class Table {
 
 
 // User flags
-define(USER_FLAG_AUTH,     0x02);
+define('USER_FLAG_AUTH',     0x02);
 
-define(USER_FLAG_MAP_AUTH, 0x0c);
-define(USER_FLAG_LISTAUTH, 0x04);
-define(USER_FLAG_ISOLAUTH, 0x08);
+define('USER_FLAG_MAP_AUTH', 0x0c);
+define('USER_FLAG_LISTAUTH', 0x04);
+define('USER_FLAG_ISOLAUTH', 0x08);
 
-define(USER_FLAG_DBFAILED, 0x10); 
+define('USER_FLAG_DBFAILED', 0x10);
 
 //   user status
-define(USER_FLAG_S_NORM,  0x000); // done
-define(USER_FLAG_S_PAU,   0x100); // done
-define(USER_FLAG_S_OUT,   0x200); // done
-define(USER_FLAG_S_DOG,   0x300); // done
-define(USER_FLAG_S_EAT,   0x400); // done
-define(USER_FLAG_S_WRK,   0x500); // done
-define(USER_FLAG_S_SMK,   0x600); // done
-define(USER_FLAG_S_EYE,   0x700); // done
-define(USER_FLAG_S_RABB,  0x800); // done
-define(USER_FLAG_S_SOCC,  0x900); // done
-define(USER_FLAG_S_BABY,  0xa00); // done
-define(USER_FLAG_S_MOP,   0xb00); // done
-
-define(USER_FLAG_S_ALL,   0xf00); // done
+define('USER_FLAG_S_NORM',  0x000); // done
+define('USER_FLAG_S_PAU',   0x100); // done
+define('USER_FLAG_S_OUT',   0x200); // done
+define('USER_FLAG_S_DOG',   0x300); // done
+define('USER_FLAG_S_EAT',   0x400); // done
+define('USER_FLAG_S_WRK',   0x500); // done
+define('USER_FLAG_S_SMK',   0x600); // done
+define('USER_FLAG_S_EYE',   0x700); // done
+define('USER_FLAG_S_RABB',  0x800); // done
+define('USER_FLAG_S_SOCC',  0x900); // done
+define('USER_FLAG_S_BABY',  0xa00); // done
+define('USER_FLAG_S_MOP',   0xb00); // done
+
+define('USER_FLAG_S_ALL',   0xf00); // done
 
 /* type of user normal, supporter etc ... */
-define(USER_FLAG_TY_ALL,     0xff0000); // done
-define(USER_FLAG_TY_NORM,    0x010000); // done
-define(USER_FLAG_TY_SUPER,   0x020000); // done
+define('USER_FLAG_TY_ALL',     0xff0000); // done
+define('USER_FLAG_TY_NORM',    0x010000); // done
+define('USER_FLAG_TY_SUPER',   0x020000); // done
 //  ... other usefull status ...
-define(USER_FLAG_TY_SUSPEND, 0x400000); // done
-define(USER_FLAG_TY_DISABLE, 0x800000); // done
+define('USER_FLAG_TY_SUSPEND', 0x400000); // done
+define('USER_FLAG_TY_DISABLE', 0x800000); // done
+
+// 240 is the right value, 600 is for fwrite error test
+define('RD_ENDTIME_DELTA',  240);
+define('RD_KEEPALIVE_TOUT',   4);
 
 class User {
   var $idx;        // index in the users array when you are in game
@@ -629,6 +708,17 @@ class User {
   var $subst;      // substatus for each status   
   var $step;       // step of the current status
   var $trans_step; // step to enable transition between pages (disable == -1)
+
+  var $rd_socket;  // socket handle of push stream
+  var $rd_endtime; // end time for push stream
+  var $rd_stat;    // actual status of push stream
+  var $rd_subst;   // actual substatus of push stream
+  var $rd_step;    // actual step of push stream
+  var $rd_from;    // referer
+  var $rd_scristp; // current script step (for each session) 
+  var $rd_kalive;  // if no message are sent after RD_KEEPALIVE_TOUT secs we send a keepalive from server
+  var $rd_cache;   // place where store failed fwrite data
+
   var $comm;       // commands array
   // var $asta_card;  // 
   // var $asta_pnt;   //
@@ -672,6 +762,17 @@ class User {
     $thiz->step       = 1;
     $thiz->trans_step = -1;
     $thiz->comm       = array();
+
+    $thiz->rd_socket  = NULL;
+    $thiz->rd_endtime = -1;
+    $thiz->rd_stat    = -1;
+    $thiz->rd_subst   = "";
+    $thiz->rd_step    = -1;
+    $thiz->rd_from    = "";
+    $thiz->rd_scristp = -1;
+    $thiz->rd_kalive  = -1;
+    $thiz->rd_cache   = "";
+
     $thiz->asta_card  = -2;
     $thiz->asta_pnt   = -1;
     $thiz->handpt     = -1;
@@ -804,6 +905,62 @@ class User {
     return ($thiz);
   }
 
+  function rd_data_set($curtime, $stat, $subst, $step, $from)
+  {
+      $this->rd_endtime = $curtime + RD_ENDTIME_DELTA;
+      $this->rd_stat    = $stat;
+      $this->rd_subst   = $subst;
+      $this->rd_step    = $step;
+      $this->rd_from    = $from;
+      $this->rd_scristp = 0;
+      $this->rd_kalive  = $curtime + RD_KEEPALIVE_TOUT;
+  }
+
+  function rd_socket_get() {
+      return ($this->rd_socket);
+  }
+
+  function rd_socket_set($sock) {
+      $this->rd_socket = $sock;
+  }
+
+  function rd_kalive_get()
+  {
+      return ($this->rd_kalive);
+  }
+
+  function rd_kalive_set($tm)
+  {
+      $this->rd_kalive = $tm;
+  }
+
+  function rd_kalive_is_expired($tm)
+  {
+      // printf("rd_kalive %d tm %d\n", $this->rd_kalive, $tm);
+      return ($this->rd_kalive < $tm);
+  }
+
+  function rd_endtime_is_expired($tm)
+  {
+      // printf("rd_endtime %d tm %d\n", $this->rd_kalive, $tm);
+      return ($this->rd_endtime < $tm);
+  }
+
+  function rd_kalive_reset($tm)
+  {
+      $this->rd_kalive = $tm + RD_KEEPALIVE_TOUT;
+  }
+
+  function rd_cache_get()
+  {
+      return ($this->rd_cache);
+  }
+
+  function rd_cache_set($cache)
+  {
+      $this->rd_cache = $cache;
+  }
+
   function idx_get() {
       return ($this->idx);
   }
@@ -819,8 +976,8 @@ class User {
     /*
     if (validate_sess($this->sess)) {
       if (file_exists(PROXY_PATH) == FALSE)
-        mkdir(PROXY_PATH);
-      $fp = fopen(PROXY_PATH."/".$this->sess.".stat", 'w');
+        mkdir(PROXY_PATH, 0775, TRUE);
+      $fp = @fopen(PROXY_PATH."/".$this->sess.".stat", 'w');
       fwrite($fp, sprintf("%s\n",$this->stat));
       fclose($fp);
     }
@@ -842,13 +999,14 @@ class User {
       return TRUE;
   }
 
+
   function save_step() 
   {
       do {
           if (validate_sess($this->sess) == FALSE)
               break;
           if (file_exists(PROXY_PATH) == FALSE)
-              mkdir(PROXY_PATH);
+              mkdir(PROXY_PATH, 0775, TRUE);
           if (($fp = @fopen(PROXY_PATH."/".$this->sess.".step", 'w')) == FALSE)
               break;
           fwrite($fp, pack("LL",$this->step, $this->idx));
@@ -870,7 +1028,7 @@ class User {
               break;
           
           if (file_exists(PROXY_PATH) == FALSE)
-              mkdir(PROXY_PATH);
+              mkdir(PROXY_PATH, 0775, TRUE);
           if (($fp = @fopen(PROXY_PATH."/".$sess.".step", 'rb')) == FALSE)
               break;
           if (($s = fread($fp, 8)) == FALSE)
@@ -892,13 +1050,20 @@ class User {
       return (FALSE);
   }
 
+  static function unproxy_step($sess) {
+      log_rd2("UNPROXY: ".PROXY_PATH."/".$sess.".step");
+      if (file_exists(PROXY_PATH) == FALSE)
+          return;
+      @unlink(PROXY_PATH."/".$sess.".step");
+  }
+
   function reset() {
     $curtime = time();
-    log_legal($curtime, $this, "STAT:LOGOUT", '');
+    log_legal($curtime, 'xxx', $this, "STAT:LOGOUT", '');
 
     $tmp_sess = $this->sess;
     $this->sess = "";
-    step_unproxy($tmp_sess);
+    self::unproxy_step($tmp_sess);
     $this->name = "";  // OK here
     while (array_pop($this->comm) != NULL);
     $this->step = 0;
@@ -914,11 +1079,9 @@ class User {
   {
       log_main("load_data: id [".$id."] sess [".($sess == FALSE ? "FALSE" : $sess)."] ");
       
-      $doexit = FALSE;
       do {
           if (($tok = @ftok(FTOK_PATH."/user".$id, "B")) == -1) {
               log_main("ftok failed");
-              $doexit = TRUE;
               break;
           }
           
@@ -930,10 +1093,10 @@ class User {
               $shm_sz = SHM_DIMS_U_MIN;
           
           if ($shm = shm_attach($tok, $shm_sz)) {
-              $user = @shm_get_var($shm, $tok);
-              
+              if (($user = @shm_get_var($shm, $tok)) == FALSE) {
+                  break;
+              }
               if ($sess != FALSE && $user->sess != $sess) {
-                  $doexit = TRUE;
                   break;
               }
               log_only("user ==  ".($user == FALSE ?   "FALSE" : "TRUE")."  user ===  ".($user === FALSE ? "FALSE" : "TRUE")."  user isset ".(isset($user) ?   "TRUE" : "FALSE"));
@@ -947,6 +1110,7 @@ class User {
                       log_only("PUT_VAR FALLITA ".strlen(serialize($user)));
                       log_only(serialize($user));
                   }
+                  log_shme("User::save_data2");
               }
               else {
                   if ($sess != FALSE) {
@@ -973,9 +1137,6 @@ class User {
           return ($user);
       } while (0);
       
-      if ($doexit)
-          exit();
-      
       return (FALSE);
   }
   
@@ -994,10 +1155,13 @@ class User {
               break;
           
           // log_only("PUT_VAR DI ".strlen(serialize($user)));
-          if (shm_put_var($shm, $tok, $user) != FALSE) {
+          if (@shm_put_var($shm, $tok, $user) != FALSE) {
               shm_detach($shm);
               if ($user->sess != "")
                   $user->save_step();
+
+              log_shme("User::save_data");
+
               log_main("User[".$id."] saved.");
               return (TRUE);
           }
@@ -1015,17 +1179,17 @@ class User {
       return (FALSE);
   }
 
+  function myname_innerHTML()
+  {
+      $class_id = ($this->flags & USER_FLAG_AUTH) + 1;
+      
+      return (sprintf('$("myname").innerHTML = "<span class=\"au%d\">%s</span>";', $class_id, 
+                      xcape($this->name,ENT_COMPAT,"UTF-8")));
+  }
 
 } // end class User
 
 
-function step_unproxy($sess) {
-  log_rd2("UNPROXY: ".PROXY_PATH."/".$sess.".step");
-  if (file_exists(PROXY_PATH) == FALSE)
-    mkdir(PROXY_PATH);
-  @unlink(PROXY_PATH."/".$sess.".step");
-}
-
 
 class Room {
     static $delta_t;
@@ -1079,8 +1243,11 @@ class Room {
     $curtime = time();
 
     // externalized if ($force || $this->garbage_timeout < $curtime) {
-    if ($force || Room::garbage_time_is_expired($curtime)) {
+    if (!$force && !Room::garbage_time_is_expired($curtime)) {
+        return ($ismod);
+    }
       
+    webservers_check();
       // FIXME BRISK4: include for each kind of table
       require_once("${G_base}briskin5/Obj/briskin5.phh");
 
@@ -1092,7 +1259,7 @@ class Room {
        if ($table_cur->player_n == PLAYERS_N) {
          log_main("PLAYERS == N TABLE ".$table_idx);
          
-         if (($sem = Bin5::lock_data($table_idx)) != FALSE) { 
+         if (($sem = Bin5::lock_data(TRUE, $table_idx)) != FALSE) { 
            log_main("bin5 lock data success");
            
            $no_recovery = FALSE;
@@ -1116,7 +1283,7 @@ class Room {
 
              // is the end of the table
              if ($bri->the_end == TRUE) {
-               /*
+                  /*
                 *  DESTROY OF FINISHED TABLE && MOVE PLAYER TO ROOM AGAIN
                 */
                log_main("garbage_manager: INSIDE THE END.");
@@ -1138,12 +1305,13 @@ class Room {
                  $user_cur->bantime    = $bri_user->bantime;
                }
 
-                log_legal($curtime, $user_cur, "STAT:DESTROY_GAME", $plist);
+                log_legal($curtime, 'xxx', $user_cur, "STAT:DESTROY_GAME", $plist);
 
                $this->room_join_wakeup($user_cur, FALSE, 0); 
                $table_cur->table_token = "";
                 $table_cur->wakeup_time = $curtime + WAKEUP_TIME;
-               Bin5::destroy_data($table_idx);
+                        
+                        $bri->destroy_data($table_idx);
              }
              else {
                log_main("gm:: save_data");
@@ -1176,7 +1344,7 @@ class Room {
               for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
                 $plist .= '|'.$this->user[$table_cur->player[$i]]->sess;
               }
-              log_legal($curtime, $user_cur, "STAT:DESTROY_GAME(RECOVERY)", $plist);
+              log_legal($curtime, 'xxx', $user_cur, "STAT:DESTROY_GAME(RECOVERY)", $plist);
               
              $this->room_join_wakeup($user_cur, TRUE, -2); 
              $table_cur->table_token = "";
@@ -1231,7 +1399,6 @@ class Room {
       // externalized $this->garbage_timeout = time() + GARBAGE_TIMEOUT;
       Room::garbage_time_expire_set($curtime + GARBAGE_TIMEOUT);
       $ismod = TRUE;
-    }
 
     return ($ismod);
   }
@@ -1267,9 +1434,8 @@ class Room {
     }
 
     $ret .= sprintf('subst = "%s";', $user->subst);
-    $itin = ($user->flags & USER_FLAG_AUTH ? "<i>" : "");
-    $itou = ($user->flags & USER_FLAG_AUTH ? "</i>" : "");
-    $ret .= sprintf('$("myname").innerHTML = "<b>%s%s%s</b>";', $itin, xcape($user->name), $itou);
+    $ret .= $user->myname_innerHTML();
+
     for ($i = 0 ; $i < TABLES_N ; $i++) {
 
       $ret .= $this->table_content($user, $i);
@@ -1342,7 +1508,7 @@ class Room {
 
       $ret = "gst.st = ".($user_cur->step+1)."; ".($remove_wagon ? sprintf("tra.rem(%d);",$table_idx) : "");
       if ($from_table && ($user_cur->table == $table_idx || $user->idx_get() == $i)) {
-       $ret .= 'gst.st_loc++; the_end=true; window.onunload = null; window.onbeforeunload = null; document.location.assign("index.php");|';
+       $ret .= 'gst.st_loc++; hstm.stop(); window.onunload = null; window.onbeforeunload = null; document.location.assign("index.php");|';
        // $ret .= 'gst.st_loc++; document.location.assign("index.php");|';
        log_main("DOCUMENT.index.php: from table");
       }
@@ -1510,9 +1676,7 @@ class Room {
        $ret .= $this->table_content($user_cur, $table_idx);
       
       if ($user->idx_get() == $i) {
-        $itin = ($user->flags & USER_FLAG_AUTH ? "<i>" : "");
-        $itou = ($user->flags & USER_FLAG_AUTH ? "</i>" : "");
-       $ret .= sprintf('$("myname").innerHTML = "<b>%s%s%s</b>: ";', $itin, xcape($user->name), $itou);
+          $ret .= $user->myname_innerHTML();
       }
       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
       $user_cur->step_inc();
@@ -1734,7 +1898,7 @@ class Room {
 
           if ($user_cur->sess == '')
             continue;
-          if ($user_cur->name == $name_new)
+          if (strcasecmp($user_cur->name,$name_new) == 0)
             break;
           }
         if ($i <  MAX_PLAYERS) {
@@ -1867,7 +2031,7 @@ class Room {
         $to_room = $to_user;
       }
 
-      log_legal($curtime, $user, 
+      log_legal($curtime, 'xxx', $user, 
                ($user->stat == 'room' ? 'room' : 'table '.$user->table),$msg);
       
       $user->chat_lst = "$msg";
@@ -1931,7 +2095,7 @@ class Room {
         if ($table_cur->player_n == PLAYERS_N) {
           log_main("PLAYERS == N TABLE ".$table_idx);
         
-          if (($sem = Bin5::lock_data($table_idx)) != FALSE) { 
+          if (($sem = Bin5::lock_data(TRUE, $table_idx)) != FALSE) { 
             log_main("bin5 lock data success");
             
             $no_recovery = FALSE;
@@ -2089,7 +2253,7 @@ class Room {
 
     log_auth("XXX", sprintf("TROVATO A QUESTO PUNTO [%d] sess [%s] name [%s]", $idx, $sess, $name_new));
 
-    /* there is another user logged with your account and you and him have authenticated => che new user
+    /* there is another user logged with your account and you and him have authenticated => new user
        get the session of the old user */
     if ($ghost > -1 && $ghost_auth && ($authenticate != FALSE)) {
       /* swap session */
@@ -2110,7 +2274,7 @@ class Room {
       if ($ghost_user->stat == "table" && $this->table[$table_idx]->player_n == PLAYERS_N) {
         // FIXME BRISK4: include for each kind of table
         require_once("${G_base}briskin5/Obj/briskin5.phh");
-        if (($brisem = Bin5::lock_data($table_idx)) != FALSE) { 
+        if (($brisem = Bin5::lock_data(TRUE, $table_idx)) != FALSE) { 
           if (($bri = Bin5::load_data($table_idx)) != FALSE) {
             if ($bri->the_end != TRUE) {
               $bri->user[$ghost_user->table_pos]->step_inc();
@@ -2181,7 +2345,7 @@ class Room {
               if (strcmp("", $this->user[$i]->sess) == 0) 
                 continue;
               
-              if (strcmp($this->user[$i]->name, $ghostname) == 0) {
+              if (strcasecmp($this->user[$i]->name, $ghostname) == 0) {
                 $ghostname = '';
                 break;
               }
@@ -2233,11 +2397,7 @@ class Room {
       if ($user_cur->stat == 'room') {
        $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ".$this->standup_content($user_cur);
        if ($user->idx_get() == $i) {
-          $itin = ($user->flags & USER_FLAG_AUTH ? "<i>" : "");
-          $itou = ($user->flags & USER_FLAG_AUTH ? "</i>" : "");
-
-         $user_cur->comm[$user_cur->step % COMM_N] .= sprintf('$("myname").innerHTML = "<b>%s%s%s</b>: ";', 
-                                                               $itin, xcape($user->name), $itou);
+          $user_cur->comm[$user_cur->step % COMM_N] .= $user->myname_innerHTML();
        }
        log_main("FROM STANDUP: NAME: ".$user_cur->name." SENDED: ".$user_cur->comm[$user_cur->step % COMM_N]);
        
@@ -2258,12 +2418,10 @@ class Room {
   function load_data() 
   {
     GLOBAL $sess;
-    $doexit = FALSE;
 
     do {
       if (($tok = @ftok(FTOK_PATH."/main", "B")) == -1) {
        log_main("ftok failed");
-       $doexit = TRUE;
        break;
       }
     
@@ -2275,7 +2433,7 @@ class Room {
        $shm_sz = SHM_DIMS_MIN;
 
       if ($shm = shm_attach($tok, $shm_sz)) {
-          $room = @shm_get_var($shm, $tok);
+          $room = @shm_get_var($shm, $tok); // CHECKED BELOW
           
           log_only("bri ==  ".($room == FALSE ?   "FALSE" : "TRUE")."  bri ===  ".($room === FALSE ? "FALSE" : "TRUE")."  bri isset ".(isset($room) ?   "TRUE" : "FALSE"));
           if (isset($room)) 
@@ -2287,6 +2445,8 @@ class Room {
               
               $room = Room::create();
               
+              log_shme("Room::create");
+
               if (Room::save_data($room) == FALSE)
                   return FALSE;
 
@@ -2297,7 +2457,13 @@ class Room {
           shm_detach($shm);
 
           for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
-              $room->user[$i] = User::load_data($i, FALSE);
+              if (($room->user[$i] = User::load_data($i, FALSE)) == FALSE) {
+                  log_crit("User::load_data failed");
+                  break;
+              }
+          }
+          if ($i < MAX_PLAYERS) {
+              break;
           }
       }
       
@@ -2307,9 +2473,6 @@ class Room {
       return ($room);
     } while (0);
     
-    if ($doexit)
-      exit();
-    
     return (FALSE);
   }
   
@@ -2330,7 +2493,7 @@ class Room {
        break;
       
       // log_only("PUT_VAR DI ".strlen(serialize($room)));
-      if (shm_put_var($shm, $tok, $room) != FALSE) {
+      if (@shm_put_var($shm, $tok, $room) != FALSE) {
        shm_detach($shm);
        return (TRUE);
       }
@@ -2372,7 +2535,8 @@ class Room {
               break;
       
           // log_only("PUT_VAR DI ".strlen(serialize($room)));
-          if (shm_put_var($shm, $tok, $room) != FALSE) {
+          if (@shm_put_var($shm, $tok, $room) != FALSE) {
+              log_shme("Room::save_data");
               $ret = TRUE;
               break;
           }
@@ -2397,27 +2561,16 @@ class Room {
       return ($ret);
   }
 
-  static function lock_data()
+  static function lock_data($is_exclusive)
   {
-      GLOBAL $sess; 
-      
-      //  echo "LOCK: ".FTOK_PATH."/main";
-      //  exit;
-      if (($tok = @ftok(FTOK_PATH."/main", "B")) == -1) {
-          return (FALSE);
-      }
-      // echo "FTOK ".$tok."<br>";
-      if (($res = sem_get($tok)) == FALSE) {
-          return (FALSE);
-      }
-      if (sem_acquire($res)) {
+      if (($res = file_lock(FTOK_PATH."/main", $is_exclusive)) != FALSE) {
           self::$delta_t = microtime(TRUE);
           log_lock("LOCK   room         [".self::$delta_t."]");
-
+          
           return ($res);
       }
-      else
-          return (FALSE);
+
+      return (FALSE);
   }
   
   static function unlock_data($res)
@@ -2426,7 +2579,7 @@ class Room {
     
     log_lock("UNLOCK room         [".(microtime(TRUE) - (self::$delta_t))."]");
 
-    return (sem_release($res));
+    file_unlock($res);
   }
 
 
@@ -2510,7 +2663,7 @@ class Room {
       $fp = FALSE;
       do {
           if (file_exists(PROXY_PATH) == FALSE)
-              mkdir(PROXY_PATH);
+              mkdir(PROXY_PATH, 0775, TRUE);
           if (($fp = @fopen(PROXY_PATH."/garbage_time.expired", 'rb')) == FALSE)
               break;
           if (($s = fread($fp, 4)) == FALSE)
@@ -2534,7 +2687,7 @@ class Room {
   {
       do {
           if (file_exists(PROXY_PATH) == FALSE)
-              mkdir(PROXY_PATH);
+              mkdir(PROXY_PATH, 0775, TRUE);
           if (($fp = @fopen(PROXY_PATH."/garbage_time.expired", 'wb')) == FALSE)
               break;
           fwrite($fp, pack("L",$tm));
@@ -2572,6 +2725,16 @@ function btrace_line($ar)
     return ($ret);
 }
 
+function trace_ftok($id, $add)
+{
+    // NOTE: without space to use sed to substitute "= @ftok("  with "= @ftok("
+    $tok=@ftok($id, $add);
+
+    log_shme($tok.": ".$id." + ".$add);
+
+    return ($tok);
+}
+
 function log_mop($step, $log)
 {
     GLOBAL $sess, $PHP_SELF;
@@ -2587,7 +2750,7 @@ function log_mop($step, $log)
     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_LMOP) == 0)
         return;
     
-    if (BRISK_DEBUG & DBG_TRAC) 
+    if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
         $btrace = btrace_line(debug_backtrace());
     else
         $btrace = "";
@@ -2613,7 +2776,7 @@ function log_only2($log)
     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_ONL2) == 0)
         return;
     
-    if (BRISK_DEBUG & DBG_TRAC) 
+    if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
         $btrace = btrace_line(debug_backtrace());
     else
         $btrace = "";
@@ -2638,7 +2801,7 @@ function log_crit($log)
     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_CRIT) == 0)
         return;
     
-    if (BRISK_DEBUG & DBG_TRAC) 
+    if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
         $btrace = btrace_line(debug_backtrace());
     else
         $btrace = "";
@@ -2663,7 +2826,7 @@ function log_only($log)
     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_ONLY) == 0)
         return;
     
-    if (BRISK_DEBUG & DBG_TRAC) 
+    if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
         $btrace = btrace_line(debug_backtrace());
     else
         $btrace = "";
@@ -2688,7 +2851,7 @@ function log_main($log)
     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_MAIN) == 0)
         return;
     
-    if (BRISK_DEBUG & DBG_TRAC) 
+    if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
         $btrace = btrace_line(debug_backtrace());
     else
         $btrace = "";
@@ -2713,7 +2876,7 @@ function log_rd($log)
     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_READ) == 0)
         return;
 
-    if (BRISK_DEBUG & DBG_TRAC) 
+    if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
         $btrace = btrace_line(debug_backtrace());
     else
         $btrace = "";    
@@ -2738,7 +2901,7 @@ function log_rd2($log)
     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_REA2) == 0)
         return;
     
-    if (BRISK_DEBUG & DBG_TRAC) 
+    if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
         $btrace = btrace_line(debug_backtrace());
     else
         $btrace = "";
@@ -2763,8 +2926,8 @@ function log_send($log)
     
     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_SEND) == 0)
         return;
-    
-    if (BRISK_DEBUG & DBG_TRAC) 
+
+    if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)    
         $btrace = btrace_line(debug_backtrace());
     else
         $btrace = "";
@@ -2789,7 +2952,7 @@ function log_lock($log)
     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_LOCK) == 0)
         return;
     
-    if (BRISK_DEBUG & DBG_TRAC) 
+    if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
         $btrace = btrace_line(debug_backtrace());
     else
         $btrace = "";
@@ -2814,7 +2977,7 @@ function log_wr($log)
     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_WRIT) == 0)
         return;
     
-    if (BRISK_DEBUG & DBG_TRAC) 
+    if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
         $btrace = btrace_line(debug_backtrace());
     else
         $btrace = "";
@@ -2839,7 +3002,7 @@ function log_load($log)
     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_LOAD) == 0)
         return;
     
-    if (BRISK_DEBUG & DBG_TRAC) 
+    if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
         $btrace = btrace_line(debug_backtrace());
     else
         $btrace = "";
@@ -2859,7 +3022,7 @@ function log_auth($sess, $log)
     if (( (BRISK_DEBUG | ($sess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_AUTH) == 0)
         return;
     
-    if (BRISK_DEBUG & DBG_TRAC) 
+    if ((BRISK_DEBUG | ($sess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
         $btrace = btrace_line(debug_backtrace());
     else
         $btrace = "";
@@ -2869,17 +3032,42 @@ function log_auth($sess, $log)
     }
 }
 
+function log_shme($log)
+{
+    GLOBAL $sess, $PHP_SELF;
+    
+    if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_SHME) == 0)
+        return;
+    
+    if (isset($sess) == FALSE)
+        $ssess = "XXXX";
+    else
+        $ssess = $sess;
+    
+    if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_SHME) == 0)
+        return;
+    
+    if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
+        $btrace = btrace_line(debug_backtrace());
+    else
+        $btrace = "";
+    if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
+        fwrite($fp, sprintf("SHME: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
+        fclose($fp);
+    }
+}
+
+
 
 // function log_legal($curtime, $sess, $name, $where, $mesg) 
-function log_legal($curtime, $user, $where, $mesg) 
+function log_legal($curtime, $addr, $user, $where, $mesg) 
 {
-  GLOBAL $_SERVER;
 
   if (($fp = @fopen(LEGAL_PATH."/legal.log", 'a')) != FALSE) {
     /* Unix time | session | nickname | IP | where was | mesg */
     fwrite($fp, sprintf("%ld|%s|%s|%s|%s|%s|%s|\n", $curtime, $user->sess,
                         ($user->flags & USER_FLAG_AUTH ? 'A' : 'N'),
-                        $user->name, $_SERVER['REMOTE_ADDR'], $where , $mesg));
+                        $user->name, $addr, $where , $mesg));
     fclose($fp);
   }
 }
@@ -2998,74 +3186,57 @@ function sharedmem_sz($tok)
   $shm_sz = shmop_size($shm_id);
   shmop_close($shm_id);
   
-  log_main("shm_sz: ".$shm_sz."   SHM_DIMS: ".SHM_DIMS);
+  // log_main("shm_sz: ".$shm_sz."   SHM_DIMS: ".SHM_DIMS);
   return ($shm_sz);
 }    
 
 class Warrant {
     static $delta_t;
 
-  function lock_data()
+  static function lock_data($is_exclusive)
   {
-    GLOBAL $sess; 
-    
-    if (($tok = @ftok(FTOK_PATH."/warrant", "B")) == -1) {
-      return (FALSE);
-    }
-    // echo "FTOK ".$tok."<br>";
-    if (($res = sem_get($tok)) == FALSE) {
-      return (FALSE);
-    }
-    if (sem_acquire($res)) {   
-        self::$delta_t = microtime(TRUE);
-        log_lock("LOCK   warrant      [".self::$delta_t."]");
-      return ($res);
-    }
-    else
+      if (($res = file_lock(FTOK_PATH."/warrant", $is_exclusive)) != FALSE) {
+          self::$delta_t = microtime(TRUE);
+          log_lock("LOCK   warrant      [".self::$delta_t."]");
+          
+          return ($res);
+      }
+
       return (FALSE);
   }
   
-  function unlock_data($res)
+  static function unlock_data($res)
   {
     GLOBAL $sess; 
     
     log_lock("UNLOCK warrant      [".(microtime(TRUE) - (self::$delta_t))."]");
 
-    return (sem_release($res));
+    file_unlock($res);
   }
 }
 
 class Poll {
     static $delta_t;
 
-  function lock_data()
+  static function lock_data($is_exclusive)
   {
-    GLOBAL $sess; 
-    
-    if (($tok = @ftok(FTOK_PATH."/poll", "B")) == -1) {
-      return (FALSE);
-    }
-    // echo "FTOK ".$tok."<br>";
-    if (($res = sem_get($tok)) == FALSE) {
-      return (FALSE);
-    }
-    if (sem_acquire($res)) {
-        self::$delta_t = microtime(TRUE);
-        log_lock("LOCK   poll         [".self::$delta_t."]");
-      
-        return ($res);
-    }
-    else
+      if (($res = file_lock(FTOK_PATH."/poll", $is_exclusive)) != FALSE) {
+          self::$delta_t = microtime(TRUE);
+          log_lock("LOCK   poll         [".self::$delta_t."]");
+          
+          return ($res);
+      }
+
       return (FALSE);
   }
   
-  function unlock_data($res)
+  static function unlock_data($res)
   {
     GLOBAL $sess; 
     
     log_lock("UNLOCK poll         [".(microtime(TRUE) - (self::$delta_t))."]");
     
-    return (sem_release($res));
+    file_unlock($res);
   }
 }