Newer
Older
/* Synchronet JavaScript "User" Object */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright Rob Swindell - http://www.synchro.net/copyright.html *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
#include "sbbs.h"
#include "filedat.h"
#include "js_request.h"

rswindell
committed
typedef struct
{
user_t* user;
user_t storage;
JSBool cached;
client_t* client;
int file; // for fast read operations, only

rswindell
committed
} private_t;
/* User Object Properties */
USER_PROP_NUMBER
, USER_PROP_ALIAS
, USER_PROP_NAME
, USER_PROP_HANDLE
, USER_PROP_LANG
, USER_PROP_NOTE
, USER_PROP_IPADDR
, USER_PROP_COMP
, USER_PROP_COMMENT
, USER_PROP_NETMAIL
, USER_PROP_EMAIL /* READ ONLY */
, USER_PROP_ADDRESS
, USER_PROP_LOCATION
, USER_PROP_ZIPCODE
, USER_PROP_PASS
, USER_PROP_PHONE
, USER_PROP_BIRTH
, USER_PROP_BIRTHYEAR
, USER_PROP_BIRTHMONTH
, USER_PROP_BIRTHDAY
, USER_PROP_AGE /* READ ONLY */
, USER_PROP_MODEM
, USER_PROP_LASTON
, USER_PROP_FIRSTON
, USER_PROP_EXPIRE
, USER_PROP_PWMOD
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
, USER_PROP_LOGONS
, USER_PROP_LTODAY
, USER_PROP_TIMEON
, USER_PROP_TEXTRA
, USER_PROP_TTODAY
, USER_PROP_TLAST
, USER_PROP_POSTS
, USER_PROP_EMAILS
, USER_PROP_FBACKS
, USER_PROP_ETODAY
, USER_PROP_PTODAY
, USER_PROP_MAIL_WAITING
, USER_PROP_READ_WAITING
, USER_PROP_UNREAD_WAITING
, USER_PROP_SPAM_WAITING
, USER_PROP_MAIL_PENDING
, USER_PROP_ULB
, USER_PROP_ULS
, USER_PROP_DLB
, USER_PROP_DLS
, USER_PROP_DLCPS
, USER_PROP_CDT
, USER_PROP_MIN
, USER_PROP_LEVEL
, USER_PROP_FLAGS1
, USER_PROP_FLAGS2
, USER_PROP_FLAGS3
, USER_PROP_FLAGS4
, USER_PROP_EXEMPT
, USER_PROP_REST
, USER_PROP_ROWS
, USER_PROP_COLS
, USER_PROP_SEX
, USER_PROP_MISC
, USER_PROP_LEECH
, USER_PROP_CURSUB
, USER_PROP_CURDIR
, USER_PROP_CURXTRN
, USER_PROP_FREECDT
, USER_PROP_XEDIT
, USER_PROP_SHELL
, USER_PROP_QWK
, USER_PROP_TMPEXT
, USER_PROP_CHAT
, USER_PROP_MAIL
, USER_PROP_NS_TIME
, USER_PROP_PROT
, USER_PROP_LOGONTIME
, USER_PROP_TIMEPERCALL
, USER_PROP_TIMEPERDAY
, USER_PROP_CALLSPERDAY
, USER_PROP_LINESPERMSG
, USER_PROP_EMAILPERDAY
, USER_PROP_POSTSPERDAY
, USER_PROP_FREECDTPERDAY
, USER_PROP_CACHED
, USER_PROP_IS_SYSOP
, USER_PROP_BATUPLST
, USER_PROP_BATDNLST
static void js_getuserdat(scfg_t* scfg, private_t* p)
{
if (p->user->number != 0 && !p->cached) {
if (p->file < 1)
p->file = openuserdat(scfg, /* for_modify: */ FALSE);
ushort usernumber = p->user->number;
if (fgetuserdat(scfg, p->user, p->file) == 0)
p->cached = TRUE;
p->user->number = usernumber; // Can be zeroed by fgetuserdat() failure
}
}
static JSBool js_user_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
jsval idval;
char* s = NULL;
char tmp[128];
int64_t val = 0;
jsint tiny;
JSString* js_str;
private_t* p;
jsrefcount rc;
scfg_t* scfg;
scfg = JS_GetRuntimePrivate(JS_GetRuntime(cx));
if ((p = (private_t*)JS_GetPrivate(cx, obj)) == NULL)
rc = JS_SUSPENDREQUEST(cx);
js_getuserdat(scfg, p);
JS_IdToValue(cx, id, &idval);
tiny = JSVAL_TO_INT(idval);
rc = JS_SUSPENDREQUEST(cx);
val = p->user->number;
case USER_PROP_ALIAS:
break;
case USER_PROP_NAME:
break;
case USER_PROP_HANDLE:

Rob Swindell
committed
case USER_PROP_LANG:
s = p->user->lang;
break;
case USER_PROP_NOTE:
case USER_PROP_COMP:
break;
case USER_PROP_COMMENT:
break;
case USER_PROP_NETMAIL:

rswindell
committed
case USER_PROP_EMAIL:
s = usermailaddr(scfg, tmp
, (scfg->inetmail_misc & NMAIL_ALIAS) || (p->user->rest & FLAG('O')) ? p->user->alias : p->user->name);

rswindell
committed
break;
case USER_PROP_ADDRESS:
break;
case USER_PROP_LOCATION:
s = p->user->location;
break;
case USER_PROP_ZIPCODE:
break;
case USER_PROP_PASS:
break;
case USER_PROP_PHONE:
break;
case USER_PROP_BIRTH:
case USER_PROP_BIRTHYEAR:
val = getbirthyear(scfg, p->user->birth);
break;
case USER_PROP_BIRTHMONTH:
val = getbirthmonth(scfg, p->user->birth);
break;
case USER_PROP_BIRTHDAY:
val = getbirthday(scfg, p->user->birth);
break;
case USER_PROP_AGE:
val = getage(scfg, p->user->birth);
break;
case USER_PROP_MODEM:
break;
case USER_PROP_LASTON:
val = p->user->laston;
break;
case USER_PROP_FIRSTON:
val = p->user->firston;
break;
case USER_PROP_EXPIRE:
val = p->user->expire;
case USER_PROP_PWMOD:
case USER_PROP_DELDATE:
val = p->user->deldate;
break;
case USER_PROP_LOGONS:
val = p->user->logons;
break;
case USER_PROP_LTODAY:
val = p->user->ltoday;
break;
case USER_PROP_TIMEON:
val = p->user->timeon;
break;
case USER_PROP_TEXTRA:
val = p->user->textra;
break;
case USER_PROP_TTODAY:
val = p->user->ttoday;
case USER_PROP_TLAST:
case USER_PROP_POSTS:
case USER_PROP_EMAILS:
val = p->user->emails;
case USER_PROP_FBACKS:
val = p->user->fbacks;
case USER_PROP_ETODAY:
val = p->user->etoday;
break;
case USER_PROP_PTODAY:
val = p->user->ptoday;
break;
case USER_PROP_ULB:
*vp = DOUBLE_TO_JSVAL((jsdouble)p->user->ulb);
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE; /* intentional early return */
break;
case USER_PROP_ULS:
break;
case USER_PROP_DLB:
*vp = DOUBLE_TO_JSVAL((jsdouble)p->user->dlb);
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE; /* intentional early return */
break;
case USER_PROP_DLS:
case USER_PROP_CDT:
*vp = DOUBLE_TO_JSVAL((jsdouble)p->user->cdt);
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE; /* intentional early return */
case USER_PROP_MIN:
break;
case USER_PROP_LEVEL:
break;
case USER_PROP_FLAGS1:
val = p->user->flags1;
break;
case USER_PROP_FLAGS2:
val = p->user->flags2;
break;
case USER_PROP_FLAGS3:
val = p->user->flags3;
break;
case USER_PROP_FLAGS4:
val = p->user->flags4;
break;
case USER_PROP_EXEMPT:
val = p->user->exempt;
break;
case USER_PROP_REST:
break;
case USER_PROP_ROWS:
case USER_PROP_SEX:
sprintf(tmp, "%c", p->user->sex);
s = tmp;
break;
case USER_PROP_LEECH:
break;
case USER_PROP_CURSUB:
break;
case USER_PROP_CURDIR:
case USER_PROP_CURXTRN:
break;
case USER_PROP_FREECDT:
*vp = DOUBLE_TO_JSVAL((jsdouble)p->user->freecdt);
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE; /* intentional early return */
case USER_PROP_XEDIT:
if (p->user->xedit > 0 && p->user->xedit <= scfg->total_xedits)
s = scfg->xedit[p->user->xedit - 1]->code;

rswindell
committed
else
s = ""; /* internal editor */
break;
case USER_PROP_SHELL:
s = scfg->shell[p->user->shell]->code;
case USER_PROP_QWK:
break;
case USER_PROP_TMPEXT:
break;
case USER_PROP_CHAT:
case USER_PROP_MAIL:
val = p->user->mail;
break;
case USER_PROP_NS_TIME:
val = p->user->ns_time;
break;
case USER_PROP_PROT:
sprintf(tmp, "%c", p->user->prot);
s = tmp;
case USER_PROP_LOGONTIME:
val = p->user->logontime;
break;
case USER_PROP_TIMEPERCALL:
val = scfg->level_timepercall[p->user->level];
break;
case USER_PROP_TIMEPERDAY:
val = scfg->level_timeperday[p->user->level];
break;
case USER_PROP_CALLSPERDAY:
val = scfg->level_callsperday[p->user->level];
break;
case USER_PROP_LINESPERMSG:
val = scfg->level_linespermsg[p->user->level];
break;
case USER_PROP_POSTSPERDAY:
val = scfg->level_postsperday[p->user->level];
break;
case USER_PROP_EMAILPERDAY:
val = scfg->level_emailperday[p->user->level];
break;
case USER_PROP_FREECDTPERDAY:
val = scfg->level_freecdtperday[p->user->level];
break;
case USER_PROP_MAIL_WAITING:
val = getmail(scfg, p->user->number, /* sent? */ FALSE, /* attr: */ 0);
break;
case USER_PROP_READ_WAITING:
val = getmail(scfg, p->user->number, /* sent? */ FALSE, /* attr: */ MSG_READ);
break;
case USER_PROP_UNREAD_WAITING:
val = getmail(scfg, p->user->number, /* sent? */ FALSE, /* attr: */ ~MSG_READ);
break;
case USER_PROP_SPAM_WAITING:
val = getmail(scfg, p->user->number, /* sent? */ FALSE, /* attr: */ MSG_SPAM);
break;
case USER_PROP_MAIL_PENDING:
val = getmail(scfg, p->user->number, /* sent? */ TRUE, /* SPAM: */ FALSE);
break;
case USER_PROP_CACHED:
*vp = BOOLEAN_TO_JSVAL(p->cached);
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE; /* intentional early return */
case USER_PROP_IS_SYSOP:
*vp = BOOLEAN_TO_JSVAL(user_is_sysop(p->user));
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE; /* intentional early return */
case USER_PROP_BATUPLST:
s = batch_list_name(scfg, p->user->number, XFER_BATCH_UPLOAD, tmp, sizeof tmp);
break;
case USER_PROP_BATDNLST:
s = batch_list_name(scfg, p->user->number, XFER_BATCH_DOWNLOAD, tmp, sizeof tmp);
break;
/* This must not set vp in order for child objects to work (stats and security) */
JS_RESUMEREQUEST(cx, rc);
JS_RESUMEREQUEST(cx, rc);
if (s != NULL) {
if ((js_str = JS_NewStringCopyZ(cx, s)) == NULL)
*vp = DOUBLE_TO_JSVAL((double)val);
static JSBool js_user_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
jsval idval;
char* str = NULL;
uint32 val;
ulong usermisc;
jsint tiny;
private_t* p;
int32 usernumber;
jsrefcount rc;
scfg_t* scfg;
scfg = JS_GetRuntimePrivate(JS_GetRuntime(cx));
if ((p = (private_t*)JS_GetPrivate(cx, obj)) == NULL)
HANDLE_PENDING(cx, str);
JS_IdToValue(cx, id, &idval);
tiny = JSVAL_TO_INT(idval);
rc = JS_SUSPENDREQUEST(cx);
switch (tiny) {
JS_RESUMEREQUEST(cx, rc);
if (!JS_ValueToInt32(cx, *vp, &usernumber)) {
rc = JS_SUSPENDREQUEST(cx);
if (usernumber != p->user->number) {
p->user->number = (ushort)usernumber;
p->cached = FALSE;
}
case USER_PROP_ALIAS:
SAFECOPY(p->user->alias, str);
/* update user.tab */
putuserstr(scfg, p->user->number, USER_ALIAS, str);
/* update name.dat */
usermisc = getusermisc(scfg, p->user->number);
if (!(usermisc & DELETED))
putusername(scfg, p->user->number, str);
break;
case USER_PROP_NAME:
SAFECOPY(p->user->name, str);
putuserstr(scfg, p->user->number, USER_NAME, str);
break;
case USER_PROP_HANDLE:
SAFECOPY(p->user->handle, str);
putuserstr(scfg, p->user->number, USER_HANDLE, str);

Rob Swindell
committed
case USER_PROP_LANG:
SAFECOPY(p->user->lang, str);
putuserstr(scfg, p->user->number, USER_LANG, str);
break;
case USER_PROP_NOTE:
SAFECOPY(p->user->note, str);
putuserstr(scfg, p->user->number, USER_NOTE, str);
case USER_PROP_IPADDR:
SAFECOPY(p->user->ipaddr, str);
putuserstr(scfg, p->user->number, USER_IPADDR, str);
case USER_PROP_COMP:
SAFECOPY(p->user->comp, str);
putuserstr(scfg, p->user->number, USER_HOST, str);
case USER_PROP_COMMENT:
SAFECOPY(p->user->comment, str);
putuserstr(scfg, p->user->number, USER_COMMENT, str);
case USER_PROP_NETMAIL:
SAFECOPY(p->user->netmail, str);
putuserstr(scfg, p->user->number, USER_NETMAIL, str);
case USER_PROP_ADDRESS:
SAFECOPY(p->user->address, str);
putuserstr(scfg, p->user->number, USER_ADDRESS, str);
case USER_PROP_LOCATION:
SAFECOPY(p->user->location, str);
putuserstr(scfg, p->user->number, USER_LOCATION, str);
case USER_PROP_ZIPCODE:
SAFECOPY(p->user->zipcode, str);
putuserstr(scfg, p->user->number, USER_ZIPCODE, str);
case USER_PROP_PHONE:
SAFECOPY(p->user->phone, str);
putuserstr(scfg, p->user->number, USER_PHONE, str);
case USER_PROP_BIRTH:
parse_birthdate(scfg, str, p->user->birth, sizeof p->user->birth);
putuserstr(scfg, p->user->number, USER_BIRTH, p->user->birth);
case USER_PROP_BIRTHYEAR:
if (JS_ValueToECMAUint32(cx, *vp, &val))
putuserdec32(scfg, p->user->number, USER_BIRTH, isoDate_create(val, getbirthmonth(scfg, p->user->birth), getbirthday(scfg, p->user->birth)));
break;
case USER_PROP_BIRTHMONTH:
if (JS_ValueToECMAUint32(cx, *vp, &val))
putuserdec32(scfg, p->user->number, USER_BIRTH, isoDate_create(getbirthyear(scfg, p->user->birth), val, getbirthday(scfg, p->user->birth)));
break;
case USER_PROP_BIRTHDAY:
if (JS_ValueToECMAUint32(cx, *vp, &val))
putuserdec32(scfg, p->user->number, USER_BIRTH, isoDate_create(getbirthyear(scfg, p->user->birth), getbirthmonth(scfg, p->user->birth), val));
case USER_PROP_MODEM:
SAFECOPY(p->user->connection, str);
putuserstr(scfg, p->user->number, USER_CONNECTION, str);
case USER_PROP_ROWS:
p->user->rows = atoi(str);
putuserdec32(scfg, p->user->number, USER_ROWS, p->user->rows);
case USER_PROP_COLS:
p->user->cols = atoi(str);
putuserdec32(scfg, p->user->number, USER_COLS, p->user->cols);
case USER_PROP_SEX:
p->user->sex = toupper(str[0]);
putuserstr(scfg, p->user->number, USER_GENDER, strupr(str)); /* single char */
case USER_PROP_CURSUB:
SAFECOPY(p->user->cursub, str);
putuserstr(scfg, p->user->number, USER_CURSUB, str);
case USER_PROP_CURDIR:
SAFECOPY(p->user->curdir, str);
putuserstr(scfg, p->user->number, USER_CURDIR, str);
case USER_PROP_CURXTRN:
SAFECOPY(p->user->curxtrn, str);
putuserstr(scfg, p->user->number, USER_CURXTRN, str);
break;
case USER_PROP_XEDIT:
p->user->xedit = getxeditnum(scfg, str);
putuserstr(scfg, p->user->number, USER_XEDIT, str);
case USER_PROP_SHELL:
p->user->shell = getshellnum(scfg, str, 0);
putuserstr(scfg, p->user->number, USER_SHELL, str);
break;
case USER_PROP_MISC:
JS_RESUMEREQUEST(cx, rc);
if (!JS_ValueToECMAUint32(cx, *vp, &val)) {
putusermisc(scfg, p->user->number, p->user->misc = val);
rc = JS_SUSPENDREQUEST(cx);
case USER_PROP_QWK:
JS_RESUMEREQUEST(cx, rc);
if (!JS_ValueToECMAUint32(cx, *vp, &val)) {
putuserqwk(scfg, p->user->number, p->user->qwk = val);
rc = JS_SUSPENDREQUEST(cx);
case USER_PROP_CHAT:
JS_RESUMEREQUEST(cx, rc);
if (!JS_ValueToECMAUint32(cx, *vp, &val)) {
putuserchat(scfg, p->user->number, p->user->chat = val);
rc = JS_SUSPENDREQUEST(cx);
case USER_PROP_MAIL:
JS_RESUMEREQUEST(cx, rc);
if (!JS_ValueToECMAUint32(cx, *vp, &val)) {
free(str);
return JS_FALSE;
}
putusermail(scfg, p->user->number, p->user->mail = val);
rc = JS_SUSPENDREQUEST(cx);
break;
case USER_PROP_TMPEXT:
SAFECOPY(p->user->tmpext, str);
putuserstr(scfg, p->user->number, USER_TMPEXT, str);
case USER_PROP_NS_TIME:
JS_RESUMEREQUEST(cx, rc);
if (!JS_ValueToECMAUint32(cx, *vp, &val)) {
putuserdatetime(scfg, p->user->number, USER_NS_TIME, p->user->ns_time = val);
rc = JS_SUSPENDREQUEST(cx);
case USER_PROP_PROT:
p->user->prot = toupper(str[0]);
putuserstr(scfg, p->user->number, USER_PROT, strupr(str)); /* single char */
case USER_PROP_LOGONTIME:
JS_RESUMEREQUEST(cx, rc);
if (!JS_ValueToECMAUint32(cx, *vp, &val)) {
putuserdatetime(scfg, p->user->number, USER_LOGONTIME, p->user->logontime = val);
rc = JS_SUSPENDREQUEST(cx);
/* security properties*/
case USER_PROP_PASS:
SAFECOPY(p->user->pass, str);
putuserstr(scfg, p->user->number, USER_PASS, strupr(str));
break;
case USER_PROP_PWMOD:
JS_RESUMEREQUEST(cx, rc);
if (!JS_ValueToECMAUint32(cx, *vp, &val)) {
putuserdatetime(scfg, p->user->number, USER_PWMOD, p->user->pwmod = val);
rc = JS_SUSPENDREQUEST(cx);
case USER_PROP_LEVEL:
p->user->level = atoi(str);
putuserdec32(scfg, p->user->number, USER_LEVEL, p->user->level);
break;
case USER_PROP_FLAGS1:
JS_RESUMEREQUEST(cx, rc);
if (JSVAL_IS_STRING(*vp)) {
val = str_to_bits(p->user->flags1 << 1, str) >> 1;
}
else {
if (!JS_ValueToECMAUint32(cx, *vp, &val)) {
return JS_FALSE;
putuserflags(scfg, p->user->number, USER_FLAGS1, p->user->flags1 = val);
rc = JS_SUSPENDREQUEST(cx);
break;
case USER_PROP_FLAGS2:
JS_RESUMEREQUEST(cx, rc);
if (JSVAL_IS_STRING(*vp)) {
val = str_to_bits(p->user->flags2 << 1, str) >> 1;
}
else {
if (!JS_ValueToECMAUint32(cx, *vp, &val)) {
return JS_FALSE;
putuserflags(scfg, p->user->number, USER_FLAGS2, p->user->flags2 = val);
rc = JS_SUSPENDREQUEST(cx);
break;
case USER_PROP_FLAGS3:
JS_RESUMEREQUEST(cx, rc);
if (JSVAL_IS_STRING(*vp)) {
val = str_to_bits(p->user->flags3 << 1, str) >> 1;
}
else {
if (!JS_ValueToECMAUint32(cx, *vp, &val)) {
return JS_FALSE;
putuserflags(scfg, p->user->number, USER_FLAGS3, p->user->flags3 = val);
rc = JS_SUSPENDREQUEST(cx);
break;
case USER_PROP_FLAGS4:
JS_RESUMEREQUEST(cx, rc);
if (JSVAL_IS_STRING(*vp)) {
val = str_to_bits(p->user->flags4 << 1, str) >> 1;
}
else {
if (!JS_ValueToECMAUint32(cx, *vp, &val)) {
return JS_FALSE;
putuserflags(scfg, p->user->number, USER_FLAGS4, p->user->flags4 = val);
rc = JS_SUSPENDREQUEST(cx);
break;
case USER_PROP_EXEMPT:
JS_RESUMEREQUEST(cx, rc);
if (JSVAL_IS_STRING(*vp)) {
val = str_to_bits(p->user->exempt << 1, str) >> 1;
}
else {
if (!JS_ValueToECMAUint32(cx, *vp, &val)) {
return JS_FALSE;
putuserflags(scfg, p->user->number, USER_EXEMPT, p->user->exempt = val);
rc = JS_SUSPENDREQUEST(cx);
case USER_PROP_REST:
JS_RESUMEREQUEST(cx, rc);
if (JSVAL_IS_STRING(*vp)) {
val = str_to_bits(p->user->rest << 1, str) >> 1;
}
else {
if (!JS_ValueToECMAUint32(cx, *vp, &val)) {
return JS_FALSE;
putuserflags(scfg, p->user->number, USER_REST, p->user->rest = val);
rc = JS_SUSPENDREQUEST(cx);
case USER_PROP_CDT:
p->user->cdt = strtoull(str, NULL, 0);
putuserdec64(scfg, p->user->number, USER_CDT, p->user->cdt);
break;
case USER_PROP_FREECDT:
p->user->freecdt = strtoull(str, NULL, 0);
putuserdec64(scfg, p->user->number, USER_FREECDT, p->user->freecdt);
case USER_PROP_MIN:
p->user->min = strtoul(str, NULL, 0);
putuserdec32(scfg, p->user->number, USER_MIN, p->user->min);
case USER_PROP_TEXTRA:
p->user->textra = (ushort)strtoul(str, NULL, 0);
putuserdec32(scfg, p->user->number, USER_TEXTRA, p->user->textra);
case USER_PROP_EXPIRE:
JS_RESUMEREQUEST(cx, rc);
if (!JS_ValueToECMAUint32(cx, *vp, &val)) {
putuserdatetime(scfg, p->user->number, USER_EXPIRE, p->user->expire = val);
rc = JS_SUSPENDREQUEST(cx);
case USER_PROP_CACHED:
JS_ValueToBoolean(cx, *vp, &p->cached);
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE; /* intentional early return */
if (!(p->user->rest & FLAG('G')))
p->cached = FALSE;
JS_RESUMEREQUEST(cx, rc);
#define USER_PROP_FLAGS JSPROP_ENUMERATE
static jsSyncPropertySpec js_user_properties[] = {
/* name ,tinyid ,flags, ver */
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
{ "number", USER_PROP_NUMBER, USER_PROP_FLAGS, 310},
{ "alias", USER_PROP_ALIAS, USER_PROP_FLAGS, 310},
{ "name", USER_PROP_NAME, USER_PROP_FLAGS, 310},
{ "handle", USER_PROP_HANDLE, USER_PROP_FLAGS, 310},
{ "lang", USER_PROP_LANG, USER_PROP_FLAGS, 320},
{ "note", USER_PROP_NOTE, USER_PROP_FLAGS, 310},
{ "ip_address", USER_PROP_IPADDR, USER_PROP_FLAGS, 310},
{ "host_name", USER_PROP_COMP, USER_PROP_FLAGS, 310},
{ "computer", USER_PROP_COMP, 0, /* Alias */ 310},
{ "comment", USER_PROP_COMMENT, USER_PROP_FLAGS, 310},
{ "netmail", USER_PROP_NETMAIL, USER_PROP_FLAGS, 310},
{ "email", USER_PROP_EMAIL, USER_PROP_FLAGS | JSPROP_READONLY, 310},
{ "address", USER_PROP_ADDRESS, USER_PROP_FLAGS, 310},
{ "location", USER_PROP_LOCATION, USER_PROP_FLAGS, 310},
{ "zipcode", USER_PROP_ZIPCODE, USER_PROP_FLAGS, 310},
{ "phone", USER_PROP_PHONE, USER_PROP_FLAGS, 310},
{ "birthdate", USER_PROP_BIRTH, USER_PROP_FLAGS, 310},
{ "birthyear", USER_PROP_BIRTHYEAR, USER_PROP_FLAGS, 31802},
{ "birthmonth", USER_PROP_BIRTHMONTH, USER_PROP_FLAGS, 31802},
{ "birthday", USER_PROP_BIRTHDAY, USER_PROP_FLAGS, 31802},
{ "age", USER_PROP_AGE, USER_PROP_FLAGS | JSPROP_READONLY, 310},
{ "connection", USER_PROP_MODEM, USER_PROP_FLAGS, 310},
{ "modem", USER_PROP_MODEM, 0, /* Alias */ 310},
{ "screen_rows", USER_PROP_ROWS, USER_PROP_FLAGS, 310},
{ "screen_columns", USER_PROP_COLS, USER_PROP_FLAGS, 31802},
{ "gender", USER_PROP_SEX, USER_PROP_FLAGS, 310},
{ "cursub", USER_PROP_CURSUB, USER_PROP_FLAGS, 310},
{ "curdir", USER_PROP_CURDIR, USER_PROP_FLAGS, 310},
{ "curxtrn", USER_PROP_CURXTRN, USER_PROP_FLAGS, 310},
{ "editor", USER_PROP_XEDIT, USER_PROP_FLAGS, 310},
{ "command_shell", USER_PROP_SHELL, USER_PROP_FLAGS, 310},
{ "settings", USER_PROP_MISC, USER_PROP_FLAGS, 310},
{ "qwk_settings", USER_PROP_QWK, USER_PROP_FLAGS, 310},
{ "chat_settings", USER_PROP_CHAT, USER_PROP_FLAGS, 310},
{ "mail_settings", USER_PROP_MAIL, USER_PROP_FLAGS, 320},
{ "temp_file_ext", USER_PROP_TMPEXT, USER_PROP_FLAGS, 310},
{ "new_file_time", USER_PROP_NS_TIME, USER_PROP_FLAGS, 311},
{ "newscan_date", USER_PROP_NS_TIME, 0, /* Alias */ 310},
{ "download_protocol", USER_PROP_PROT, USER_PROP_FLAGS, 310},
{ "logontime", USER_PROP_LOGONTIME, USER_PROP_FLAGS, 310},
{ "cached", USER_PROP_CACHED, USER_PROP_FLAGS, 314},
{ "is_sysop", USER_PROP_IS_SYSOP, JSPROP_ENUMERATE | JSPROP_READONLY, 315},
{ "batch_upload_list", USER_PROP_BATUPLST, JSPROP_ENUMERATE | JSPROP_READONLY, 320},
{ "batch_download_list", USER_PROP_BATDNLST, JSPROP_ENUMERATE | JSPROP_READONLY, 320},
#ifdef BUILD_JSDOCS
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
static const char* user_prop_desc[] = {
"Record number (1-based)"
, "Alias/name"
, "Real name"
, "Chat handle"
, "Language code (blank, if default, e.g. English)"
, "Sysop note"
, "IP address last logged-in from"
, "Host name last logged-in from (AKA <tt>computer</tt>)"
, "Sysop's comment"
, "External e-mail address"
, "Local Internet e-mail address - <small>READ ONLY</small>"
, "Street address"
, "Location (e.g. city, state)"
, "Zip/postal code"
, "Phone number"
, "Birth date in 'YYYYMMDD' format or legacy format: 'MM/DD/YY' or 'DD/MM/YY', depending on system configuration"
, "Birth year"
, "Birth month (1-12)"
, "Birth day of month (1-31)"
, "Calculated age in years - <small>READ ONLY</small>"
, "Connection type (protocol, AKA <tt>modem</tt>)"
, "Terminal rows (0 = auto-detect)"
, "Terminal columns (0 = auto-detect)"
, "Gender type (e.g. M or F or any single-character)"
, "Current/last message sub-board (internal code)"
, "Current/last file directory (internal code)"
, "Current/last external program (internal code) run"
, "External message editor (internal code) or <i>blank</i> if none"
, "Command shell (internal code)"
, "Settings bit-flags - see <tt>USER_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions"
, "QWK packet settings bit-flags - see <tt>QWK_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions"
, "Chat settings bit-flags - see <tt>CHAT_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions"
, "Mail settings bit-flags - see <tt>MAIL_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions"
, "Temporary file type (extension)"
, "New file scan date/time (time_t format)"
, "File transfer protocol (command key)"
, "Logon time (time_t format)"
, "Record is currently cached in memory"
, "User has a System Operator's security level"
, "Batch upload list file path/name"
, "Batch download list file path/name"
, NULL
/* user.security */
static jsSyncPropertySpec js_user_security_properties[] = {
/* name ,tinyid ,flags, ver */
{ "password", USER_PROP_PASS, USER_PROP_FLAGS, 310 },
{ "password_date", USER_PROP_PWMOD, USER_PROP_FLAGS, 310 },
{ "level", USER_PROP_LEVEL, USER_PROP_FLAGS, 310 },
{ "flags1", USER_PROP_FLAGS1, USER_PROP_FLAGS, 310 },
{ "flags2", USER_PROP_FLAGS2, USER_PROP_FLAGS, 310 },
{ "flags3", USER_PROP_FLAGS3, USER_PROP_FLAGS, 310 },
{ "flags4", USER_PROP_FLAGS4, USER_PROP_FLAGS, 310 },
{ "exemptions", USER_PROP_EXEMPT, USER_PROP_FLAGS, 310 },
{ "restrictions", USER_PROP_REST, USER_PROP_FLAGS, 310 },
{ "credits", USER_PROP_CDT, USER_PROP_FLAGS, 310 },
{ "free_credits", USER_PROP_FREECDT, USER_PROP_FLAGS, 310 },
{ "minutes", USER_PROP_MIN, USER_PROP_FLAGS, 310 },
{ "extra_time", USER_PROP_TEXTRA, USER_PROP_FLAGS, 310 },
{ "expiration_date", USER_PROP_EXPIRE, USER_PROP_FLAGS, 310 },
{ "deletion_date", USER_PROP_DELDATE, JSPROP_ENUMERATE | JSPROP_READONLY, 32002 },
#ifdef BUILD_JSDOCS
static const char* user_security_prop_desc[] = {
"Password"
, "Date password last modified (time_t format)"
, "Security level (0-99)"
, "Flag set #1 (bit-flags) can use +/-[A-?] notation"
, "Flag set #2 (bit-flags) can use +/-[A-?] notation"
, "Flag set #3 (bit-flags) can use +/-[A-?] notation"
, "Flag set #4 (bit-flags) can use +/-[A-?] notation"
, "Exemption flags (bit-flags) can use +/-[A-?] notation"
, "Restriction flags (bit-flags) can use +/-[A-?] notation"
, "Credits"
, "Free credits (for today only)"
, "Extra minutes (time bank)"
, "Extra minutes (for today only)"
, "Expiration date/time (time_t format)"
, "Deletion date/time (time_t format) - <small>READ ONLY</small>"
#undef USER_PROP_FLAGS
#define USER_PROP_FLAGS JSPROP_ENUMERATE | JSPROP_READONLY
/* user.limits: These should be READ ONLY by nature */
static jsSyncPropertySpec js_user_limits_properties[] = {
/* name ,tinyid ,flags, ver */
{ "time_per_logon", USER_PROP_TIMEPERCALL, USER_PROP_FLAGS, 311 },
{ "time_per_day", USER_PROP_TIMEPERDAY, USER_PROP_FLAGS, 311 },
{ "logons_per_day", USER_PROP_CALLSPERDAY, USER_PROP_FLAGS, 311 },
{ "lines_per_message", USER_PROP_LINESPERMSG, USER_PROP_FLAGS, 311 },
{ "email_per_day", USER_PROP_EMAILPERDAY, USER_PROP_FLAGS, 311 },
{ "posts_per_day", USER_PROP_POSTSPERDAY, USER_PROP_FLAGS, 311 },
{ "free_credits_per_day", USER_PROP_FREECDTPERDAY, USER_PROP_FLAGS, 311 },
{0}
};
#ifdef BUILD_JSDOCS
static const char* user_limits_prop_desc[] = {
"Time (in minutes) per logon"
, "Time (in minutes) per day"
, "Logons per day"
, "Lines per message (post or email)"
, "Email sent per day"
, "Messages posted per day"
, "Free credits given per day"
, NULL
};
#endif
#undef USER_PROP_FLAGS
#define USER_PROP_FLAGS JSPROP_ENUMERATE | JSPROP_READONLY
/* user.stats: These should be READ ONLY by nature */
static jsSyncPropertySpec js_user_stats_properties[] = {
/* name ,tinyid ,flags, ver */
{ "laston_date", USER_PROP_LASTON, USER_PROP_FLAGS, 310 },