-
Notifications
You must be signed in to change notification settings - Fork 0
/
TODO
1117 lines (784 loc) · 42.6 KB
/
TODO
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
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
864
865
866
867
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
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
[original TODO list]
*** When a session terminates, make sure to disconnect it from /send targets!
*** Modify input history to somehow include current input line so it's not
*** lost when scrolling through history lines!
Add Hebrew support?
Allow /set date to adjust server time relative to system time...
Implement /group.
Add some sort of lily bridge. Possibly add /lily command to connect to lily
server as user, use special character (such as ">" or pseudo-user "lily" for
input and output prefixing, configurable)
/at, /every, /signal at, /signal every
implement !force. (output as text to forced session, don't dequeue output.)
add /last command to show last message sent to someone. (if multiple, replay
the set of last messages sent to those people) [dunno about discussions]
/last alone should replay the last message sent. Should /last also *set* the
last message so that /also and /oops work relative to it?
finger-type info -- real name, web page, email, etc.
/notify, /info, /group, /finger, server banner w/admin address, crash recovery
guest questionnaire
Add /help language (aliases /help spanish, /help french, etc.) to document
Latin-1 compose sequences.
Add /ayuda to give help text in Spanish?
Cleanup response messages from SendMessage() for /oops and /also. Fix /also
(and /oops?) to resend messages with bogus sendlists.
*** Integrate Berkeley DB library for external data storage at least, if not
*** actual persistent objects. (multiple access issues?)
Add DB support, have an Associative class for it, allowing both internal hash
tables and external (DB) hash tables a la perl, use String type for key/data!
Maybe even overload [] to act like {} perl associative array reference...
Have [] dereference to Element object which knows the reference internally,
then have conversions Element <-> String cause actual hash table lookup/store
and (possibly) DB read/write. Make sure Element <-> Element copies, using
operator=, so foo["bar"]=foo["baz"] will work. Also have numeric->String so
foo[1] will be the same as foo["1"]. Have Element.operator=(String) maybe too.
Fix the input editing for up & down arrows. Add i-search?
Should input editing use String class? Maybe make a Buffer class or extend
the String class to serve the purpose? (Maybe allow String or Buffer objects
to store text in multiple allocated blocks of memory, but presented logically
as a contiguous region?)
Write String::sprintf() (how to buffer?)...
Modify String class to do [] operator as substrings? Can it be done as lvalue?
Instead of dequoting sendlist items in message_start(), do it elsewhere, and
call from DoWho(), etc. Maybe do dequoting in Sendlist::set()?
Modify "busy" state to discourage others sending to busy people. Does this
need a /confirm command or something else? Also, discourage sending while
state is "gone"...
As well as I/O modules, have "sendable" modules which define sendlist targets.
For example, sessions, offline users, discussions, logical groups (e.g. all),
bridged lily users, etc. (how to handle permissions in general form?) Maybe
have "default" keyword be a "sendable" target instead of special-case code...
Can UI's also be modular? Would they be considered I/O modules or another
basic type instead?
Allow ASCII ShiftIn/ShiftOut (C-n/C-o or C-o/C-n) for Latin-1 input and output.
(only use for output if binary mode refused)
Sundance requested tuning for tinyfugue...
Use C-o to embed newlines in messages and make formatted multiline messages?
Add general code to interpret time values (Timestamp(String) constructor?), as
relative offsets or absolute. Add parsing code for durations, as static class
function, use from string constructor/absdate parse for relative... Allow for
user-level Timestamps in /eval...
*** Add time limits for "away" states.
*** Timed messages -- delayed send, timeouts. (Allow a message in a detach
buffer to expire if undelivered.)
*** Add /leave command. Force disconnect unless /leave cancel is done.
"trolling" flag? :-) [Maybe allow "sealed" messages?]
Fix TCP detection to require a minimum time delay before giving up on telnet.
After this timeout, perhaps give a prompt for TCP users? Do event queue first.
When printing a message, if the destination name doesn't match the current
name, show the original destination name.
implement notifications and messages as events, include event queue in session
for past events while detached, have global or per-session future events in
another event queue to allow for future message sending... No bell for any
messages played back from being detached.
info files
*** use identd (port 113) server:
request of the form: <port-on-identd-server-host>, <port-on-client> [6789]
response: <echoed ports> : <response-type> : <additional-info>
e.g. 2351, 6789 : USER-ID : UNIX : deven
e.g. 2351, 6789 : ERROR : NO-USER
[ignore whitespace]
[use event queue timeout on server response]
Have a response event in event queue? make action event queue or set?
/msg command for multiline sends. (ideally allowing multiline edit)
Allow multiline message sends, info file entry, etc. using "." to terminate
input? Postpone notifications/messages in event queue a la detach for the
duration, but still ring bell. Maybe allow emacs-style editing between lines
or such? possibly create a second screen window?
*** use accept() 3rd arg instead of getpeername()
fix hang after /det (use final option negotiation different from TIMING-MARK?)
*** Use shutdown()
Allow system variables (e.g. uptime) to be abbreviated?
*** PROBLEM: anonymous signons with duplicate and reserved names!!!
If a sendlist match fails, attempt match against non-joined discussions for a
better error message. Fix sendlist matching in /who (et al) to be consistent.
spruce up ; and : processing -- fix smiley processing!
Add "realms" which users can be in, perhaps visible, perhaps not. Need a realm
for family...
Create a generalized I/O streams facility that can have modules added and
removed a la SysV STREAMS or Amiga InputHandlers. Use for any I/O or stream
manipulation, chain together. Possible uses: tcp (data transfer), udp (data
transfer), FD?, telnet (protocol), tcpuser (for non-telnet TCP users?), lclient
(pretend to be a lily server), lily (for managing "forked session" to lily),
phoenix client (could connect to either tcp or udp for data transfer), tee (to
split a stream), IRC (client, forked), listen (listening TCP socket), lookup
(to do DNS queries), terminal handling (variable by type), editing (emacs, vi,
unix line mode, etc), pager (would interact with editing and terminal), parser
(for /,!,% commands or whatever, other classes could interface to parser to get
commands installed), games, talk (protocol), encrypt, mux, multi-server, etc.
Modules would have to have clearly defined stream connections; some are simple
filters (e.g. pager) and others are single stream sources/sinks (e.g. tcp) and
others may have more complex configurations (e.g. tee) -- adding and removing
modules should be possible on the fly...
Latin-1 -> ASCII as 2 types of I/O stream modules -- one doing something like
e' to simulate accents, another to discard accents. Enable filter whenever
TRANSMIT-BINARY option is refused.
Do Latin-1 character compose filter as I/O stream module also...
Maybe use canonical names in ; expansion?
TAB sendlist completion & cycling.
Telnet::PrintMessage still has an "everyone" send -- is this used?
Change message sending to empty discussion; save in discussion review, don't
say "message not sent", whatever.
If a client is doing local echo, does ;/: expansion happen invisibly?
Add some option to implicitly copy message to self? If so, erase input line?
Make more generalized parser and keyword matching? (needs to be tunable)
Abstract out terminal handling, editing (emacs-style vs. basic input line vs.
possibly vi-style?) and telnet protocol itself into separate classes that can
be disabled, perhaps a la STREAMS modules or such.
-------------------------------------------------------------------------------
"Enter name: " prompt should not have appeared below!
(Also, should the echo be done anyhow, despite CR's?)
[for input received before echo is negotiated, that is]
-------------------------------------------------------------------------------
deven
REDACTED
Trying 192.48.232.17...
Connected to asylum.elf.com.
Escape character is '^]'.
Welcome to Phoenix!
A "guest" account is available.
login: Password:
Your default name is "Deven".
Enter name: Re-attaching to detached session...
[You were idle for 19 minutes.]
You have been detached.
*** 12bit is now attached. [12:24] ***
*** 12bit has intentionally detached. [12:24] ***
*** End of reviewed output. ***
Enter name: /who me
Name On Since Idle Away
---- -------- ---- ----
Deven [errands] Nov 13 1:48 Gone
-------------------------------------------------------------------------------
Make /date into /display variables.
Add /set banner and /display banner, and /news...
Move some Session string fields into sys_vars?
Allow $variables in general command parameters. (need better parser)
Modify String class to allow initialization/cast from int->String.
Allow /save command to save user or system variables persistently.
Make an Assoc-based substitute for match() against a known set of keywords to
avoid having to do an exhaustive search. Downcase initialization and match
string to make case-insensitive. Maybe use for sendlist items, maybe not.
(If used for sendlists, how to handle collisions and updates of match set?)
Allow for client<->server encryption of basic TCP stream.
Allow user<->user encryption on a per-message or per-user basis. Allow for
multiple-recipient encrypted messages and some sort of encrypted discussions.
Do NOT allow guest users to create discussions!
Add privileged discussion overrides.
Possibly have here/away/busy/gone set "transient" blurbs, and /blurb set
"persistent" blurbs. here/away/busy/gone without arguments would revert
to last persistent blurb. Maybe allow /finger or some other command show
both transient AND persistent blurbs...
Possible: *** User [persistent, maybe] is now "gone". [transient, if any] ***
When persistent object database is done, possible allow commands to make
current session state permanent, like "/save blurb" or such?
Should detaching reset idle? Not sure...
*** (18:06) Chaos! All members of perl are now moderators ***
Allow some mechanism via which the server can request a specific prompt from
the client to the user -- either a one-shot or a repeating prompt. For a
repeating prompt, maybe include when to stop prompting, e.g. "." line. Also
specify whether input is blanked. For blanked input, the client should NOT
display it on the screen, even if it was being redrawn; redraw as blank, AND
remove from scrollback/input history/kill ring/etc. Maybe a repeating prompt
should be a hint, and only lines which have another prompt request come back
KEEP the prompt; it might have to be erased ex post facto. Actually, maybe
repeating prompts aren't worth the trouble. Some prompts might be considered
special prompts (e.g. initial login/password/name/blurb prompts) and be tagged
with predefined prompt tags so the client could specially process them if it
chooses to do so, e.g. auto-login.
*** Does the standard telnet linemode allow for protocol-specified prompts?
How to handle asynchronous output received while prompting? block? output?
prompt needs to be redrawn if output. If multiple prompts, (e.g. info set)
can output be redrawing before _sequence_ of prompted lines, or maybe saved
until later?
Perhaps the client should have two forms of prompting -- one-line prompts, and
buffer prompts; buffer prompts might be in a different window or something,
the mechanism for marking the end of the buffer could be client-local, any
asynchronous output would be printed (or saved by the client) but not print
in the middle of the buffer input, buffer prompting would be up to the client,
maybe with a suggested prompt from the server, which the client could ignore.
The server could specify maximum rows and columns for the buffer, maybe both
soft (suggested) and hard (enforced) limits on each, similar for character
sets. Some buffers might actually be binary data, depending on what type of
data the server requests. The server might also recommend that the client
ask the user for a filename to satisfy a buffer request, possibly with either
a suggested filename, or an automatic filename that wouldn't prompt the user
(this might have security implications; maybe some should be automatic like a
startup file and all others confirmed by the user; this would be within the
client's discretion how to handle any given buffer request.) The server
could either block waiting on a buffer, or offer a buffer ID and return to
normal mode, allowing to send the buffer (with ID) at its convenience. Have
to watch out that such buffer tags can't stay outstanding forever; probably
have either a timeout or wipe them when the connection clears. Also, allow
client to CANCEL a pending buffer request. If client doesn't handle buffer
management, use server-based one-shot prompting as a fallback.
In client & server both, allow client to send TIMING-MARK sequence, server
responds at appropriate time. e.g. client sends /who command and TIMING-MARK,
server sends all /who output and THEN sends the TIMING-MARK reply. Client
keep redrawing input until the TIMING-MARK reply, even if return was typed;
it would just redraw multiple input lines. Then, when the reply comes, the
next "sent" input line (if any) is placed into its place in the client's I/O
buffers/scrollback and is no longer redrawn. if 5 lines are send from the
client, they can all be sent at once, each with a TIMING-MARK.
Example from lily: /info set -- each line has a * prompt. Suppose user does
/info set and all the lines of the info and the trailing . all in a single
xterm paste operation. On lily with the lily client, all the user's lines
are printed at once, then * * * * * * across the screen as the prompts come
back from the server. Obviously this is less than ideal. With TIMING-MARK
events used, the /info set would be followed by TIMING-MARK, then the first
info line, then TIMING-MARK, etc. All this input would appear on the screen
immediately, and all of it would be sent immediately, with a TIMING-MARK after
every line sent. In the server reply, a TIMING-MARK reply would come at the
end of each prompt. As the server response came back, the client would redraw
ALL of the input lines pending, shifting into the middle of a line if need be,
and as soon as a TIMING-MARK came back, that would mark the location of the
start of the next input line -- info lines would be redrawn after the *, then
the TIMING-MARK would fix the location of the first input line, on the line
with the first prompt. Then the next prompt and TIMING-MARK would come in,
filling in the prompt on the second line, etc. In this fashion, all the lines
could be sent at once and yet be in exactly the right place on the screen and
in scrollback.
ACTUALLY, the TIMING-MARK should probably be sent BEFORE the input, instead
of after (or both?) -- that way a *** notification couldn't come between /who
and the /who output, for example. Would another one be useful after, or would
that be redundant? Probably redundant. Perhaps the best approach is for the
client to send TIMING-MARK before the line of data; the server sets a flag.
When the server gets the newline, it sends the TIMING-MARK reply and then the
response to the input. That way, if any asynchronous output is generated as
the input line is being sent, it won't have to be blocked. After would be
bad because we really want the reply TIMING-MARK just BEFORE the synchronous
output as a marker, and the server can't KNOW if a TIMING-MARK will follow
the newline.
If the server receives IAC DO TIMING-MARK, set a flag. If the flag was set
already, then instead return IAC WONT TIMING-MARK immediately. When a newline
is received, check the flag -- if set, send IAC WILL TIMING-MARK and then do
the processing of the input line. Client should keep redrawing input until
the IAC WILL/WONT TIMING-MARK comes back, then fix ONE input line and continue
to redraw any remaining input lines.
Add more info to /howmany command? e.g. idle/active/etc maximums?
full-screen -- when reviewing log, if message arrives, create split window at
bottom, switchable to it, let it grow to up to half screen.
Allow sending to discussion _except_ specific people or discussions?
Show discussion quits on /bye?
Show multi-discussion notifications.
Destroy discussions when empty unless special? Maybe an idle timeout?
"/here" alone act as "/here off"? have "/here same"? configurable default?
*** discussions show people not signed on
For /detach, always switch to "gone" unless here/away/busy/gone keyword
specified. (same or brb as keywords?) allow blurb w/detach
pronouns?
/submit
/review
better attach review, no beeps, filter, session list
Optimize character input in telnet.cc -- if a group of characters comes in,
only queue the block of characters to output buffer, not each one. Replace
switch statement with array lookup of handling functions so text can be
inserted before calling the function if necessary.
Make new Keymap class and include Escape and CSI maps with it.
make new classes for terminals (use termcap) and for editing functionality.
split Session class into smaller classes? how? command-mode classes? maybe
a chain of active modes, possibly prioritized? e.g. privileged command parser,
standard command parser, login parser/prompter, etc.
Do direct DNS lookup? What RFC? (1034/1035 I think.) tcp or udp? (both?)
Fix for very long names, /who wraps as if blurb.
Use unsigned for idle? check for overflow on /set idle.
*** Update client editing to match server!
Add a "/sync" command to see if messages were actually *received* or not.
Allow a username argument(s), and if not sent, pause if recipient attached,
unless "sync" user decides to abort. (this probably can't work for public's)
For discussion-matching efficiency, maintain list of joined discussions for
each session.
Deal with saving edited text somehow when tossing to get history lines.
Have minibuffer? [after current input line if non-empty, don't erase]
M-ESC -> "Eval:"? M-x commands? command mode?
Fix trim(line) on messages. Need to keep leading spaces.
Allow login & password both at the login: prompt (ideally blank password)
Better, use ...'s for password echo.
fix sending to Name object (with last or default sendlist or other?) when
associated session is gone.
fix problems with Name objects not aligning with Sessions after a /rename.
announcements
Allow true idle-time (keystroke level) timer on /signal. (reminder too?)
Allow !permit or !appoint or such to allow privileged discussion override.
Maybe add discussion moderator privilege level? Creator = 50, others = 10 by
default, /appoint can only create a lower-level moderator, allow privilege
level to be specified, privilege level 1 can't appoint modertors. Or, allow
up to equal level created, level 0 can't create new ones, default to (level-1).
Alternatively, record who appointed a moderator, only an "ancestor" could then
unappoint.
Let name/blurb use an extra column when there's a date in the "On Since".
(But not one with a year!)
/notify status on => *** You are "away", with blurb [shower]. ***
Let final ] and + share column in /who, etc.
Have Set class maintain a "universe" of objects and use bitmasks?
Have ~name match only against reserved names?
Have import and export procedures for object database for easy hand editing.
Maybe allow << to work on String or File objects as well as Datum objects?
Add receive blurb limit.
have match_name() take "exact" parameter to return boolean, match whitespace
and _'s uniformly, middle and ends.
disallow leading and trailing spaces in sendables, treat consecutive spaces
as one for matching purposes. Allow leading and trailing _'s, but treat like
spaces for matching purposes. ("___foo___bar___" == "_foo bar_" == "foo bar"
== "foo_ bar_" == "__foo bar", BUT "foo bar" != "foobar")
fix rename -> permissions
have permanent discussions.
/notify,/signal,/alias,/ignore?
PAGING.
inbox/771,772
Add OutputStream to user.h
full-screen idea -- when reviewing log, if message arrives, create a split
window at the bottom, switchable to it, let it grow to up to half screen.
===============================================================================
Add persistent objects. Have Object contain a database file & logical
address. Use blocks for data storage, addressing to multiples of 16 bytes,
first word of block & 0xfffffff0 == address of next block (link) in entry,
first word & 0x0f == encoded block size -- 0=16, 1=32, 2=64, 3=128, 4=256,
5=512, 6=1024, 7=2048, 8=4096, 9=8192, 10=16384, 11=32768, 12=65536,
13=131072, 14=262144, 15=524288. [maybe use 8 instead of 16?] [maybe use
mixed scheme, some scaling, some multiplying?]
Have root object for each database file, returned when opened. Overload <<
operator for outputting parts of objects to database entry, including for
Pointer class, saving logical database address. When object is to be
written to database, call << on object, which may recurse for subobjects.
When Object is swapped to disk, replace Object with StubObject? Or, maybe
objects can be swapped to disk, decrementing refcounts, letting Objects
expire? Or, have Pointer class hold logical address? Need some way to
release memory by swapping old objects to disk...
Possibly implement Btrees in objects saved? [inefficient, but integrated.]
-------------------------------------------------------------------------------
Registry Information: class ID, description, version (major/minor), class name,
code version, $Id$, compatibility version (major/minor or major only?).
Have a Token class.
Session(Token &key) calls OpenStream(ID,key)
class Storable: public Object
-------------------------------------------------------------------------------
class Database: public Object {
public:
Pointer<String> name;
int fd;
DBEntry header;
Database(char *db): name(db) {
fd = open(db,O_RDWR);
header = Open(0);
}
~Database() {
// Do what?
}
DBEntry Open(long addr) {
return DBEntry(*this,addr);
}
};
class DBEntry: public Object {
private:
long addr;
public:
// ...
};
-------------------------------------------------------------------------------
Add Handle class?
-------------------------------------------------------------------------------
block - 1st word - & ~0x0f = logical address (link)
& 0x0f = size/16
0x01 = 16
0x02 = 32,etc.
0x00 = extended size
=> next word (2 bytes)
= size/16 - 16
0x0000 = 256
0x0001 = 282
0xfff0 = 1048576
===============================================================================
*** make output streams persistent, and sessions. (Pending stream should not
*** be persistent, only Output stream in Session.) [flag on constructor?]
"group" class? privilege required for general group sending like "all" or
"everyone"?
session.h -- make *sendlist of type Pointer<Sendlist>. [Sendlist?]
[should reply be sendlist or name? reply to sender or sender and other
recipients?]
name.h -- name,user,blurb [wipe session on signoff, restore on name/user match]
List class -- add RemoveUnused() for Name list in session
*** save session information so state can be reset on restart?
*** permissions
*** watches -- List<Name> watch; //extend for what to watch for?
[have a concept of "friends" that get more attention?]
*** list commands, list commands w/multiple sendlists
*** input history
/alias
any operators worth using in general? <<? [watch for "out << Newline" --
needs to output '\n', not 10, need "out << endl" too, probably, and also
"out << format("%...",...)"]
use <<, >> operators for logfile, other files, telnet connection, buffer, etc.
have all outputting classes be derived from some base output class?
Add "/mode line" and "/mode char" commands to have server initiate change.
Ideally have "/mode auto" (default?) which switches to/from line mode as
network speed varies... (measure round-trip time of TIMING-MARKs?)
add blurb notification (not double notify for /here [blurb]?)
/reply command to set automatic reply while away/busy/gone.
(also "reply" keyword on /away et al, but still take blurb, prompt for reply.)
["Automatic reply from ...", send only once.]
multiple reserved names
save email address in User
sending to user
save detached sessions
add "zombie" session list for killed sessions that have detached output?
restart migration
!force
handle name [blurb] at Name: prompt.
/who & /idle keywords: here, away, idle (>5?), unidle (<=5?), idle < #,
idle > #, idle <= #, idle >= #, active (here/unidle), inactive (away/idle)
history
make two output streams in session, one for all output (no clear screen) and
another for pending output to be sent (including reviews of the other output)
make output stream(s) in discussions.
Review input line with output.
fix margin handling
No bells during output review!
Add past output queue, when input line is entered, queue input line as output,
in pending queue if nonempty (means the line is undrawn and not being echoed)
or in past output queue if pending queue is empty (means line has been echoed
and therefore does not need to be resent as output; echoing newline is enough).
-------------------------------------------------------------------------------
allow infinite blurbs and truncate when necessary? Could have "Name [blurb]+"
form when truncated; a /who-type command matching one name or given a "blurb"
("blurbs"?) option would show complete blurbs, perhaps broken across lines...
example:
/who
Name On Since Idle User
---- -------- ---- ----
~Rob [ This is an example of an ]+ detached 1d14:33 rob
+[extremely long blurb. A blurb so incredibly long that it could get quite ]+
+[annoying after a while... in fact, a blurb this long is downright obnoxio]+
+[us, if you think about it. ]
Deven Jan 5 8 deven
-------------------------------------------------------------------------------
Have server fork & exec new server, pass connections & sessions...
Have trailing spaces trimmed from output.
Add String class.
/away when idle 15
Move static Telnet::announce() to non-static Session::announce().
add array class for fdtable to use?
maybe have some sort of InitSession object? A different Session object for
Session protocol? Make announcements Session-based?
fd_set scanning optimization (portable & non-portable) [32/8/1 bit]
definitely make terminal-handling class, maybe use termcap
Allow a who default instead of here,active... (allow separate /idle one?)
maybe save some sort of "persona" structure or something so multiple string
copies of a name don't have to be saved, but the session doesn't either, or
the session can change the current name.
Do reference counting in objects and share as many objects as possible. For
example, share notification event objects until they have been delivered to
all parties. (all have reattached)
put in hash functions, symbol tables/variables for each user/session, etc?
improve editing support (kill-ring)
abstract terminal handling
allow for minimum-privilege level required for entry.
allow changed privileges with a !command
log !commands?
support tcp w/o telnet by not blocking on options and assuming no telnet
unless/until reply received.
no go aheads unless sga *refused* no block at least
check options against 0 or 3,could be 1 or 2!!
real command parser
improve account handling
add /notify
allow sending to users not signed on (send email notifications?)
add /invite command (email/talk/?)
output to files merged with Telnet I/O?
session layer (multi-session<->multi-user?)
telnet linemode option?
add "account" layer also, for account (person) versus "user" (alias)?
perhaps support highlighting somehow?
message length limits? (recipient confirmation?)
anti-spamming?
incorporate any sort of data compression/encryption/database code?
allow file transfers between users? (storage?)
Have new-handler to toss less important structures, like notifications?
Have operator new and operator delete for Block, etc. save "free" blocks?
User message logging? deliver with email/ftp? conversation/thread logging?
Public vs. private multiple reserved names?
user/pseudo-oriented permissions/notifications, permanent & temporary interest
levels, etc. (i.e. mark friends, etc.)
Have parent process with pipe as database manager, child as conferencing
server? both with connections
Clover gateway? Email/News/IRC/FTP/other?
Have some sort of /boot or /eject command to boot a user who is unwanted.
Require someone to second the motion, then ask for votes from all users.
Given a yes vote by a 1/2 or 2/3 majority given a quorom of votes cast,
eject the user for some period of time. (should quorom be based on active
users or all?)
more generalized parsing/tokenizing? (like a compiler)
use handles to some objects? (to allow swapping a la Mac)
persistent object storage
!restart to restart server. (fork, pass data over pipe, restart seamlessly)
have macro processor
/talk user@host <-> messages! [otalk/ntalk]
Add Meta-<digits> for repeat values, make ^U as repeat configurable.
Overload operator new in class Object so auto objects can be created?
===============================================================================
If the following patch is applied to object.h, all derived classes need to
declare their Pointer class as a friend. For example:
class Session: public Object {
friend class Pointer<Session>;
...
};
-------------------------------------------------------------------------------
This patch is against object.h 1.3:
-------------------------------------------------------------------------------
24c24
< private:
---
> protected:
29,31d28
< int References() { return RefCnt; }
< void NewReference() { RefCnt++; }
< void DeleteReference() { if (--RefCnt == 0) delete this; }
40,43c37,40
< Pointer(Pointer &p): ptr(p.ptr) { if (ptr) ptr->NewReference(); }
< Pointer(Type *p): ptr(p) { if (ptr) ptr->NewReference(); }
< Pointer(Type &p): ptr(&p) { if (ptr) ptr->NewReference(); }
< ~Pointer() { if (ptr) ptr->DeleteReference(); }
---
> Pointer(Pointer &p): ptr(p.ptr) { if (ptr) ptr->RefCnt++; }
> Pointer(Type *p): ptr(p) { if (ptr) ptr->RefCnt++; }
> Pointer(Type &p): ptr(&p) { if (ptr) ptr->RefCnt++; }
> ~Pointer() { if (ptr && --ptr->RefCnt == 0) delete ptr; }
45,46c42,43
< if (p.ptr) p.ptr->NewReference();
< if (ptr) ptr->DeleteReference();
---
> if (p.ptr) p.ptr->RefCnt++;
> if (ptr && --ptr->RefCnt == 0) delete ptr;
51,52c48,49
< if (p) p->NewReference();
< if (ptr) ptr->DeleteReference();
---
> if (p) p->RefCnt++;
> if (ptr && --ptr->RefCnt == 0) delete ptr;
58c55
< if (ptr) ptr->DeleteReference();
---
> if (ptr && --ptr->RefCnt == 0) delete ptr;
===============================================================================
===============================================================================
Use allocation pools for each class. (or at least some)
[Derived classes must use their own pool if the parent class uses a pool.]
-------------------------------------------------------------------------------
#include <sys/types.h>
#include "object.h"
template <class Type>
class Pool {
private:
void *blocks; // List of allocated blocks.
void *avail; // List of available objects.
Pool(Pool &); // copy protection
void operator =(Pool &); // copy protection
void grow(); // Allocate a new block of objects.
public:
Pool(): blocks(0),avail(0) { } // constructor
~Pool() { // destructor
while (blocks) {
char *p = (char *) blocks;
blocks = *((void **) p);
delete p;
}
}
void *alloc(size_t size) { // Allocate an available object.
if (!avail) grow();
void *p = avail;
avail = *((void **) p);
return p;
}
void free(void *obj) { // Free (make available) an object.
*((void **) obj) = avail;
avail = obj;
}
};
template <class Type>
void Pool<Type>::grow() // Allocate a new block of objects.
{
const int vsize = sizeof(void *);
const int size = sizeof(Type) < vsize ? vsize : sizeof(Type);
const int overhead = 12;
const int bsize = (((size + overhead - 1) / 8192) + 1) * 8192 - overhead;
const int elements = (bsize - vsize) / size;
char *block = new char[bsize];
char *p = block + vsize;
char *end = p + (elements - 1) * size;
*((void **) block) = blocks;
blocks = block;
avail = (void *) p;
while (p < end) {
*((void **) p) = (void *) (p + size);
p += size;
}
*((void **) end) = 0;
}
class Foo: public Object {
friend class Pointer<Foo>;
private:
static Pool<Foo> pool;
public:
Pointer<Foo> next;
void *operator new(size_t size) { return pool.alloc(size); }
void operator delete(void *p) { pool.free(p); }
Foo(Pointer<Foo> &foo): next(foo) { }
};
Pool<Foo> Foo::pool;
main()
{
Pointer<Foo> foo;
for (unsigned long i = 0; i < 100000; i++) foo = new Foo(foo);
}
===============================================================================
[original pre-1.0.0 TODO list]
Avoid adding duplicate lines to input history. (Check against last line.)
Possibly avoid adding <space><return>? (But only Session knows not to!)
Write a sendlist parsing function, call from DoSend() and message_start() in
session.cc... (For that matter, get rid of message_start()!)
Raw TCP connections don't disconnect on login timeout. (hang on TIMING-MARK)
[#33?]
Possibly add a VERSIONS document, listing the CVS versions for a release?
Regenerate configure.scan? Seems to be different; update configure.ac?
It would be nice to be able to promote an active guest session into a user
session when the account is created.
Strip leading and trailing spaces from names! Consider " " vs "_" a conflict.
Allow leading/trailing "_" chars, but strip them for conflict checking; maybe
make a utility routine to check names for conflicts?)
Fix /date command to show timezone, allow user to set a custom timezone?
Should leading ! be treated as a meta-character for non-admin sessions?
Auto-generated sendlist for a name with a leading / or ! is not quoted!
Implement "/set priv" command? (to lower privilege level, or maybe even raise
it by prompting for a username/passwd?)
Tie discussions to sessions/users instead of names?
Add privileged discussion overrides. [#24]
Add --help and --version command-line options. Add better options processing,
decide whether to use -word, --word or both.
Add a config file before 1.0.0? (Server name, admin email, banner message,
port number, etc.)
Add a length limit on names! (1024? 50-100?) Check in /rename too! Same
for discussion names and titles!
Add /set banner and /display banner, and /news...
Should be able to configure a site-specific banner. (Use %v or such for
version? Could this be integrated with a vsprintf() replacement?)
Add DoDisplay("uptime") with DoHowMany("") in Session::EnteredBlurb()?
Add a /set command to enable linemode in the telnet client.
Update history notes -- link to lilyCore history pages?
Allow a variable to control timestamp location, for those who prefer it at
the front of the line.
Review old Phoenix TODO list for relevant tasks.
Use getservbyname(), pass default port as string, to allow symbolic ports.
Add a -inittab option for foreground operation?
Use getrlimit(), setrlimit() and sysconf() in addition to getdtablesize().
*** Add time limits for "away" states.
Fix TCP detection to require a minimum time delay before giving up on telnet.
After this timeout, perhaps give a prompt for TCP users?
Destroy discussions when empty unless special? Maybe an idle timeout?
*** use accept() 3rd arg instead of getpeername()
Allow system variables (e.g. uptime) to be abbreviated?
Telnet::PrintMessage still has an "everyone" send -- is this used?
If a client is doing local echo, does ;/: expansion happen invisibly?
Have here/away/busy/gone set "transient" blurbs that mask "persistent" blurbs
set by /blurb; here/away/busy/gone without arguments would revert to the last
persistent blurb. (Maybe allow /finger or some other command show both
transient AND persistent blurbs?)
Possible: *** User [persistent, maybe] is now "gone". [transient, if any] ***
fix sending to Name object (with last or default sendlist or other?) when
associated session is gone.
fix problems with Name objects not aligning with Sessions after a /rename.
[original maybe-1.0.0 TODO list]
Fix discussion permissions not to operate by name. (How to handle guests?
[#26])
/kick to boot someone from a discussion without depermitting them?
/invite to ensure someone is permitted to a discussion and send an invitation?
Have ~name match only against reserved names?
Change event queue to use a Btree or similar instead of linear search? (Are
there other linear searches?)
"/here" alone act as "/here off"? have "/here same"? configurable default?
For /detach, always switch to "gone" unless here/away/busy/gone keyword
specified. (same or brb as keywords?) allow blurb w/detach
TAB sendlist completion & cycling.
Add some option to implicitly copy message to self? If so, erase input line?
Maybe reformat all messages automatically? (<-, << headers)
Make more generalized parser and keyword matching? (needs to be tunable)
When printing a message, if the destination name doesn't match the current
name, show the original destination name.
Instead of dequoting sendlist items in message_start(), do it elsewhere, and
call from DoWho(), etc. Maybe do dequoting in Sendlist::set()?
Modify "busy" state to discourage others sending to busy people. Does this