|
|
1.1 root 1: /* js_user.c */
2:
3: /* Synchronet JavaScript "User" Object */
4:
1.1.1.2 ! root 5: /* $Id: js_user.c,v 1.80 2010/03/01 07:02:58 rswindell Exp $ */
1.1 root 6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
1.1.1.2 ! root 11: * Copyright 2010 Rob Swindell - http://www.synchro.net/copyright.html *
1.1 root 12: * *
13: * This program is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU General Public License for more details: gpl.txt or *
18: * http://www.fsf.org/copyleft/gpl.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: #include "sbbs.h"
1.1.1.2 ! root 39: #include "js_request.h"
1.1 root 40:
41: #ifdef JAVASCRIPT
42:
43: static scfg_t* scfg=NULL;
44:
45: static const char* getprivate_failure = "line %d %s JS_GetPrivate failed";
46:
47: typedef struct
48: {
1.1.1.2 ! root 49: user_t* user;
! 50: user_t storage;
! 51: BOOL cached;
! 52: scfg_t* cfg;
! 53: client_t* client;
1.1 root 54:
55: } private_t;
56:
57: /* User Object Properites */
58: enum {
59: USER_PROP_NUMBER
60: ,USER_PROP_ALIAS
61: ,USER_PROP_NAME
62: ,USER_PROP_HANDLE
63: ,USER_PROP_NOTE
64: ,USER_PROP_COMP
65: ,USER_PROP_COMMENT
66: ,USER_PROP_NETMAIL
67: ,USER_PROP_EMAIL /* READ ONLY */
68: ,USER_PROP_ADDRESS
69: ,USER_PROP_LOCATION
70: ,USER_PROP_ZIPCODE
71: ,USER_PROP_PASS
72: ,USER_PROP_PHONE
73: ,USER_PROP_BIRTH
74: ,USER_PROP_AGE /* READ ONLY */
75: ,USER_PROP_MODEM
76: ,USER_PROP_LASTON
77: ,USER_PROP_FIRSTON
78: ,USER_PROP_EXPIRE
79: ,USER_PROP_PWMOD
80: ,USER_PROP_LOGONS
81: ,USER_PROP_LTODAY
82: ,USER_PROP_TIMEON
83: ,USER_PROP_TEXTRA
84: ,USER_PROP_TTODAY
85: ,USER_PROP_TLAST
86: ,USER_PROP_POSTS
87: ,USER_PROP_EMAILS
88: ,USER_PROP_FBACKS
89: ,USER_PROP_ETODAY
90: ,USER_PROP_PTODAY
91: ,USER_PROP_MAIL_WAITING
92: ,USER_PROP_MAIL_PENDING
93: ,USER_PROP_ULB
94: ,USER_PROP_ULS
95: ,USER_PROP_DLB
96: ,USER_PROP_DLS
97: ,USER_PROP_CDT
98: ,USER_PROP_MIN
99: ,USER_PROP_LEVEL
100: ,USER_PROP_FLAGS1
101: ,USER_PROP_FLAGS2
102: ,USER_PROP_FLAGS3
103: ,USER_PROP_FLAGS4
104: ,USER_PROP_EXEMPT
105: ,USER_PROP_REST
106: ,USER_PROP_ROWS
107: ,USER_PROP_SEX
108: ,USER_PROP_MISC
109: ,USER_PROP_LEECH
110: ,USER_PROP_CURSUB
111: ,USER_PROP_CURDIR
112: ,USER_PROP_CURXTRN
113: ,USER_PROP_FREECDT
114: ,USER_PROP_XEDIT
115: ,USER_PROP_SHELL
116: ,USER_PROP_QWK
117: ,USER_PROP_TMPEXT
118: ,USER_PROP_CHAT
119: ,USER_PROP_NS_TIME
120: ,USER_PROP_PROT
121: ,USER_PROP_LOGONTIME
122: ,USER_PROP_TIMEPERCALL
123: ,USER_PROP_TIMEPERDAY
124: ,USER_PROP_CALLSPERDAY
125: ,USER_PROP_LINESPERMSG
126: ,USER_PROP_EMAILPERDAY
127: ,USER_PROP_POSTSPERDAY
128: ,USER_PROP_FREECDTPERDAY
129: ,USER_PROP_CACHED
1.1.1.2 ! root 130: ,USER_PROP_IS_SYSOP
1.1 root 131: };
132:
133: static void js_getuserdat(private_t* p)
134: {
135: if(!p->cached) {
1.1.1.2 ! root 136: if(getuserdat(p->cfg,p->user)==0)
1.1 root 137: p->cached=TRUE;
138: }
139: }
140:
141:
142: static JSBool js_user_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
143: {
144: char* s=NULL;
145: char tmp[128];
146: ulong val=0;
147: jsint tiny;
148: JSString* js_str;
149: private_t* p;
1.1.1.2 ! root 150: jsrefcount rc;
1.1 root 151:
1.1.1.2 ! root 152: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
! 153: return(JS_TRUE);
1.1 root 154:
1.1.1.2 ! root 155: rc=JS_SUSPENDREQUEST(cx);
1.1 root 156: js_getuserdat(p);
157:
158: tiny = JSVAL_TO_INT(id);
159:
160: switch(tiny) {
161: case USER_PROP_NUMBER:
1.1.1.2 ! root 162: val=p->user->number;
1.1 root 163: break;
164: case USER_PROP_ALIAS:
1.1.1.2 ! root 165: s=p->user->alias;
1.1 root 166: break;
167: case USER_PROP_NAME:
1.1.1.2 ! root 168: s=p->user->name;
1.1 root 169: break;
170: case USER_PROP_HANDLE:
1.1.1.2 ! root 171: s=p->user->handle;
1.1 root 172: break;
173: case USER_PROP_NOTE:
1.1.1.2 ! root 174: s=p->user->note;
1.1 root 175: break;
176: case USER_PROP_COMP:
1.1.1.2 ! root 177: s=p->user->comp;
1.1 root 178: break;
179: case USER_PROP_COMMENT:
1.1.1.2 ! root 180: s=p->user->comment;
1.1 root 181: break;
182: case USER_PROP_NETMAIL:
1.1.1.2 ! root 183: s=p->user->netmail;
1.1 root 184: break;
185: case USER_PROP_EMAIL:
186: s=usermailaddr(p->cfg, tmp
1.1.1.2 ! root 187: ,p->cfg->inetmail_misc&NMAIL_ALIAS ? p->user->alias : p->user->name);
1.1 root 188: break;
189: case USER_PROP_ADDRESS:
1.1.1.2 ! root 190: s=p->user->address;
1.1 root 191: break;
192: case USER_PROP_LOCATION:
1.1.1.2 ! root 193: s=p->user->location;
1.1 root 194: break;
195: case USER_PROP_ZIPCODE:
1.1.1.2 ! root 196: s=p->user->zipcode;
1.1 root 197: break;
198: case USER_PROP_PASS:
1.1.1.2 ! root 199: s=p->user->pass;
1.1 root 200: break;
201: case USER_PROP_PHONE:
1.1.1.2 ! root 202: s=p->user->phone;
1.1 root 203: break;
204: case USER_PROP_BIRTH:
1.1.1.2 ! root 205: s=p->user->birth;
1.1 root 206: break;
207: case USER_PROP_AGE:
1.1.1.2 ! root 208: val=getage(p->cfg,p->user->birth);
1.1 root 209: break;
210: case USER_PROP_MODEM:
1.1.1.2 ! root 211: s=p->user->modem;
1.1 root 212: break;
213: case USER_PROP_LASTON:
1.1.1.2 ! root 214: val=p->user->laston;
1.1 root 215: break;
216: case USER_PROP_FIRSTON:
1.1.1.2 ! root 217: val=p->user->firston;
1.1 root 218: break;
219: case USER_PROP_EXPIRE:
1.1.1.2 ! root 220: val=p->user->expire;
1.1 root 221: break;
222: case USER_PROP_PWMOD:
1.1.1.2 ! root 223: val=p->user->pwmod;
1.1 root 224: break;
225: case USER_PROP_LOGONS:
1.1.1.2 ! root 226: val=p->user->logons;
1.1 root 227: break;
228: case USER_PROP_LTODAY:
1.1.1.2 ! root 229: val=p->user->ltoday;
1.1 root 230: break;
231: case USER_PROP_TIMEON:
1.1.1.2 ! root 232: val=p->user->timeon;
1.1 root 233: break;
234: case USER_PROP_TEXTRA:
1.1.1.2 ! root 235: val=p->user->textra;
1.1 root 236: break;
237: case USER_PROP_TTODAY:
1.1.1.2 ! root 238: val=p->user->ttoday;
1.1 root 239: break;
240: case USER_PROP_TLAST:
1.1.1.2 ! root 241: val=p->user->tlast;
1.1 root 242: break;
243: case USER_PROP_POSTS:
1.1.1.2 ! root 244: val=p->user->posts;
1.1 root 245: break;
246: case USER_PROP_EMAILS:
1.1.1.2 ! root 247: val=p->user->emails;
1.1 root 248: break;
249: case USER_PROP_FBACKS:
1.1.1.2 ! root 250: val=p->user->fbacks;
1.1 root 251: break;
252: case USER_PROP_ETODAY:
1.1.1.2 ! root 253: val=p->user->etoday;
1.1 root 254: break;
255: case USER_PROP_PTODAY:
1.1.1.2 ! root 256: val=p->user->ptoday;
1.1 root 257: break;
258: case USER_PROP_ULB:
1.1.1.2 ! root 259: val=p->user->ulb;
1.1 root 260: break;
261: case USER_PROP_ULS:
1.1.1.2 ! root 262: val=p->user->uls;
1.1 root 263: break;
264: case USER_PROP_DLB:
1.1.1.2 ! root 265: val=p->user->dlb;
1.1 root 266: break;
267: case USER_PROP_DLS:
1.1.1.2 ! root 268: val=p->user->dls;
1.1 root 269: break;
270: case USER_PROP_CDT:
1.1.1.2 ! root 271: val=p->user->cdt;
1.1 root 272: break;
273: case USER_PROP_MIN:
1.1.1.2 ! root 274: val=p->user->min;
1.1 root 275: break;
276: case USER_PROP_LEVEL:
1.1.1.2 ! root 277: val=p->user->level;
1.1 root 278: break;
279: case USER_PROP_FLAGS1:
1.1.1.2 ! root 280: val=p->user->flags1;
1.1 root 281: break;
282: case USER_PROP_FLAGS2:
1.1.1.2 ! root 283: val=p->user->flags2;
1.1 root 284: break;
285: case USER_PROP_FLAGS3:
1.1.1.2 ! root 286: val=p->user->flags3;
1.1 root 287: break;
288: case USER_PROP_FLAGS4:
1.1.1.2 ! root 289: val=p->user->flags4;
1.1 root 290: break;
291: case USER_PROP_EXEMPT:
1.1.1.2 ! root 292: val=p->user->exempt;
1.1 root 293: break;
294: case USER_PROP_REST:
1.1.1.2 ! root 295: val=p->user->rest;
1.1 root 296: break;
297: case USER_PROP_ROWS:
1.1.1.2 ! root 298: val=p->user->rows;
1.1 root 299: break;
300: case USER_PROP_SEX:
1.1.1.2 ! root 301: sprintf(tmp,"%c",p->user->sex);
1.1 root 302: s=tmp;
303: break;
304: case USER_PROP_MISC:
1.1.1.2 ! root 305: val=p->user->misc;
1.1 root 306: break;
307: case USER_PROP_LEECH:
1.1.1.2 ! root 308: val=p->user->leech;
1.1 root 309: break;
310: case USER_PROP_CURSUB:
1.1.1.2 ! root 311: s=p->user->cursub;
1.1 root 312: break;
313: case USER_PROP_CURDIR:
1.1.1.2 ! root 314: s=p->user->curdir;
1.1 root 315: break;
316: case USER_PROP_CURXTRN:
1.1.1.2 ! root 317: s=p->user->curxtrn;
1.1 root 318: break;
319:
320: case USER_PROP_FREECDT:
1.1.1.2 ! root 321: val=p->user->freecdt;
1.1 root 322: break;
323: case USER_PROP_XEDIT:
1.1.1.2 ! root 324: if(p->user->xedit>0 && p->user->xedit<=p->cfg->total_xedits)
! 325: s=p->cfg->xedit[p->user->xedit-1]->code;
1.1 root 326: else
327: s=""; /* internal editor */
328: break;
329: case USER_PROP_SHELL:
1.1.1.2 ! root 330: s=p->cfg->shell[p->user->shell]->code;
1.1 root 331: break;
332: case USER_PROP_QWK:
1.1.1.2 ! root 333: val=p->user->qwk;
1.1 root 334: break;
335: case USER_PROP_TMPEXT:
1.1.1.2 ! root 336: s=p->user->tmpext;
1.1 root 337: break;
338: case USER_PROP_CHAT:
1.1.1.2 ! root 339: val=p->user->chat;
1.1 root 340: break;
341: case USER_PROP_NS_TIME:
1.1.1.2 ! root 342: val=p->user->ns_time;
1.1 root 343: break;
344: case USER_PROP_PROT:
1.1.1.2 ! root 345: sprintf(tmp,"%c",p->user->prot);
1.1 root 346: s=tmp;
347: break;
348: case USER_PROP_LOGONTIME:
1.1.1.2 ! root 349: val=p->user->logontime;
1.1 root 350: break;
351: case USER_PROP_TIMEPERCALL:
1.1.1.2 ! root 352: val=p->cfg->level_timepercall[p->user->level];
1.1 root 353: break;
354: case USER_PROP_TIMEPERDAY:
1.1.1.2 ! root 355: val=p->cfg->level_timeperday[p->user->level];
1.1 root 356: break;
357: case USER_PROP_CALLSPERDAY:
1.1.1.2 ! root 358: val=p->cfg->level_callsperday[p->user->level];
1.1 root 359: break;
360: case USER_PROP_LINESPERMSG:
1.1.1.2 ! root 361: val=p->cfg->level_linespermsg[p->user->level];
1.1 root 362: break;
363: case USER_PROP_POSTSPERDAY:
1.1.1.2 ! root 364: val=p->cfg->level_postsperday[p->user->level];
1.1 root 365: break;
366: case USER_PROP_EMAILPERDAY:
1.1.1.2 ! root 367: val=p->cfg->level_emailperday[p->user->level];
1.1 root 368: break;
369: case USER_PROP_FREECDTPERDAY:
1.1.1.2 ! root 370: val=p->cfg->level_freecdtperday[p->user->level];
1.1 root 371: break;
372: case USER_PROP_MAIL_WAITING:
1.1.1.2 ! root 373: val=getmail(p->cfg,p->user->number,/* sent? */FALSE);
1.1 root 374: break;
375: case USER_PROP_MAIL_PENDING:
1.1.1.2 ! root 376: val=getmail(p->cfg,p->user->number,/* sent? */TRUE);
1.1 root 377: break;
378:
379: case USER_PROP_CACHED:
380: *vp = BOOLEAN_TO_JSVAL(p->cached);
1.1.1.2 ! root 381: JS_RESUMEREQUEST(cx, rc);
! 382: return(JS_TRUE); /* intentional early return */
! 383:
! 384: case USER_PROP_IS_SYSOP:
! 385: *vp = BOOLEAN_TO_JSVAL(p->user->level >= SYSOP_LEVEL);
! 386: JS_RESUMEREQUEST(cx, rc);
1.1 root 387: return(JS_TRUE); /* intentional early return */
388:
389: default:
390: /* This must not set vp in order for child objects to work (stats and security) */
1.1.1.2 ! root 391: JS_RESUMEREQUEST(cx, rc);
1.1 root 392: return(JS_TRUE);
393: }
1.1.1.2 ! root 394: JS_RESUMEREQUEST(cx, rc);
1.1 root 395: if(s!=NULL) {
396: if((js_str=JS_NewStringCopyZ(cx, s))==NULL)
397: return(JS_FALSE);
398: *vp = STRING_TO_JSVAL(js_str);
399: } else
400: JS_NewNumberValue(cx,val,vp);
401:
402: return(JS_TRUE);
403: }
404:
405: static JSBool js_user_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
406: {
407: char* str;
408: char tmp[64];
409: jsint val;
410: ulong usermisc;
411: jsint tiny;
412: JSString* js_str;
413: private_t* p;
414: int32 usernumber;
1.1.1.2 ! root 415: jsrefcount rc;
1.1 root 416:
1.1.1.2 ! root 417: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
! 418: return(JS_TRUE);
1.1 root 419:
420: if((js_str=JS_ValueToString(cx,*vp))==NULL)
421: return(JS_FALSE);
422:
423: if((str=JS_GetStringBytes(js_str))==NULL)
424: return(JS_FALSE);
425:
426: tiny = JSVAL_TO_INT(id);
427:
1.1.1.2 ! root 428: rc=JS_SUSPENDREQUEST(cx);
1.1 root 429: switch(tiny) {
430: case USER_PROP_NUMBER:
1.1.1.2 ! root 431: JS_RESUMEREQUEST(cx, rc);
1.1 root 432: JS_ValueToInt32(cx, *vp, &usernumber);
1.1.1.2 ! root 433: rc=JS_SUSPENDREQUEST(cx);
! 434: if(usernumber!=p->user->number) {
! 435: p->user->number=(ushort)usernumber;
! 436: p->cached=FALSE;
! 437: }
1.1 root 438: break;
439: case USER_PROP_ALIAS:
1.1.1.2 ! root 440: SAFECOPY(p->user->alias,str);
1.1 root 441: /* update USER.DAT */
1.1.1.2 ! root 442: putuserrec(p->cfg,p->user->number,U_ALIAS,LEN_ALIAS,str);
1.1 root 443:
444: /* update NAME.DAT */
1.1.1.2 ! root 445: getuserrec(p->cfg,p->user->number,U_MISC,8,tmp);
1.1 root 446: usermisc=ahtoul(tmp);
447: if(!(usermisc&DELETED))
1.1.1.2 ! root 448: putusername(p->cfg,p->user->number,str);
1.1 root 449: break;
450: case USER_PROP_NAME:
1.1.1.2 ! root 451: SAFECOPY(p->user->name,str);
! 452: putuserrec(p->cfg,p->user->number,U_NAME,LEN_NAME,str);
1.1 root 453: break;
454: case USER_PROP_HANDLE:
1.1.1.2 ! root 455: SAFECOPY(p->user->handle,str);
! 456: putuserrec(p->cfg,p->user->number,U_HANDLE,LEN_HANDLE,str);
1.1 root 457: break;
458: case USER_PROP_NOTE:
1.1.1.2 ! root 459: SAFECOPY(p->user->note,str);
! 460: putuserrec(p->cfg,p->user->number,U_NOTE,LEN_NOTE,str);
1.1 root 461: break;
1.1.1.2 ! root 462: case USER_PROP_COMP:
! 463: SAFECOPY(p->user->comp,str);
! 464: putuserrec(p->cfg,p->user->number,U_COMP,LEN_COMP,str);
1.1 root 465: break;
466: case USER_PROP_COMMENT:
1.1.1.2 ! root 467: SAFECOPY(p->user->comment,str);
! 468: putuserrec(p->cfg,p->user->number,U_COMMENT,LEN_COMMENT,str);
1.1 root 469: break;
470: case USER_PROP_NETMAIL:
1.1.1.2 ! root 471: SAFECOPY(p->user->netmail,str);
! 472: putuserrec(p->cfg,p->user->number,U_NETMAIL,LEN_NETMAIL,str);
1.1 root 473: break;
474: case USER_PROP_ADDRESS:
1.1.1.2 ! root 475: SAFECOPY(p->user->address,str);
! 476: putuserrec(p->cfg,p->user->number,U_ADDRESS,LEN_ADDRESS,str);
1.1 root 477: break;
478: case USER_PROP_LOCATION:
1.1.1.2 ! root 479: SAFECOPY(p->user->location,str);
! 480: putuserrec(p->cfg,p->user->number,U_LOCATION,LEN_LOCATION,str);
1.1 root 481: break;
482: case USER_PROP_ZIPCODE:
1.1.1.2 ! root 483: SAFECOPY(p->user->zipcode,str);
! 484: putuserrec(p->cfg,p->user->number,U_ZIPCODE,LEN_ZIPCODE,str);
1.1 root 485: break;
486: case USER_PROP_PHONE:
1.1.1.2 ! root 487: SAFECOPY(p->user->phone,str);
! 488: putuserrec(p->cfg,p->user->number,U_PHONE,LEN_PHONE,str);
1.1 root 489: break;
490: case USER_PROP_BIRTH:
1.1.1.2 ! root 491: SAFECOPY(p->user->birth,str);
! 492: putuserrec(p->cfg,p->user->number,U_BIRTH,LEN_BIRTH,str);
1.1 root 493: break;
494: case USER_PROP_MODEM:
1.1.1.2 ! root 495: SAFECOPY(p->user->modem,str);
! 496: putuserrec(p->cfg,p->user->number,U_MODEM,LEN_MODEM,str);
1.1 root 497: break;
1.1.1.2 ! root 498: case USER_PROP_ROWS:
! 499: p->user->rows=atoi(str);
! 500: putuserrec(p->cfg,p->user->number,U_ROWS,0,str); /* base 10 */
1.1 root 501: break;
502: case USER_PROP_SEX:
1.1.1.2 ! root 503: p->user->sex=toupper(str[0]);
! 504: putuserrec(p->cfg,p->user->number,U_SEX,0,strupr(str)); /* single char */
1.1 root 505: break;
506: case USER_PROP_CURSUB:
1.1.1.2 ! root 507: SAFECOPY(p->user->cursub,str);
! 508: putuserrec(p->cfg,p->user->number,U_CURSUB,0,str);
1.1 root 509: break;
510: case USER_PROP_CURDIR:
1.1.1.2 ! root 511: SAFECOPY(p->user->curdir,str);
! 512: putuserrec(p->cfg,p->user->number,U_CURDIR,0,str);
1.1 root 513: break;
514: case USER_PROP_CURXTRN:
1.1.1.2 ! root 515: SAFECOPY(p->user->curxtrn,str);
! 516: putuserrec(p->cfg,p->user->number,U_CURXTRN,0,str);
1.1 root 517: break;
518: case USER_PROP_XEDIT:
1.1.1.2 ! root 519: putuserrec(p->cfg,p->user->number,U_XEDIT,0,str);
1.1 root 520: break;
521: case USER_PROP_SHELL:
1.1.1.2 ! root 522: putuserrec(p->cfg,p->user->number,U_SHELL,0,str);
1.1 root 523: break;
524: case USER_PROP_MISC:
1.1.1.2 ! root 525: JS_RESUMEREQUEST(cx, rc);
1.1 root 526: if(JS_ValueToInt32(cx,*vp,&val))
1.1.1.2 ! root 527: putuserrec(p->cfg,p->user->number,U_MISC,0,ultoa(p->user->misc=val,tmp,16));
! 528: rc=JS_SUSPENDREQUEST(cx);
1.1 root 529: break;
530: case USER_PROP_QWK:
1.1.1.2 ! root 531: JS_RESUMEREQUEST(cx, rc);
1.1 root 532: if(JS_ValueToInt32(cx,*vp,&val))
1.1.1.2 ! root 533: putuserrec(p->cfg,p->user->number,U_QWK,0,ultoa(p->user->qwk=val,tmp,16));
! 534: rc=JS_SUSPENDREQUEST(cx);
1.1 root 535: break;
536: case USER_PROP_CHAT:
1.1.1.2 ! root 537: JS_RESUMEREQUEST(cx, rc);
1.1 root 538: if(JS_ValueToInt32(cx,*vp,&val))
1.1.1.2 ! root 539: putuserrec(p->cfg,p->user->number,U_CHAT,0,ultoa(p->user->chat=val,tmp,16));
! 540: rc=JS_SUSPENDREQUEST(cx);
1.1 root 541: break;
542: case USER_PROP_TMPEXT:
1.1.1.2 ! root 543: SAFECOPY(p->user->tmpext,str);
! 544: putuserrec(p->cfg,p->user->number,U_TMPEXT,0,str);
1.1 root 545: break;
546: case USER_PROP_NS_TIME:
1.1.1.2 ! root 547: JS_RESUMEREQUEST(cx, rc);
1.1 root 548: if(JS_ValueToInt32(cx,*vp,&val))
1.1.1.2 ! root 549: putuserrec(p->cfg,p->user->number,U_NS_TIME,0,ultoa(p->user->ns_time=val,tmp,16));
! 550: rc=JS_SUSPENDREQUEST(cx);
1.1 root 551: break;
552: case USER_PROP_PROT:
1.1.1.2 ! root 553: p->user->prot=toupper(str[0]);
! 554: putuserrec(p->cfg,p->user->number,U_PROT,0,strupr(str)); /* single char */
1.1 root 555: break;
556: case USER_PROP_LOGONTIME:
1.1.1.2 ! root 557: JS_RESUMEREQUEST(cx, rc);
1.1 root 558: if(JS_ValueToInt32(cx,*vp,&val))
1.1.1.2 ! root 559: putuserrec(p->cfg,p->user->number,U_LOGONTIME,0,ultoa(p->user->logontime=val,tmp,16));
! 560: rc=JS_SUSPENDREQUEST(cx);
1.1 root 561: break;
562:
563: /* security properties*/
564: case USER_PROP_PASS:
1.1.1.2 ! root 565: SAFECOPY(p->user->pass,str);
! 566: putuserrec(p->cfg,p->user->number,U_PASS,LEN_PASS,strupr(str));
1.1 root 567: break;
568: case USER_PROP_PWMOD:
1.1.1.2 ! root 569: JS_RESUMEREQUEST(cx, rc);
1.1 root 570: if(JS_ValueToInt32(cx,*vp,&val))
1.1.1.2 ! root 571: putuserrec(p->cfg,p->user->number,U_PWMOD,0,ultoa(p->user->pwmod=val,tmp,16));
! 572: rc=JS_SUSPENDREQUEST(cx);
1.1 root 573: break;
574: case USER_PROP_LEVEL:
1.1.1.2 ! root 575: p->user->level=atoi(str);
! 576: putuserrec(p->cfg,p->user->number,U_LEVEL,0,str);
1.1 root 577: break;
578: case USER_PROP_FLAGS1:
1.1.1.2 ! root 579: JS_RESUMEREQUEST(cx, rc);
1.1 root 580: if(JS_ValueToInt32(cx,*vp,&val))
1.1.1.2 ! root 581: putuserrec(p->cfg,p->user->number,U_FLAGS1,0,ultoa(p->user->flags1=val,tmp,16));
! 582: rc=JS_SUSPENDREQUEST(cx);
1.1 root 583: break;
584: case USER_PROP_FLAGS2:
1.1.1.2 ! root 585: JS_RESUMEREQUEST(cx, rc);
1.1 root 586: if(JS_ValueToInt32(cx,*vp,&val))
1.1.1.2 ! root 587: putuserrec(p->cfg,p->user->number,U_FLAGS2,0,ultoa(p->user->flags2=val,tmp,16));
! 588: rc=JS_SUSPENDREQUEST(cx);
1.1 root 589: break;
590: case USER_PROP_FLAGS3:
1.1.1.2 ! root 591: JS_RESUMEREQUEST(cx, rc);
1.1 root 592: if(JS_ValueToInt32(cx,*vp,&val))
1.1.1.2 ! root 593: putuserrec(p->cfg,p->user->number,U_FLAGS3,0,ultoa(p->user->flags3=val,tmp,16));
! 594: rc=JS_SUSPENDREQUEST(cx);
1.1 root 595: break;
596: case USER_PROP_FLAGS4:
1.1.1.2 ! root 597: JS_RESUMEREQUEST(cx, rc);
1.1 root 598: if(JS_ValueToInt32(cx,*vp,&val))
1.1.1.2 ! root 599: putuserrec(p->cfg,p->user->number,U_FLAGS4,0,ultoa(p->user->flags4=val,tmp,16));
! 600: rc=JS_SUSPENDREQUEST(cx);
1.1 root 601: break;
602: case USER_PROP_EXEMPT:
1.1.1.2 ! root 603: JS_RESUMEREQUEST(cx, rc);
1.1 root 604: if(JS_ValueToInt32(cx,*vp,&val))
1.1.1.2 ! root 605: putuserrec(p->cfg,p->user->number,U_EXEMPT,0,ultoa(p->user->exempt=val,tmp,16));
! 606: rc=JS_SUSPENDREQUEST(cx);
1.1 root 607: break;
608: case USER_PROP_REST:
1.1.1.2 ! root 609: JS_RESUMEREQUEST(cx, rc);
1.1 root 610: if(JS_ValueToInt32(cx,*vp,&val))
1.1.1.2 ! root 611: putuserrec(p->cfg,p->user->number,U_REST,0,ultoa(p->user->rest=val,tmp,16));
! 612: rc=JS_SUSPENDREQUEST(cx);
1.1 root 613: break;
614: case USER_PROP_CDT:
1.1.1.2 ! root 615: p->user->cdt=strtoul(str,NULL,0);
! 616: putuserrec(p->cfg,p->user->number,U_CDT,0,str);
1.1 root 617: break;
618: case USER_PROP_FREECDT:
1.1.1.2 ! root 619: p->user->freecdt=strtoul(str,NULL,0);
! 620: putuserrec(p->cfg,p->user->number,U_FREECDT,0,str);
1.1 root 621: break;
622: case USER_PROP_MIN:
1.1.1.2 ! root 623: p->user->min=strtoul(str,NULL,0);
! 624: putuserrec(p->cfg,p->user->number,U_MIN,0,str);
1.1 root 625: break;
626: case USER_PROP_TEXTRA:
1.1.1.2 ! root 627: p->user->textra=(ushort)strtoul(str,NULL,0);
! 628: putuserrec(p->cfg,p->user->number,U_TEXTRA,0,str);
1.1 root 629: break;
630: case USER_PROP_EXPIRE:
1.1.1.2 ! root 631: JS_RESUMEREQUEST(cx, rc);
1.1 root 632: if(JS_ValueToInt32(cx,*vp,&val))
1.1.1.2 ! root 633: putuserrec(p->cfg,p->user->number,U_EXPIRE,0,ultoa(p->user->expire=val,tmp,16));
! 634: rc=JS_SUSPENDREQUEST(cx);
1.1 root 635: break;
636:
637: case USER_PROP_CACHED:
638: JS_ValueToBoolean(cx, *vp, &p->cached);
1.1.1.2 ! root 639: JS_RESUMEREQUEST(cx, rc);
1.1 root 640: return(JS_TRUE); /* intentional early return */
641:
642: }
1.1.1.2 ! root 643: if(!(p->user->rest&FLAG('G')))
! 644: p->cached=FALSE;
1.1 root 645:
1.1.1.2 ! root 646: JS_RESUMEREQUEST(cx, rc);
1.1 root 647: return(JS_TRUE);
648: }
649:
650: #define USER_PROP_FLAGS JSPROP_ENUMERATE
651:
652: static jsSyncPropertySpec js_user_properties[] = {
653: /* name ,tinyid ,flags, ver */
654:
655: { "number" ,USER_PROP_NUMBER ,USER_PROP_FLAGS, 310},
656: { "alias" ,USER_PROP_ALIAS ,USER_PROP_FLAGS, 310},
657: { "name" ,USER_PROP_NAME ,USER_PROP_FLAGS, 310},
658: { "handle" ,USER_PROP_HANDLE ,USER_PROP_FLAGS, 310},
659: { "ip_address" ,USER_PROP_NOTE ,USER_PROP_FLAGS, 310},
660: { "note" ,USER_PROP_NOTE ,USER_PROP_FLAGS, 310},
661: { "host_name" ,USER_PROP_COMP ,USER_PROP_FLAGS, 310},
662: { "computer" ,USER_PROP_COMP ,USER_PROP_FLAGS, 310},
663: { "comment" ,USER_PROP_COMMENT ,USER_PROP_FLAGS, 310},
664: { "netmail" ,USER_PROP_NETMAIL ,USER_PROP_FLAGS, 310},
665: { "email" ,USER_PROP_EMAIL ,USER_PROP_FLAGS|JSPROP_READONLY, 310},
666: { "address" ,USER_PROP_ADDRESS ,USER_PROP_FLAGS, 310},
667: { "location" ,USER_PROP_LOCATION ,USER_PROP_FLAGS, 310},
668: { "zipcode" ,USER_PROP_ZIPCODE ,USER_PROP_FLAGS, 310},
669: { "phone" ,USER_PROP_PHONE ,USER_PROP_FLAGS, 310},
670: { "birthdate" ,USER_PROP_BIRTH ,USER_PROP_FLAGS, 310},
671: { "age" ,USER_PROP_AGE ,USER_PROP_FLAGS|JSPROP_READONLY, 310},
672: { "connection" ,USER_PROP_MODEM ,USER_PROP_FLAGS, 310},
673: { "modem" ,USER_PROP_MODEM ,USER_PROP_FLAGS, 310},
674: { "screen_rows" ,USER_PROP_ROWS ,USER_PROP_FLAGS, 310},
675: { "gender" ,USER_PROP_SEX ,USER_PROP_FLAGS, 310},
676: { "cursub" ,USER_PROP_CURSUB ,USER_PROP_FLAGS, 310},
677: { "curdir" ,USER_PROP_CURDIR ,USER_PROP_FLAGS, 310},
678: { "curxtrn" ,USER_PROP_CURXTRN ,USER_PROP_FLAGS, 310},
679: { "editor" ,USER_PROP_XEDIT ,USER_PROP_FLAGS, 310},
680: { "command_shell" ,USER_PROP_SHELL ,USER_PROP_FLAGS, 310},
681: { "settings" ,USER_PROP_MISC ,USER_PROP_FLAGS, 310},
682: { "qwk_settings" ,USER_PROP_QWK ,USER_PROP_FLAGS, 310},
683: { "chat_settings" ,USER_PROP_CHAT ,USER_PROP_FLAGS, 310},
684: { "temp_file_ext" ,USER_PROP_TMPEXT ,USER_PROP_FLAGS, 310},
685: { "new_file_time" ,USER_PROP_NS_TIME ,USER_PROP_FLAGS, 311},
686: { "newscan_date" ,USER_PROP_NS_TIME ,0, /* Alias */ 310},
687: { "download_protocol" ,USER_PROP_PROT ,USER_PROP_FLAGS, 310},
688: { "logontime" ,USER_PROP_LOGONTIME ,USER_PROP_FLAGS, 310},
689: { "cached" ,USER_PROP_CACHED ,USER_PROP_FLAGS, 314},
1.1.1.2 ! root 690: { "is_sysop" ,USER_PROP_IS_SYSOP ,JSPROP_ENUMERATE|JSPROP_READONLY, 315},
1.1 root 691: {0}
692: };
693:
694: #ifdef BUILD_JSDOCS
695: static char* user_prop_desc[] = {
696:
697: "record number (1-based)"
698: ,"alias/name"
699: ,"real name"
700: ,"chat handle"
701: ,"IP address last logged on from"
702: ,"AKA ip_address"
703: ,"host name last logged on from"
704: ,"AKA host_name"
705: ,"sysop's comment"
706: ,"external e-mail address"
707: ,"local Internet e-mail address - <small>READ ONLY</small>"
708: ,"street address"
709: ,"location (city, state)"
710: ,"zip/postal code"
711: ,"phone number"
712: ,"birth date"
713: ,"calculated age in years - <small>READ ONLY</small>"
714: ,"connection type"
715: ,"AKA connection"
716: ,"terminal rows (lines)"
717: ,"gender type"
1.1.1.2 ! root 718: ,"current/last message sub-board (internal code)"
! 719: ,"current/last file directory (internal code)"
! 720: ,"current/last external program (internal code) run"
! 721: ,"external message editor (internal code) or <i>blank</i> if none"
! 722: ,"command shell (internal code)"
1.1 root 723: ,"settings bitfield - see <tt>USER_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions"
724: ,"QWK packet settings bitfield - see <tt>QWK_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions"
725: ,"chat settings bitfield - see <tt>CHAT_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions"
726: ,"temporary file type (extension)"
727: ,"new file scan date/time (time_t format)"
728: ,"file transfer protocol (command key)"
729: ,"logon time (time_t format)"
730: ,"record is currently cached in memory"
1.1.1.2 ! root 731: ,"user has a System Operator's security level"
1.1 root 732: ,NULL
733: };
734: #endif
735:
736:
737: /* user.security */
738: static jsSyncPropertySpec js_user_security_properties[] = {
739: /* name ,tinyid ,flags, ver */
740:
741: { "password" ,USER_PROP_PASS ,USER_PROP_FLAGS, 310 },
742: { "password_date" ,USER_PROP_PWMOD ,USER_PROP_FLAGS, 310 },
743: { "level" ,USER_PROP_LEVEL ,USER_PROP_FLAGS, 310 },
744: { "flags1" ,USER_PROP_FLAGS1 ,USER_PROP_FLAGS, 310 },
745: { "flags2" ,USER_PROP_FLAGS2 ,USER_PROP_FLAGS, 310 },
746: { "flags3" ,USER_PROP_FLAGS3 ,USER_PROP_FLAGS, 310 },
747: { "flags4" ,USER_PROP_FLAGS4 ,USER_PROP_FLAGS, 310 },
748: { "exemptions" ,USER_PROP_EXEMPT ,USER_PROP_FLAGS, 310 },
749: { "restrictions" ,USER_PROP_REST ,USER_PROP_FLAGS, 310 },
750: { "credits" ,USER_PROP_CDT ,USER_PROP_FLAGS, 310 },
751: { "free_credits" ,USER_PROP_FREECDT ,USER_PROP_FLAGS, 310 },
752: { "minutes" ,USER_PROP_MIN ,USER_PROP_FLAGS, 310 },
753: { "extra_time" ,USER_PROP_TEXTRA ,USER_PROP_FLAGS, 310 },
754: { "expiration_date" ,USER_PROP_EXPIRE ,USER_PROP_FLAGS, 310 },
755: {0}
756: };
757:
758: #ifdef BUILD_JSDOCS
759: static char* user_security_prop_desc[] = {
760:
761: "password"
762: ,"date password last modified (time_t format)"
763: ,"security level (0-99)"
764: ,"flag set #1 (bitfield)"
765: ,"flag set #2 (bitfield)"
766: ,"flag set #3 (bitfield)"
767: ,"flag set #4 (bitfield)"
768: ,"exemption flags (bitfield)"
769: ,"restriction flags (bitfield)"
770: ,"credits"
771: ,"free credits (for today only)"
772: ,"extra minutes (time bank)"
773: ,"extra minutes (for today only)"
774: ,"expiration date/time (time_t format)"
775: ,NULL
776: };
777: #endif
778:
779: #undef USER_PROP_FLAGS
780: #define USER_PROP_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY
781:
782: /* user.limits: These should be READ ONLY by nature */
783: static jsSyncPropertySpec js_user_limits_properties[] = {
784: /* name ,tinyid ,flags, ver */
785:
786: { "time_per_logon" ,USER_PROP_TIMEPERCALL ,USER_PROP_FLAGS, 311 },
787: { "time_per_day" ,USER_PROP_TIMEPERDAY ,USER_PROP_FLAGS, 311 },
788: { "logons_per_day" ,USER_PROP_CALLSPERDAY ,USER_PROP_FLAGS, 311 },
789: { "lines_per_message" ,USER_PROP_LINESPERMSG ,USER_PROP_FLAGS, 311 },
790: { "email_per_day" ,USER_PROP_EMAILPERDAY ,USER_PROP_FLAGS, 311 },
791: { "posts_per_day" ,USER_PROP_POSTSPERDAY ,USER_PROP_FLAGS, 311 },
792: { "free_credits_per_day" ,USER_PROP_FREECDTPERDAY,USER_PROP_FLAGS, 311 },
793: {0}
794: };
795:
796:
797: #ifdef BUILD_JSDOCS
798: static char* user_limits_prop_desc[] = {
799:
800: "time (in minutes) per logon"
801: ,"time (in minutes) per day"
802: ,"logons per day"
803: ,"lines per message (post or email)"
804: ,"email sent per day"
805: ,"messages posted per day"
806: ,"free credits given per day"
807: ,NULL
808: };
809: #endif
810:
811:
812: #undef USER_PROP_FLAGS
813: #define USER_PROP_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY
814:
815: /* user.stats: These should be READ ONLY by nature */
816: static jsSyncPropertySpec js_user_stats_properties[] = {
817: /* name ,tinyid ,flags, ver */
818:
819: { "laston_date" ,USER_PROP_LASTON ,USER_PROP_FLAGS, 310 },
820: { "firston_date" ,USER_PROP_FIRSTON ,USER_PROP_FLAGS, 310 },
821: { "total_logons" ,USER_PROP_LOGONS ,USER_PROP_FLAGS, 310 },
822: { "logons_today" ,USER_PROP_LTODAY ,USER_PROP_FLAGS, 310 },
823: { "total_timeon" ,USER_PROP_TIMEON ,USER_PROP_FLAGS, 310 },
824: { "timeon_today" ,USER_PROP_TTODAY ,USER_PROP_FLAGS, 310 },
825: { "timeon_last_logon" ,USER_PROP_TLAST ,USER_PROP_FLAGS, 310 },
826: { "total_posts" ,USER_PROP_POSTS ,USER_PROP_FLAGS, 310 },
827: { "total_emails" ,USER_PROP_EMAILS ,USER_PROP_FLAGS, 310 },
828: { "total_feedbacks" ,USER_PROP_FBACKS ,USER_PROP_FLAGS, 310 },
829: { "email_today" ,USER_PROP_ETODAY ,USER_PROP_FLAGS, 310 },
830: { "posts_today" ,USER_PROP_PTODAY ,USER_PROP_FLAGS, 310 },
831: { "bytes_uploaded" ,USER_PROP_ULB ,USER_PROP_FLAGS, 310 },
832: { "files_uploaded" ,USER_PROP_ULS ,USER_PROP_FLAGS, 310 },
833: { "bytes_downloaded" ,USER_PROP_DLB ,USER_PROP_FLAGS, 310 },
834: { "files_downloaded" ,USER_PROP_DLS ,USER_PROP_FLAGS, 310 },
835: { "leech_attempts" ,USER_PROP_LEECH ,USER_PROP_FLAGS, 310 },
836: { "mail_waiting" ,USER_PROP_MAIL_WAITING ,USER_PROP_FLAGS, 312 },
837: { "mail_pending" ,USER_PROP_MAIL_PENDING ,USER_PROP_FLAGS, 312 },
838: {0}
839: };
840:
841: #ifdef BUILD_JSDOCS
842: static char* user_stats_prop_desc[] = {
843:
1.1.1.2 ! root 844: "date of previous logon (time_t format)"
! 845: ,"date of first logon (time_t format)"
1.1 root 846: ,"total number of logons"
847: ,"total logons today"
848: ,"total time used (in minutes)"
849: ,"time used today"
850: ,"time used last session"
851: ,"total messages posted"
852: ,"total e-mails sent"
853: ,"total feedback messages sent"
854: ,"e-mail sent today"
855: ,"messages posted today"
856: ,"total bytes uploaded"
857: ,"total files uploaded"
858: ,"total bytes downloaded"
859: ,"total files downloaded"
860: ,"suspected leech downloads"
861: ,"number of e-mail messages currently waiting"
862: ,"number of e-mail messages sent, currently pending deletion"
863: ,NULL
864: };
865: #endif
866:
867:
868: static void js_user_finalize(JSContext *cx, JSObject *obj)
869: {
870: private_t* p;
871:
872: p=(private_t*)JS_GetPrivate(cx,obj);
873:
874: if(p!=NULL && (scfg_t*)p!=scfg)
875: free(p);
876:
877: p=NULL;
878: JS_SetPrivate(cx,obj,p);
879: }
880:
881: static JSBool
882: js_chk_ar(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
883: {
884: uchar* ar;
885: JSString* js_str;
886: private_t* p;
1.1.1.2 ! root 887: jsrefcount rc;
1.1 root 888:
889: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
890: return JS_FALSE;
891:
892: if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
893: return JS_FALSE;
894:
1.1.1.2 ! root 895: rc=JS_SUSPENDREQUEST(cx);
1.1 root 896: ar = arstr(NULL,JS_GetStringBytes(js_str),p->cfg);
897:
898: js_getuserdat(p);
899:
1.1.1.2 ! root 900: *rval = BOOLEAN_TO_JSVAL(chk_ar(p->cfg,ar,p->user,p->client));
1.1 root 901:
902: if(ar!=NULL && ar!=nular)
903: free(ar);
1.1.1.2 ! root 904: JS_RESUMEREQUEST(cx, rc);
1.1 root 905:
906: return JS_TRUE;
907: }
908:
909: static JSBool
910: js_posted_msg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
911: {
912: private_t* p;
913: int32 count=1;
1.1.1.2 ! root 914: jsrefcount rc;
1.1 root 915:
916: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
917: return JS_FALSE;
918:
919: if(argc)
920: JS_ValueToInt32(cx, argv[0], &count);
921:
1.1.1.2 ! root 922: rc=JS_SUSPENDREQUEST(cx);
1.1 root 923: js_getuserdat(p);
924:
1.1.1.2 ! root 925: *rval = BOOLEAN_TO_JSVAL(user_posted_msg(p->cfg, p->user, count));
! 926: JS_RESUMEREQUEST(cx, rc);
1.1 root 927:
928: return JS_TRUE;
929: }
930:
931: static JSBool
932: js_sent_email(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
933: {
934: private_t* p;
935: int32 count=1;
936: BOOL feedback=FALSE;
1.1.1.2 ! root 937: jsrefcount rc;
1.1 root 938:
939: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
940: return JS_FALSE;
941:
942: if(argc)
943: JS_ValueToInt32(cx, argv[0], &count);
944: if(argc>1)
945: JS_ValueToBoolean(cx, argv[1], &feedback);
946:
1.1.1.2 ! root 947: rc=JS_SUSPENDREQUEST(cx);
1.1 root 948: js_getuserdat(p);
949:
1.1.1.2 ! root 950: *rval = BOOLEAN_TO_JSVAL(user_sent_email(p->cfg, p->user, count, feedback));
! 951: JS_RESUMEREQUEST(cx, rc);
1.1 root 952:
953: return JS_TRUE;
954: }
955:
956: static JSBool
957: js_downloaded_file(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
958: {
959: private_t* p;
960: int32 files=1;
961: int32 bytes=0;
1.1.1.2 ! root 962: jsrefcount rc;
1.1 root 963:
964: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
965: return JS_FALSE;
966:
967: if(argc)
968: JS_ValueToInt32(cx, argv[0], &bytes);
969: if(argc>1)
970: JS_ValueToInt32(cx, argv[1], &files);
971:
1.1.1.2 ! root 972: rc=JS_SUSPENDREQUEST(cx);
1.1 root 973: js_getuserdat(p);
974:
1.1.1.2 ! root 975: *rval = BOOLEAN_TO_JSVAL(user_downloaded(p->cfg, p->user, files, bytes));
! 976: JS_RESUMEREQUEST(cx, rc);
1.1 root 977:
978: return JS_TRUE;
979: }
980:
981: static JSBool
982: js_uploaded_file(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
983: {
984: private_t* p;
985: int32 files=1;
986: int32 bytes=0;
1.1.1.2 ! root 987: jsrefcount rc;
1.1 root 988:
989: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
990: return JS_FALSE;
991:
992: if(argc)
993: JS_ValueToInt32(cx, argv[0], &bytes);
994: if(argc>1)
995: JS_ValueToInt32(cx, argv[1], &files);
996:
1.1.1.2 ! root 997: rc=JS_SUSPENDREQUEST(cx);
1.1 root 998: js_getuserdat(p);
999:
1.1.1.2 ! root 1000: *rval = BOOLEAN_TO_JSVAL(user_uploaded(p->cfg, p->user, files, bytes));
! 1001: JS_RESUMEREQUEST(cx, rc);
1.1 root 1002:
1003: return JS_TRUE;
1004: }
1005:
1006: static JSBool
1007: js_adjust_credits(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1008: {
1009: private_t* p;
1010: int32 count=0;
1.1.1.2 ! root 1011: jsrefcount rc;
1.1 root 1012:
1013: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
1014: return JS_FALSE;
1015:
1016: if(argc)
1017: JS_ValueToInt32(cx, argv[0], &count);
1018:
1.1.1.2 ! root 1019: rc=JS_SUSPENDREQUEST(cx);
1.1 root 1020: js_getuserdat(p);
1021:
1.1.1.2 ! root 1022: *rval = BOOLEAN_TO_JSVAL(user_adjust_credits(p->cfg, p->user, count));
! 1023: JS_RESUMEREQUEST(cx, rc);
1.1 root 1024:
1025: return JS_TRUE;
1026: }
1027:
1028: static JSBool
1029: js_adjust_minutes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1030: {
1031: private_t* p;
1032: int32 count=0;
1.1.1.2 ! root 1033: jsrefcount rc;
1.1 root 1034:
1035: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
1036: return JS_FALSE;
1037:
1038: if(argc)
1039: JS_ValueToInt32(cx, argv[0], &count);
1040:
1.1.1.2 ! root 1041: rc=JS_SUSPENDREQUEST(cx);
! 1042: js_getuserdat(p);
! 1043:
! 1044: *rval = BOOLEAN_TO_JSVAL(user_adjust_minutes(p->cfg, p->user, count));
! 1045: JS_RESUMEREQUEST(cx, rc);
! 1046:
! 1047: return JS_TRUE;
! 1048: }
! 1049:
! 1050: static JSBool
! 1051: js_get_time_left(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
! 1052: {
! 1053: private_t* p;
! 1054: int32 start_time=0;
! 1055: jsrefcount rc;
! 1056:
! 1057: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
! 1058: return JS_FALSE;
! 1059:
! 1060: if(argc)
! 1061: JS_ValueToInt32(cx, argv[0], &start_time);
! 1062:
! 1063: rc=JS_SUSPENDREQUEST(cx);
1.1 root 1064: js_getuserdat(p);
1065:
1.1.1.2 ! root 1066: *rval = INT_TO_JSVAL(gettimeleft(p->cfg, p->user, (time_t)start_time));
! 1067: JS_RESUMEREQUEST(cx, rc);
1.1 root 1068:
1069: return JS_TRUE;
1070: }
1071:
1.1.1.2 ! root 1072:
1.1 root 1073: static jsSyncMethodSpec js_user_functions[] = {
1074: {"compare_ars", js_chk_ar, 1, JSTYPE_BOOLEAN, JSDOCSTR("string ars")
1075: ,JSDOCSTR("Verify user meets access requirements string")
1076: ,310
1077: },
1078: {"adjust_credits", js_adjust_credits, 1, JSTYPE_BOOLEAN, JSDOCSTR("count")
1079: ,JSDOCSTR("Adjust user's credits by <i>count</i> (negative to subtract)")
1080: ,314
1081: },
1082: {"adjust_minutes", js_adjust_minutes, 1, JSTYPE_BOOLEAN, JSDOCSTR("count")
1083: ,JSDOCSTR("Adjust user's extra minutes <i>count</i> (negative to subtract)")
1084: ,314
1085: },
1086: {"posted_message", js_posted_msg, 1, JSTYPE_BOOLEAN, JSDOCSTR("[count]")
1087: ,JSDOCSTR("Adjust user's posted-messages statistics by <i>count</i> (default: 1) (negative to subtract)")
1088: ,314
1089: },
1090: {"sent_email", js_sent_email, 1, JSTYPE_BOOLEAN, JSDOCSTR("[count] [,bool feedback]")
1091: ,JSDOCSTR("Adjust user's email/feedback-sent statistics by <i>count</i> (default: 1) (negative to subtract)")
1092: ,314
1093: },
1094: {"uploaded_file", js_uploaded_file, 1, JSTYPE_BOOLEAN, JSDOCSTR("[bytes] [,files]")
1095: ,JSDOCSTR("Adjust user's files/bytes-uploaded statistics")
1096: ,314
1097: },
1098: {"downloaded_file", js_downloaded_file, 1, JSTYPE_BOOLEAN, JSDOCSTR("[bytes] [,files]")
1099: ,JSDOCSTR("Adjust user's files/bytes-downloaded statistics")
1100: ,314
1.1.1.2 ! root 1101: },
! 1102: {"get_time_left", js_get_time_left, 1, JSTYPE_NUMBER, JSDOCSTR("start_time")
! 1103: ,JSDOCSTR("Returns the user's available remaining time online, in seconds,<br>"
! 1104: "based on the passed <i>start_time</i> value (in time_t format)<br>"
! 1105: "Note: this method does not account for pending forced timed events")
! 1106: ,31401
! 1107: },
1.1 root 1108: {0}
1109: };
1110:
1.1.1.2 ! root 1111: static JSBool js_user_stats_resolve(JSContext *cx, JSObject *obj, jsval id)
! 1112: {
! 1113: char* name=NULL;
! 1114:
! 1115: if(id != JSVAL_NULL)
! 1116: name=JS_GetStringBytes(JSVAL_TO_STRING(id));
! 1117:
! 1118: return(js_SyncResolve(cx, obj, name, js_user_stats_properties, NULL, NULL, 0));
! 1119: }
! 1120:
! 1121: static JSBool js_user_stats_enumerate(JSContext *cx, JSObject *obj)
! 1122: {
! 1123: return(js_user_stats_resolve(cx, obj, JSVAL_NULL));
! 1124: }
! 1125:
! 1126: static JSBool js_user_security_resolve(JSContext *cx, JSObject *obj, jsval id)
! 1127: {
! 1128: char* name=NULL;
! 1129:
! 1130: if(id != JSVAL_NULL)
! 1131: name=JS_GetStringBytes(JSVAL_TO_STRING(id));
! 1132:
! 1133: return(js_SyncResolve(cx, obj, name, js_user_security_properties, NULL, NULL, 0));
! 1134: }
! 1135:
! 1136: static JSBool js_user_security_enumerate(JSContext *cx, JSObject *obj)
! 1137: {
! 1138: return(js_user_security_resolve(cx, obj, JSVAL_NULL));
! 1139: }
! 1140:
! 1141: static JSBool js_user_limits_resolve(JSContext *cx, JSObject *obj, jsval id)
! 1142: {
! 1143: char* name=NULL;
! 1144:
! 1145: if(id != JSVAL_NULL)
! 1146: name=JS_GetStringBytes(JSVAL_TO_STRING(id));
! 1147:
! 1148: return(js_SyncResolve(cx, obj, name, js_user_limits_properties, NULL, NULL, 0));
! 1149: }
! 1150:
! 1151: static JSBool js_user_limits_enumerate(JSContext *cx, JSObject *obj)
! 1152: {
! 1153: return(js_user_limits_resolve(cx, obj, JSVAL_NULL));
! 1154: }
1.1 root 1155:
1156: static JSClass js_user_stats_class = {
1157: "UserStats" /* name */
1158: ,JSCLASS_HAS_PRIVATE /* flags */
1159: ,JS_PropertyStub /* addProperty */
1160: ,JS_PropertyStub /* delProperty */
1161: ,js_user_get /* getProperty */
1162: ,js_user_set /* setProperty */
1.1.1.2 ! root 1163: ,js_user_stats_enumerate /* enumerate */
! 1164: ,js_user_stats_resolve /* resolve */
1.1 root 1165: ,JS_ConvertStub /* convert */
1166: ,JS_FinalizeStub /* finalize */
1167: };
1168:
1169: static JSClass js_user_security_class = {
1170: "UserSecurity" /* name */
1171: ,JSCLASS_HAS_PRIVATE /* flags */
1172: ,JS_PropertyStub /* addProperty */
1173: ,JS_PropertyStub /* delProperty */
1174: ,js_user_get /* getProperty */
1175: ,js_user_set /* setProperty */
1.1.1.2 ! root 1176: ,js_user_security_enumerate /* enumerate */
! 1177: ,js_user_security_resolve /* resolve */
1.1 root 1178: ,JS_ConvertStub /* convert */
1179: ,JS_FinalizeStub /* finalize */
1180: };
1181:
1182: static JSClass js_user_limits_class = {
1183: "UserLimits" /* name */
1184: ,JSCLASS_HAS_PRIVATE /* flags */
1185: ,JS_PropertyStub /* addProperty */
1186: ,JS_PropertyStub /* delProperty */
1187: ,js_user_get /* getProperty */
1188: ,js_user_set /* setProperty */
1.1.1.2 ! root 1189: ,js_user_limits_enumerate /* enumerate */
! 1190: ,js_user_limits_resolve /* resolve */
1.1 root 1191: ,JS_ConvertStub /* convert */
1192: ,JS_FinalizeStub /* finalize */
1193: };
1194:
1.1.1.2 ! root 1195: static JSBool js_user_resolve(JSContext *cx, JSObject *obj, jsval id)
! 1196: {
! 1197: char* name=NULL;
! 1198: JSObject* newobj;
! 1199: private_t* p;
! 1200:
! 1201: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
! 1202: return(JS_TRUE);
! 1203:
! 1204: if(id != JSVAL_NULL)
! 1205: name=JS_GetStringBytes(JSVAL_TO_STRING(id));
! 1206:
! 1207: if(name==NULL || strcmp(name, "stats")==0) {
! 1208: /* user.stats */
! 1209: if((newobj=JS_DefineObject(cx, obj, "stats"
! 1210: ,&js_user_stats_class, NULL, JSPROP_ENUMERATE|JSPROP_READONLY))==NULL)
! 1211: return(JS_FALSE);
! 1212: JS_SetPrivate(cx, newobj, p);
! 1213: #ifdef BUILD_JSDOCS
! 1214: js_DescribeSyncObject(cx,newobj,"User statistics (all <small>READ ONLY</small>)",310);
! 1215: js_CreateArrayOfStrings(cx, newobj, "_property_desc_list", user_stats_prop_desc, JSPROP_READONLY);
! 1216: #endif
! 1217: if(name)
! 1218: return(JS_TRUE);
! 1219:
! 1220: }
! 1221:
! 1222: if(name==NULL || strcmp(name, "security")==0) {
! 1223: /* user.security */
! 1224: if((newobj=JS_DefineObject(cx, obj, "security"
! 1225: ,&js_user_security_class, NULL, JSPROP_ENUMERATE|JSPROP_READONLY))==NULL)
! 1226: return(JS_FALSE);
! 1227: JS_SetPrivate(cx, newobj, p);
! 1228: #ifdef BUILD_JSDOCS
! 1229: js_DescribeSyncObject(cx,newobj,"User limitations based on security level (all <small>READ ONLY</small>)",311);
! 1230: js_CreateArrayOfStrings(cx, newobj, "_property_desc_list", user_limits_prop_desc, JSPROP_READONLY);
! 1231: #endif
! 1232: if(name)
! 1233: return(JS_TRUE);
! 1234: }
! 1235:
! 1236: if(name==NULL || strcmp(name, "limits")==0) {
! 1237: /* user.limits */
! 1238: if((newobj=JS_DefineObject(cx, obj, "limits"
! 1239: ,&js_user_limits_class, NULL, JSPROP_ENUMERATE|JSPROP_READONLY))==NULL)
! 1240: return(JS_FALSE);
! 1241: JS_SetPrivate(cx, newobj, p);
! 1242: #ifdef BUILD_JSDOCS
! 1243: js_DescribeSyncObject(cx,newobj,"User security settings",310);
! 1244: js_CreateArrayOfStrings(cx, newobj, "_property_desc_list", user_security_prop_desc, JSPROP_READONLY);
! 1245: #endif
! 1246: if(name)
! 1247: return(JS_TRUE);
! 1248: }
! 1249:
! 1250: return(js_SyncResolve(cx, obj, name, js_user_properties, js_user_functions, NULL, 0));
! 1251: }
! 1252:
! 1253: static JSBool js_user_enumerate(JSContext *cx, JSObject *obj)
! 1254: {
! 1255: return(js_user_resolve(cx, obj, JSVAL_NULL));
! 1256: }
! 1257:
! 1258: static JSClass js_user_class = {
! 1259: "User" /* name */
! 1260: ,JSCLASS_HAS_PRIVATE /* flags */
! 1261: ,JS_PropertyStub /* addProperty */
! 1262: ,JS_PropertyStub /* delProperty */
! 1263: ,js_user_get /* getProperty */
! 1264: ,js_user_set /* setProperty */
! 1265: ,js_user_enumerate /* enumerate */
! 1266: ,js_user_resolve /* resolve */
! 1267: ,JS_ConvertStub /* convert */
! 1268: ,js_user_finalize /* finalize */
! 1269: };
! 1270:
1.1 root 1271: /* User Constructor (creates instance of user class) */
1272:
1273: static JSBool
1274: js_user_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1275: {
1276: int i;
1277: int32 val=0;
1278: user_t user;
1279: private_t* p;
1280:
1281: JS_ValueToInt32(cx,argv[0],&val);
1282: user.number=(ushort)val;
1283: if(user.number!=0 && (i=getuserdat(scfg,&user))!=0) {
1284: JS_ReportError(cx,"Error %d reading user number %d",i,val);
1285: return(JS_FALSE);
1286: }
1287:
1288: if((p=(private_t*)malloc(sizeof(private_t)))==NULL)
1289: return(JS_FALSE);
1290:
1.1.1.2 ! root 1291: memset(p,0,sizeof(private_t));
! 1292:
1.1 root 1293: p->cfg = scfg;
1.1.1.2 ! root 1294: p->storage = user;
! 1295: p->user = &p->storage;
1.1 root 1296: p->cached = (user.number==0 ? FALSE : TRUE);
1297:
1.1.1.2 ! root 1298: JS_SetPrivate(cx, obj, p);
1.1 root 1299:
1300: return(JS_TRUE);
1301: }
1302:
1303: JSObject* DLLCALL js_CreateUserClass(JSContext* cx, JSObject* parent, scfg_t* cfg)
1304: {
1305: JSObject* userclass;
1306:
1307: scfg = cfg;
1308: userclass = JS_InitClass(cx, parent, NULL
1309: ,&js_user_class
1310: ,js_user_constructor
1311: ,1 /* number of constructor args */
1312: ,NULL /* props, defined in constructor */
1313: ,NULL /* funcs, defined in constructor */
1314: ,NULL,NULL);
1315:
1316: return(userclass);
1317: }
1318:
1319: JSObject* DLLCALL js_CreateUserObject(JSContext* cx, JSObject* parent, scfg_t* cfg, char* name
1.1.1.2 ! root 1320: ,user_t* user, client_t* client, BOOL global_user)
1.1 root 1321: {
1322: JSObject* userobj;
1323: private_t* p;
1324: jsval val;
1325:
1326: if(name==NULL)
1327: userobj = JS_NewObject(cx, &js_user_class, NULL, parent);
1328: else if(JS_GetProperty(cx,parent,name,&val) && val!=JSVAL_VOID)
1329: userobj = JSVAL_TO_OBJECT(val); /* Return existing user object */
1330: else
1331: userobj = JS_DefineObject(cx, parent, name, &js_user_class
1332: , NULL, JSPROP_ENUMERATE|JSPROP_READONLY);
1333: if(userobj==NULL)
1334: return(NULL);
1335:
1336: if((p=JS_GetPrivate(cx, userobj)) == NULL) /* Uses existing private pointer: Fix memory leak? */
1337: if((p=(private_t*)malloc(sizeof(private_t)))==NULL)
1338: return(NULL);
1339:
1.1.1.2 ! root 1340: memset(p,0,sizeof(private_t));
! 1341:
1.1 root 1342: p->cfg = cfg;
1.1.1.2 ! root 1343: p->client = client;
1.1 root 1344: p->cached = FALSE;
1.1.1.2 ! root 1345: p->user = &p->storage;
! 1346: if(user!=NULL) {
! 1347: p->storage = *user;
! 1348: if(global_user)
! 1349: p->user = user;
! 1350: }
1.1 root 1351:
1352: JS_SetPrivate(cx, userobj, p);
1353:
1354: #ifdef BUILD_JSDOCS
1355: js_DescribeSyncObject(cx,userobj
1356: ,"Instance of <i>User</i> class, representing current user online"
1357: ,310);
1358: js_DescribeSyncConstructor(cx,userobj
1359: ,"To create a new user object: <tt>var u = new User(<i>number</i>)</tt>");
1360: js_CreateArrayOfStrings(cx, userobj
1361: ,"_property_desc_list", user_prop_desc, JSPROP_READONLY);
1362: #endif
1363:
1364: return(userobj);
1365: }
1366:
1367: /****************************************************************************/
1368: /* Creates all the user-specific objects: user, msg_area, file_area */
1369: /****************************************************************************/
1370: JSBool DLLCALL
1.1.1.2 ! root 1371: js_CreateUserObjects(JSContext* cx, JSObject* parent, scfg_t* cfg, user_t* user, client_t* client
1.1 root 1372: ,char* html_index_file, subscan_t* subscan)
1373: {
1.1.1.2 ! root 1374: if(js_CreateUserObject(cx,parent,cfg,"user",user,client,/* global_user */TRUE)==NULL)
1.1 root 1375: return(JS_FALSE);
1.1.1.2 ! root 1376: if(js_CreateFileAreaObject(cx,parent,cfg,user,client,html_index_file)==NULL)
1.1 root 1377: return(JS_FALSE);
1.1.1.2 ! root 1378: if(js_CreateMsgAreaObject(cx,parent,cfg,user,client,subscan)==NULL)
1.1 root 1379: return(JS_FALSE);
1.1.1.2 ! root 1380: if(js_CreateXtrnAreaObject(cx,parent,cfg,user,client)==NULL)
1.1 root 1381: return(JS_FALSE);
1382:
1383: return(JS_TRUE);
1384: }
1385:
1386: #endif /* JAVSCRIPT */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.