|
|
1.1 root 1: /* js_user.c */
2:
3: /* Synchronet JavaScript "User" Object */
4:
5: /* $Id: js_user.c,v 1.55 2004/12/30 10:59:16 rswindell Exp $ */
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: * *
11: * Copyright 2003 Rob Swindell - http://www.synchro.net/copyright.html *
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"
39:
40: #ifdef JAVASCRIPT
41:
42: static scfg_t* scfg=NULL;
43:
44: static const char* getprivate_failure = "line %d %s JS_GetPrivate failed";
45:
46: typedef struct
47: {
48: uint usernumber;
49: scfg_t* cfg;
50:
51: } private_t;
52:
53: /* User Object Properites */
54: enum {
55: USER_PROP_NUMBER
56: ,USER_PROP_ALIAS
57: ,USER_PROP_NAME
58: ,USER_PROP_HANDLE
59: ,USER_PROP_NOTE
60: ,USER_PROP_COMP
61: ,USER_PROP_COMMENT
62: ,USER_PROP_NETMAIL
63: ,USER_PROP_EMAIL /* READ ONLY */
64: ,USER_PROP_ADDRESS
65: ,USER_PROP_LOCATION
66: ,USER_PROP_ZIPCODE
67: ,USER_PROP_PASS
68: ,USER_PROP_PHONE
69: ,USER_PROP_BIRTH
70: ,USER_PROP_AGE /* READ ONLY */
71: ,USER_PROP_MODEM
72: ,USER_PROP_LASTON
73: ,USER_PROP_FIRSTON
74: ,USER_PROP_EXPIRE
75: ,USER_PROP_PWMOD
76: ,USER_PROP_LOGONS
77: ,USER_PROP_LTODAY
78: ,USER_PROP_TIMEON
79: ,USER_PROP_TEXTRA
80: ,USER_PROP_TTODAY
81: ,USER_PROP_TLAST
82: ,USER_PROP_POSTS
83: ,USER_PROP_EMAILS
84: ,USER_PROP_FBACKS
85: ,USER_PROP_ETODAY
86: ,USER_PROP_PTODAY
87: ,USER_PROP_MAIL_WAITING
88: ,USER_PROP_MAIL_PENDING
89: ,USER_PROP_ULB
90: ,USER_PROP_ULS
91: ,USER_PROP_DLB
92: ,USER_PROP_DLS
93: ,USER_PROP_CDT
94: ,USER_PROP_MIN
95: ,USER_PROP_LEVEL
96: ,USER_PROP_FLAGS1
97: ,USER_PROP_FLAGS2
98: ,USER_PROP_FLAGS3
99: ,USER_PROP_FLAGS4
100: ,USER_PROP_EXEMPT
101: ,USER_PROP_REST
102: ,USER_PROP_ROWS
103: ,USER_PROP_SEX
104: ,USER_PROP_MISC
105: ,USER_PROP_LEECH
106: ,USER_PROP_CURSUB
107: ,USER_PROP_CURDIR
108: ,USER_PROP_CURXTRN
109: ,USER_PROP_FREECDT
110: ,USER_PROP_XEDIT
111: ,USER_PROP_SHELL
112: ,USER_PROP_QWK
113: ,USER_PROP_TMPEXT
114: ,USER_PROP_CHAT
115: ,USER_PROP_NS_TIME
116: ,USER_PROP_PROT
117: ,USER_PROP_LOGONTIME
118: ,USER_PROP_TIMEPERCALL
119: ,USER_PROP_TIMEPERDAY
120: ,USER_PROP_CALLSPERDAY
121: ,USER_PROP_LINESPERMSG
122: ,USER_PROP_EMAILPERDAY
123: ,USER_PROP_POSTSPERDAY
124: ,USER_PROP_FREECDTPERDAY
125: };
126:
127:
128: static JSBool js_user_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
129: {
130: char* s=NULL;
131: char tmp[128];
132: ulong val=0;
133: jsint tiny;
134: JSString* js_str;
135: user_t user;
136: private_t* p;
137:
138: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
139: JS_ReportError(cx,getprivate_failure,WHERE);
140: return(JS_FALSE);
141: }
142:
143: user.number=p->usernumber;
144: getuserdat(p->cfg,&user);
145:
146: tiny = JSVAL_TO_INT(id);
147:
148: switch(tiny) {
149: case USER_PROP_NUMBER:
150: val=user.number;
151: break;
152: case USER_PROP_ALIAS:
153: s=user.alias;
154: break;
155: case USER_PROP_NAME:
156: s=user.name;
157: break;
158: case USER_PROP_HANDLE:
159: s=user.handle;
160: break;
161: case USER_PROP_NOTE:
162: s=user.note;
163: break;
164: case USER_PROP_COMP:
165: s=user.comp;
166: break;
167: case USER_PROP_COMMENT:
168: s=user.comment;
169: break;
170: case USER_PROP_NETMAIL:
171: s=user.netmail;
172: break;
173: case USER_PROP_EMAIL:
174: s=usermailaddr(p->cfg, tmp
175: ,p->cfg->inetmail_misc&NMAIL_ALIAS ? user.alias : user.name);
176: break;
177: case USER_PROP_ADDRESS:
178: s=user.address;
179: break;
180: case USER_PROP_LOCATION:
181: s=user.location;
182: break;
183: case USER_PROP_ZIPCODE:
184: s=user.zipcode;
185: break;
186: case USER_PROP_PASS:
187: s=user.pass;
188: break;
189: case USER_PROP_PHONE:
190: s=user.phone;
191: break;
192: case USER_PROP_BIRTH:
193: s=user.birth;
194: break;
195: case USER_PROP_AGE:
196: val=getage(p->cfg,user.birth);
197: break;
198: case USER_PROP_MODEM:
199: s=user.modem;
200: break;
201: case USER_PROP_LASTON:
202: val=user.laston;
203: break;
204: case USER_PROP_FIRSTON:
205: val=user.firston;
206: break;
207: case USER_PROP_EXPIRE:
208: val=user.expire;
209: break;
210: case USER_PROP_PWMOD:
211: val=user.pwmod;
212: break;
213: case USER_PROP_LOGONS:
214: val=user.logons;
215: break;
216: case USER_PROP_LTODAY:
217: val=user.ltoday;
218: break;
219: case USER_PROP_TIMEON:
220: val=user.timeon;
221: break;
222: case USER_PROP_TEXTRA:
223: val=user.textra;
224: break;
225: case USER_PROP_TTODAY:
226: val=user.ttoday;
227: break;
228: case USER_PROP_TLAST:
229: val=user.tlast;
230: break;
231: case USER_PROP_POSTS:
232: val=user.posts;
233: break;
234: case USER_PROP_EMAILS:
235: val=user.emails;
236: break;
237: case USER_PROP_FBACKS:
238: val=user.fbacks;
239: break;
240: case USER_PROP_ETODAY:
241: val=user.etoday;
242: break;
243: case USER_PROP_PTODAY:
244: val=user.ptoday;
245: break;
246: case USER_PROP_ULB:
247: val=user.ulb;
248: break;
249: case USER_PROP_ULS:
250: val=user.uls;
251: break;
252: case USER_PROP_DLB:
253: val=user.dlb;
254: break;
255: case USER_PROP_DLS:
256: val=user.dls;
257: break;
258: case USER_PROP_CDT:
259: val=user.cdt;
260: break;
261: case USER_PROP_MIN:
262: val=user.min;
263: break;
264: case USER_PROP_LEVEL:
265: val=user.level;
266: break;
267: case USER_PROP_FLAGS1:
268: val=user.flags1;
269: break;
270: case USER_PROP_FLAGS2:
271: val=user.flags2;
272: break;
273: case USER_PROP_FLAGS3:
274: val=user.flags3;
275: break;
276: case USER_PROP_FLAGS4:
277: val=user.flags4;
278: break;
279: case USER_PROP_EXEMPT:
280: val=user.exempt;
281: break;
282: case USER_PROP_REST:
283: val=user.rest;
284: break;
285: case USER_PROP_ROWS:
286: val=user.rows;
287: break;
288: case USER_PROP_SEX:
289: sprintf(tmp,"%c",user.sex);
290: s=tmp;
291: break;
292: case USER_PROP_MISC:
293: val=user.misc;
294: break;
295: case USER_PROP_LEECH:
296: val=user.leech;
297: break;
298: case USER_PROP_CURSUB:
299: s=user.cursub;
300: break;
301: case USER_PROP_CURDIR:
302: s=user.curdir;
303: break;
304: case USER_PROP_CURXTRN:
305: s=user.curxtrn;
306: break;
307:
308: case USER_PROP_FREECDT:
309: val=user.freecdt;
310: break;
311: case USER_PROP_XEDIT:
312: if(user.xedit>0 && user.xedit<=p->cfg->total_xedits)
313: s=p->cfg->xedit[user.xedit-1]->code;
314: else
315: s=""; /* internal editor */
316: break;
317: case USER_PROP_SHELL:
318: s=p->cfg->shell[user.shell]->code;
319: break;
320: case USER_PROP_QWK:
321: val=user.qwk;
322: break;
323: case USER_PROP_TMPEXT:
324: s=user.tmpext;
325: break;
326: case USER_PROP_CHAT:
327: val=user.chat;
328: break;
329: case USER_PROP_NS_TIME:
330: val=user.ns_time;
331: break;
332: case USER_PROP_PROT:
333: sprintf(tmp,"%c",user.prot);
334: s=tmp;
335: break;
336: case USER_PROP_LOGONTIME:
337: val=user.logontime;
338: break;
339: case USER_PROP_TIMEPERCALL:
340: val=p->cfg->level_timepercall[user.level];
341: break;
342: case USER_PROP_TIMEPERDAY:
343: val=p->cfg->level_timeperday[user.level];
344: break;
345: case USER_PROP_CALLSPERDAY:
346: val=p->cfg->level_callsperday[user.level];
347: break;
348: case USER_PROP_LINESPERMSG:
349: val=p->cfg->level_linespermsg[user.level];
350: break;
351: case USER_PROP_POSTSPERDAY:
352: val=p->cfg->level_postsperday[user.level];
353: break;
354: case USER_PROP_EMAILPERDAY:
355: val=p->cfg->level_emailperday[user.level];
356: break;
357: case USER_PROP_FREECDTPERDAY:
358: val=p->cfg->level_freecdtperday[user.level];
359: break;
360: case USER_PROP_MAIL_WAITING:
361: val=getmail(p->cfg,user.number,/* sent? */FALSE);
362: break;
363: case USER_PROP_MAIL_PENDING:
364: val=getmail(p->cfg,user.number,/* sent? */TRUE);
365: break;
366:
367: default:
368: /* This must not set vp in order for child objects to work (stats and security) */
369: return(JS_TRUE);
370: }
371: if(s!=NULL) {
372: if((js_str=JS_NewStringCopyZ(cx, s))==NULL)
373: return(JS_FALSE);
374: *vp = STRING_TO_JSVAL(js_str);
375: } else
376: JS_NewNumberValue(cx,val,vp);
377:
378: return(JS_TRUE);
379: }
380:
381: static JSBool js_user_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
382: {
383: char* str;
384: char tmp[64];
385: jsint val;
386: ulong usermisc;
387: jsint tiny;
388: JSString* js_str;
389: private_t* p;
390:
391: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
392: JS_ReportError(cx,getprivate_failure,WHERE);
393: return(JS_FALSE);
394: }
395:
396: if((js_str=JS_ValueToString(cx,*vp))==NULL)
397: return(JS_FALSE);
398:
399: if((str=JS_GetStringBytes(js_str))==NULL)
400: return(JS_FALSE);
401:
402: tiny = JSVAL_TO_INT(id);
403:
404: switch(tiny) {
405: case USER_PROP_NUMBER:
406: JS_ValueToInt32(cx, *vp, (jsint*)&p->usernumber);
407: break;
408: case USER_PROP_ALIAS:
409: /* update USER.DAT */
410: putuserrec(p->cfg,p->usernumber,U_ALIAS,LEN_ALIAS,str);
411:
412: /* update NAME.DAT */
413: getuserrec(p->cfg,p->usernumber,U_MISC,8,tmp);
414: usermisc=ahtoul(tmp);
415: if(!(usermisc&DELETED))
416: putusername(p->cfg,p->usernumber,str);
417: break;
418: case USER_PROP_NAME:
419: putuserrec(p->cfg,p->usernumber,U_NAME,LEN_NAME,str);
420: break;
421: case USER_PROP_HANDLE:
422: putuserrec(p->cfg,p->usernumber,U_HANDLE,LEN_HANDLE,str);
423: break;
424: case USER_PROP_NOTE:
425: putuserrec(p->cfg,p->usernumber,U_NOTE,LEN_NOTE,str);
426: break;
427: case USER_PROP_COMP:
428: putuserrec(p->cfg,p->usernumber,U_COMP,LEN_COMP,str);
429: break;
430: case USER_PROP_COMMENT:
431: putuserrec(p->cfg,p->usernumber,U_COMMENT,LEN_COMMENT,str);
432: break;
433: case USER_PROP_NETMAIL:
434: putuserrec(p->cfg,p->usernumber,U_NETMAIL,LEN_NETMAIL,str);
435: break;
436: case USER_PROP_ADDRESS:
437: putuserrec(p->cfg,p->usernumber,U_ADDRESS,LEN_ADDRESS,str);
438: break;
439: case USER_PROP_LOCATION:
440: putuserrec(p->cfg,p->usernumber,U_LOCATION,LEN_LOCATION,str);
441: break;
442: case USER_PROP_ZIPCODE:
443: putuserrec(p->cfg,p->usernumber,U_ZIPCODE,LEN_ZIPCODE,str);
444: break;
445: case USER_PROP_PHONE:
446: putuserrec(p->cfg,p->usernumber,U_PHONE,LEN_PHONE,str);
447: break;
448: case USER_PROP_BIRTH:
449: putuserrec(p->cfg,p->usernumber,U_BIRTH,LEN_BIRTH,str);
450: break;
451: case USER_PROP_MODEM:
452: putuserrec(p->cfg,p->usernumber,U_MODEM,LEN_MODEM,str);
453: break;
454: case USER_PROP_ROWS:
455: putuserrec(p->cfg,p->usernumber,U_ROWS,0,str); /* base 10 */
456: break;
457: case USER_PROP_SEX:
458: putuserrec(p->cfg,p->usernumber,U_SEX,0,strupr(str)); /* single char */
459: break;
460: case USER_PROP_CURSUB:
461: putuserrec(p->cfg,p->usernumber,U_CURSUB,0,strupr(str));
462: break;
463: case USER_PROP_CURDIR:
464: putuserrec(p->cfg,p->usernumber,U_CURDIR,0,strupr(str));
465: break;
466: case USER_PROP_CURXTRN:
467: putuserrec(p->cfg,p->usernumber,U_CURXTRN,0,strupr(str));
468: break;
469: case USER_PROP_XEDIT:
470: putuserrec(p->cfg,p->usernumber,U_XEDIT,0,strupr(str));
471: break;
472: case USER_PROP_SHELL:
473: putuserrec(p->cfg,p->usernumber,U_COMP,0,strupr(str));
474: break;
475: case USER_PROP_MISC:
476: JS_ValueToInt32(cx,*vp,&val);
477: putuserrec(p->cfg,p->usernumber,U_MISC,0,ultoa(val,tmp,16));
478: break;
479: case USER_PROP_QWK:
480: JS_ValueToInt32(cx,*vp,&val);
481: putuserrec(p->cfg,p->usernumber,U_QWK,0,ultoa(val,tmp,16));
482: break;
483: case USER_PROP_CHAT:
484: JS_ValueToInt32(cx,*vp,&val);
485: putuserrec(p->cfg,p->usernumber,U_CHAT,0,ultoa(val,tmp,16));
486: break;
487: case USER_PROP_TMPEXT:
488: putuserrec(p->cfg,p->usernumber,U_TMPEXT,0,str);
489: break;
490: case USER_PROP_NS_TIME:
491: JS_ValueToInt32(cx,*vp,&val);
492: putuserrec(p->cfg,p->usernumber,U_NS_TIME,0,ultoa(val,tmp,16));
493: break;
494: case USER_PROP_PROT:
495: putuserrec(p->cfg,p->usernumber,U_PROT,0,strupr(str)); /* single char */
496: break;
497: case USER_PROP_LOGONTIME:
498: JS_ValueToInt32(cx,*vp,&val);
499: putuserrec(p->cfg,p->usernumber,U_LOGONTIME,0,ultoa(val,tmp,16));
500: break;
501:
502: /* security properties*/
503: case USER_PROP_PASS:
504: putuserrec(p->cfg,p->usernumber,U_PASS,LEN_PASS,strupr(str));
505: break;
506: case USER_PROP_PWMOD:
507: JS_ValueToInt32(cx,*vp,&val);
508: putuserrec(p->cfg,p->usernumber,U_PWMOD,0,ultoa(val,tmp,16));
509: break;
510: case USER_PROP_LEVEL:
511: putuserrec(p->cfg,p->usernumber,U_LEVEL,0,str);
512: break;
513: case USER_PROP_FLAGS1:
514: JS_ValueToInt32(cx,*vp,&val);
515: putuserrec(p->cfg,p->usernumber,U_FLAGS1,0,ultoa(val,tmp,16));
516: break;
517: case USER_PROP_FLAGS2:
518: JS_ValueToInt32(cx,*vp,&val);
519: putuserrec(p->cfg,p->usernumber,U_FLAGS2,0,ultoa(val,tmp,16));
520: break;
521: case USER_PROP_FLAGS3:
522: JS_ValueToInt32(cx,*vp,&val);
523: putuserrec(p->cfg,p->usernumber,U_FLAGS3,0,ultoa(val,tmp,16));
524: break;
525: case USER_PROP_FLAGS4:
526: JS_ValueToInt32(cx,*vp,&val);
527: putuserrec(p->cfg,p->usernumber,U_FLAGS4,0,ultoa(val,tmp,16));
528: break;
529: case USER_PROP_EXEMPT:
530: JS_ValueToInt32(cx,*vp,&val);
531: putuserrec(p->cfg,p->usernumber,U_EXEMPT,0,ultoa(val,tmp,16));
532: break;
533: case USER_PROP_REST:
534: JS_ValueToInt32(cx,*vp,&val);
535: putuserrec(p->cfg,p->usernumber,U_REST,0,ultoa(val,tmp,16));
536: break;
537: case USER_PROP_CDT:
538: putuserrec(p->cfg,p->usernumber,U_CDT,0,str);
539: break;
540: case USER_PROP_FREECDT:
541: putuserrec(p->cfg,p->usernumber,U_FREECDT,0,str);
542: break;
543: case USER_PROP_MIN:
544: putuserrec(p->cfg,p->usernumber,U_MIN,0,str);
545: break;
546: case USER_PROP_TEXTRA:
547: putuserrec(p->cfg,p->usernumber,U_TEXTRA,0,str);
548: break;
549: case USER_PROP_EXPIRE:
550: JS_ValueToInt32(cx,*vp,&val);
551: putuserrec(p->cfg,p->usernumber,U_EXPIRE,0,ultoa(val,tmp,16));
552: break;
553: }
554:
555: return(JS_TRUE);
556: }
557:
558: #define USER_PROP_FLAGS JSPROP_ENUMERATE
559:
560: static jsSyncPropertySpec js_user_properties[] = {
561: /* name ,tinyid ,flags, ver */
562:
563: { "number" ,USER_PROP_NUMBER ,USER_PROP_FLAGS, 310},
564: { "alias" ,USER_PROP_ALIAS ,USER_PROP_FLAGS, 310},
565: { "name" ,USER_PROP_NAME ,USER_PROP_FLAGS, 310},
566: { "handle" ,USER_PROP_HANDLE ,USER_PROP_FLAGS, 310},
567: { "ip_address" ,USER_PROP_NOTE ,USER_PROP_FLAGS, 310},
568: { "note" ,USER_PROP_NOTE ,USER_PROP_FLAGS, 310},
569: { "host_name" ,USER_PROP_COMP ,USER_PROP_FLAGS, 310},
570: { "computer" ,USER_PROP_COMP ,USER_PROP_FLAGS, 310},
571: { "comment" ,USER_PROP_COMMENT ,USER_PROP_FLAGS, 310},
572: { "netmail" ,USER_PROP_NETMAIL ,USER_PROP_FLAGS, 310},
573: { "email" ,USER_PROP_EMAIL ,USER_PROP_FLAGS|JSPROP_READONLY, 310},
574: { "address" ,USER_PROP_ADDRESS ,USER_PROP_FLAGS, 310},
575: { "location" ,USER_PROP_LOCATION ,USER_PROP_FLAGS, 310},
576: { "zipcode" ,USER_PROP_ZIPCODE ,USER_PROP_FLAGS, 310},
577: { "phone" ,USER_PROP_PHONE ,USER_PROP_FLAGS, 310},
578: { "birthdate" ,USER_PROP_BIRTH ,USER_PROP_FLAGS, 310},
579: { "age" ,USER_PROP_AGE ,USER_PROP_FLAGS|JSPROP_READONLY, 310},
580: { "connection" ,USER_PROP_MODEM ,USER_PROP_FLAGS, 310},
581: { "modem" ,USER_PROP_MODEM ,USER_PROP_FLAGS, 310},
582: { "screen_rows" ,USER_PROP_ROWS ,USER_PROP_FLAGS, 310},
583: { "gender" ,USER_PROP_SEX ,USER_PROP_FLAGS, 310},
584: { "cursub" ,USER_PROP_CURSUB ,USER_PROP_FLAGS, 310},
585: { "curdir" ,USER_PROP_CURDIR ,USER_PROP_FLAGS, 310},
586: { "curxtrn" ,USER_PROP_CURXTRN ,USER_PROP_FLAGS, 310},
587: { "editor" ,USER_PROP_XEDIT ,USER_PROP_FLAGS, 310},
588: { "command_shell" ,USER_PROP_SHELL ,USER_PROP_FLAGS, 310},
589: { "settings" ,USER_PROP_MISC ,USER_PROP_FLAGS, 310},
590: { "qwk_settings" ,USER_PROP_QWK ,USER_PROP_FLAGS, 310},
591: { "chat_settings" ,USER_PROP_CHAT ,USER_PROP_FLAGS, 310},
592: { "temp_file_ext" ,USER_PROP_TMPEXT ,USER_PROP_FLAGS, 310},
593: { "new_file_time" ,USER_PROP_NS_TIME ,USER_PROP_FLAGS, 311},
594: { "newscan_date" ,USER_PROP_NS_TIME ,0, /* Alias */ 310},
595: { "download_protocol" ,USER_PROP_PROT ,USER_PROP_FLAGS, 310},
596: { "logontime" ,USER_PROP_LOGONTIME ,USER_PROP_FLAGS, 310},
597: {0}
598: };
599:
600: #ifdef _DEBUG
601: static char* user_prop_desc[] = {
602:
603: "record number (1-based)"
604: ,"alias/name"
605: ,"real name"
606: ,"chat handle"
607: ,"IP address last logged on from"
608: ,"AKA ip_address"
609: ,"host name last logged on from"
610: ,"AKA host_name"
611: ,"sysop's comment"
612: ,"external e-mail address"
613: ,"local Internet e-mail address - <small>READ ONLY</small>"
614: ,"street address"
615: ,"location (city, state)"
616: ,"zip/postal code"
617: ,"phone number"
618: ,"birth date"
619: ,"calculated age in years - <small>READ ONLY</small>"
620: ,"connection type"
621: ,"AKA connection"
622: ,"terminal rows (lines)"
623: ,"gender type"
624: ,"current message sub-board"
625: ,"current file directory"
626: ,"current external program being run"
627: ,"external message editor"
628: ,"command shell"
629: ,"settings bitfield - see <tt>USER_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions"
630: ,"QWK packet settings bitfield - see <tt>QWK_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions"
631: ,"chat settings bitfield - see <tt>CHAT_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions"
632: ,"temporary file type (extension)"
633: ,"new file scan date/time (time_t format)"
634: ,"file transfer protocol (command key)"
635: ,"logon time (time_t format)"
636: ,NULL
637: };
638: #endif
639:
640:
641: /* user.security */
642: static jsSyncPropertySpec js_user_security_properties[] = {
643: /* name ,tinyid ,flags, ver */
644:
645: { "password" ,USER_PROP_PASS ,USER_PROP_FLAGS, 310 },
646: { "password_date" ,USER_PROP_PWMOD ,USER_PROP_FLAGS, 310 },
647: { "level" ,USER_PROP_LEVEL ,USER_PROP_FLAGS, 310 },
648: { "flags1" ,USER_PROP_FLAGS1 ,USER_PROP_FLAGS, 310 },
649: { "flags2" ,USER_PROP_FLAGS2 ,USER_PROP_FLAGS, 310 },
650: { "flags3" ,USER_PROP_FLAGS3 ,USER_PROP_FLAGS, 310 },
651: { "flags4" ,USER_PROP_FLAGS4 ,USER_PROP_FLAGS, 310 },
652: { "exemptions" ,USER_PROP_EXEMPT ,USER_PROP_FLAGS, 310 },
653: { "restrictions" ,USER_PROP_REST ,USER_PROP_FLAGS, 310 },
654: { "credits" ,USER_PROP_CDT ,USER_PROP_FLAGS, 310 },
655: { "free_credits" ,USER_PROP_FREECDT ,USER_PROP_FLAGS, 310 },
656: { "minutes" ,USER_PROP_MIN ,USER_PROP_FLAGS, 310 },
657: { "extra_time" ,USER_PROP_TEXTRA ,USER_PROP_FLAGS, 310 },
658: { "expiration_date" ,USER_PROP_EXPIRE ,USER_PROP_FLAGS, 310 },
659: {0}
660: };
661:
662: #ifdef _DEBUG
663: static char* user_security_prop_desc[] = {
664:
665: "password"
666: ,"date password last modified (time_t format)"
667: ,"security level (0-99)"
668: ,"flag set #1 (bitfield)"
669: ,"flag set #2 (bitfield)"
670: ,"flag set #3 (bitfield)"
671: ,"flag set #4 (bitfield)"
672: ,"exemption flags (bitfield)"
673: ,"restriction flags (bitfield)"
674: ,"credits"
675: ,"free credits (for today only)"
676: ,"extra minutes (time bank)"
677: ,"extra minutes (for today only)"
678: ,"expiration date/time (time_t format)"
679: ,NULL
680: };
681: #endif
682:
683: #undef USER_PROP_FLAGS
684: #define USER_PROP_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY
685:
686: /* user.limits: These should be READ ONLY by nature */
687: static jsSyncPropertySpec js_user_limits_properties[] = {
688: /* name ,tinyid ,flags, ver */
689:
690: { "time_per_logon" ,USER_PROP_TIMEPERCALL ,USER_PROP_FLAGS, 311 },
691: { "time_per_day" ,USER_PROP_TIMEPERDAY ,USER_PROP_FLAGS, 311 },
692: { "logons_per_day" ,USER_PROP_CALLSPERDAY ,USER_PROP_FLAGS, 311 },
693: { "lines_per_message" ,USER_PROP_LINESPERMSG ,USER_PROP_FLAGS, 311 },
694: { "email_per_day" ,USER_PROP_EMAILPERDAY ,USER_PROP_FLAGS, 311 },
695: { "posts_per_day" ,USER_PROP_POSTSPERDAY ,USER_PROP_FLAGS, 311 },
696: { "free_credits_per_day" ,USER_PROP_FREECDTPERDAY,USER_PROP_FLAGS, 311 },
697: {0}
698: };
699:
700:
701: #ifdef _DEBUG
702: static char* user_limits_prop_desc[] = {
703:
704: "time (in minutes) per logon"
705: ,"time (in minutes) per day"
706: ,"logons per day"
707: ,"lines per message (post or email)"
708: ,"email sent per day"
709: ,"messages posted per day"
710: ,"free credits given per day"
711: ,NULL
712: };
713: #endif
714:
715:
716: #undef USER_PROP_FLAGS
717: #define USER_PROP_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY
718:
719: /* user.stats: These should be READ ONLY by nature */
720: static jsSyncPropertySpec js_user_stats_properties[] = {
721: /* name ,tinyid ,flags, ver */
722:
723: { "laston_date" ,USER_PROP_LASTON ,USER_PROP_FLAGS, 310 },
724: { "firston_date" ,USER_PROP_FIRSTON ,USER_PROP_FLAGS, 310 },
725: { "total_logons" ,USER_PROP_LOGONS ,USER_PROP_FLAGS, 310 },
726: { "logons_today" ,USER_PROP_LTODAY ,USER_PROP_FLAGS, 310 },
727: { "total_timeon" ,USER_PROP_TIMEON ,USER_PROP_FLAGS, 310 },
728: { "timeon_today" ,USER_PROP_TTODAY ,USER_PROP_FLAGS, 310 },
729: { "timeon_last_logon" ,USER_PROP_TLAST ,USER_PROP_FLAGS, 310 },
730: { "total_posts" ,USER_PROP_POSTS ,USER_PROP_FLAGS, 310 },
731: { "total_emails" ,USER_PROP_EMAILS ,USER_PROP_FLAGS, 310 },
732: { "total_feedbacks" ,USER_PROP_FBACKS ,USER_PROP_FLAGS, 310 },
733: { "email_today" ,USER_PROP_ETODAY ,USER_PROP_FLAGS, 310 },
734: { "posts_today" ,USER_PROP_PTODAY ,USER_PROP_FLAGS, 310 },
735: { "bytes_uploaded" ,USER_PROP_ULB ,USER_PROP_FLAGS, 310 },
736: { "files_uploaded" ,USER_PROP_ULS ,USER_PROP_FLAGS, 310 },
737: { "bytes_downloaded" ,USER_PROP_DLB ,USER_PROP_FLAGS, 310 },
738: { "files_downloaded" ,USER_PROP_DLS ,USER_PROP_FLAGS, 310 },
739: { "leech_attempts" ,USER_PROP_LEECH ,USER_PROP_FLAGS, 310 },
740: { "mail_waiting" ,USER_PROP_MAIL_WAITING ,USER_PROP_FLAGS, 312 },
741: { "mail_pending" ,USER_PROP_MAIL_PENDING ,USER_PROP_FLAGS, 312 },
742: {0}
743: };
744:
745: #ifdef _DEBUG
746: static char* user_stats_prop_desc[] = {
747:
748: "date of previous logon"
749: ,"date of first logon"
750: ,"total number of logons"
751: ,"total logons today"
752: ,"total time used (in minutes)"
753: ,"time used today"
754: ,"time used last session"
755: ,"total messages posted"
756: ,"total e-mails sent"
757: ,"total feedback messages sent"
758: ,"e-mail sent today"
759: ,"messages posted today"
760: ,"total bytes uploaded"
761: ,"total files uploaded"
762: ,"total bytes downloaded"
763: ,"total files downloaded"
764: ,"suspected leech downloads"
765: ,"number of e-mail messages currently waiting"
766: ,"number of e-mail messages sent, currently pending deletion"
767: ,NULL
768: };
769: #endif
770:
771:
772: static void js_user_finalize(JSContext *cx, JSObject *obj)
773: {
774: private_t* p;
775:
776: p=(private_t*)JS_GetPrivate(cx,obj);
777:
778: if(p!=NULL && (scfg_t*)p!=scfg)
779: free(p);
780:
781: p=NULL;
782: JS_SetPrivate(cx,obj,p);
783: }
784:
785: static JSBool
786: js_chk_ar(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
787: {
788: uchar* ar;
789: JSString* js_str;
790: user_t user;
791: private_t* p;
792:
793: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
794: return JS_FALSE;
795:
796: if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
797: return JS_FALSE;
798:
799: ar = arstr(NULL,JS_GetStringBytes(js_str),p->cfg);
800:
801: user.number=p->usernumber;
802: getuserdat(p->cfg,&user);
803:
804: *rval = BOOLEAN_TO_JSVAL(chk_ar(p->cfg,ar,&user));
805:
806: if(ar!=NULL && ar!=nular)
807: free(ar);
808:
809: return(JS_TRUE);
810: }
811:
812:
813: static jsSyncMethodSpec js_user_functions[] = {
814: {"compare_ars", js_chk_ar, 1, JSTYPE_BOOLEAN, JSDOCSTR("string ars")
815: ,JSDOCSTR("Verify user meets access requirements string")
816: ,310
817: },
818: {0}
819: };
820:
821: static JSClass js_user_class = {
822: "User" /* name */
823: ,JSCLASS_HAS_PRIVATE /* flags */
824: ,JS_PropertyStub /* addProperty */
825: ,JS_PropertyStub /* delProperty */
826: ,js_user_get /* getProperty */
827: ,js_user_set /* setProperty */
828: ,JS_EnumerateStub /* enumerate */
829: ,JS_ResolveStub /* resolve */
830: ,JS_ConvertStub /* convert */
831: ,js_user_finalize /* finalize */
832: };
833:
834: static JSClass js_user_stats_class = {
835: "UserStats" /* name */
836: ,JSCLASS_HAS_PRIVATE /* flags */
837: ,JS_PropertyStub /* addProperty */
838: ,JS_PropertyStub /* delProperty */
839: ,js_user_get /* getProperty */
840: ,js_user_set /* setProperty */
841: ,JS_EnumerateStub /* enumerate */
842: ,JS_ResolveStub /* resolve */
843: ,JS_ConvertStub /* convert */
844: ,JS_FinalizeStub /* finalize */
845: };
846:
847: static JSClass js_user_security_class = {
848: "UserSecurity" /* name */
849: ,JSCLASS_HAS_PRIVATE /* flags */
850: ,JS_PropertyStub /* addProperty */
851: ,JS_PropertyStub /* delProperty */
852: ,js_user_get /* getProperty */
853: ,js_user_set /* setProperty */
854: ,JS_EnumerateStub /* enumerate */
855: ,JS_ResolveStub /* resolve */
856: ,JS_ConvertStub /* convert */
857: ,JS_FinalizeStub /* finalize */
858: };
859:
860: static JSClass js_user_limits_class = {
861: "UserLimits" /* name */
862: ,JSCLASS_HAS_PRIVATE /* flags */
863: ,JS_PropertyStub /* addProperty */
864: ,JS_PropertyStub /* delProperty */
865: ,js_user_get /* getProperty */
866: ,js_user_set /* setProperty */
867: ,JS_EnumerateStub /* enumerate */
868: ,JS_ResolveStub /* resolve */
869: ,JS_ConvertStub /* convert */
870: ,JS_FinalizeStub /* finalize */
871: };
872:
873: /* User Constructor (creates instance of user class) */
874:
875: static JSBool
876: js_user_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
877: {
878: int i;
879: int32 val=0;
880: user_t user;
881: private_t* p;
882: JSObject* statsobj;
883: JSObject* securityobj;
884: JSObject* limitsobj;
885:
886: JS_ValueToInt32(cx,argv[0],&val);
887: user.number=(ushort)val;
888: if(user.number!=0 && (i=getuserdat(scfg,&user))!=0) {
889: JS_ReportError(cx,"Error %d reading user number %d",i,val);
890: return(JS_FALSE);
891: }
892:
893: /* user.stats */
894: if((statsobj=JS_DefineObject(cx, obj, "stats"
895: ,&js_user_stats_class, NULL, JSPROP_ENUMERATE|JSPROP_READONLY))==NULL)
896: return(JS_FALSE);
897:
898: if(!js_DefineSyncProperties(cx, statsobj, js_user_stats_properties))
899: return(JS_FALSE);
900:
901: /* user.security */
902: if((securityobj=JS_DefineObject(cx, obj, "security"
903: ,&js_user_security_class, NULL, JSPROP_ENUMERATE|JSPROP_READONLY))==NULL)
904: return(JS_FALSE);
905:
906: if(!js_DefineSyncProperties(cx, securityobj, js_user_security_properties))
907: return(JS_FALSE);
908:
909: /* user.limits */
910: if((limitsobj=JS_DefineObject(cx, obj, "limits"
911: ,&js_user_limits_class, NULL, JSPROP_ENUMERATE|JSPROP_READONLY))==NULL)
912: return(JS_FALSE);
913:
914: if(!js_DefineSyncProperties(cx, limitsobj, js_user_limits_properties))
915: return(JS_FALSE);
916:
917: /* other user properties */
918: if(!js_DefineSyncProperties(cx, obj, js_user_properties))
919: return(JS_FALSE);
920:
921: if((p=(private_t*)malloc(sizeof(private_t)))==NULL)
922: return(JS_FALSE);
923:
924: p->cfg = scfg;
925: p->usernumber = user.number;
926:
927: JS_SetPrivate(cx, obj, p); /* Must do this before calling js_DefineSyncMethods() */
928:
929: if(!js_DefineSyncMethods(cx, obj, js_user_functions, FALSE)) {
930: JS_SetPrivate(cx, obj, NULL);
931: free(p);
932: return(JS_FALSE);
933: }
934:
935: JS_SetPrivate(cx, statsobj, p);
936: JS_SetPrivate(cx, securityobj, p);
937: JS_SetPrivate(cx, limitsobj, p);
938:
939: return(JS_TRUE);
940: }
941:
942: JSObject* DLLCALL js_CreateUserClass(JSContext* cx, JSObject* parent, scfg_t* cfg)
943: {
944: JSObject* userclass;
945:
946: scfg = cfg;
947: userclass = JS_InitClass(cx, parent, NULL
948: ,&js_user_class
949: ,js_user_constructor
950: ,1 /* number of constructor args */
951: ,NULL /* props, defined in constructor */
952: ,NULL /* funcs, defined in constructor */
953: ,NULL,NULL);
954:
955: return(userclass);
956: }
957:
958: JSObject* DLLCALL js_CreateUserObject(JSContext* cx, JSObject* parent, scfg_t* cfg, char* name
959: , uint usernumber)
960: {
961: JSObject* userobj;
962: JSObject* statsobj;
963: JSObject* limitsobj;
964: JSObject* securityobj;
965: private_t* p;
966: jsval val;
967:
968: if(name==NULL)
969: userobj = JS_NewObject(cx, &js_user_class, NULL, parent);
970: else if(JS_GetProperty(cx,parent,name,&val) && val!=JSVAL_VOID)
971: userobj = JSVAL_TO_OBJECT(val); /* Return existing user object */
972: else
973: userobj = JS_DefineObject(cx, parent, name, &js_user_class
974: , NULL, JSPROP_ENUMERATE|JSPROP_READONLY);
975: if(userobj==NULL)
976: return(NULL);
977:
978: if((p=(private_t*)malloc(sizeof(private_t)))==NULL)
979: return(NULL);
980:
981: p->cfg = cfg;
982: p->usernumber = usernumber;
983:
984: JS_SetPrivate(cx, userobj, p);
985:
986: if(!js_DefineSyncProperties(cx, userobj, js_user_properties)) {
987: free(p);
988: return(NULL);
989: }
990:
991: #ifdef _DEBUG
992: js_DescribeSyncObject(cx,userobj
993: ,"Instance of <i>User</i> class, representing current user online"
994: ,310);
995: js_DescribeSyncConstructor(cx,userobj
996: ,"To create a new user object: <tt>var u = new User(<i>number</i>)</tt>");
997: js_CreateArrayOfStrings(cx, userobj
998: ,"_property_desc_list", user_prop_desc, JSPROP_READONLY);
999: #endif
1000:
1001: js_DefineSyncMethods(cx, userobj, js_user_functions, FALSE);
1002:
1003: /* user.stats */
1004: statsobj = JS_DefineObject(cx, userobj, "stats"
1005: ,&js_user_stats_class, NULL, JSPROP_ENUMERATE|JSPROP_READONLY);
1006:
1007: if(statsobj==NULL) {
1008: free(p);
1009: return(NULL);
1010: }
1011:
1012: JS_SetPrivate(cx, statsobj, p);
1013:
1014: if(!js_DefineSyncProperties(cx, statsobj, js_user_stats_properties)) {
1015: free(p);
1016: return(NULL);
1017: }
1018:
1019: #ifdef _DEBUG
1020: js_DescribeSyncObject(cx,statsobj,"User statistics (all <small>READ ONLY</small>)",310);
1021: js_CreateArrayOfStrings(cx, statsobj, "_property_desc_list", user_stats_prop_desc, JSPROP_READONLY);
1022: #endif
1023:
1024: /* user.limits */
1025: limitsobj = JS_DefineObject(cx, userobj, "limits"
1026: ,&js_user_limits_class, NULL, JSPROP_ENUMERATE|JSPROP_READONLY);
1027:
1028: if(limitsobj==NULL) {
1029: free(p);
1030: return(NULL);
1031: }
1032:
1033: JS_SetPrivate(cx, limitsobj, p);
1034:
1035: if(!js_DefineSyncProperties(cx, limitsobj, js_user_limits_properties)) {
1036: free(p);
1037: return(NULL);
1038: }
1039:
1040: #ifdef _DEBUG
1041: js_DescribeSyncObject(cx,limitsobj,"User limitations based on security level (all <small>READ ONLY</small>)",311);
1042: js_CreateArrayOfStrings(cx, limitsobj, "_property_desc_list", user_limits_prop_desc, JSPROP_READONLY);
1043: #endif
1044:
1045:
1046: /* user.security */
1047: securityobj = JS_DefineObject(cx, userobj, "security"
1048: ,&js_user_security_class, NULL, JSPROP_ENUMERATE|JSPROP_READONLY);
1049:
1050: if(securityobj==NULL) {
1051: free(p);
1052: return(NULL);
1053: }
1054:
1055: JS_SetPrivate(cx, securityobj, p);
1056:
1057: if(!js_DefineSyncProperties(cx, securityobj, js_user_security_properties)) {
1058: free(p);
1059: return(NULL);
1060: }
1061:
1062: #ifdef _DEBUG
1063: js_DescribeSyncObject(cx,securityobj,"User security settings",310);
1064: js_CreateArrayOfStrings(cx, securityobj, "_property_desc_list", user_security_prop_desc, JSPROP_READONLY);
1065: #endif
1066:
1067: return(userobj);
1068: }
1069:
1070: /****************************************************************************/
1071: /* Creates all the user-specific objects: user, msg_area, file_area */
1072: /****************************************************************************/
1073: JSBool DLLCALL
1074: js_CreateUserObjects(JSContext* cx, JSObject* parent, scfg_t* cfg, user_t* user
1075: ,char* html_index_file, subscan_t* subscan)
1076: {
1077: if(js_CreateUserObject(cx,parent,cfg,"user",user==NULL ? 0 : user->number)==NULL)
1078: return(JS_FALSE);
1079: if(js_CreateFileAreaObject(cx,parent,cfg,user,html_index_file)==NULL)
1080: return(JS_FALSE);
1081: if(js_CreateMsgAreaObject(cx,parent,cfg,user,subscan)==NULL)
1082: return(JS_FALSE);
1083: if(js_CreateXtrnAreaObject(cx,parent,cfg,user)==NULL)
1084: return(JS_FALSE);
1085:
1086: return(JS_TRUE);
1087: }
1088:
1089: #endif /* JAVSCRIPT */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.