|  |  | @ -47,7 +47,7 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | #define DB_VLOCK "1" |  |  |  | #define DB_VLOCK "1" | 
			
		
	
		
		
			
				
					
					|  |  |  | #define DB_VERSION "0.8" |  |  |  | #define DB_VERSION "0.8" | 
			
		
	
		
		
			
				
					
					|  |  |  | #define CKDB_VERSION DB_VERSION"-0.211" |  |  |  | #define CKDB_VERSION DB_VERSION"-0.213" | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | #define WHERE_FFL " - from %s %s() line %d" |  |  |  | #define WHERE_FFL " - from %s %s() line %d" | 
			
		
	
		
		
			
				
					
					|  |  |  | #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ |  |  |  | #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ | 
			
		
	
	
		
		
			
				
					|  |  | @ -783,6 +783,7 @@ enum cmd_values { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	CMD_ADDUSER, |  |  |  | 	CMD_ADDUSER, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	CMD_NEWPASS, |  |  |  | 	CMD_NEWPASS, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	CMD_CHKPASS, |  |  |  | 	CMD_CHKPASS, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	CMD_USERSET, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	CMD_POOLSTAT, |  |  |  | 	CMD_POOLSTAT, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	CMD_USERSTAT, |  |  |  | 	CMD_USERSTAT, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	CMD_BLOCK, |  |  |  | 	CMD_BLOCK, | 
			
		
	
	
		
		
			
				
					|  |  | @ -1009,7 +1010,6 @@ static K_STORE *workers_store; | 
			
		
	
		
		
			
				
					
					|  |  |  | #define IDLENOTIFICATIONTIME_DEF IDLENOTIFICATIONTIME_MIN |  |  |  | #define IDLENOTIFICATIONTIME_DEF IDLENOTIFICATIONTIME_MIN | 
			
		
	
		
		
			
				
					
					|  |  |  | #define IDLENOTIFICATIONTIME_DEF_STR STRINT(IDLENOTIFICATIONTIME_DEF) |  |  |  | #define IDLENOTIFICATIONTIME_DEF_STR STRINT(IDLENOTIFICATIONTIME_DEF) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | /* unused yet
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | // PAYMENTADDRESSES
 |  |  |  | // PAYMENTADDRESSES
 | 
			
		
	
		
		
			
				
					
					|  |  |  | typedef struct paymentaddresses { |  |  |  | typedef struct paymentaddresses { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int64_t paymentaddressid; |  |  |  | 	int64_t paymentaddressid; | 
			
		
	
	
		
		
			
				
					|  |  | @ -1027,7 +1027,6 @@ typedef struct paymentaddresses { | 
			
		
	
		
		
			
				
					
					|  |  |  | static K_TREE *paymentaddresses_root; |  |  |  | static K_TREE *paymentaddresses_root; | 
			
		
	
		
		
			
				
					
					|  |  |  | static K_LIST *paymentaddresses_free; |  |  |  | static K_LIST *paymentaddresses_free; | 
			
		
	
		
		
			
				
					
					|  |  |  | static K_STORE *paymentaddresses_store; |  |  |  | static K_STORE *paymentaddresses_store; | 
			
		
	
		
		
			
				
					
					|  |  |  | */ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | // PAYMENTS
 |  |  |  | // PAYMENTS
 | 
			
		
	
		
		
			
				
					
					|  |  |  | typedef struct payments { |  |  |  | typedef struct payments { | 
			
		
	
	
		
		
			
				
					|  |  | @ -2491,9 +2490,9 @@ static K_ITEM *find_userid(int64_t userid) | 
			
		
	
		
		
			
				
					
					|  |  |  | 	return find_in_ktree(userid_root, &look, cmp_userid, ctx); |  |  |  | 	return find_in_ktree(userid_root, &look, cmp_userid, ctx); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static bool users_pass(PGconn *conn, K_ITEM *u_item, char *oldhash, |  |  |  | static bool users_pass_email(PGconn *conn, K_ITEM *u_item, char *oldhash, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			char *newhash, char *by, char *code, char *inet, |  |  |  | 			     char *newhash, char *email, char *by, char *code, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			tv_t *cd, K_TREE *trf_root) |  |  |  | 			     char *inet, tv_t *cd, K_TREE *trf_root) | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	ExecStatusType rescode; |  |  |  | 	ExecStatusType rescode; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	bool conned = false; |  |  |  | 	bool conned = false; | 
			
		
	
	
		
		
			
				
					|  |  | @ -2505,12 +2504,18 @@ static bool users_pass(PGconn *conn, K_ITEM *u_item, char *oldhash, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	char *upd, *ins; |  |  |  | 	char *upd, *ins; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	bool ok = false; |  |  |  | 	bool ok = false; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	char *params[4 + HISTORYDATECOUNT]; |  |  |  | 	char *params[4 + HISTORYDATECOUNT]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	bool hash; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int par; |  |  |  | 	int par; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	LOGDEBUG("%s(): change", __func__); |  |  |  | 	LOGDEBUG("%s(): change", __func__); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (oldhash != NULL) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		hash = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	else | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		hash = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	DATA_USERS(users, u_item); |  |  |  | 	DATA_USERS(users, u_item); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (strcasecmp(oldhash, users->passwordhash)) |  |  |  | 	if (hash && strcasecmp(oldhash, users->passwordhash)) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 		return false; |  |  |  | 		return false; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	K_WLOCK(users_free); |  |  |  | 	K_WLOCK(users_free); | 
			
		
	
	
		
		
			
				
					|  |  | @ -2519,17 +2524,20 @@ static bool users_pass(PGconn *conn, K_ITEM *u_item, char *oldhash, | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	DATA_USERS(row, item); |  |  |  | 	DATA_USERS(row, item); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	memcpy(row, users, sizeof(*row)); |  |  |  | 	memcpy(row, users, sizeof(*row)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	// Update one, leave the other
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (hash) | 
			
		
	
		
		
			
				
					
					|  |  |  | 		STRNCPY(row->passwordhash, newhash); |  |  |  | 		STRNCPY(row->passwordhash, newhash); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	else | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		STRNCPY(row->emailaddress, email); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	HISTORYDATEINIT(row, cd, by, code, inet); |  |  |  | 	HISTORYDATEINIT(row, cd, by, code, inet); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	HISTORYDATETRANSFER(trf_root, row); |  |  |  | 	HISTORYDATETRANSFER(trf_root, row); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	upd = "update users set expirydate=$1 where userid=$2 and passwordhash=$3 and expirydate=$4"; |  |  |  | 	upd = "update users set expirydate=$1 where userid=$2 and expirydate=$3"; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 	par = 0; |  |  |  | 	par = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	params[par++] = tv_to_buf(cd, NULL, 0); |  |  |  | 	params[par++] = tv_to_buf(cd, NULL, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	params[par++] = bigint_to_buf(row->userid, NULL, 0); |  |  |  | 	params[par++] = bigint_to_buf(row->userid, NULL, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	params[par++] = str_to_buf(oldhash, NULL, 0); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	params[par++] = tv_to_buf((tv_t *)&default_expiry, NULL, 0); |  |  |  | 	params[par++] = tv_to_buf((tv_t *)&default_expiry, NULL, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	PARCHKVAL(par, 4, params); |  |  |  | 	PARCHKVAL(par, 3, params); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (conn == NULL) { |  |  |  | 	if (conn == NULL) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		conn = dbconnect(); |  |  |  | 		conn = dbconnect(); | 
			
		
	
	
		
		
			
				
					|  |  | @ -2558,17 +2566,18 @@ static bool users_pass(PGconn *conn, K_ITEM *u_item, char *oldhash, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	par = 0; |  |  |  | 	par = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	params[par++] = bigint_to_buf(row->userid, NULL, 0); |  |  |  | 	params[par++] = bigint_to_buf(row->userid, NULL, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	params[par++] = tv_to_buf(cd, NULL, 0); |  |  |  | 	params[par++] = tv_to_buf(cd, NULL, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	// Copy them both in - one will be new and one will be old
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	params[par++] = str_to_buf(row->emailaddress, NULL, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	params[par++] = str_to_buf(row->passwordhash, NULL, 0); |  |  |  | 	params[par++] = str_to_buf(row->passwordhash, NULL, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	HISTORYDATEPARAMS(params, par, row); |  |  |  | 	HISTORYDATEPARAMS(params, par, row); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	PARCHKVAL(par, 3 + HISTORYDATECOUNT, params); // 8 as per ins
 |  |  |  | 	PARCHKVAL(par, 4 + HISTORYDATECOUNT, params); // 9 as per ins
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	ins = "insert into users " |  |  |  | 	ins = "insert into users " | 
			
		
	
		
		
			
				
					
					|  |  |  | 		"(userid,username,emailaddress,joineddate,passwordhash," |  |  |  | 		"(userid,username,emailaddress,joineddate,passwordhash," | 
			
		
	
		
		
			
				
					
					|  |  |  | 		"secondaryuserid" |  |  |  | 		"secondaryuserid" | 
			
		
	
		
		
			
				
					
					|  |  |  | 		HISTORYDATECONTROL ") select " |  |  |  | 		HISTORYDATECONTROL ") select " | 
			
		
	
		
		
			
				
					
					|  |  |  | 		"userid,username,emailaddress,joineddate,$3," |  |  |  | 		"userid,username,$3,joineddate,$4,secondaryuserid," | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		"secondaryuserid," |  |  |  | 		"$5,$6,$7,$8,$9 from users where " | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		"$4,$5,$6,$7,$8 from users where " |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 		"userid=$1 and expirydate=$2"; |  |  |  | 		"userid=$1 and expirydate=$2"; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	res = PQexecParams(conn, ins, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE); |  |  |  | 	res = PQexecParams(conn, ins, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE); | 
			
		
	
	
		
		
			
				
					|  |  | @ -3260,6 +3269,264 @@ void workers_reload() | 
			
		
	
		
		
			
				
					
					|  |  |  | 	PQfinish(conn); |  |  |  | 	PQfinish(conn); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // order by userid asc,expirydate desc,payaddress asc
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | static cmp_t cmp_paymentaddresses(K_ITEM *a, K_ITEM *b) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	PAYMENTADDRESSES *pa, *pb; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	DATA_PAYMENTADDRESSES(pa, a); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	DATA_PAYMENTADDRESSES(pb, b); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	cmp_t c = CMP_BIGINT(pa->userid, pb->userid); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (c == 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		c = CMP_TV(pb->expirydate, pa->expirydate); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		if (c == 0) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			c = CMP_STR(pa->payaddress, pb->payaddress); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	return c; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | static K_ITEM *find_paymentaddresses(int64_t userid) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	PAYMENTADDRESSES paymentaddresses, *pa; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	K_TREE_CTX ctx[1]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	K_ITEM look, *item; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	paymentaddresses.userid = userid; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	paymentaddresses.payaddress[0] = '\0'; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	paymentaddresses.expirydate.tv_sec = DATE_S_EOT; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	INIT_PAYMENTADDRESSES(&look); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	look.data = (void *)(&paymentaddresses); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	item = find_after_in_ktree(paymentaddresses_root, &look, cmp_paymentaddresses, ctx); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (item) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		DATA_PAYMENTADDRESSES(pa, item); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		if (pa->userid == userid && CURRENT(&(pa->expirydate))) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			return item; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		else | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			return NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} else | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		return NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Whatever the current paymentaddresses are, replace them with this one
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | static K_ITEM *paymentaddresses_set(PGconn *conn, int64_t userid, char *payaddress, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					char *by, char *code, char *inet, tv_t *cd, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					K_TREE *trf_root) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	ExecStatusType rescode; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	bool conned = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	PGresult *res; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	K_TREE_CTX ctx[1], ctx2[1]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	K_ITEM *item, *old, *this, look; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	PAYMENTADDRESSES *row, pa, *thispa; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	char *upd, *ins; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	bool ok = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	char *params[4 + HISTORYDATECOUNT]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	int par; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	int n; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	LOGDEBUG("%s(): add", __func__); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	K_WLOCK(paymentaddresses_free); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	item = k_unlink_head(paymentaddresses_free); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	K_WUNLOCK(paymentaddresses_free); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	DATA_PAYMENTADDRESSES(row, item); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	row->paymentaddressid = nextid(conn, "paymentaddressid", 1, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					cd, by, code, inet); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (row->paymentaddressid == 0) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		goto unitem; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	row->userid = userid; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	STRNCPY(row->payaddress, payaddress); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	row->payratio = 1000000; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	HISTORYDATEINIT(row, cd, by, code, inet); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	HISTORYDATETRANSFER(trf_root, row); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	upd = "update paymentaddresses set expirydate=$1 where userid=$2 and expirydate=$3"; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	par = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	params[par++] = tv_to_buf(cd, NULL, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	params[par++] = bigint_to_buf(row->userid, NULL, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	params[par++] = tv_to_buf((tv_t *)&default_expiry, NULL, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	PARCHKVAL(par, 3, params); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (conn == NULL) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		conn = dbconnect(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		conned = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	res = PQexec(conn, "Begin", CKPQ_WRITE); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	rescode = PQresultStatus(res); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (!PGOK(rescode)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		PGLOGERR("Begin", rescode, conn); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		goto unparam; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	PQclear(res); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	res = PQexecParams(conn, upd, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	rescode = PQresultStatus(res); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	PQclear(res); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (!PGOK(rescode)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		PGLOGERR("Update", rescode, conn); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		res = PQexec(conn, "Rollback", CKPQ_WRITE); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		goto unparam; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	for (n = 0; n < par; n++) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		free(params[n]); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	ins = "insert into paymentaddresses " | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		"(paymentaddressid,userid,payaddress,payratio" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		HISTORYDATECONTROL ") values (" PQPARAM9 ")"; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	par = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	params[par++] = bigint_to_buf(row->paymentaddressid, NULL, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	params[par++] = bigint_to_buf(row->userid, NULL, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	params[par++] = str_to_buf(row->payaddress, NULL, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	params[par++] = int_to_buf(row->payratio, NULL, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	HISTORYDATEPARAMS(params, par, row); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	PARCHK(par, params); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	res = PQexecParams(conn, ins, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	rescode = PQresultStatus(res); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (!PGOK(rescode)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		PGLOGERR("Insert", rescode, conn); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		goto unparam; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	res = PQexec(conn, "Commit", CKPQ_WRITE); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	ok = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | unparam: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	PQclear(res); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (conned) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		PQfinish(conn); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	for (n = 0; n < par; n++) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		free(params[n]); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | unitem: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	K_WLOCK(paymentaddresses_free); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (!ok) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		k_add_head(paymentaddresses_free, item); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		// Remove old (unneeded) records
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		pa.userid = userid; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		pa.expirydate.tv_sec = 0L; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		pa.payaddress[0] = '\0'; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		INIT_PAYMENTADDRESSES(&look); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		look.data = (void *)(&pa); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		old = find_after_in_ktree(paymentaddresses_root, &look, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					  cmp_paymentaddresses, ctx); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		while (old) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			this = old; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			DATA_PAYMENTADDRESSES(thispa, this); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			if (thispa->userid != userid) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			old = next_in_ktree(ctx); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			paymentaddresses_root = remove_from_ktree(paymentaddresses_root, this, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 								  cmp_paymentaddresses, ctx2); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			k_add_head(paymentaddresses_free, this); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		paymentaddresses_root = add_to_ktree(paymentaddresses_root, item, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 						     cmp_paymentaddresses); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		k_add_head(paymentaddresses_store, item); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	K_WUNLOCK(paymentaddresses_free); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (ok) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		return item; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	else | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		return NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | static bool paymentaddresses_fill(PGconn *conn) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	ExecStatusType rescode; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	PGresult *res; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	K_ITEM *item; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	int n, i; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	PAYMENTADDRESSES *row; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	char *params[1]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	int par; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	char *field; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	char *sel; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	int fields = 4; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	bool ok; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	LOGDEBUG("%s(): select", __func__); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	sel = "select " | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		"paymentaddressid,userid,payaddress,payratio" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		HISTORYDATECONTROL | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		" from paymentaddresses where expirydate=$1"; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	par = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	params[par++] = tv_to_buf((tv_t *)(&default_expiry), NULL, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	PARCHK(par, params); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	res = PQexecParams(conn, sel, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_READ); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	rescode = PQresultStatus(res); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (!PGOK(rescode)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		PGLOGERR("Select", rescode, conn); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		PQclear(res); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	n = PQnfields(res); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (n != (fields + HISTORYDATECOUNT)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		LOGERR("%s(): Invalid field count - should be %d, but is %d", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			__func__, fields + HISTORYDATECOUNT, n); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		PQclear(res); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	n = PQntuples(res); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	LOGDEBUG("%s(): tree build count %d", __func__, n); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	ok = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	K_WLOCK(paymentaddresses_free); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	for (i = 0; i < n; i++) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		item = k_unlink_head(paymentaddresses_free); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		DATA_PAYMENTADDRESSES(row, item); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		PQ_GET_FLD(res, i, "paymentaddressid", field, ok); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		if (!ok) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		TXT_TO_BIGINT("paymentaddressid", field, row->paymentaddressid); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		PQ_GET_FLD(res, i, "userid", field, ok); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		if (!ok) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		TXT_TO_BIGINT("userid", field, row->userid); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		PQ_GET_FLD(res, i, "payaddress", field, ok); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		if (!ok) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		TXT_TO_STR("payaddress", field, row->payaddress); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		PQ_GET_FLD(res, i, "payratio", field, ok); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		if (!ok) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		TXT_TO_INT("payratio", field, row->payratio); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		HISTORYDATEFLDS(res, i, row, ok); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		if (!ok) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		paymentaddresses_root = add_to_ktree(paymentaddresses_root, item, cmp_paymentaddresses); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		k_add_head(paymentaddresses_store, item); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (!ok) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		k_add_head(paymentaddresses_free, item); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	K_WUNLOCK(paymentaddresses_free); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	PQclear(res); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (ok) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		LOGDEBUG("%s(): built", __func__); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		LOGWARNING("%s(): loaded %d paymentaddresses records", __func__, n); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	return ok; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | // order by userid asc,paydate asc,payaddress asc,expirydate desc
 |  |  |  | // order by userid asc,paydate asc,payaddress asc,expirydate desc
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static cmp_t cmp_payments(K_ITEM *a, K_ITEM *b) |  |  |  | static cmp_t cmp_payments(K_ITEM *a, K_ITEM *b) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
	
		
		
			
				
					|  |  | @ -6811,6 +7078,8 @@ static bool getdata2() | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (!(ok = blocks_fill(conn)) || everyone_die) |  |  |  | 	if (!(ok = blocks_fill(conn)) || everyone_die) | 
			
		
	
		
		
			
				
					
					|  |  |  | 		goto sukamudai; |  |  |  | 		goto sukamudai; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (!confirm_sharesummary) { |  |  |  | 	if (!confirm_sharesummary) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		if (!(ok = paymentaddresses_fill(conn)) || everyone_die) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			goto sukamudai; | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if (!(ok = payments_fill(conn)) || everyone_die) |  |  |  | 		if (!(ok = payments_fill(conn)) || everyone_die) | 
			
		
	
		
		
			
				
					
					|  |  |  | 			goto sukamudai; |  |  |  | 			goto sukamudai; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
	
		
		
			
				
					|  |  | @ -7019,6 +7288,13 @@ static void alloc_storage() | 
			
		
	
		
		
			
				
					
					|  |  |  | 	workers_store = k_new_store(workers_free); |  |  |  | 	workers_store = k_new_store(workers_free); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	workers_root = new_ktree(); |  |  |  | 	workers_root = new_ktree(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	paymentaddresses_free = k_new_list("PaymentAddresses", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					   sizeof(PAYMENTADDRESSES), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					   ALLOC_PAYMENTADDRESSES, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					   LIMIT_PAYMENTADDRESSES, true); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	paymentaddresses_store = k_new_store(paymentaddresses_free); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	paymentaddresses_root = new_ktree(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	payments_free = k_new_list("Payments", sizeof(PAYMENTS), |  |  |  | 	payments_free = k_new_list("Payments", sizeof(PAYMENTS), | 
			
		
	
		
		
			
				
					
					|  |  |  | 					ALLOC_PAYMENTS, LIMIT_PAYMENTS, true); |  |  |  | 					ALLOC_PAYMENTS, LIMIT_PAYMENTS, true); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	payments_store = k_new_store(payments_free); |  |  |  | 	payments_store = k_new_store(payments_free); | 
			
		
	
	
		
		
			
				
					|  |  | @ -7205,9 +7481,10 @@ static char *cmd_newpass(__maybe_unused PGconn *conn, char *cmd, char *id, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	K_RUNLOCK(users_free); |  |  |  | 	K_RUNLOCK(users_free); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (u_item) { |  |  |  | 	if (u_item) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		ok = users_pass(NULL, u_item, |  |  |  | 		ok = users_pass_email(NULL, u_item, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 					    transfer_data(i_oldhash), |  |  |  | 					    transfer_data(i_oldhash), | 
			
		
	
		
		
			
				
					
					|  |  |  | 					    transfer_data(i_newhash), |  |  |  | 					    transfer_data(i_newhash), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					    NULL, | 
			
		
	
		
		
			
				
					
					|  |  |  | 					    by, code, inet, now, trf_root); |  |  |  | 					    by, code, inet, now, trf_root); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -7262,6 +7539,124 @@ static char *cmd_chkpass(__maybe_unused PGconn *conn, char *cmd, char *id, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	return strdup("ok."); |  |  |  | 	return strdup("ok."); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | static char *cmd_userset(PGconn *conn, char *cmd, char *id, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			 __maybe_unused tv_t *now, __maybe_unused char *by, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			 __maybe_unused char *code, __maybe_unused char *inet, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			 __maybe_unused tv_t *notcd, K_TREE *trf_root) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	K_ITEM *i_username, *i_passwordhash, *i_address, *i_email, *u_item, *pa_item; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	char *email, *address; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	char reply[1024] = ""; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	size_t siz = sizeof(reply); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	char tmp[1024]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	PAYMENTADDRESSES *paymentaddresses; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	USERS *users; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	char *reason = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	char *answer = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	size_t len, off; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	bool ok; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	LOGDEBUG("%s(): cmd '%s'", __func__, cmd); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	i_username = require_name(trf_root, "username", 3, (char *)userpatt, reply, siz); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (!i_username) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		// For web this message is detailed enough
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		reason = "System error"; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		goto struckout; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	K_RLOCK(users_free); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	u_item = find_users(transfer_data(i_username)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	K_RUNLOCK(users_free); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (!u_item) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		reason = "Unknown user"; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		goto struckout; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		DATA_USERS(users, u_item); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		i_passwordhash = optional_name(trf_root, "passwordhash", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 						64, (char *)hashpatt); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		if (!i_passwordhash) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			APPEND_REALLOC_INIT(answer, off, len); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			snprintf(tmp, sizeof(tmp), "email=%s%c", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				 users->emailaddress, FLDSEP); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			APPEND_REALLOC(answer, off, len, tmp); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			K_RLOCK(paymentaddresses_free); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			pa_item = find_paymentaddresses(users->userid); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			K_RUNLOCK(paymentaddresses_free); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			if (pa_item) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				DATA_PAYMENTADDRESSES(paymentaddresses, pa_item); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				snprintf(tmp, sizeof(tmp), "addr=%s", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					 paymentaddresses->payaddress); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				APPEND_REALLOC(answer, off, len, tmp); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			} else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				snprintf(tmp, sizeof(tmp), "addr="); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				APPEND_REALLOC(answer, off, len, tmp); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		} else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			if (strcasecmp(transfer_data(i_passwordhash), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					users->passwordhash) == 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				reason = "Incorrect password"; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				goto struckout; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			i_email = optional_name(trf_root, "email", 1, (char *)mailpatt); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			if (i_email) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				email = transfer_data(i_email); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			else | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				email = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			i_address = optional_name(trf_root, "address", 1, NULL); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			if (i_address) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				address = transfer_data(i_address); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			else | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				address = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			if ((email == NULL || *email == '\0') && | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			    (address == NULL || *address == '\0')) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				reason = "Missing/Invalid value"; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				goto struckout; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | //			if (address && *address)
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | //				TODO: validate it
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			if (email && *email) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				ok = users_pass_email(conn, u_item, NULL, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 							    NULL, email, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 							    by, code, inet, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 							    now, trf_root); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				if (!ok) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					reason = "email error"; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					goto struckout; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			if (address && *address) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				ok = paymentaddresses_set(conn, users->userid, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 								address, by, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 								code, inet, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 								now, trf_root); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				if (!ok) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					reason = "address error"; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					goto struckout; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			answer = strdup("updated"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | struckout: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (reason) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		snprintf(reply, siz, "ERR.%s", reason); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		LOGERR("%s.%s", id, reply); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		return strdup(reply); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	snprintf(reply, siz, "ok.%s", answer); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	LOGDEBUG("%s.%s", id, answer); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	free(answer); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	return strdup(reply); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static char *cmd_poolstats_do(PGconn *conn, char *cmd, char *id, char *by, |  |  |  | static char *cmd_poolstats_do(PGconn *conn, char *cmd, char *id, char *by, | 
			
		
	
		
		
			
				
					
					|  |  |  | 			      char *code, char *inet, tv_t *cd, bool igndup, |  |  |  | 			      char *code, char *inet, tv_t *cd, bool igndup, | 
			
		
	
		
		
			
				
					
					|  |  |  | 			      K_TREE *trf_root) |  |  |  | 			      K_TREE *trf_root) | 
			
		
	
	
		
		
			
				
					|  |  | @ -9248,6 +9643,7 @@ static char *cmd_stats(__maybe_unused PGconn *conn, char *cmd, char *id, | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	USEINFO(users, 1, 2); |  |  |  | 	USEINFO(users, 1, 2); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	USEINFO(workers, 1, 1); |  |  |  | 	USEINFO(workers, 1, 1); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	USEINFO(paymentaddresses, 1, 1); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	USEINFO(payments, 1, 1); |  |  |  | 	USEINFO(payments, 1, 1); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	USEINFO(idcontrol, 1, 0); |  |  |  | 	USEINFO(idcontrol, 1, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	USEINFO(workinfo, 1, 1); |  |  |  | 	USEINFO(workinfo, 1, 1); | 
			
		
	
	
		
		
			
				
					|  |  | @ -9349,6 +9745,7 @@ static struct CMDS { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	{ CMD_ADDUSER,	"adduser",	false,	false,	cmd_adduser,	ACCESS_WEB }, |  |  |  | 	{ CMD_ADDUSER,	"adduser",	false,	false,	cmd_adduser,	ACCESS_WEB }, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	{ CMD_NEWPASS,	"newpass",	false,	false,	cmd_newpass,	ACCESS_WEB }, |  |  |  | 	{ CMD_NEWPASS,	"newpass",	false,	false,	cmd_newpass,	ACCESS_WEB }, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	{ CMD_CHKPASS,	"chkpass",	false,	false,	cmd_chkpass,	ACCESS_WEB }, |  |  |  | 	{ CMD_CHKPASS,	"chkpass",	false,	false,	cmd_chkpass,	ACCESS_WEB }, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	{ CMD_USERSET,	"usersettings",	false,	false,	cmd_userset,	ACCESS_WEB }, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	{ CMD_POOLSTAT,	"poolstats",	false,	true,	cmd_poolstats,	ACCESS_POOL }, |  |  |  | 	{ CMD_POOLSTAT,	"poolstats",	false,	true,	cmd_poolstats,	ACCESS_POOL }, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	{ CMD_USERSTAT,	"userstats",	false,	true,	cmd_userstats,	ACCESS_POOL }, |  |  |  | 	{ CMD_USERSTAT,	"userstats",	false,	true,	cmd_userstats,	ACCESS_POOL }, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	{ CMD_BLOCK,	"block",	false,	true,	cmd_blocks,	ACCESS_POOL }, |  |  |  | 	{ CMD_BLOCK,	"block",	false,	true,	cmd_blocks,	ACCESS_POOL }, | 
			
		
	
	
		
		
			
				
					|  |  | @ -9886,6 +10283,7 @@ static void *socketer(__maybe_unused void *arg) | 
			
		
	
		
		
			
				
					
					|  |  |  | 	char *last_chkpass = NULL, *reply_chkpass = NULL; |  |  |  | 	char *last_chkpass = NULL, *reply_chkpass = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	char *last_adduser = NULL, *reply_adduser = NULL; |  |  |  | 	char *last_adduser = NULL, *reply_adduser = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	char *last_newpass = NULL, *reply_newpass = NULL; |  |  |  | 	char *last_newpass = NULL, *reply_newpass = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	char *last_userset = NULL, *reply_userset = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	char *last_newid = NULL, *reply_newid = NULL; |  |  |  | 	char *last_newid = NULL, *reply_newid = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	char *last_web = NULL, *reply_web = NULL; |  |  |  | 	char *last_web = NULL, *reply_web = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	char *reply_last, duptype[CMD_SIZ+1]; |  |  |  | 	char *reply_last, duptype[CMD_SIZ+1]; | 
			
		
	
	
		
		
			
				
					|  |  | @ -10058,6 +10456,7 @@ static void *socketer(__maybe_unused void *arg) | 
			
		
	
		
		
			
				
					
					|  |  |  | 					case CMD_CHKPASS: |  |  |  | 					case CMD_CHKPASS: | 
			
		
	
		
		
			
				
					
					|  |  |  | 					case CMD_ADDUSER: |  |  |  | 					case CMD_ADDUSER: | 
			
		
	
		
		
			
				
					
					|  |  |  | 					case CMD_NEWPASS: |  |  |  | 					case CMD_NEWPASS: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					case CMD_USERSET: | 
			
		
	
		
		
			
				
					
					|  |  |  | 					case CMD_BLOCKLIST: |  |  |  | 					case CMD_BLOCKLIST: | 
			
		
	
		
		
			
				
					
					|  |  |  | 					case CMD_NEWID: |  |  |  | 					case CMD_NEWID: | 
			
		
	
		
		
			
				
					
					|  |  |  | 					case CMD_STATS: |  |  |  | 					case CMD_STATS: | 
			
		
	
	
		
		
			
				
					|  |  | @ -10088,6 +10487,9 @@ static void *socketer(__maybe_unused void *arg) | 
			
		
	
		
		
			
				
					
					|  |  |  | 							case CMD_NEWPASS: |  |  |  | 							case CMD_NEWPASS: | 
			
		
	
		
		
			
				
					
					|  |  |  | 								STORELASTREPLY(newpass); |  |  |  | 								STORELASTREPLY(newpass); | 
			
		
	
		
		
			
				
					
					|  |  |  | 								break; |  |  |  | 								break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 							case CMD_USERSET: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 								STORELASTREPLY(userset); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 								break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 							case CMD_NEWID: |  |  |  | 							case CMD_NEWID: | 
			
		
	
		
		
			
				
					
					|  |  |  | 								STORELASTREPLY(newid); |  |  |  | 								STORELASTREPLY(newid); | 
			
		
	
		
		
			
				
					
					|  |  |  | 								break; |  |  |  | 								break; | 
			
		
	
	
		
		
			
				
					|  |  | @ -10277,6 +10679,7 @@ static bool reload_line(PGconn *conn, char *filename, uint64_t count, char *buf) | 
			
		
	
		
		
			
				
					
					|  |  |  | 			case CMD_ADDUSER: |  |  |  | 			case CMD_ADDUSER: | 
			
		
	
		
		
			
				
					
					|  |  |  | 			case CMD_NEWPASS: |  |  |  | 			case CMD_NEWPASS: | 
			
		
	
		
		
			
				
					
					|  |  |  | 			case CMD_CHKPASS: |  |  |  | 			case CMD_CHKPASS: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			case CMD_USERSET: | 
			
		
	
		
		
			
				
					
					|  |  |  | 			case CMD_BLOCKLIST: |  |  |  | 			case CMD_BLOCKLIST: | 
			
		
	
		
		
			
				
					
					|  |  |  | 			case CMD_BLOCKSTATUS: |  |  |  | 			case CMD_BLOCKSTATUS: | 
			
		
	
		
		
			
				
					
					|  |  |  | 			case CMD_NEWID: |  |  |  | 			case CMD_NEWID: | 
			
		
	
	
		
		
			
				
					|  |  | 
 |