From 0cfa3abe61461e4c4fa3d025873a79a0b41f3564 Mon Sep 17 00:00:00 2001
From: kanoi <gitkanoi@k1k2.com>
Date: Thu, 11 Sep 2014 08:31:55 +1000
Subject: [PATCH 1/6] sql - comments and updates for bs.sql

---
 sql/bs.sql | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/sql/bs.sql b/sql/bs.sql
index 4d526cc0..c39b6abe 100644
--- a/sql/bs.sql
+++ b/sql/bs.sql
@@ -1,3 +1,12 @@
+-- SQL to calculate a block's diffacc (difficulty accepted)
+-- This should match the block's confirmed diffacc
+--  i.e. when a block has statsconfirmed='Y'
+-- If the block has any unaged sharesummaries,
+--  the script will abort and report the count
+-- Sharesummaries are aged at ~10 minutes after the next workinfo,
+--  after the sharesummary's workinfo, was first generated
+-- You need to set the block number at line 21 - hi := blockheight;
+
 SET SESSION AUTHORIZATION 'postgres';
 
 DO $$
@@ -12,23 +21,30 @@ BEGIN
  hi := 318177;
 
  -- This will randomly choose between multiple blocks of the same height
- --  if we happen to orphan ourselves
+ --  if we happen to orphan ourselves on block 'hi'
  select workinfoid from blocks where height = hi
-	and expirydate > '6666-06-01' into wi;
+	and expirydate > '6666-06-01' limit 1 into wi;
  IF NOT found THEN
   RAISE EXCEPTION 'Block % not found', hi;
  END IF;
 
  select max(height) from blocks where height < hi into hi0;
- IF NOT found THEN
+ IF hi0 is NULL THEN
   wi0 := -1;
  ELSE
+  -- This will randomly choose between multiple blocks of the same height
+  --  if we happen to orphan ourselves on block 'hi0'
   select workinfoid from blocks where height = hi0
-	and expirydate > '6666-06-01' into Wi0;
+	and expirydate > '6666-06-01' limit 1 into wi0;
  END IF;
 
- RAISE WARNING 'Block: %(%)', hi, wi;
- RAISE WARNING 'Previous block: %(%)', hi0, wi0;
+ RAISE NOTICE 'Block: %(%)', hi, wi;
+
+ IF hi0 is NULL THEN
+  RAISE NOTICE 'No previous block';
+ ELSE
+  RAISE NOTICE 'Previous block: %(%)', hi0, wi0;
+ END IF;
 
  select count(*) from sharesummary where workinfoid > wi0
 	and workinfoid <= wi and complete = 'n' into ssc;
@@ -39,6 +55,6 @@ BEGIN
   select sum(diffacc) from sharesummary where workinfoid > wi0
 	and workinfoid <= wi into da;
 
-  RAISE WARNING 'diffacc: %', to_char(da::bigint, 'FM999,999,999,999,999,990');
+  RAISE NOTICE 'diffacc: %', to_char(da::bigint, 'FM999,999,999,999,999,990');
  END IF;
 END $$;

From ac509aa98dfac1b3dcb202e13b2193eac99195d0 Mon Sep 17 00:00:00 2001
From: kanoi <gitkanoi@k1k2.com>
Date: Thu, 11 Sep 2014 11:04:58 +1000
Subject: [PATCH 2/6] ckdb/sql - db v0.9.1 changes

---
 sql/ckdb.sql        | 19 +++++++++++++
 sql/tables.sql      |  1 +
 sql/v0.9-v0.9.1.sql | 42 ++++++++++++++++++++++++++++
 src/ckdb.c          | 68 +++++++++++++++++++++++++++------------------
 4 files changed, 103 insertions(+), 27 deletions(-)
 create mode 100644 sql/v0.9-v0.9.1.sql

diff --git a/sql/ckdb.sql b/sql/ckdb.sql
index 9d509506..8c933670 100644
--- a/sql/ckdb.sql
+++ b/sql/ckdb.sql
@@ -19,6 +19,7 @@ CREATE TABLE users (
     joineddate timestamp with time zone NOT NULL,
     passwordhash character varying(256) NOT NULL,
     secondaryuserid character varying(64) NOT NULL,
+    salt character varying(256) DEFAULT ''::character varying NOT NULL,
     createdate timestamp with time zone NOT NULL,
     createby character varying(64) DEFAULT ''::character varying NOT NULL,
     createcode character varying(128) DEFAULT ''::character varying NOT NULL,
@@ -29,6 +30,24 @@ CREATE TABLE users (
 CREATE UNIQUE INDEX usersusername ON users USING btree (username, expirydate);
 
 
+CREATE TABLE useratts (
+    userid bigint NOT NULL,
+    attname character varying(64) NOT NULL,
+    attstr character varying(256) DEFAULT ''::character varying NOT NULL,
+    attstr2 character varying(256) DEFAULT ''::character varying NOT NULL,
+    attnum bigint DEFAULT 0 NOT NULL,
+    attnum2 bigint DEFAULT 0 NOT NULL,
+    attdate timestamp with time zone DEFAULT '1970-01-01 00:00:00+00',
+    attdate2 timestamp with time zone DEFAULT '1970-01-01 00:00:00+00',
+    createdate timestamp with time zone NOT NULL,
+    createby character varying(64) DEFAULT ''::character varying NOT NULL,
+    createcode character varying(128) DEFAULT ''::character varying NOT NULL,
+    createinet character varying(128) DEFAULT ''::character varying NOT NULL,
+    expirydate timestamp with time zone DEFAULT '6666-06-06 06:06:06+00',
+    PRIMARY KEY (userid, attname, expirydate)
+);
+
+
 CREATE TABLE workers (
     workerid bigint NOT NULL, -- unique per record
     userid bigint NOT NULL,
diff --git a/sql/tables.sql b/sql/tables.sql
index b3e1f529..e9c63491 100644
--- a/sql/tables.sql
+++ b/sql/tables.sql
@@ -15,6 +15,7 @@ select 'shareerrors' as "shareerrors",count(*) from shareerrors;
 select 'shares' as "shares",count(*) from shares;
 select 'sharesummary' as "sharesummary",count(*) from sharesummary;
 select 'users' as "users",count(*) from users;
+select 'useratts' as "useratts",count(*) from useratts;
 select 'userstats' as "userstats",count(*) from userstats;
 select 'version' as "version",count(*) from version;
 select 'workers' as "workers",count(*) from workers;
diff --git a/sql/v0.9-v0.9.1.sql b/sql/v0.9-v0.9.1.sql
new file mode 100644
index 00000000..6c9352e9
--- /dev/null
+++ b/sql/v0.9-v0.9.1.sql
@@ -0,0 +1,42 @@
+SET SESSION AUTHORIZATION 'postgres';
+
+BEGIN transaction;
+
+DO $$
+DECLARE ver TEXT;
+BEGIN
+
+ UPDATE version set version='0.9.1' where vlock=1 and version='0.9';
+
+ IF found THEN
+  RETURN;
+ END IF;
+
+ SELECT version into ver from version
+  WHERE vlock=1;
+
+ RAISE EXCEPTION 'Wrong DB version - expect "0.9" - found "%"', ver;
+
+END $$;
+
+CREATE TABLE useratts (
+    userid bigint NOT NULL,
+    attname character varying(64) NOT NULL,
+    attstr character varying(256) DEFAULT ''::character varying NOT NULL,
+    attstr2 character varying(256) DEFAULT ''::character varying NOT NULL,
+    attnum bigint DEFAULT 0 NOT NULL,
+    attnum2 bigint DEFAULT 0 NOT NULL,
+    attdate timestamp with time zone DEFAULT '1970-01-01 00:00:00+00',
+    attdate2 timestamp with time zone DEFAULT '1970-01-01 00:00:00+00',
+    createdate timestamp with time zone NOT NULL,
+    createby character varying(64) DEFAULT ''::character varying NOT NULL,
+    createcode character varying(128) DEFAULT ''::character varying NOT NULL,
+    createinet character varying(128) DEFAULT ''::character varying NOT NULL,
+    expirydate timestamp with time zone DEFAULT '6666-06-06 06:06:06+00',
+    PRIMARY KEY (userid, attname, expirydate)
+);
+
+ALTER TABLE ONLY users
+  ADD COLUMN salt character varying(256) DEFAULT ''::character varying NOT NULL;
+
+END transaction;
diff --git a/src/ckdb.c b/src/ckdb.c
index 26e16ac2..cf1e57ed 100644
--- a/src/ckdb.c
+++ b/src/ckdb.c
@@ -46,8 +46,8 @@
  */
 
 #define DB_VLOCK "1"
-#define DB_VERSION "0.9"
-#define CKDB_VERSION DB_VERSION"-0.276"
+#define DB_VERSION "0.9.1"
+#define CKDB_VERSION DB_VERSION"-0.280"
 
 #define WHERE_FFL " - from %s %s() line %d"
 #define WHERE_FFL_HERE __FILE__, __func__, __LINE__
@@ -838,8 +838,6 @@ typedef struct logqueue {
 
 static K_LIST *logqueue_free;
 static K_STORE *logqueue_store;
-static pthread_mutex_t wq_waitlock;
-static pthread_cond_t wq_waitcond;
 
 // WORKQUEUE
 typedef struct workqueue {
@@ -865,6 +863,8 @@ typedef struct workqueue {
 
 static K_LIST *workqueue_free;
 static K_STORE *workqueue_store;
+static pthread_mutex_t wq_waitlock;
+static pthread_cond_t wq_waitcond;
 
 // TRANSFER
 #define NAME_SIZE 63
@@ -954,6 +954,7 @@ typedef struct users {
 	tv_t joineddate;
 	char passwordhash[TXT_BIG+1];
 	char secondaryuserid[TXT_SML+1];
+	char salt[TXT_BIG+1];
 	HISTORYDATECONTROLFIELDS;
 } USERS;
 
@@ -968,23 +969,28 @@ static K_TREE *userid_root;
 static K_LIST *users_free;
 static K_STORE *users_store;
 
-/* TODO: for account settings - but do we want manual/auto payouts?
-// USERACCOUNTS
-typedef struct useraccounts {
+/* TODO:
+// USERATTS
+typedef struct useratts {
 	int64_t userid;
-	int64_t payoutlimit;
-	char autopayout[TXT_FLG+1];
+	char attstr[TXT_BIG+1];
+	char attstr2[TXT_BIG+1];
+	int64_t attnum;
+	int64_t attnum2;
+	tv_t attdate;
+	tv_t attdate2;
 	HISTORYDATECONTROLFIELDS;
-} USERACCOUNTS;
+} USERATTS;
 
-#define ALLOC_USERACCOUNTS 1024
-#define LIMIT_USERACCOUNTS 0
-#define INIT_USERACCOUNTS(_item) INIT_GENERIC(_item, useraccounts)
-#define DATA_USERACCOUNTS(_var, _item) DATA_GENERIC(_var, _item, useraccounts, true)
+#define ALLOC_USERATTS 1024
+#define LIMIT_USERATTS 0
+#define INIT_USERATTS(_item) INIT_GENERIC(_item, useratts)
+#define DATA_USERATTS(_var, _item) DATA_GENERIC(_var, _item, useratts, true)
+#define DATA_USERATTS_NULL(_var, _item) DATA_GENERIC(_var, _item, useratts, true)
 
-static K_TREE *useraccounts_root;
-static K_LIST *useraccounts_free;
-static K_STORE *useraccounts_store;
+static K_TREE *useratts_root;
+static K_LIST *useratts_free;
+static K_STORE *useratts_store;
 */
 
 // WORKERS
@@ -2202,8 +2208,8 @@ static PGconn *dbconnect()
 
 	snprintf(conninfo, sizeof(conninfo),
 		 "host=127.0.0.1 dbname=%s user=%s%s%s",
-		 db_name,
-		 db_user, db_pass ? " password=" : "",
+		 db_name, db_user,
+		 db_pass ? " password=" : "",
 		 db_pass ? db_pass : "");
 
 	conn = PQconnectdb(conninfo);
@@ -2730,9 +2736,9 @@ static bool users_pass_email(PGconn *conn, K_ITEM *u_item, char *oldhash,
 
 	ins = "insert into users "
 		"(userid,username,emailaddress,joineddate,passwordhash,"
-		"secondaryuserid"
+		"secondaryuserid,salt"
 		HISTORYDATECONTROL ") select "
-		"userid,username,$3,joineddate,$4,secondaryuserid,"
+		"userid,username,$3,joineddate,$4,secondaryuserid,salt,"
 		"$5,$6,$7,$8,$9 from users where "
 		"userid=$1 and expirydate=$2";
 
@@ -2788,7 +2794,7 @@ static K_ITEM *users_add(PGconn *conn, char *username, char *emailaddress,
 	uint64_t hash;
 	__maybe_unused uint64_t tmp;
 	bool ok = false;
-	char *params[6 + HISTORYDATECOUNT];
+	char *params[7 + HISTORYDATECOUNT];
 	int par;
 
 	LOGDEBUG("%s(): add", __func__);
@@ -2814,6 +2820,8 @@ static K_ITEM *users_add(PGconn *conn, char *username, char *emailaddress,
 	HASH_BER(tohash, strlen(tohash), 1, hash, tmp);
 	__bin2hex(row->secondaryuserid, (void *)(&hash), sizeof(hash));
 
+	row->salt[0] = '\0';
+
 	HISTORYDATEINIT(row, cd, by, code, inet);
 	HISTORYDATETRANSFER(trf_root, row);
 
@@ -2828,13 +2836,14 @@ static K_ITEM *users_add(PGconn *conn, char *username, char *emailaddress,
 	params[par++] = tv_to_buf(&(row->joineddate), NULL, 0);
 	params[par++] = str_to_buf(row->passwordhash, NULL, 0);
 	params[par++] = str_to_buf(row->secondaryuserid, NULL, 0);
+	params[par++] = str_to_buf(row->salt, NULL, 0);
 	HISTORYDATEPARAMS(params, par, row);
 	PARCHK(par, params);
 
 	ins = "insert into users "
 		"(userid,username,emailaddress,joineddate,passwordhash,"
-		"secondaryuserid"
-		HISTORYDATECONTROL ") values (" PQPARAM11 ")";
+		"secondaryuserid,salt"
+		HISTORYDATECONTROL ") values (" PQPARAM12 ")";
 
 	if (!conn) {
 		conn = dbconnect();
@@ -2881,14 +2890,14 @@ static bool users_fill(PGconn *conn)
 	USERS *row;
 	char *field;
 	char *sel;
-	int fields = 6;
+	int fields = 7;
 	bool ok;
 
 	LOGDEBUG("%s(): select", __func__);
 
 	sel = "select "
 		"userid,username,emailaddress,joineddate,passwordhash,"
-		"secondaryuserid"
+		"secondaryuserid,salt"
 		HISTORYDATECONTROL
 		" from users";
 	res = PQexec(conn, sel, CKPQ_READ);
@@ -2950,6 +2959,11 @@ static bool users_fill(PGconn *conn)
 			break;
 		TXT_TO_STR("secondaryuserid", field, row->secondaryuserid);
 
+		PQ_GET_FLD(res, i, "salt", field, ok);
+		if (!ok)
+			break;
+		TXT_TO_STR("salt", field, row->salt);
+
 		HISTORYDATEFLDS(res, i, row, ok);
 		if (!ok)
 			break;
@@ -3585,7 +3599,7 @@ unitem:
 	if (!ok)
 		k_add_head(paymentaddresses_free, item);
 	else {
-		// Remove old (unneeded) records
+		// Remove from ram, old (unneeded) records
 		pa.userid = userid;
 		pa.expirydate.tv_sec = 0L;
 		pa.payaddress[0] = '\0';

From 51a1d6ac6a6bbd6d56b6b6920c13f906c5799ffd Mon Sep 17 00:00:00 2001
From: kanoi <gitkanoi@k1k2.com>
Date: Thu, 11 Sep 2014 14:49:42 +1000
Subject: [PATCH 3/6] php - break up workers into functions, add an Admin menu,
 and add an Admin allworkers

---
 pool/page_allwork.php |  43 +++++++++++++++
 pool/page_workers.php | 121 +++++++++++++++++++++++-------------------
 pool/prime.php        |  11 ++--
 3 files changed, 118 insertions(+), 57 deletions(-)
 create mode 100644 pool/page_allwork.php

diff --git a/pool/page_allwork.php b/pool/page_allwork.php
new file mode 100644
index 00000000..ac1d9471
--- /dev/null
+++ b/pool/page_allwork.php
@@ -0,0 +1,43 @@
+<?php
+#
+include_once('page_workers.php');
+#
+function doallwork($data, $user)
+{
+ $pg = '<h1>All Workers</h1>';
+
+ $pg .= "<table callpadding=0 cellspacing=0 border=0>\n";
+
+ $totshare = 0;
+ $totdiff = 0;
+ $totinvalid = 0;
+ $totrate = 0;
+ $offset = 0;
+
+ $pg .= worktitle($data, $user);
+
+ $ans = getAllUsers();
+ if ($ans['STATUS'] == 'ok')
+ {
+	$count = $ans['rows'];
+	for ($i = 0; $i < $count; $i++)
+	{
+		$pg .= workuser($data, $ans['username:'.$i],
+				$offset, $totshare, $totdiff,
+				$totinvalid, $totrate, 3600);
+	}
+ }
+
+ $pg .= worktotal($offset, $totshare, $totdiff, $totinvalid, $totrate);
+
+ $pg .= "</table>\n";
+
+ return $pg;
+}
+#
+function show_allwork($page, $menu, $name, $user)
+{
+ gopage(NULL, 'doallwork', $page, $menu, $name, $user);
+}
+#
+?>
diff --git a/pool/page_workers.php b/pool/page_workers.php
index 4eb8707b..625630e6 100644
--- a/pool/page_workers.php
+++ b/pool/page_workers.php
@@ -1,62 +1,47 @@
 <?php
 #
-function doworker($data, $user)
+function worktitle($data, $user)
+{
+ $pg  = '<tr class=title>';
+ $pg .= '<td class=dl>Worker Name</td>';
+ $pg .= '<td class=dr>Work Diff</td>';
+ $pg .= '<td class=dr>Last Share</td>';
+ $pg .= '<td class=dr>Shares</td>';
+ $pg .= '<td class=dr>Diff</td>';
+ $pg .= '<td class=dr>Invalid</td>';
+ $pg .= '<td class=dr>Hash Rate</td>';
+ $pg .= "</tr>\n";
+ return $pg;
+}
+#
+function workuser($data, $user, &$offset, &$totshare, &$totdiff,
+			&$totinvalid, &$totrate, $old = false)
 {
- $pg = '<h1>Workers</h1>';
-
  $ans = getWorkers($user);
 
- $pg .= "<table callpadding=0 cellspacing=0 border=0>\n";
- $pg .= "<tr class=title>";
- $pg .= "<td class=dl>Worker Name</td>";
-// $pg .= "<td class=dr>Difficulty</td>";
-// $pg .= "<td class=dc>Idle Notifications</td>";
-// $pg .= "<td class=dr>Idle Notification Time</td>";
- $pg .= "<td class=dr>Work Diff</td>";
- $pg .= "<td class=dr>Last Share</td>";
- $pg .= "<td class=dr>Shares</td>";
- $pg .= "<td class=dr>Diff</td>";
- $pg .= "<td class=dr>Invalid</td>";
- $pg .= "<td class=dr>Hash Rate</td>";
- $pg .= "</tr>\n";
- $tsh = 0;
- $tdif = 0;
- $tinv = 0;
- $thr = 0;
- $i = 0;
+ $pg = '';
  if ($ans['STATUS'] == 'ok')
  {
 	$count = $ans['rows'];
 	for ($i = 0; $i < $count; $i++)
 	{
-		if (($i % 2) == 0)
+		$lst = $ans['STAMP'] - $ans['w_lastshare:'.$i];
+		if ($old !== false && $lst > $old)
+			continue;
+
+		if ((($offset) % 2) == 0)
 			$row = 'even';
 		else
 			$row = 'odd';
 
 		$pg .= "<tr class=$row>";
 		$pg .= '<td class=dl>'.$ans['workername:'.$i].'</td>';
-/*
-		$pg .= '<td class=dr>'.$ans['difficultydefault:'.$i].'</td>';
-		$nots = $ans['idlenotificationenabled:'.$i];
-		switch ($nots)
-		{
-		case 'Y':
-		case 'y':
-			$nots = 'Y';
-			break;
-		default:
-			$nots = 'N';
-		}
-		$pg .= '<td class=dc>'.$nots.'</td>';
-		$pg .= '<td class=dr>'.$ans['idlenotificationtime:'.$i].'</td>';
-*/
 		if ($ans['w_lastdiff:'.$i] > 0)
 			$ld = difffmt($ans['w_lastdiff:'.$i]);
 		else
 			$ld = '&nbsp;';
 		$pg .= "<td class=dr>$ld</td>";
-		$lst = $ans['STAMP'] - $ans['w_lastshare:'.$i];
+
 		if ($lst < 60)
 			$lstdes = $lst.'s';
 		else
@@ -90,9 +75,9 @@ function doworker($data, $user)
 		$pg .= "<td class=dr>$lstdes</td>";
 
 		$shareacc = number_format($ans['w_shareacc:'.$i], 0);
-		$tsh += $ans['w_shareacc:'.$i];
+		$totshare += $ans['w_shareacc:'.$i];
 		$diffacc = number_format($ans['w_diffacc:'.$i], 0);
-		$tdif += $ans['w_diffacc:'.$i];
+		$totdiff += $ans['w_diffacc:'.$i];
 		$pg .= "<td class=dr>$shareacc</td>";
 		$pg .= "<td class=dr>$diffacc</td>";
 
@@ -101,7 +86,7 @@ function doworker($data, $user)
 			$rej = number_format(100.0 * $ans['w_diffinv:'.$i] / $dtot, 3);
 		else
 			$rej = '0';
-		$tinv +=  $ans['w_diffinv:'.$i];
+		$totinvalid +=  $ans['w_diffinv:'.$i];
 
 		$pg .= "<td class=dr>$rej%</td>";
 
@@ -113,7 +98,7 @@ function doworker($data, $user)
 			$uhr = '?GHs';
 		else
 		{
-			$thr += $uhr;
+			$totrate += $uhr;
 			$uhr /= 10000000;
 			if ($uhr < 0.01)
 				$uhr = '0GHs';
@@ -128,34 +113,62 @@ function doworker($data, $user)
 		$pg .= "<td class=dr>$uhr</td>";
 
 		$pg .= "</tr>\n";
+
+		$offset++;
 	}
  }
- $thr /= 10000000;
- if ($thr < 0.01)
-	$thr = '0GHs';
+ return $pg;
+}
+#
+function worktotal($offset, $totshare, $totdiff, $totinvalid, $totrate)
+{
+ $pg = '';
+ $totrate /= 10000000;
+ if ($totrate < 0.01)
+	$totrate = '0GHs';
  else
  {
-	if ($thr < 100000)
-		$thr = number_format(round($thr)/100,2).'GHs';
+	if ($totrate < 100000)
+		$totrate = number_format(round($totrate)/100,2).'GHs';
 	else
-		$thr = number_format(round($thr/1000)/100,2).'THs';
+		$totrate = number_format(round($totrate/1000)/100,2).'THs';
  }
- if (($i % 2) == 0)
+ if (($offset % 2) == 0)
 	$row = 'even';
  else
 	$row = 'odd';
  $pg .= "<tr class=$row><td class=dl>Total:</td><td colspan=2 class=dl></td>";
- $shareacc = number_format($tsh, 0);
+ $shareacc = number_format($totshare, 0);
  $pg .= "<td class=dr>$shareacc</td>";
- $diffacc = number_format($tdif, 0);
+ $diffacc = number_format($totdiff, 0);
  $pg .= "<td class=dr>$diffacc</td>";
- $dtot = $tdif + $tinv;
+ $dtot = $totdiff + $totinvalid;
  if ($dtot > 0)
-	$rej = number_format(100.0 * $tinv / $dtot, 3);
+	$rej = number_format(100.0 * $totinvalid / $dtot, 3);
  else
 	$rej = '0';
  $pg .= "<td class=dr>$rej%</td>";
- $pg .= "<td class=dr>$thr</td></tr>\n";
+ $pg .= "<td class=dr>$totrate</td></tr>\n";
+ return $pg;
+}
+#
+function doworker($data, $user)
+{
+ $pg = '<h1>Workers</h1>';
+
+ $pg .= "<table callpadding=0 cellspacing=0 border=0>\n";
+
+ $totshare = 0;
+ $totdiff = 0;
+ $totinvalid = 0;
+ $totrate = 0;
+ $offset = 0;
+
+ $pg .= worktitle($data, $user);
+ $pg .= workuser($data, $user, $offset, $totshare, $totdiff, $totinvalid,
+			$totrate, false);
+ $pg .= worktotal($offset, $totshare, $totdiff, $totinvalid, $totrate);
+
  $pg .= "</table>\n";
 
  return $pg;
diff --git a/pool/prime.php b/pool/prime.php
index 3b1dd670..ab73a08e 100644
--- a/pool/prime.php
+++ b/pool/prime.php
@@ -18,16 +18,21 @@ function process($p, $user)
 		'Stats' => 'stats',
 		'Blocks' => 'blocks'
 	),
+	'Admin' => NULL,
 	'gap' => NULL,
 	'Help' => array(
 		'Help' => 'help',
 		'Payouts' => 'payout'
 	)
  );
- if ($user == 'Kano' || $user == 'ckolivas' || $user == 'aphorise')
-	$menu['Help']['ckp'] = 'ckp';
  if ($user == 'Kano' || $user == 'ckolivas' || $user == 'wvr2' || $user == 'aphorise')
-	$menu['Pool']['PPLNS'] = 'pplns';
+ {
+	$menu['Admin']['ckp'] = 'ckp';
+	$menu['Admin']['PPLNS'] = 'pplns';
+	$menu['Admin']['AllWork'] = 'allwork';
+ }
+ else
+	unset($menu['Admin']);
  $page = '';
  $n = '';
  foreach ($menu as $item => $options)

From ce31d71a82d33a78f56261e18339da016e84adbb Mon Sep 17 00:00:00 2001
From: kanoi <gitkanoi@k1k2.com>
Date: Thu, 11 Sep 2014 15:49:11 +1000
Subject: [PATCH 4/6] php - add a php runtime stat

---
 pool/page.php  | 15 +++++++++++----
 pool/prime.php |  3 +++
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/pool/page.php b/pool/page.php
index 54eafadd..d042864a 100644
--- a/pool/page.php
+++ b/pool/page.php
@@ -133,6 +133,7 @@ h1 {margin-top: 20px; float:middle; font-size: 20px;}
 .st1 {color:red; font-weight:bold; }
 .st2 {color:green; font-weight:bold; }
 .st3 {color:blue; font-weight:bold; }
+.ft {color:blue; font-size:7px; }
 </style>\n";
 
  $head .= '<meta name="robots" content="noindex">';
@@ -431,7 +432,7 @@ function pgfoot()
  $now = date('Y');
  if ($now != '2014')
 	$foot .= "-$now";
- $foot .= '</div>';
+ $foot .= ' <span class=ft>Z/s</span></div>';
  $foot .= "</body></html>\n";
 
  return $foot;
@@ -439,7 +440,7 @@ function pgfoot()
 #
 function gopage($data, $pagefun, $page, $menu, $name, $user, $ispage = true, $dotop = true, $douser = true)
 {
- global $dbg;
+ global $dbg, $stt;
  global $page_scripts;
 
  $dbg_marker = '[@dbg@]';
@@ -473,11 +474,17 @@ function gopage($data, $pagefun, $page, $menu, $name, $user, $ispage = true, $do
  $all = $head;
  $all .= trm_force($body);
  $all .= trm($pg);
- $all .= trm_force($foot);
+
+ if (isset($_SERVER["REQUEST_TIME_FLOAT"]))
+	$elapsed = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
+ else
+	$elapsed = microtime(true) - $stt;
+
+ $foot = trm_force(str_replace('Z/', number_format($elapsed, 4), $foot));
 
  usleep(100000);
 
- echo $all;
+ echo $all.$foot;
 
  exit(0);
 }
diff --git a/pool/prime.php b/pool/prime.php
index ab73a08e..55fba0b0 100644
--- a/pool/prime.php
+++ b/pool/prime.php
@@ -1,5 +1,8 @@
 <?php
 #
+global $stt;
+$stt = microtime();
+#
 include_once('param.php');
 include_once('base.php');
 #

From 45776131f9b36ac003bc5cf4d89cf9eea0c0fd6d Mon Sep 17 00:00:00 2001
From: kanoi <gitkanoi@k1k2.com>
Date: Thu, 11 Sep 2014 15:58:34 +1000
Subject: [PATCH 5/6] php - pass user to getAllUsers()

---
 pool/db.php           | 2 +-
 pool/page_allwork.php | 2 +-
 pool/page_stats.php   | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/pool/db.php b/pool/db.php
index 14688111..af562cea 100644
--- a/pool/db.php
+++ b/pool/db.php
@@ -166,7 +166,7 @@ function userSettings($user, $email = null, $addr = null, $pass = null)
  return repDecode($rep);
 }
 #
-function getAllUsers()
+function getAllUsers($user)
 {
  $flds = array();
  $msg = msgEncode('allusers', 'all', $flds);
diff --git a/pool/page_allwork.php b/pool/page_allwork.php
index ac1d9471..15e35a3e 100644
--- a/pool/page_allwork.php
+++ b/pool/page_allwork.php
@@ -16,7 +16,7 @@ function doallwork($data, $user)
 
  $pg .= worktitle($data, $user);
 
- $ans = getAllUsers();
+ $ans = getAllUsers($user);
  if ($ans['STATUS'] == 'ok')
  {
 	$count = $ans['rows'];
diff --git a/pool/page_stats.php b/pool/page_stats.php
index 7a6190db..7b27d35c 100644
--- a/pool/page_stats.php
+++ b/pool/page_stats.php
@@ -12,7 +12,7 @@ function dostats($data, $user)
 {
  $pg = '<h1>Pool Stats</h1>';
 
- $ans = getAllUsers();
+ $ans = getAllUsers($user);
 
  $pg .= "<table callpadding=0 cellspacing=0 border=0>\n";
  $pg .= "<tr class=title>";

From 3e041c8baed4cc8967c5b284901c3b5d01b8529e Mon Sep 17 00:00:00 2001
From: kanoi <gitkanoi@k1k2.com>
Date: Thu, 11 Sep 2014 16:43:02 +1000
Subject: [PATCH 6/6] php - add web information to ckdb requests

---
 pool/db.php         | 40 ++++++++++++++++------------------------
 pool/page_ckp.php   |  2 +-
 pool/page_pplns.php |  3 ++-
 3 files changed, 19 insertions(+), 26 deletions(-)

diff --git a/pool/db.php b/pool/db.php
index af562cea..ab67c284 100644
--- a/pool/db.php
+++ b/pool/db.php
@@ -65,34 +65,26 @@ function repDecode($rep)
  return $ans;
 }
 #
-function msgEncode($cmd, $id, $fields)
+function msgEncode($cmd, $id, $fields, $user)
 {
  global $send_sep, $fld_sep, $val_sep;
 
  $t = time() % 10000;
- $msg = $cmd . $send_sep . $id.$t;
- $first = true;
+ $msg = $cmd . $send_sep . $id.$t . $send_sep;
  foreach ($fields as $name => $value)
- {
-	if ($first === true)
-	{
-		$msg .= $send_sep;
-		$first = false;
-	}
-	else
-		$msg .= $fld_sep;
-
-	$msg .= $name . $val_sep . $value;
- }
+	$msg .= $name . $val_sep . $value . $fld_sep;
+ $msg .= 'createcode' . $val_sep . 'php' . $fld_sep;
+ $msg .= 'createby' . $val_sep . $user . $fld_sep;
+ $msg .= 'createinet' . $val_sep . $_SERVER['REMOTE_ADDR'];
  return $msg;
 }
 #
 function getStats($user)
 {
  if ($user === null)
-	$msg = msgEncode('homepage', 'home', array());
+	$msg = msgEncode('homepage', 'home', array(), $user);
  else
-	$msg = msgEncode('homepage', 'home', array('username'=>$user));
+	$msg = msgEncode('homepage', 'home', array('username'=>$user), $user);
  return $msg;
 }
 #
@@ -120,7 +112,7 @@ function checkPass($user, $pass)
 {
  $passhash = myhash($pass);
  $flds = array('username' => $user, 'passwordhash' => $passhash);
- $msg = msgEncode('chkpass', 'log', $flds);
+ $msg = msgEncode('chkpass', 'log', $flds, $user);
  $rep = sendsockreply('checkPass', $msg);
  if (!$rep)
 	dbdown();
@@ -132,7 +124,7 @@ function setPass($user, $oldpass, $newpass)
  $oldhash = myhash($oldpass);
  $newhash = myhash($newpass);
  $flds = array('username' => $user, 'oldhash' => $oldhash, 'newhash' => $newhash);
- $msg = msgEncode('newpass', 'log', $flds);
+ $msg = msgEncode('newpass', 'log', $flds, $user);
  $rep = sendsockreply('setPass', $msg);
  if (!$rep)
 	dbdown();
@@ -143,7 +135,7 @@ function userReg($user, $email, $pass)
 {
  $passhash = myhash($pass);
  $flds = array('username' => $user, 'emailaddress' => $email, 'passwordhash' => $passhash);
- $msg = msgEncode('adduser', 'reg', $flds);
+ $msg = msgEncode('adduser', 'reg', $flds, $user);
  $rep = sendsockreply('userReg', $msg);
  if (!$rep)
 	dbdown();
@@ -159,7 +151,7 @@ function userSettings($user, $email = null, $addr = null, $pass = null)
 	$flds['address'] = $addr;
  if ($pass != null)
 	$flds['passwordhash'] = myhash($pass);
- $msg = msgEncode('usersettings', 'userset', $flds);
+ $msg = msgEncode('usersettings', 'userset', $flds, $user);
  $rep = sendsockreply('userSettings', $msg);
  if (!$rep)
 	dbdown();
@@ -169,7 +161,7 @@ function userSettings($user, $email = null, $addr = null, $pass = null)
 function getAllUsers($user)
 {
  $flds = array();
- $msg = msgEncode('allusers', 'all', $flds);
+ $msg = msgEncode('allusers', 'all', $flds, $user);
  $rep = sendsockreply('getAllUsers', $msg);
  if (!$rep)
 	dbdown();
@@ -181,7 +173,7 @@ function getWorkers($user)
  if ($user == false)
 	showIndex();
  $flds = array('username' => $user, 'stats' => 'Y');
- $msg = msgEncode('workers', 'work', $flds);
+ $msg = msgEncode('workers', 'work', $flds, $user);
  $rep = sendsockreply('getWorkers', $msg);
  if (!$rep)
 	dbdown();
@@ -193,7 +185,7 @@ function getPayments($user)
  if ($user == false)
 	showIndex();
  $flds = array('username' => $user);
- $msg = msgEncode('payments', 'pay', $flds);
+ $msg = msgEncode('payments', 'pay', $flds, $user);
  $rep = sendsockreply('getPayments', $msg);
  if (!$rep)
 	dbdown();
@@ -205,7 +197,7 @@ function getBlocks($user)
  if ($user == false)
 	showIndex();
  $flds = array();
- $msg = msgEncode('blocklist', 'blk', $flds);
+ $msg = msgEncode('blocklist', 'blk', $flds, $user);
  $rep = sendsockreply('getBlocks', $msg);
  if (!$rep)
 	dbdown();
diff --git a/pool/page_ckp.php b/pool/page_ckp.php
index adc356a2..a082684f 100644
--- a/pool/page_ckp.php
+++ b/pool/page_ckp.php
@@ -18,7 +18,7 @@ function dockp($data, $user)
 {
  $pg = '<h1>CKPool</h1>';
 
- $msg = msgEncode('stats', 'stats', array());
+ $msg = msgEncode('stats', 'stats', array(), $user);
  $rep = sendsockreply('stats', $msg);
  if ($rep == false)
 	$ans = array();
diff --git a/pool/page_pplns.php b/pool/page_pplns.php
index 610f00c4..1470d59f 100644
--- a/pool/page_pplns.php
+++ b/pool/page_pplns.php
@@ -30,7 +30,8 @@ Block: <input type=text name=blk size=10 value=''>
  }
  else
  {
-	$msg = msgEncode('pplns', 'pplns', array('height' => $blk, 'allow_aged' => 'Y'));
+	$flds = array('height' => $blk, 'allow_aged' => 'Y');
+	$msg = msgEncode('pplns', 'pplns', $flds, $user);
 	$rep = sendsockreply('pplns', $msg);
 	if ($rep == false)
 		$ans = array();