1
0
Fork 0
mirror of git://git.psyced.org/git/psyclpc synced 2024-08-15 03:20:16 +00:00

initial git creation

This commit is contained in:
PSYC 2009-03-03 04:27:01 +01:00
commit 2ede0de60e
278 changed files with 230984 additions and 0 deletions

80
mudlib/ACCESS.ALLOW Normal file
View file

@ -0,0 +1,80 @@
# ACCESS.ALLOW - Game access allowance rules
#----------------------------------------------------------------------------
# Access to the game is based on the user's IP address and the current time.
# These are matched against a set of rules and if a match is detected, a
# proper message is sent back and the connection is shutdown.
#
# This facility is active only if ACCESS_CONTROL has been defined in config.h
# If ACCESS_LOG is defined in config.h, all checks and their results are
# logged in the specified file.
#
# The rules are read from the file ACCESS_FILE (defined in config.h,
# typically "ACCESS.ALLOW" with a name relative to the mudlib directory).
# Every line specifies one rule and has to follow the syntax given below.
# Lines with a '#' as first character count as comments and are ignored, as
# are lines which do not conform to the rule syntax (but except for empty
# lines this should be relied upon).
#
# The rule file is (re)read whenever the gamedriver detects a change in its
# timestamp.
#
# The syntax for a rule is (no leading whitespace allowed!):
#
# <ipnum>:[p<port>]:<class>:<max>:<start>:<end>:<text>
# <ipnum>:[p<port>]:<class>:<max>:h<hours>:w<days>:m=<text>
#
# where
# ipnum: <byte>.<byte>.<byte>.<byte>, with byte = * or number
# There is only loose error checking - specifying an illegal
# address will have interesting consequences, but would
# most likely cause no error to occur.
# port: the port number to which the connection is made. Omission
# means 'any port'.
# class: number
# max: the maximum number of users, a number. The value -1 allows
# an unlimited number of users.
# start: hour this rule starts to be valid (0..23).
# end: hour this rule ceases to be valid (0..23).
# Setting both start and end to 0 skips any time check.
# hours: hours this rule is valid.
# This form allows several entries, separated with a ','.
# Every entry can be a single hour (0..23), or a range in the
# form '<start>-<end>'
# Omitting the entry skips any time check.
# days: the days this rule is valid.
# The syntax is similar to <hours> except for the
# allowable values: the days Sunday..Saturday are given as
# the numbers 0..6.
# Omitting the entry skips any day check.
# text: string to send if the rule matches.
#
# A class is defined by the first rule using it's number. This
# definition specifies the allowable <max>imum of users and the <text>
# to send. Subsequent rules for the same class just add new ipnumber/
# time rules, but don't change <max> or <text>
#
# ORDER MATTERS. That means if you allow 129.*.*.*, you have to put
# any restrictions on 129.132.*.* BEFORE this rule.
#
# Addresses not matching any rule at all are not allowed to connect. To get
# around this, add an appropriate 'allow-all' rule *.*.*.* at the very end.
#
# A typical rulefile would look like this one:
# SPARC cluster has access denied. Class 1
129.132.122.*:1:0:0:0:LPMUD access denied for your cluster.
# CALL-1A0 has access limited to some maximum, for now 5 logins. Class 2
129.132.106.*:2:5:8:20:Sorry, LPMUD is currently full.
# CALL-1A0 at all other times, its a 10 limit.
# Due to the rule order, this is effectively limited to times
# outside 8-20.
129.132.106.*:3:10:0:0:Sorry, LPMUD is currently full.
# No more than 5 users allowed from localhost while working hours :-)
127.0.0.1:42:5:h8-12,13-18:w1-5:m=Pick a better time.
# Everybody else is welcome.
*.*.*.*:0:-1:0:0:This message should never be printed.

22
mudlib/README Normal file
View file

@ -0,0 +1,22 @@
This directory holds various example and support files for mudlibs.
Especially important is the sys/ subdirectory with the driver-related
include files.
Other files are:
ACCESS.ALLOW : a typical access control file.
master_skeleton.c: a skeleton master, documenting all master lfuns.
telnet.h, telnetneg.c: the Wunderland telnet module, a complete implementation
of the telnet protocol.
test_master.c : a minimal test master for driver tests.
simul_efun-dr.c : a very old simul_efun file for a very old DR mudlib.
erq-tool.c : for 2.4.5 muds, a tool for interactive erq experiments.
dhrystone.c : an implementation of Dhrystone, called by the
test_master.
astar.c : an implementation of the A* pathfinding algorithm.
pgsql.c : example for using PostgreSQL
dns_resolve.c : a simul-efun for non-block DNS lookups
query_ip_name.c : a simul-efun for IPv4/IPv6 name lookups
uni-crasher/ : A stress test program, see the README in this dir.

196
mudlib/astar.c Normal file
View file

@ -0,0 +1,196 @@
#if 0
--------------------------------------------------------------------------
Date: Thu, 13 Dec 2001 00:34:12 -0700
From: Acius <helpsfamily@attbi.com>
A while back we were talking about eventually putting path-finding in
the driver, but I don't know if anyone came up with anything really
specific (I might add that I've been off the mailing list for a little
while now, thanks to @Home's problems). I wanted path-finding for my
MUD, and since it sounded like it might be a while until Lars has enough
time to play with it, I've implemented A-star in LP/C. The code is
attached to this message.
I have a couple reasons for posting the code: Firstly, anyone who might
want to use it can try it, and if they post their modifications and
bugfixes, I get better code for free :-). Also, it serves as an
interface and behavior suggestion for future code to be put into the
driver. I wrote it with this idea in mind, and I have attempted to make
the code a very general way to do 2d path-finding. The code could be
placed in a simul_efun for now, and simply commented out or removed when
and if driver path-finding code comes on line.
The parameters are:
* A string, giving the map on which you're doing the search
* The x, y of the starting location
* The x, y of the goal location
* A mapping of ([ character: cost ]) for all of the characters used in
the map string. All characters not included in the mapping are assumed
to be walls. A cost of 0 might not get the best path if you use it,
since Manhattan distance is used to guide the search and it will
overestimate (go read a good article on A-star).
Here's a quick example of how to use it:
.*.#.
.#...
...
I want to get from the upper left corner (0, 0) to the upper right
corner (4, 0), and I need to know the path to get there. The #'s are
walls, and may not be crossed. The '*' may be crossed, but it is a
"poisonous" tile and should not be crossed if there is an alternative.
Note that the grid doesn't have to be square; the function will append
each line with "\27"'s to make it square.
Here's how to make a function call to get this path:
string path;
path =
find_path(".*.#.\n.#...\n...", 0, 0, 4, 0, ([ '.': 1, '*': 100 ]));
if( path )
write("You should go "+path+"\n");
else
write("No path could be found.\n");
On my MUD, the call to find_path returns the string "sseeneen". If you
lower the cost of '*' to 5 (just change the 100 to a 5), then it returns
the string "eeseen".
If there are any other questions, please email me; this message is
getting long enough already. I particularly want to hear from you if you
get it working (or can't!) and if you find bugs or ways to make it more
efficient (it is not very efficient). I tried not to put in anything
MUDlib-specific, but sometimes I forget.
-- Acius
--------------------------------------------------------------------------
#endif
string find_path( string map, int startx, int starty, int goalx, int goaly, mapping costs ) {
// split_map will be an array of equal-length
//strings (will pad spaces to assure this)
string *split_map;
// i is for generic loops, map_width is width
// of split_map, goal is the destination point
// (All coordinates are stored as x + y *
// width). currpos is where the algorithm is
// looking, currcost is cost at currpos, newx,
// newy, newpos, and newcost are temps for
// figuring out where to look next.
int i, map_width, start, goal, currpos, currcost, newx, newy, newpos, newcost;
int ineighbor, iparent, iheap;
// closed is mapping from (int)coordinate:
// (int) cost & direction. Note that costs
// > 2^28 will cause undetected overflow
// problems -- if you keep costs reasonable,
// you shouldn't have a problem.
mapping closed;
// The open list, stored as a heap.
// Even-numbered elements hold coordinate information,
// odd-numbered ones give the cost for the previous
// even numbered coordinate.
int *open;
string path;
mixed tmp;
// Process the map into an easier-to-use format.
split_map = explode( map, "\n" );
map_width = 0;
// Find the length of the longest line in the "map"
for( i = sizeof(split_map); i-- ; )
if( map_width < strlen(split_map[i]) ) map_width = strlen(split_map[i]);
// Make all the lines that length by padding with escape characters.
// (Note: I use escapes because they are an unlikely character to be
// chosen for walking over, and unused characters are 'walls')
for( i = sizeof(split_map); i-- ; )
split_map[i] += sprintf( "%" + (map_width-strlen(split_map[i])) + "'\27's", "" );
// Sanity check
if( goalx < 0 || goalx >= map_width || goaly < 0 || goaly >= sizeof(split_map) )
return 0;
// Setup initial state.
start = startx + starty * map_width;
goal = goalx + goaly * map_width;
open = ({ 0, start });
closed = ([ start:0 ]);
while( sizeof(open) && !member(closed, goal) ) {
currcost = open[0];
currpos = open[1];
// Check if done.
if( currpos == goal ) {
closed[currpos] = currcost;
break;
}
// Pop the top cell off the heap.
open[0] = open[<2];
open[1] = open[<1];
open = open[0..<3];
iparent = 0;
iheap = 2;
while( iheap < sizeof(open) ) {
if( open[iparent] > open[iheap] && (iheap + 2 >= sizeof(open) || open[iheap] < open[iheap + 2]) ) {
tmp = open[iparent..iparent+1];
open[iparent..iparent + 1] = open[iheap..iheap + 1];
open[iheap..iheap + 1] = tmp;
}
else if( iheap + 2 < sizeof(open) && open[iparent] > open[iheap + 2] ) {
tmp = open[iparent..iparent+1];
open[iparent..iparent + 1] = open[iheap + 2..iheap + 3];
open[iheap + 2..iheap + 3] = tmp;
}
else
break;
iparent = iheap;
iheap = (iparent + 1) << 1;
}
// Add the neighbors of the popped cell to the heap
// 0 = east, 1 = north, 2 = west, 3 = south
for( ineighbor = 0; ineighbor < 4; ineighbor++ ) {
newx = (currpos % map_width) + ({ 1, 0, -1, 0 })[ineighbor];
newy = (currpos / map_width) + ({ 0, -1, 0, 1 })[ineighbor];
newcost = ({ 0x0, 0x1, 0x2, 0x3 })[ineighbor];
// Out of bounds, ignore it.
if( newx < 0 || newx >= map_width || newy < 0 || newy >= sizeof(split_map) )
continue;
// Solid wall, ignore it.
if( !member(costs, split_map[newy][newx]) ) continue;
newpos = newx + newy * map_width;
// Already checked, ignore it.
if( member(closed, newpos) ) continue;
// Ok, it's legit. Add it to the heap:
newcost |= (currcost & 0xFFFC) + (costs[split_map[newy][newx]] << 2);
newcost -= (abs(currpos % map_width) + abs(currpos / map_width)) << 2;
newcost += (abs(goalx - newx) + abs(goaly - newy)) << 2;
// Mark this cell as 'considered'
closed[newpos] = newcost;
iheap = sizeof(open);
open += ({ newcost, newpos });
if( iheap > 0 )
while( open[iparent = ((iheap >> 1) - 1) & -2] > open[iheap] ) {
tmp = open[iparent..iparent+1];
open[iparent..iparent+1] = open[iheap..iheap+1];
open[iheap..iheap+1] = tmp;
}
}
}
i = goal;
if( !member(closed, i) ) return 0;
path = "";
while( i != start ) {
path = ({ "e", "n", "w", "s" })[closed[i]&0x3] + path;
i += ({ -1, map_width, 1, -map_width })[closed[i]&0x3];
}
return path;
}

365
mudlib/dhrystone.c Normal file
View file

@ -0,0 +1,365 @@
//===========================================================================
// Dhrystone-2.1 Benchmark for LPC
//
// Don't take this too serious :-) Sven C. Dack
//===========================================================================
#define Default_Number_Of_Runs 10000
#pragma strong_types
//===========================================================================
// Support functions to simulate memory allocation and other stuff..
mixed *alloc_array_50() { return allocate(50); }
mixed *alloc_array_50_50() {
mixed *arr;
int i;
for (i = 50, arr = allocate(50); i--; arr[i] = allocate(50));
return arr;
}
mapping alloc_record() {
return ([ "Ptr_Comp": 0, "Discr": 0, "var_1": ({ 0, 0, "" }) ]);
}
mapping copy_record(mapping rec) {
mapping r;
r = copy(rec);
r["var_1"] = ({}) + rec["var_1"];
return r;
}
int times() {
int *ru;
ru = rusage();
return ru[0] + ru[1];
}
//===========================================================================
// The global variables.
#define Ident_1 0
#define Ident_2 1
#define Ident_3 2
#define Ident_4 3
#define Ident_5 4
#define Enum_Comp 0
#define Int_Comp 1
#define Str_Comp 2
mapping Ptr_Glob, Next_Ptr_Glob;
int Int_Glob;
int Bool_Glob;
int Ch_1_Glob, Ch_2_Glob;
mixed *Arr_1_Glob;
mixed *Arr_2_Glob;
int Begin_Time, End_Time, User_Time;
float Milliseconds, Dhrystones_Per_Second;
//===========================================================================
// Prototypes all functions (including those defined later).
void Proc_1(mapping m1);
void Proc_2(int i1);
void Proc_3(mapping m1);
void Proc_4();
void Proc_5();
void Proc_6(int i1, int i2);
void Proc_7(int i1, int i2, int i3);
void Proc_8(mixed *a1, mixed *a2, int i1, int i2);
int Func_1(int i1, int i2);
int Func_2(string s1, string s2);
int Func_3(int i1);
//===========================================================================
float main(int Number_Of_Runs, int silent) {
int Int_1_Loc, Int_2_Loc, Int_3_Loc;
int Ch_Index;
int Enum_Loc;
string Str_1_Loc, Str_2_Loc;
int Run_Index;
if (Number_Of_Runs <= 0)
Number_Of_Runs = Default_Number_Of_Runs;
Arr_1_Glob = alloc_array_50();
Arr_2_Glob = alloc_array_50_50();
Str_1_Loc = "";
Str_2_Loc = "";
Next_Ptr_Glob = alloc_record();
Ptr_Glob = alloc_record();
Ptr_Glob["Ptr_Comp"] = Next_Ptr_Glob;
Ptr_Glob["Discr"] = Ident_1;
Ptr_Glob["var_1"][Enum_Comp] = Ident_3;
Ptr_Glob["var_1"][Int_Comp] = 40;
Ptr_Glob["var_1"][Str_Comp] = "DHRYSTONE PROGRAM, SOME STRING";
Str_1_Loc = "DHRYSTONE PROGRAM, 1'ST STRING";
Arr_2_Glob[8][7] = 10;
if (!silent)
{
write("Dhrystone Benchmark, Version 2.1 (Language: LPC)\n");
write("Execution starts, " + Number_Of_Runs + " runs through Dhrystone\n");
}
Begin_Time = times();
for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index) {
Proc_5();
Proc_4();
Int_1_Loc = 2;
Int_2_Loc = 3;
Str_2_Loc = "DHRYSTONE PROGRAM, 2'ND STRING";
Enum_Loc = Ident_2;
Bool_Glob = !Func_2(Str_1_Loc, Str_2_Loc);
while (Int_1_Loc < Int_2_Loc) {
Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
Proc_7(Int_1_Loc, Int_2_Loc, &Int_3_Loc);
Int_1_Loc += 1;
}
Proc_8(Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
Proc_1(Ptr_Glob);
for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index) {
if (Enum_Loc == Func_1(Ch_Index, 'C')) {
Proc_6(Ident_1, &Enum_Loc);
Str_2_Loc = "DHRYSTONE PROGRAM, 3'RD STRING";
Int_2_Loc = Run_Index;
Int_Glob = Run_Index;
}
}
Int_2_Loc = Int_2_Loc * Int_1_Loc;
Int_1_Loc = Int_2_Loc / Int_3_Loc;
Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
Proc_2(&Int_1_Loc);
}
End_Time = times();
if (!silent)
{
write("Execution ends.\n");
write("Final values of the variables used in the benchmark:\n\n");
printf("Int_Glob: %d\n", Int_Glob);
printf(" should be: %d\n", 5);
printf("Bool_Glob: %d\n", Bool_Glob);
printf(" should be: %d\n", 1);
printf("Ch_1_Glob: %c\n", Ch_1_Glob);
printf(" should be: %c\n", 'A');
printf("Ch_2_Glob: %c\n", Ch_2_Glob);
printf(" should be: %c\n", 'B');
printf("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]);
printf(" should be: %d\n", 7);
printf("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]);
printf(" should be: Number_Of_Runs + 10\n");
#if 0
printf("Ptr_Glob->\n");
printf(" Ptr_Comp: %O\n", Ptr_Glob["Ptr_Comp"]);
printf(" should be: (implementation-dependent)\n");
#endif
printf(" Discr: %d\n", Ptr_Glob["Discr"]);
printf(" should be: %d\n", 0);
printf(" Enum_Comp: %d\n", Ptr_Glob["var_1"][Enum_Comp]);
printf(" should be: %d\n", 2);
printf(" Int_Comp: %d\n", Ptr_Glob["var_1"][Int_Comp]);
printf(" should be: %d\n", 17);
printf(" Str_Comp: %s\n", Ptr_Glob["var_1"][Str_Comp]);
printf(" should be: DHRYSTONE PROGRAM, SOME STRING\n");
#if 0
printf("Next_Ptr_Glob->\n");
printf(" Ptr_Comp: %O\n", Next_Ptr_Glob["Ptr_Comp"]);
printf(" should be: (implementation-dependent), same as above\n");
#endif
printf(" Discr: %d\n", Next_Ptr_Glob["Discr"]);
printf(" should be: %d\n", 0);
printf(" Enum_Comp: %d\n", Next_Ptr_Glob["var_1"][Enum_Comp]);
printf(" should be: %d\n", 1);
printf(" Int_Comp: %d\n", Next_Ptr_Glob["var_1"][Int_Comp]);
printf(" should be: %d\n", 18);
printf(" Str_Comp: %s\n", Next_Ptr_Glob["var_1"][Str_Comp]);
printf(" should be: DHRYSTONE PROGRAM, SOME STRING\n");
printf("Int_1_Loc: %d\n", Int_1_Loc);
printf(" should be: %d\n", 5);
printf("Int_2_Loc: %d\n", Int_2_Loc);
printf(" should be: %d\n", 13);
printf("Int_3_Loc: %d\n", Int_3_Loc);
printf(" should be: %d\n", 7);
printf("Enum_Loc: %d\n", Enum_Loc);
printf(" should be: %d\n", 1);
printf("Str_1_Loc: %s\n", Str_1_Loc);
printf(" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
printf("Str_2_Loc: %s\n", Str_2_Loc);
printf(" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
printf("\n");
}
User_Time = End_Time - Begin_Time;
if (User_Time <= 0) {
if (!silent) {
printf("Your rusage() doesn't seem to work: User_Time is %d.\n", User_Time);
write("\n");
}
} else if (User_Time < (2*100)) {
if (!silent) {
write("Measured time too small to obtain meaningful results\n");
write("Please increase number of runs\n");
write("\n");
}
} else {
Milliseconds = to_float(User_Time) / Number_Of_Runs;
Dhrystones_Per_Second = 1000.0 * Number_Of_Runs / User_Time;
if (!silent) {
printf ("Milliseconds for one run through Dhrystone: ");
printf ("%6.1f \n", Milliseconds);
printf ("Dhrystones per Second: ");
printf ("%6.1f \n", Dhrystones_Per_Second);
}
}
return Dhrystones_Per_Second;
}
void Proc_1(mapping Ptr_Val_Par) {
mapping Next_Record;
Next_Record = Ptr_Val_Par["Ptr_Comp"];
Ptr_Val_Par["Ptr_Comp"] = copy_record(Ptr_Glob);
Ptr_Val_Par["var_1"][Int_Comp] = 5;
Next_Record["var_1"][Str_Comp] = Ptr_Val_Par["var_1"][Str_Comp];
Next_Record["var_1"][Int_Comp] = Ptr_Val_Par["var_1"][Int_Comp];
Next_Record["Ptr_Comp"] = Ptr_Val_Par["Ptr_Comp"];
Proc_3(&(Next_Record["Ptr_Comp"]));
if (Next_Record["Discr"] == Ident_1) {
Next_Record["var_1"][Int_Comp] = 6;
Proc_6( Ptr_Val_Par["var_1"][Enum_Comp],
&(Next_Record["var_1"][Enum_Comp]));
Next_Record["Ptr_Comp"] = Ptr_Glob["Ptr_Comp"];
Proc_7( Next_Record["var_1"][Int_Comp], 10,
&(Next_Record["var_1"][Int_Comp]));
} else
Ptr_Val_Par = copy_record(Ptr_Val_Par["Ptr_Comp"]);
}
void Proc_2(int Int_Par_Ref) {
int Int_Loc, Enum_Loc;
Int_Loc = Int_Par_Ref + 10;
do
if (Ch_1_Glob == 'A') {
Int_Loc -= 1;
Int_Par_Ref = Int_Loc - Int_Glob;
Enum_Loc = Ident_1;
} while (Enum_Loc != Ident_1);
}
void Proc_3(mapping Ptr_Ref_Par) {
if (Ptr_Glob != 0)
Ptr_Ref_Par = Ptr_Glob["Ptr_Comp"];
Proc_7(10, Int_Glob, &(Ptr_Glob["var_1"][Int_Comp]));
}
void Proc_4() {
int Bool_Loc;
Bool_Loc = Ch_1_Glob == 'A';
Bool_Glob = Bool_Loc | Bool_Glob;
Ch_2_Glob = 'B';
}
void Proc_5() {
Ch_1_Glob = 'A';
Bool_Glob = 0 ;
}
void Proc_6(int Enum_Val_Par, int Enum_Ref_Par) {
Enum_Ref_Par = Enum_Val_Par;
if (!Func_3(Enum_Val_Par))
Enum_Ref_Par = Ident_4;
switch (Enum_Val_Par) {
case Ident_1:
Enum_Ref_Par = Ident_1;
break;
case Ident_2:
if (Int_Glob > 100)
Enum_Ref_Par = Ident_1;
else
Enum_Ref_Par = Ident_4;
break;
case Ident_3:
Enum_Ref_Par = Ident_2;
break;
case Ident_4:
break;
case Ident_5:
Enum_Ref_Par = Ident_3;
break;
}
}
void Proc_7(int Int_1_Par_Val, int Int_2_Par_Val, int Int_Par_Ref) {
int Int_Loc;
Int_Loc = Int_1_Par_Val + 2;
Int_Par_Ref = Int_2_Par_Val + Int_Loc;
}
void Proc_8 (mixed *Arr_1_Par_Ref, mixed *Arr_2_Par_Ref,
int Int_1_Par_Val, int Int_2_Par_Val) {
int Int_Index, Int_Loc;
Int_Loc = Int_1_Par_Val + 5;
Arr_1_Par_Ref[Int_Loc] = Int_2_Par_Val;
Arr_1_Par_Ref[Int_Loc + 1] = Arr_1_Par_Ref[Int_Loc];
Arr_1_Par_Ref[Int_Loc + 30] = Int_Loc;
for (Int_Index = Int_Loc; Int_Index <= Int_Loc + 1; ++Int_Index)
Arr_2_Par_Ref[Int_Loc][Int_Index] = Int_Loc;
Arr_2_Par_Ref[Int_Loc][Int_Loc - 1] += 1;
Arr_2_Par_Ref[Int_Loc + 20][Int_Loc] = Arr_1_Par_Ref[Int_Loc];
Int_Glob = 5;
}
int Func_1(int Ch_1_Par_Val, int Ch_2_Par_Val) {
int Ch_1_Loc, Ch_2_Loc;
Ch_1_Loc = Ch_1_Par_Val;
Ch_2_Loc = Ch_1_Loc;
if (Ch_2_Loc != Ch_2_Par_Val)
return Ident_1;
else {
Ch_1_Glob = Ch_1_Loc;
return Ident_2;
}
}
int Func_2(string Str_1_Par_Ref, string Str_2_Par_Ref) {
int Int_Loc, Ch_Loc;
Int_Loc = 2;
while (Int_Loc <= 2)
if (Func_1(Str_1_Par_Ref[Int_Loc], Str_2_Par_Ref[Int_Loc + 1]) == Ident_1) {
Ch_Loc = 'A';
Int_Loc += 1;
}
if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
Int_Loc = 7;
if (Ch_Loc == 'R')
return 1;
else {
if (Str_1_Par_Ref > Str_2_Par_Ref) {
Int_Loc += 7;
Int_Glob = Int_Loc;
return 1;
} else
return 0;
}
}
int Func_3(int Enum_Par_Val) {
int Enum_Loc;
Enum_Loc = Enum_Par_Val;
if (Enum_Loc == Ident_3)
return 1;
else
return 0;
}

381
mudlib/dhrystone2.c Normal file
View file

@ -0,0 +1,381 @@
//===========================================================================
// Dhrystone-2.1 Benchmark for LPC
//
// Don't take this too serious :-) Sven C. Dack
//
// Compared to the original LPC dhrystone, this one has been modified
// to make less indirect data accesses in order to bring it more in
// line with Python's pystone.
//===========================================================================
#define Default_Number_Of_Runs 1000
#pragma strong_types
//===========================================================================
// Support functions to simulate memory allocation and other stuff..
mixed *alloc_array_50() { return allocate(50); }
mixed *alloc_array_50_50() {
mixed *arr;
int i;
for (i = 50, arr = allocate(50); i--; arr[i] = allocate(50));
return arr;
}
mixed * alloc_record() {
#define M_PTR_COMP 0
#define M_DISCR 1
#define M_ENUM_COMP 2
#define M_INT_COMP 3
#define M_STR_COMP 4
#define M_LENGTH 5
return ({ /* M_PTR_COMP */ 0
, /* M_DISCR */ 0
, /* M_ENUM_COMP */ 0
, /* M_INT_COMP */ 0
, /* M_STR_COMP */ ""
});
}
mixed * copy_record(mixed * rec) {
mixed * r;
return copy(rec);
}
int times() {
int *ru;
ru = rusage();
return ru[0] + ru[1];
}
//===========================================================================
// The global variables.
#define Ident_1 0
#define Ident_2 1
#define Ident_3 2
#define Ident_4 3
#define Ident_5 4
#define Enum_Comp 0
#define Int_Comp 1
#define Str_Comp 2
mixed * Ptr_Glob, Next_Ptr_Glob;
int Int_Glob;
int Bool_Glob;
int Ch_1_Glob, Ch_2_Glob;
mixed *Arr_1_Glob;
mixed *Arr_2_Glob;
int Begin_Time, End_Time, User_Time;
float Milliseconds, Dhrystones_Per_Second;
//===========================================================================
// Prototypes all functions (including those defined later).
void Proc_1(mixed * m1);
int Proc_2(int i1);
mixed * Proc_3(mixed * m1);
void Proc_4();
void Proc_5();
int Proc_6(int i1);
int Proc_7(int i1, int i2);
void Proc_8(mixed *a1, mixed *a2, int i1, int i2);
int Func_1(int i1, int i2);
int Func_2(string s1, string s2);
int Func_3(int i1);
//===========================================================================
float main(int Number_Of_Runs, int silent) {
int Int_1_Loc, Int_2_Loc, Int_3_Loc;
int Ch_Index;
int Enum_Loc;
string Str_1_Loc, Str_2_Loc;
int Run_Index;
if (Number_Of_Runs <= 0)
Number_Of_Runs = Default_Number_Of_Runs;
Arr_1_Glob = alloc_array_50();
Arr_2_Glob = alloc_array_50_50();
Str_1_Loc = "";
Str_2_Loc = "";
Next_Ptr_Glob = alloc_record();
Ptr_Glob = alloc_record();
Ptr_Glob[M_PTR_COMP] = Next_Ptr_Glob;
Ptr_Glob[M_DISCR] = Ident_1;
Ptr_Glob[M_ENUM_COMP] = Ident_3;
Ptr_Glob[M_INT_COMP] = 40;
Ptr_Glob[M_STR_COMP] = "DHRYSTONE PROGRAM, SOME STRING";
Str_1_Loc = "DHRYSTONE PROGRAM, 1'ST STRING";
Arr_2_Glob[8][7] = 10;
if (!silent) {
write("Dhrystone Benchmark, Version 2.1 (Language: LPC)\n");
write("Execution starts, " + Number_Of_Runs + " runs through Dhrystone\n");
}
Begin_Time = times();
for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index) {
Proc_5();
Proc_4();
Int_1_Loc = 2;
Int_2_Loc = 3;
Str_2_Loc = "DHRYSTONE PROGRAM, 2'ND STRING";
Enum_Loc = Ident_2;
Bool_Glob = !Func_2(Str_1_Loc, Str_2_Loc);
while (Int_1_Loc < Int_2_Loc) {
Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
Int_3_Loc = Proc_7(Int_1_Loc, Int_2_Loc);
Int_1_Loc += 1;
}
Proc_8(Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
Proc_1(Ptr_Glob);
for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index) {
if (Enum_Loc == Func_1(Ch_Index, 'C')) {
Enum_Loc = Proc_6(Ident_1);
//Str_2_Loc = "DHRYSTONE PROGRAM, 3'RD STRING";
//Int_2_Loc = Run_Index;
//Int_Glob = Run_Index;
}
}
Int_2_Loc = Int_2_Loc * Int_1_Loc;
Int_1_Loc = Int_2_Loc / Int_3_Loc;
Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
Int_1_Loc = Proc_2(Int_1_Loc);
}
End_Time = times();
if (!silent)
{
write("Execution ends.\n");
write("Final values of the variables used in the benchmark:\n\n");
printf("Int_Glob: %d\n", Int_Glob);
printf(" should be: %d\n", 5);
printf("Bool_Glob: %d\n", Bool_Glob);
printf(" should be: %d\n", 1);
printf("Ch_1_Glob: %c\n", Ch_1_Glob);
printf(" should be: %c\n", 'A');
printf("Ch_2_Glob: %c\n", Ch_2_Glob);
printf(" should be: %c\n", 'B');
printf("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]);
printf(" should be: %d\n", 7);
printf("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]);
printf(" should be: Number_Of_Runs + 10\n");
#if 0
printf("Ptr_Glob->\n");
printf(" Ptr_Comp: %O\n", Ptr_Glob[M_PTR_COMP]);
printf(" should be: (implementation-dependent)\n");
#endif
printf(" Discr: %d\n", Ptr_Glob[M_DISCR]);
printf(" should be: %d\n", 0);
printf(" Enum_Comp: %d\n", Ptr_Glob[M_ENUM_COMP]);
printf(" should be: %d\n", 2);
printf(" Int_Comp: %d\n", Ptr_Glob[M_INT_COMP]);
printf(" should be: %d\n", 17);
printf(" Str_Comp: %s\n", Ptr_Glob[M_STR_COMP]);
printf(" should be: DHRYSTONE PROGRAM, SOME STRING\n");
#if 0
printf("Next_Ptr_Glob->\n");
printf(" Ptr_Comp: %O\n", Next_Ptr_Glob[M_PTR_COMP]);
printf(" should be: (implementation-dependent), same as above\n");
#endif
printf(" Discr: %d\n", Next_Ptr_Glob[M_DISCR]);
printf(" should be: %d\n", 0);
printf(" Enum_Comp: %d\n", Next_Ptr_Glob[M_ENUM_COMP]);
printf(" should be: %d\n", 1);
printf(" Int_Comp: %d\n", Next_Ptr_Glob[M_INT_COMP]);
printf(" should be: %d\n", 18);
printf(" Str_Comp: %s\n", Next_Ptr_Glob[M_STR_COMP]);
printf(" should be: DHRYSTONE PROGRAM, SOME STRING\n");
printf("Int_1_Loc: %d\n", Int_1_Loc);
printf(" should be: %d\n", 5);
printf("Int_2_Loc: %d\n", Int_2_Loc);
printf(" should be: %d\n", 13);
printf("Int_3_Loc: %d\n", Int_3_Loc);
printf(" should be: %d\n", 7);
printf("Enum_Loc: %d\n", Enum_Loc);
printf(" should be: %d\n", 1);
printf("Str_1_Loc: %s\n", Str_1_Loc);
printf(" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
printf("Str_2_Loc: %s\n", Str_2_Loc);
printf(" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
printf("\n");
}
User_Time = End_Time - Begin_Time;
if (User_Time <= 0) {
if (!silent) {
printf("Your rusage() doesn't seem to work: User_Time is %d.\n", User_Time);
write("\n");
}
} else if (User_Time < (2*100)) {
if (!silent) {
write("Measured time too small to obtain meaningful results\n");
write("Please increase number of runs\n");
write("\n");
}
} else {
Milliseconds = to_float(User_Time) / Number_Of_Runs;
Dhrystones_Per_Second = 1000.0 * Number_Of_Runs / User_Time;
if (!silent)
{
printf ("Milliseconds for one run through Dhrystone: ");
printf ("%6.1f \n", Milliseconds);
printf ("Dhrystones per Second: ");
printf ("%6.1f \n", Dhrystones_Per_Second);
}
}
return Dhrystones_Per_Second;
}
void Proc_1(mixed * Ptr_Val_Par) {
mixed * Next_Record;
Next_Record = Ptr_Val_Par[M_PTR_COMP];
Ptr_Val_Par[M_PTR_COMP] = copy_record(Ptr_Glob);
Ptr_Val_Par[M_INT_COMP] = 5;
Next_Record[M_STR_COMP] = Ptr_Val_Par[M_STR_COMP];
Next_Record[M_INT_COMP] = Ptr_Val_Par[M_INT_COMP];
Next_Record[M_PTR_COMP] = Ptr_Val_Par[M_PTR_COMP];
Next_Record[M_PTR_COMP] = Proc_3(Next_Record[M_PTR_COMP]);
if (Next_Record[M_DISCR] == Ident_1) {
Next_Record[M_INT_COMP] = 6;
Next_Record[M_ENUM_COMP] = Proc_6(Ptr_Val_Par[M_ENUM_COMP]);
Next_Record[M_PTR_COMP] = Ptr_Glob[M_PTR_COMP];
Next_Record[M_INT_COMP] = Proc_7( Next_Record[M_INT_COMP], 10);
} else
Ptr_Val_Par = copy_record(Ptr_Val_Par[M_PTR_COMP]);
}
int Proc_2(int Int_Par) {
int Int_Loc, Enum_Loc;
Int_Loc = Int_Par + 10;
do
if (Ch_1_Glob == 'A') {
Int_Loc -= 1;
Int_Par = Int_Loc - Int_Glob;
Enum_Loc = Ident_1;
}
while (Enum_Loc != Ident_1);
return Int_Par;
}
mixed * Proc_3(mixed * Ptr_Ref_Par) {
if (Ptr_Glob != 0)
Ptr_Ref_Par = Ptr_Glob[M_PTR_COMP];
Ptr_Glob[M_INT_COMP] = Proc_7(10, Int_Glob);
return Ptr_Ref_Par;
}
void Proc_4() {
int Bool_Loc;
Bool_Loc = Ch_1_Glob == 'A';
Bool_Glob = Bool_Loc | Bool_Glob;
Ch_2_Glob = 'B';
}
void Proc_5() {
Ch_1_Glob = 'A';
Bool_Glob = 0 ;
}
int Proc_6(int Enum_Val_Par) {
int Enum_Par_Out;
Enum_Par_Out = Enum_Val_Par;
if (!Func_3(Enum_Val_Par))
Enum_Par_Out = Ident_4;
switch (Enum_Val_Par) {
case Ident_1:
Enum_Par_Out = Ident_1;
break;
case Ident_2:
if (Int_Glob > 100)
Enum_Par_Out = Ident_1;
else
Enum_Par_Out = Ident_4;
break;
case Ident_3:
Enum_Par_Out = Ident_2;
break;
case Ident_4:
break;
case Ident_5:
Enum_Par_Out = Ident_3;
break;
}
return Enum_Par_Out;
}
int Proc_7(int Int_1_Par_Val, int Int_2_Par_Val) {
int Int_Loc;
Int_Loc = Int_1_Par_Val + 2;
return Int_2_Par_Val + Int_Loc;
}
void Proc_8 (mixed *Arr_1_Par_Ref, mixed *Arr_2_Par_Ref,
int Int_1_Par_Val, int Int_2_Par_Val) {
int Int_Index, Int_Loc;
Int_Loc = Int_1_Par_Val + 5;
Arr_1_Par_Ref[Int_Loc] = Int_2_Par_Val;
Arr_1_Par_Ref[Int_Loc + 1] = Arr_1_Par_Ref[Int_Loc];
Arr_1_Par_Ref[Int_Loc + 30] = Int_Loc;
for (Int_Index = Int_Loc; Int_Index <= Int_Loc + 1; ++Int_Index)
Arr_2_Par_Ref[Int_Loc][Int_Index] = Int_Loc;
Arr_2_Par_Ref[Int_Loc][Int_Loc - 1] += 1;
Arr_2_Par_Ref[Int_Loc + 20][Int_Loc] = Arr_1_Par_Ref[Int_Loc];
Int_Glob = 5;
}
int Func_1(int Ch_1_Par_Val, int Ch_2_Par_Val) {
int Ch_1_Loc, Ch_2_Loc;
Ch_1_Loc = Ch_1_Par_Val;
Ch_2_Loc = Ch_1_Loc;
if (Ch_2_Loc != Ch_2_Par_Val)
return Ident_1;
else {
Ch_1_Glob = Ch_1_Loc;
return Ident_2;
}
}
int Func_2(string Str_1_Par_Ref, string Str_2_Par_Ref) {
int Int_Loc, Ch_Loc;
Int_Loc = 2;
while (Int_Loc <= 2)
if (Func_1(Str_1_Par_Ref[Int_Loc], Str_2_Par_Ref[Int_Loc + 1]) == Ident_1) {
Ch_Loc = 'A';
Int_Loc += 1;
}
if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
Int_Loc = 7;
if (Ch_Loc == 'R')
return 1;
else {
if (Str_1_Par_Ref > Str_2_Par_Ref) {
Int_Loc += 7;
Int_Glob = Int_Loc;
return 1;
} else
return 0;
}
}
int Func_3(int Enum_Par_Val) {
int Enum_Loc;
Enum_Loc = Enum_Par_Val;
if (Enum_Loc == Ident_3)
return 1;
else
return 0;
}

112
mudlib/dns_resolve.c Normal file
View file

@ -0,0 +1,112 @@
void
dns_resolve (string hostname, closure callback)
// Try to lookup the IP for the fully qualified <hostname> using direct ERQ
// communication. Once the name is resolved, call callback() with the
// resolved name as parameter.
//
// Note: If the ERQ is unavailable, callback() is called with the original
// hostname.
//
// preferably to be installed as "simul efun." latest version available
// in world/net/library.i of psycMUVE (download from http://muve.pages.de)
// this version runs with broken and fixed erq's alike.
//
// Written by Tobias@Heldensaga and Arne@Elridion.
{
closure c;
if (sscanf(hostname,"%~D.%~D.%~D.%~D") == 4) {
// hostname is an IP already. Just call the callback.
funcall(callback, hostname);
return;
}
c = lambda( ({ 'name }), ({
(#'switch), ({ #'sizeof, 'name }),
({ 4 }), // ERQ: name resolved!
({ (#',),
({ (#'=),'name,({ (#'map),'name,#'&,255 }) }),
({ (#'=),'name,
({
(#'sprintf),"%d.%d.%d.%d",
({ #'[, 'name, 0 }),
({ #'[, 'name, 1 }),
({ #'[, 'name, 2 }),
({ #'[, 'name, 3 })
})
}),
({ (#'funcall), callback, 'name })
}),
(#'break),
({ 6 + strlen(hostname) }), // XERQ
({ (#',),
({ (#'=),'name,({ (#'map),'name,#'&,255 }) }),
({ (#'=),'name,
({
(#'sprintf),"%d.%d.%d.%d",
({ #'[, 'name, 1
}),
({ #'[, 'name, 2
}),
({ #'[, 'name, 3
}),
({ #'[, 'name, 4 })
})
}),
({ (#'funcall), callback, 'name })
}),
(#'break),
({ #'default }),
({
#'debug_message, "FATAL: ERQ could not resolve \""
+ hostname + "\". The callback will not be called.\n"
}),
(#'break)
})
);
#ifdef THEDAYWEARESURENOONERUNSABUGGYERQ
if (!send_erq(ERQ_LOOKUP, hostname, c))
#else
// appending the zero byte fixes a bug in erq. sick!
if (!send_erq(ERQ_LOOKUP, to_array(hostname) + ({ 0 }), c))
#endif
{
// if we cannot resolve using erq, we'll send back the hostname,
// so the driver can do a blocking resolve itself (needed for
// net_connect())
funcall(callback, hostname);
}
}
#if 0
/*------------------------------------------------------------------------*/
// typical usage example taken from PSYCmuve world/net/irc/gatebot.c
// this ensures a non-blocking connect to a remote service even by name.
//
connect(host, port) {
unless (host) host = IRCNET_HOST;
unless (port) port = IRCNET_PORT;
D2( D("IRCgate resolving hostname "+ host +"\n"); )
dns_resolve(host, lambda(({ 'result }),
({ #'connect2, 'result, port })));
}
connect2(host, port) {
#if __EFUN_DEFINED__(net_connect)
int res;
D0( D(S("IRCgate attempting connect to %O:%O\n", host, port)); )
res = net_connect(host, port);
if (res) monitor_report("_failure_network_connect_call",
"ircbot: connect to "+host+" returns "+ res);
return res;
#else
D2( D("IRCgate * Oh, driver does not provide net_connect()\n"); )
return -9;
#endif
}
#endif /* EXAMPLE */

214
mudlib/erq-tool.c Normal file
View file

@ -0,0 +1,214 @@
#include <erq.h>
object command_giver;
int *ticket;
int verbose = 1;
short() {
return "Erq tool";
}
id(s) {
switch(s) {
case "erq-tool":
case "erq tool":
case "erq":
return 1;
default:
return 0;
}
}
long() {
return "\
This tool allows you to use the ERQ_SPAWN / ERQ_SEND / ERQ_KILL requests\n\
of the external command demon.\n\
\n\
Usage:\n\
e <program> <arguments>\n\
start <program> with <arguments>. Blanks, tabs and backslashes have to be\n\
quoted if desired as a part of the program name and / or an argument.\n\
The text is directly sent to the ERQ_SPAWN request, which does the\n\
commandline interpretation wrt. blanks and whitespace.\n\
You can only start a new program with this tool while it is not\n\
currently controlling another one.\n\
e <text>\n\
send <text> to the standard input of the running program.\n\
er\n\
send a single newline to the standard input of the running program.\n\
ekill\n\
kill the running program\n\
ekill <signal>\n\
send <signal> to the running program.\n\
everbose\n\
toggle verbose mode.\n\
econnect\n\
send all input to stdin of the running program.\n\
\n\
output from stdout will be displayed with a prepended single quote,\n\
output from stderr will be displayed with a prepended double quote.\n\
";
}
get() {
return 1;
}
drop(silently) {
return query_verb() != "give";
}
init() {
add_action("erq", "e");
add_action("erq", "er");
add_action("ekill", "ekill");
add_action("everbose", "everbose");
add_action("econnect", "econnect");
}
receive_output(a) {
if (!ticket) {
switch(a[0]) {
case ERQ_OK:
write("Command accepted.\n");
ticket = a[1..];
return;
case ERQ_E_ARGLENGTH:
write("Too long argument\n");
break;
case ERQ_E_ARGNUMBER:
write("Too many arguments\n");
break;
case ERQ_E_PATHLEN:
write("Too long pathname\n");
break;
case ERQ_E_ARGFORMAT:
write("Syntax error\n");
break;
case ERQ_E_ILLEGAL:
write("Illegal pathname\n");
break;
case ERQ_E_FORKFAIL:
write("Fork failed\n");
break;
default:
write("Unknown error, command rejected\n");
break;
}
command_giver = 0;
return;
}
switch(a[0]) {
case ERQ_STDOUT:
a[0] = '\'';
tell_object(command_giver, to_string(a));
return;
case ERQ_STDERR:
a[0] = '\"';
tell_object(command_giver, to_string(a));
return;
case ERQ_EXITED:
tell_object(command_giver,
sprintf("Program exited with status %d.\n", a[1]));
break;
case ERQ_SIGNALED:
tell_object(command_giver,
sprintf("Program caught signal %d.\n", a[1]));
break;
case ERQ_E_UNKNOWN:
tell_object(command_giver, "Unknown error.\n");
break;
}
command_giver = 0;
ticket = 0;
}
send_reply(a, p, s) {
switch (a[0]) {
case ERQ_OK:
if (verbose)
tell_object(p, "Ok.\n");
break;
default:
tell_object(p, "Input not fully accepted.\n");
break;
}
}
kill_reply(a, p, s) {
switch (a[0]) {
case ERQ_OK:
if (verbose)
tell_object(p, "Ok.\n");
break;
case ERQ_E_TICKET:
tell_object(p, "Trying to kill a dead process\n");
break;
case ERQ_E_ILLEGAL:
tell_object(p, "Illegal signal\n");
break;
default:
tell_object(p, "Kill error.\n");
break;
}
}
erq(s) {
if (!s)
s = "";
if (ticket) {
send_erq(ERQ_SEND, ticket+to_array(s)+({'\n'}), lambda(({'a}),
({#'send_reply, 'a, command_giver, s})));
return 1;
} else if (!command_giver) {
command_giver = this_player();
send_erq(ERQ_SPAWN, s, #'receive_output);
return 1;
} else {
write("Waiting for command to be accepted\n");
return 1;
}
}
ekill(s) {
int signal;
if (!ticket) {
write("No program running\n");
return 1;
}
if ( !(s && sscanf(s, "%d", signal)) )
signal = 9;
send_erq(ERQ_KILL, ticket+({0,0,0,signal}), lambda(({'a}),
({#'kill_reply, 'a, command_giver, signal})));
return 1;
}
everbose(s) {
switch(s) {
case "on":
verbose = 1;
return 1;
case "off":
verbose = 0;
return 1;
case 0:
verbose = !verbose;
return 1;
}
}
econnect() {
write("Use 'edisconnect' to stop.\n");
add_action("erq", "", 2);
add_action("edisconnect", "edisconnect");
add_action("erq", "er");
return 1;
}
edisconnect() {
remove_action("");
remove_action("edisconnect");
remove_action("er");
return 1;
}

1255
mudlib/master_skeleton.c Normal file

File diff suppressed because it is too large Load diff

171
mudlib/pgsql.c Normal file
View file

@ -0,0 +1,171 @@
// Example object for the use of PostgreSQL efuns.
inherit "/i/item";
inherit "/i/move";
#define TP(x) player->tell(x)
//#define TP(x) this_player()->tell(x)
#include <input_to.h>
#include <pgsql.h>
#include <lpctypes.h>
int connected = 0;
object player;
string *keyvalues(mapping m, string key) {
string *ret = ({});
int i, rows = widthof(m);
for (i = 0; i < rows; i++) {
ret += ({ m[key,i] });
}
return ret;
}
string *prettytable (mixed res) {
int rows, cols, i, j, total, tmp;
string row;
string *ret, *fnames, line, *fsizes;
ret = ({});
fsizes = ({});
cols = sizeof(res);
if (typeof(res) == T_POINTER) {
for (i = 0; i < cols; i++)
ret += ({ implode(res[i], ",") });
return ret;
}
fnames = m_indices(res);
rows = widthof(res);
for (i = 0; i < cols; i++) {
tmp = max(map(keyvalues(res, fnames[i])+({ fnames[i] }), #'sizeof));
total += tmp;
fsizes += ({ to_string(tmp) });
}
total += sizeof(fsizes)*3 + 1;
ret += ({ sprintf(" +%"+to_string(total-2)+"'-'s+", "") });
line = " | ";
for (j = 0; j < cols; j++) {
line += sprintf("%|"+fsizes[j]+"."+fsizes[j]+"s | ", fnames[j]);
}
ret += ({ line });
ret += ({ ret[0] });
for (i = 0; i < rows; i++) {
line = " | ";
for (j = 0; j < cols; j++) {
line += sprintf("%-"+fsizes[j]+"."+fsizes[j]+"s | ",
res[fnames[j],i]);
}
ret += ({ line });
}
ret += ({ ret[0] });
return ret;
}
int result (int nr, mixed res, int id) {
string *table;
TP("\n");
switch (nr) {
case PGRES_COMMAND_OK:
TP(res+"\n");
break;
case PGRES_TUPLES_OK:
if (res) {
table = prettytable(res);
table += ({ "Rows: "+to_string(widthof(res))+"\n" });
TP(implode(table, "\n"));
} else {
TP("No rows matched.\n");
}
break;
case PGRES_BAD_RESPONSE:
case PGRES_NONFATAL_ERROR:
case PGRES_FATAL_ERROR:
TP(res);
break;
case PGRES_NOTICE:
TP(res);
break;
case PGCONN_SUCCESS:
TP("PG-connection established.\n");
connected = 1;
break;
case PGCONN_FAILED:
TP("PG-connection failed: "+res+"\n");
connected = 0;
break;
case PGCONN_ABORTED:
TP("PG-connection lost: "+res+"\n");
connected = 0;
break;
}
if (connected)
tell_object(player, "SQL> ");
else
tell_object(player, "sql> ");
}
int _sql (string str) {
string prompt;
if (str && !connected && (lower_case(str[0..6]) == "connect")) {
str = str[8..];
if (pg_connect(str, "result") < 0)
TP("Error in connect-string");
else
TP("Connecting...");
} else if (str && connected && (lower_case(str) == "disconnect")) {
pg_close();
connected = 0;
TP("Disconnected...");
} else if (str && ((lower_case(str) == "exit") || (lower_case(str) == "quit")))
return 1;
else if (str && strlen(str)) {
if (!connected)
TP("Connect first, brainy\n");
else
pg_query(str, RESULT_ASSOC);
}
if (connected)
prompt = "SQL> ";
else
prompt = "sql> ";
input_to("_sql", INPUT_PROMPT, prompt);
return 1;
}
int sql (string str) {
TP("SQL-Shell v0.1a");
TP("===============");
TP("Commands: connect, disconnect, exit, quit");
TP("Everything else is treated as SQL-command");
TP("");
_sql(str);
return 1;
}
void init (void) {
::init();
player = this_player();
if (playerp(environment()))
add_action("sql", "sql");
}
void create (void) {
::create();
set_name("sqlshell");
set_id(({"sqlshell","sql"}));
set_long("Eine SQL-Shell");
set_gender("w");
}

108
mudlib/psyc-tls.c Normal file
View file

@ -0,0 +1,108 @@
#include <net.h> // vim syntax=lpc
/* Wrapper for using the tls_check_certificate() efun.
*
* If for example the efun returns this raw data:
* ({
* 0,
* ({
* "2.5.4.3",
* "commonName",
* "goodadvice.pages.de"
* }),
* ({
* 0,
* 0,
* 0,
* 0,
* 0,
* 0,
* 0,
* 0,
* 0,
* 0,
* 0,
* 0,
* "2.5.29.17",
* "X509v3 Subject Alternative Name",
* ({
* "dNSName",
* "dNSName",
* "goodadvice.pages.de",
* "1.3.6.1.5.5.7.8.5",
* "1.3.6.1.5.5.7.8.5",
* "goodadvice.pages.de"
* })
* })
* })
*
* the wrapper will transform it into:
* ([
* 0: 0
* "2.5.29.17:dNSName": "goodadvice.pages.de",
* "2.5.4.3": "goodadvice.pages.de",
* "2.5.29.17:1.3.6.1.5.5.7.8.5": "goodadvice.pages.de",
* ])*
*/
mapping tls_certificate(object who, int longnames) {
mixed *extra, extensions;
mapping cert;
int i, j;
cert = ([ ]);
#if __EFUN_DEFINED__(tls_check_certificate)
# ifdef WANT_S2S_SASL
extra = tls_check_certificate(who, 1);
unless (extra) return 0;
cert[0] = extra[0];
extensions = extra[2];
extra = extra[1];
for (i = 0; i < sizeof(extra); i += 3) {
mixed t;
t = cert[extra[i]];
unless (t) {
cert[extra[i]] = extra[i+2];
} else if (stringp(t)) {
cert[extra[i]] = ({ t, extra[i+2] });
} else if (pointerp(t)) {
cert[extra[i]] += ({ extra[i+2] });
} else {
// should not happen
}
}
if (longnames) {
// set up short/long names
for (i = 0; i < sizeof(extra); i +=3) {
cert[extra[i+1]] = cert[extra[i]];
}
}
for (i = 0; i < sizeof(extensions); i += 3) {
string key, mkey;
mixed *val;
unless(extensions[i]) continue;
key = extensions[i];
val = extensions[i+2];
for (j = 0; j < sizeof(val); j += 3) {
mixed t;
mkey = key + ":" + val[j];
t = cert[mkey];
unless (t) {
cert[mkey] = val[j+2];
} else if (stringp(t)) {
cert[mkey] = ({ t, val[j+2] });
} else if (pointerp(t)) {
cert[mkey] += ({ val[j+2] });
} else {
// should not happen
}
}
}
# endif
#endif
return cert;
}

40
mudlib/query_ip_name.c Normal file
View file

@ -0,0 +1,40 @@
/* IPv4/IPv6 name lookup using ERQ
* by Fini <ujastrow@mail.desy.de>
* Tue, 9 Mar 2004 08:20:16 +0100 (MET)
*/
void get_ip_name(string ip_num) {
[...]
num=allocate(4);
if (sscanf(ip_num, "%d.%d.%d.%d", num[0], num[1], num[2], num[3])!=4)
continue;
# ifdef RDNS_DEBUG
log_file("IP-NAME",
sprintf(" ** RDNS request for IPv4 %s sent\n", ip_num));
# endif
send_erq(ERQ_RLOOKUP, num, #'_got_ipv4_name);
[...]
}
void _got_ipv4_name(int* data, int len) {
int* x;
string ip_num, ip_nam;
if (previous_object()) return; // only the driver may call this
if (!pointerp(data) || len<5) return;
x=allocate(4);
if ((x[0]=data[0])<0) x[0]+=256; // not needed with newer drivers
if ((x[1]=data[1])<0) x[1]+=256;
if ((x[2]=data[2])<0) x[2]+=256;
if ((x[3]=data[3])<0) x[3]+=256;
ip_num=sprintf("%d.%d.%d.%d", x[0], x[1], x[2], x[3]);
ip_nam=to_string(data[4..]);
# ifdef RDNS_DEBUG
log_file("IP-NAME", sprintf("got v4: %s -> %s\n", ip_num, ip_nam));
# endif
if (ip_num==ip_nam) return; // not resolved
if (!ip_map) ip_map=get_extra_wizinfo(0)[IP_NAMES];
ip_map[ip_num, 0]=ip_nam;
ip_map[ip_num, 1]=time();
}

449
mudlib/simul_efun-dr.c Normal file
View file

@ -0,0 +1,449 @@
/* This is an addition to the simul_efun file for a fast migration from
* the -DR parser. Only the ls() function of the original simul_efun need to
* be commented out
*/
#include "/sys/lpctypes.h"
#define ATTRIBUTE_INDEX 2
#define TEXT_WIDTH 70
/*
* check_ref() is only a fake function.
* missing: query_arg/this_arg(), remove_action()
*
* The following defines might be appropriate when you need to stay with
* old code and want speed. Put them in an appropriate header file or in
* the auto_include string.
*
* #define caller() previous_object()
* if using OLD_PREVIOUS_OBJECT_BEHAVIOUR :
* #define caller() previous_object(0) // always works, but slower
*
* #define contents(ob) all_inventory((ob))
* #define deletem(m, d) efun::m_delete((m), (d))
* #define this_verb() query_verb()
* #define atoi(str) to_int(str)
* #define keys(m) m_indices(m)
* #define mapp(m) mappingp(m)
*
* The following defines have a problem: a parameter is used twice.
* #define deletea(a, start, end) ((a)[0..(start)-1] + (a)[(end)+1..])
* #define index(a, d, start) member((start) ? (a)[(start)..] : (a) , (d))
* #define searcha(a, d, start) member((start) ? (a)[(start)..] : (a) , (d))
*/
static void start_simul_efun_dr() {
mixed *info;
info = get_extra_wizinfo(0);
if (!info[ATTRIBUTE_INDEX])
info[ATTRIBUTE_INDEX] = allocate_mapping(0, 1);
if (find_call_out("clean_simul_efun_dr") < 0)
call_out("clean_simul_efun_dr", 900);
}
static void clean_simul_efun_dr() {
/* There might be destructed objects as keys. */
m_indices(get_extra_wizinfo(0)[ATTRIBUTE_INDEX]);
remove_call_out("clean_simul_efun_dr");
call_out("clean_simul_efun_dr", 3600);
}
varargs void add_attribute(string name, mixed value, object ob) {
mapping attributes;
if (!ob) {
if (objectp(value)) {
ob = value;
value = 1;
} else {
ob = previous_object();
}
}
attributes =
(attributes = get_extra_wizinfo(0)[ATTRIBUTE_INDEX])[ob] ||
(attributes[ob] = allocate_mapping(1, 1));
if (member(attributes, quote(name))) {
attributes[quote(name)] = value;
return;
}
attributes[name] = value;
}
varargs void add_prot_attribute(string name, mixed value, object ob) {
mapping attributes;
if (!ob) {
if (objectp(value)) {
ob = value;
value = 1;
} else {
ob = previous_object();
}
}
efun::m_delete(
( (attributes = get_extra_wizinfo(0)[ATTRIBUTE_INDEX])[ob] ||
(attributes[ob] = allocate_mapping(1, 1)) )
, name)[quote(name)] = value;
}
#ifndef caller
object caller() {
return previous_object(1);
}
#endif /* caller */
/* int */ mixed check_ref() {
/* There are other ways to debug ref counts. Although a simul_efun is
* possible, I doubt that it would be worth the trouble
*/
return 42.42;
}
object *contents(object ob) {
return all_inventory(ob);
}
varargs void delete_attribute(string name, object ob) {
mapping attributes;
if (attributes =
get_extra_wizinfo(0)[ATTRIBUTE_INDEX][ob || previous_object()])
{
if (member(attributes, quote(name)))
raise_error(
sprintf("Error, cannot delete protected attribute %s.\n", name));
if ( !sizeof(efun::m_delete(attributes, name)) )
efun::m_delete(
get_extra_wizinfo(0)[ATTRIBUTE_INDEX],
ob || previous_object()
);
}
}
varargs mixed deletea(mixed a, int start, int end)
{
if (!end) /* This isn't really exact; it should */
end = start; /* only be done if end is not given. */
if (end == sizeof(a) - 1) /* Avoid "out of bounds" . */
return a[0..start - 1];
return a[0..start-1] + a[end+1..];
}
mapping deletem(mapping m, mixed d) {
return efun::m_delete(m, d);
}
void dumpobjs(int start, int end) {
object ob;
rm("/OBJDUMP");
if (end <= 0) {
printf("Dumping all objects starting with %d.\n", start);
end = 0x7fffffff;
} else {
printf("Dumping objects %d through %d.\n", start, end);
}
write_file("/OBJDUMP",
sprintf("Object Location\n"));
for (ob = debug_info(start); ob && start <= end;
ob = debug_info(2, ob), start++)
write_file("/OBJDUMP", sprintf("%-40s %s\n", file_name(ob),
(environment(ob)?file_name(environment(ob)):"None")));
write("Done.\n");
}
int exists(string file) {
return file_size(file) != -1;
}
string *files(string path) {
mixed *a;
string *b;
int i, j;
set_this_object(previous_object());
a = get_dir(path, 3);
/* Don't call this locally, unless you add code to set this_object() back */
b = allocate(j = (i = sizeof(a)) >> 1);
while (i)
b[--j] = a[--i] < 0 ? a[--i] + "/" : a[--i];
return b;
}
string format(string text, int width) {
if (width < 0)
raise_error("Bad width given to format(); must be >= 0.\n");
return sprintf("%*-=s", width || TEXT_WIDTH, text);
}
varargs mixed get_attribute(mixed m, object ob) {
mapping attributes;
if (!stringp(m))
return
transpose_array( ({
m_indices(
attributes =
get_extra_wizinfo(0)
[ATTRIBUTE_INDEX][m || previous_object()] ||
allocate_mapping(0,1)),
m_values(attributes)
}) ) ;
if ( ( attributes =
get_extra_wizinfo(0)[ATTRIBUTE_INDEX][ob || previous_object()]
) && (mapping_contains(&m, attributes, m) ||
mapping_contains(&m, attributes, quote(m)))
)
return m;
return -1;
}
varargs string *grab_file(string path, int start, int len) {
set_this_object(previous_object());
return explode(read_file(path, start, len), "\n");
/* Don't call this locally, unless you add code to set this_object() back */
}
int index(mixed a, mixed d, int start) {
return member(start ? a[start..] : a , d);
}
string pad(mixed str, int len, int padchar) {
string sp_format;
str = to_string(str);
if (len < 0) {
if (padchar) {
sp_format = "%' '*.*s";
sp_format[2] = padchar;
return sprintf(sp_format, -len, -len, str);
}
return sprintf("%*.*s", -len, -len, str);
}
if (padchar) {
sp_format = "%' '-*.*s%s";
sp_format[2] = padchar;
return sprintf(sp_format, len, len, str, "");
}
return sprintf("%-*.*s%s", len, len, str, "");
}
varargs void print(string text, int width) {
if (width > TEXT_WIDTH)
raise_error("Invalid size for argument 2 to print()\n");
if (width < 0)
raise_error("Bad width given to print(); must be >= 0.\n");
write(sprintf("%*-=s", width || TEXT_WIDTH, text));
}
varargs mixed query_attribute(string m, object ob) {
mapping attributes;
return
( attributes =
get_extra_wizinfo(0)[ATTRIBUTE_INDEX][ob || previous_object()]
) && (member(attributes, m) || member(attributes, quote(m)));
}
static int remote_command_flag;
int command(string str, object ob) {
/* Don't call this locally, unless you add code to set this_object() back */
int result;
object me;
if (!ob) {
set_this_object(previous_object());
return efun::command(str);
}
if (ob == previous_object()) {
set_this_object(previous_object());
return efun::command(str);
}
remote_command_flag++;
me = this_object();
set_this_object(previous_object());
result = efun::command(str, ob);
set_this_object(me);
remote_command_flag = 0; /* global variable... */
return result;
}
int remote_command() { return remote_command_flag; }
int root(object ob) {
return member(file_name(ob || previous_object()), '#') == -1;
}
int searcha(mixed a, mixed d, int start) {
return member(start ? a[start..] : a , d);
}
static private string *strsub_formats = ({0, "\\<%s\\B","\\B%s\\>","\\<%s\\>"});
string strsub(string input,string *patterns, int mode) {
int i;
string format;
if ( (i = sizeof(patterns)) & 1)
raise_error("Odd length array given to strsub.\n");
if (!mode) {
while (i) {
input = implode(explode(input, patterns[<i--]), patterns[<i--]);
}
return input;
}
format = strsub_formats[mode];
while (i) {
input =
implode(
regexplode(input, sprintf(format, patterns[<i--])),
patterns[<i--]
);
}
return input;
}
string this_verb() { return query_verb(); }
int atoi(string str) { return to_int(str); }
int cp(string from, string to) {
string str;
set_this_object(previous_object());
rm(to);
str = read_file(from);
write_file(to, str);
/* Don't call this locally, unless you add code to set this_object() back */
}
int in_editor(object ob) { return query_editing(ob) && 1; }
mixed *keys(mapping m) { return m_indices(m); }
int mapp(mixed m) { return mappingp(m); }
int memused() {
return rusage()[2];
}
object remove_shadow(object ob) {
if (!(ob))
if ( !(ob = previous_object()) )
return 0;
/* we are missing a test here to test for actual shadowing. */
funcall(bind_lambda(#'unshadow, ob || previous_object()));
return ob;
}
mixed *reallocate(mixed *a, int size) {
if (size > sizeof(a))
return a + allocate(size - sizeof(a));
return a[0..size-1];
}
string typeof(mixed m) {
switch(efun::typeof(m)) {
case T_OBJECT:
return "object";
case T_NUMBER:
return "int";
case T_POINTER:
return "vector";
case T_STRING:
return "string";
case T_MAPPING:
return "mapping";
default:
return "";
}
}
static int last_destruct;
static private mapping destructing = ([]);
varargs void destruct(object ob, int flag) {
if (flag && !member(destructing, ob)) {
if (last_destruct != time())
destructing = allocate_mapping(0,0);
destructing += ([ob]);
ob->destructor();
}
efun::destruct(ob);
}
/*
* The ls() function is no longer needed, as get_dir() can do the same
* work.
*/
void ls(string path) {
int max, i, len, tmp;
status trunc_flag;
mixed *dir;
set_this_object(previous_object());
if (!path)
path = ".";
dir = get_dir (path,3);
#if defined(COMPAT_FLAG) && 0
if (path[0] == '/')
path = extract(path, 1);
if (path != "")
path += "/";
#else
if (path != "/")
path += "/";
#endif
if (!dir) {
write("No such directory.\n");
return;
}
if (sizeof(dir) > 999)
{
dir = dir[0..998];
trunc_flag = 1;
}
for(i = sizeof(dir); i--; ) {
if(dir[i--] == -2)
dir[i]+="/";
len = strlen(dir[i]);
if (len > max)
max = len;
}
++max;
if (max > 79)
max = 79;
for (i=0; i < sizeof(dir); i+=2) {
string name;
name = dir[i];
tmp = strlen(name);
if (len + tmp > 79) {
len = 0;
write("\n");
}
write(name);
if (len + max > 79) {
write("\n");
len = 0;
} else {
write(extract(
" ",
80-max+tmp));
len += max;
}
}
write("\n");
if (trunc_flag) write("***TRUNCATED***\n");
}
#if 0 /* This is probably too costly; just replace this_player(1) with
this_interactive() */
/*
* Not accurate.
* Original behaviour: if arg _supplied_ return current_interactive.
*/
varargs object this_player(int x)
{
return x ? this_interactive() : efun::this_player();
}
#endif

11
mudlib/sys/comm.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef LPC_COMM_H_
#define LPC_COMM_H_
/* Mode values recognized by the efun get_combine_charset()
* and get_connection_charset() */
#define CHARSET_VECTOR 0 /* Return the charset as bitvector array */
#define CHARSET_STRING 1 /* Return the charset as string */
#define CHARSET_QUOTE_IAC 2 /* Return the status of the IAC quoting */
#endif /* LPC_COMM_H_ */

50
mudlib/sys/commands.h Normal file
View file

@ -0,0 +1,50 @@
#ifndef LPC_COMMANDS_H_
#define LPC_COMMANDS_H_
/* Flags accepted by add_action(fun, verb, flag).
* (Below, VERB is what the player enters).
* Negative flag values allow VERB to be just the first -<flag>
* characters of <verb> (abbreviated verb).
*/
#define AA_VERB 0 /* VERB must be <verb> */
#define AA_SHORT 1 /* VERB must start with <verb>,
* args do not include extra characters */
#define AA_NOSPACE 2 /* VERB must start with <verb>,
* args and verb do include extra characters */
#define AA_IMM_ARGS 3 /* VERB must start with <verb>,
* args do include extra characters */
/* Bitflags accepted by query_actions(object ob, int mask)
*/
#define QA_VERB 1
#define QA_TYPE 2
#define QA_SHORT_VERB 4
#define QA_OBJECT 8
#define QA_FUNCTION 16
/* Indices in the arrays returned from command_stack()
*/
#define CMD_VERB 0
#define CMD_TEXT 1
#define CMD_ORIGIN 2
#define CMD_PLAYER 3
#define CMD_FAIL 4
#define CMD_FAILOBJ 5
#define CMD_SIZE 6
/* Indices into the subarrays returned from match_command()
*/
#define CMDM_VERB 0
#define CMDM_ARG 1
#define CMDM_OBJECT 2
#define CMDM_FUN 3
#define CMDM_SIZE 4
#endif /* LPC_COMMANDS_H_ */

240
mudlib/sys/debug_info.h Normal file
View file

@ -0,0 +1,240 @@
#ifndef LPC_DEBUG_INFO_H_
#define LPC_DEBUG_INFO_H_ 1
/* Request values for efun debug_info().
*/
#define DINFO_OBJECT 0 /* Print information about an object */
#define DINFO_MEMORY 1 /* Print memory usage of an object */
#define DINFO_OBJLIST 2 /* Return an object from the global list */
#define DINFO_MALLOC 3 /* Print the information from the 'malloc' cmd */
#define DINFO_STATUS 4 /* Return the 'status' information */
#define DINFO_DUMP 5 /* Dump some special information into files */
#define DINFO_DATA 6 /* Return internal information */
#define DINFO_TRACE 7 /* Return the current call trace */
/* Sub-request values for debug_info(DINFO_DATA) */
#define DID_STATUS 0 /* Return the 'status' and 'status tables' information */
#define DID_SWAP 1 /* Return the 'status swap' information */
#define DID_MEMORY 2 /* Return the 'status malloc' information */
/* Sub-request values for debug_info(DINFO_TRACE) */
#define DIT_CURRENT 0 /* Return the current call chain as an array */
#define DIT_ERROR 1 /* Return the last error call chain as an array */
#define DIT_UNCAUGHT_ERROR 2 /* Return the last uncaught error call chain */
#define DIT_STR_CURRENT 3 /* Return the current call chain as a string */
/* Indices into the array resulting from debug_info(DINFO_DATA, DID_STATUS)
*/
#define DID_ST_ACTIONS 0
#define DID_ST_ACTIONS_SIZE 1
#define DID_ST_SHADOWS 2
#define DID_ST_SHADOWS_SIZE 3
#define DID_ST_OBJECTS 4
#define DID_ST_OBJECTS_SIZE 5
#define DID_ST_OBJECTS_SWAPPED 6
#define DID_ST_OBJECTS_SWAP_SIZE 7
#define DID_ST_OBJECTS_LIST 8
#define DID_ST_OBJECTS_NEWLY_DEST 9
#define DID_ST_OBJECTS_DESTRUCTED 10
#define DID_ST_OBJECTS_PROCESSED 11
#define DID_ST_OBJECTS_AVG_PROC 12
#define DID_ST_OTABLE 13
#define DID_ST_OTABLE_SLOTS 14
#define DID_ST_OTABLE_SIZE 15
#define DID_ST_HBEAT_OBJS 16
#define DID_ST_HBEAT_CALLS 17
#define DID_ST_HBEAT_CALLS_TOTAL 18
#define DID_ST_HBEAT_SLOTS 19
#define DID_ST_HBEAT_SIZE 20
#define DID_ST_HBEAT_PROCESSED 21
#define DID_ST_HBEAT_AVG_PROC 22
#define DID_ST_CALLOUTS 23
#define DID_ST_CALLOUT_SIZE 24
#define DID_ST_ARRAYS 25
#define DID_ST_ARRAYS_SIZE 26
#define DID_ST_MAPPINGS 27
#define DID_ST_MAPPINGS_SIZE 28
#define DID_ST_HYBRID_MAPPINGS 51
#define DID_ST_HASH_MAPPINGS 54
#define DID_ST_STRUCTS 29
#define DID_ST_STRUCTS_SIZE 30
#define DID_ST_STRUCT_TYPES 31
#define DID_ST_STRUCT_TYPES_SIZE 32
#define DID_ST_PROGS 33
#define DID_ST_PROGS_SIZE 34
#define DID_ST_PROGS_SWAPPED 35
#define DID_ST_PROGS_SWAP_SIZE 36
#define DID_ST_USER_RESERVE 37
#define DID_ST_MASTER_RESERVE 38
#define DID_ST_SYSTEM_RESERVE 39
#define DID_ST_ADD_MESSAGE 40
#define DID_ST_PACKETS 41
#define DID_ST_PACKET_SIZE 42
#define DID_ST_PACKETS_IN 43
#define DID_ST_PACKET_SIZE_IN 44
#define DID_ST_APPLY 45
#define DID_ST_APPLY_HITS 46
#define DID_ST_STRINGS 47
#define DID_ST_STRING_SIZE 48
#define DID_ST_STR_TABLE_SIZE 49
#define DID_ST_STR_OVERHEAD 50
#define DID_ST_UNTABLED 52
#define DID_ST_UNTABLED_SIZE 53
#define DID_ST_UNUSED54 54 /* UNUSED */
#define DID_ST_UNUSED55 55 /* UNUSED */
#define DID_ST_TABLED 56
#define DID_ST_TABLED_SIZE 57
#define DID_ST_STR_SEARCHES 58
#define DID_ST_STR_SEARCHLEN 59
#define DID_ST_STR_SEARCHES_BYVALUE 60
#define DID_ST_STR_SEARCHLEN_BYVALUE 61
#define DID_ST_STR_CHAINS 62
#define DID_ST_STR_ADDED 63
#define DID_ST_STR_DELETED 64
#define DID_ST_STR_COLLISIONS 65
#define DID_ST_STR_FOUND 66
#define DID_ST_STR_FOUND_BYVALUE 67
#define DID_ST_RX_CACHED 68
#define DID_ST_RX_TABLE 69
#define DID_ST_RX_TABLE_SIZE 70
#define DID_ST_RX_REQUESTS 71
#define DID_ST_RX_REQ_FOUND 72
#define DID_ST_RX_REQ_COLL 73
#define DID_ST_MB_FILE 74
#define DID_ST_MB_SWAP 75
#define DID_ST_BOOT_TIME 76
#define DID_STATUS_MAX 77 /* Total number of entries */
/* Indices into the array resulting from debug_info(DINFO_DATA, DID_SWAP)
*/
#define DID_SW_PROGS 0
#define DID_SW_PROG_SIZE 1
#define DID_SW_PROG_UNSWAPPED 2
#define DID_SW_PROG_U_SIZE 3
#define DID_SW_VARS 4
#define DID_SW_VAR_SIZE 5
#define DID_SW_FREE 6
#define DID_SW_FREE_SIZE 7
#define DID_SW_FILE_SIZE 8
#define DID_SW_REUSED 9
#define DID_SW_SEARCHES 10
#define DID_SW_SEARCH_LEN 11
#define DID_SW_F_SEARCHES 12
#define DID_SW_F_SEARCH_LEN 13
#define DID_SW_COMPACT 14
#define DID_SW_RECYCLE_FREE 15
#define DID_SWAP_MAX 16
/* Indices into the array resulting from debug_info(DINFO_DATA, DID_MEMORY)
*/
#define DID_MEM_NAME 0
#define DID_MEM_SBRK 1
#define DID_MEM_SBRK_SIZE 2
#define DID_MEM_LARGE 3
#define DID_MEM_LARGE_SIZE 4
#define DID_MEM_MMAP (DID_MEM_LARGE)
#define DID_MEM_MMAP_SIZE (DID_MEM_LARGE_SIZE)
#define DID_MEM_LFREE 5
#define DID_MEM_FREE_CHUNKS (DID_MEM_LFREE)
#define DID_MEM_LFREE_SIZE 6
#define DID_MEM_LWASTED 7
#define DID_MEM_LWASTED_SIZE 8
#define DID_MEM_KEEP_COST (DID_MEM_LWASTED_SIZE)
#define DID_MEM_CHUNK 9
#define DID_MEM_CHUNK_SIZE 10
#define DID_MEM_SLAB (DID_MEM_CHUNK)
#define DID_MEM_SLAB_SIZE (DID_MEM_CHUNK_SIZE)
#define DID_MEM_MAX_ALLOCATED (DID_MEM_CHUNK_SIZE)
#define DID_MEM_SMALL 11
#define DID_MEM_SMALL_SIZE 12
#define DID_MEM_SFREE 13
#define DID_MEM_SFREE_SIZE 14
#define DID_MEM_FFREE (DID_MEM_SFREE)
#define DID_MEM_FFREE_SIZE (DID_MEM_SFREE_SIZE)
#define DID_MEM_SWASTED 15
#define DID_MEM_SWASTED_SIZE 16
#define DID_MEM_SMALL_OVERHEAD_SIZE (DID_MEM_SWASTED_SIZE)
#define DID_MEM_MINC_CALLS 17
#define DID_MEM_MINC_SUCCESS 19
#define DID_MEM_MINC_SIZE 19
#define DID_MEM_PERM 20
#define DID_MEM_PERM_SIZE 21
#define DID_MEM_CLIB 22
#define DID_MEM_CLIB_SIZE 23
#define DID_MEM_OVERHEAD 24
#define DID_MEM_ALLOCATED 25
#define DID_MEM_USED 26
#define DID_MEM_TOTAL_UNUSED 27
#define DID_MEM_DEFRAG_CALLS 28
#define DID_MEM_DEFRAG_CALLS_REQ 29
#define DID_MEM_SLAB_FREE (DID_MEM_DEFRAG_CALLS)
#define DID_MEM_SLAB_FREE_SIZE (DID_MEM_DEFRAG_CALLS_REQ)
#define DID_MEM_DEFRAG_REQ_SUCCESS 30
#define DID_MEM_DEFRAG_BLOCKS_INSPECTED 31
#define DID_MEM_DEFRAG_BLOCKS_MERGED 32
#define DID_MEM_DEFRAG_BLOCKS_RESULT 33
#define DID_MEM_AVL_NODES 34
#define DID_MEM_EXT_STATISTICS 35
#define DID_MEMORY_MAX 36
/* Indices into the subarrays of DID_MEM_EXT_STATISTICS (if given) */
#define DID_MEM_ES_MAX_ALLOC 0
#define DID_MEM_ES_CUR_ALLOC 1
#define DID_MEM_ES_MAX_FREE 2
#define DID_MEM_ES_CUR_FREE 3
#define DID_MEM_ES_AVG_XALLOC 4
#define DID_MEM_ES_AVG_XFREE 5
#define DID_MEM_ES_FULL_SLABS 6
#define DID_MEM_ES_FREE_SLABS 7
#define DID_MEM_ES_TOTAL_SLABS 8
#define DID_MEM_ES_MAX 9
/* Indices into the subarrays resulting from debug_info(DINFO_TRACE, 0)
*/
#define TRACE_TYPE 0
#define TRACE_NAME 1
#define TRACE_PROGRAM 2
#define TRACE_OBJECT 3
#define TRACE_LOC 4
#define TRACE_MAX 5
/* Values for entry TRACE_TYPE */
#define TRACE_TYPE_SYMBOL 0
#define TRACE_TYPE_SEFUN 1
#define TRACE_TYPE_EFUN 2
#define TRACE_TYPE_LAMBDA 3
#define TRACE_TYPE_LFUN 4
#endif /* LPC_DEBUG_INFO_H_ */

View file

@ -0,0 +1,18 @@
#ifndef LPC_DEBUG_MESSAGE_H_
#define LPC_DEBUG_MESSAGE_H_ 1
/* Definitions and macros for the debug_message() */
#define DMSG_DEFAULT 0 /* log to stdout and .debug.log */
#define DMSG_STDOUT (1 << 0) /* log to stdout */
#define DMSG_STDERR (1 << 1) /* log to stderr */
#define DMSG_LOGFILE (1 << 2) /* log to .debug.log */
#define DMSG_STAMP (1 << 3) /* Prepend the timestamp */
/* Derived macros */
#define DMSG_TARGET (DMSG_STDOUT|DMSG_STDERR|DMSG_LOGFILE)
/* Mask for all target bitflags */
#endif /* LPC_DEBUG_MESSAGE_H_ */

35
mudlib/sys/driver_hook.h Normal file
View file

@ -0,0 +1,35 @@
#ifndef LPC_DRIVER_HOOK_H_
#define LPC_DRIVER_HOOK_H_ 1
/* --- Driver Hooks ---
*/
#define H_MOVE_OBJECT0 0
#define H_MOVE_OBJECT1 1
#define H_LOAD_UIDS 2
#define H_CLONE_UIDS 3
#define H_CREATE_SUPER 4
#define H_CREATE_OB 5
#define H_CREATE_CLONE 6
#define H_RESET 7
#define H_CLEAN_UP 8
#define H_MODIFY_COMMAND 9
#define H_NOTIFY_FAIL 10
#define H_NO_IPC_SLOT 11
#define H_INCLUDE_DIRS 12
#define H_TELNET_NEG 13
#define H_NOECHO 14
#define H_ERQ_STOP 15
#define H_MODIFY_COMMAND_FNAME 16
#define H_COMMAND 17
#define H_SEND_NOTIFY_FAIL 18
#define H_AUTO_INCLUDE 19
#define H_DEFAULT_METHOD 20
#define H_DEFAULT_PROMPT 21
#define H_PRINT_PROMPT 22
#define H_REGEXP_PACKAGE 23
#define NUM_DRIVER_HOOKS 24 /* Number of hooks */
#endif /* LPC_DRIVER_HOOK_ */

59
mudlib/sys/erq.h Normal file
View file

@ -0,0 +1,59 @@
/* external request demon interface definitions */
#ifndef LPC__ERQ_H__
#define LPC__ERQ_H__ 1
/* servive request types */
#define ERQ_RLOOKUP 0 /* Lookup ip -> name */
#define ERQ_EXECUTE 1 /* Execute a program */
#define ERQ_FORK 2 /* Fork a program */
#define ERQ_AUTH 3 /* Connect to a remote authd */
#define ERQ_SPAWN 4 /* Spawn a program */
#define ERQ_SEND 5 /* Send data to a program or connection */
#define ERQ_KILL 6 /* Kill a program or connection */
#define ERQ_OPEN_UDP 7 /* Open a UDP socket */
#define ERQ_OPEN_TCP 8 /* Open a TCP connection */
#define ERQ_LISTEN 9 /* Open a TCP accept-socket */
#define ERQ_ACCEPT 10 /* Accept a connection from a accept-socket */
#define ERQ_LOOKUP 11 /* Lookup name -> ip */
#ifdef __IPV6__
#define ERQ_RLOOKUPV6 12 /* Lookup name/ip6 */
#endif
/* Additional service request type flags evaluated by efun send_erq().
* The ERQ itself won't get to see it.
*/
#define ERQ_CB_STRING (1 << 31) /* Callback closure takes a string arg */
/* answers from ERQ_EXECUTE / ERQ_FORK */
#define ERQ_OK 0
#define ERQ_SIGNALED 1
#define ERQ_E_NOTFOUND 2 /* process not found by wait */
#define ERQ_E_UNKNOWN 3 /* unknown exit condition from wait() */
#define ERQ_E_ARGLENGTH 4
#define ERQ_E_ARGFORMAT 5
#define ERQ_E_ARGNUMBER 6
#define ERQ_E_ILLEGAL 7
#define ERQ_E_PATHLEN 8
#define ERQ_E_FORKFAIL 9
#define ERQ_E_TICKET 11
#define ERQ_E_INCOMPLETE 12
#define ERQ_E_WOULDBLOCK 13
#define ERQ_E_PIPE 14
#define ERQ_STDOUT 15 /* Normal data received */
#define ERQ_STDERR 16
#define ERQ_EXITED 17 /* Connection closed on EOF */
#define ERQ_E_NSLOTS 18
/* reserved handles */
#define ERQ_HANDLE_RLOOKUP (-1)
#define ERQ_HANDLE_KEEP_HANDLE (-2)
#define ERQ_HANDLE_RLOOKUPV6 (-3)
#endif /* LPC__ERQ_H__ */

29
mudlib/sys/files.h Normal file
View file

@ -0,0 +1,29 @@
#ifndef LPC_FILES_H_
#define LPC_FILES_H_ 1
/* Definitions and macros for the various file efuns */
/* Special return values of file_size() and the size part of get_dir().
*/
#define FSIZE_NOFILE -1 /* File doesn't exist or is not readable */
#define FSIZE_DIR -2 /* The file is actually a directory */
/* Flag values for get_dir().
*/
#define GETDIR_EMPTY (0) /* return an empty array (not very useful) */
#define GETDIR_NAMES (0x01) /* return the filenames */
#define GETDIR_SIZES (0x02) /* return the file sizes */
#define GETDIR_DATES (0x04) /* return the dates of last modification */
/* (0x08) unused */
#define GETDIR_ACCESS (0x40) /* return the dates of last access */
#define GETDIR_MODES (0x80) /* return the file mode */
#define GETDIR_PATH (0x10) /* with _NAMES: add the path to the filenames */
#define GETDIR_UNSORTED (0x20) /* return the results unsorted */
#define GETDIR_ALL (0xDF) /* return all */
#endif /* LPC_FILES_H_ */

69
mudlib/sys/functionlist.h Normal file
View file

@ -0,0 +1,69 @@
#ifndef LPC_FUNCTIONLIST_H
#define LPC_FUNCTIONLIST_H
#ifndef __DRIVER_SOURCE__
#include "lpctypes.h"
#define NAME_INHERITED 0x80000000 /* Defined by inheritance */
#define TYPE_MOD_STATIC 0x40000000 /* Static function or variable */
#define TYPE_MOD_NO_MASK 0x20000000 /* The nomask => not redefineable */
#define TYPE_MOD_PRIVATE 0x10000000 /* Can't be inherited */
#define TYPE_MOD_PUBLIC 0x08000000 /* Force inherit through private */
#define TYPE_MOD_VARARGS 0x04000000 /* Used for type checking */
#define TYPE_MOD_VIRTUAL 0x02000000 /* can be re- and cross- defined */
#define TYPE_MOD_PROTECTED 0x01000000 /* cannot be called externally */
#define TYPE_MOD_XVARARGS 0x00800000 /* accepts optional arguments */
#define TYPE_MOD_NOSAVE TYPE_MOD_STATIC /* vars: can't be saved */
/* Internally TYPE_MOD_NOSAVE is 0x00400000, but that never leaves
* the compiler.
*/
#define NAME_CROSS_DEFINED 0x00080000 /* function defined from other program */
#if defined(__LPC_STRUCTS__) || defined(USE_STRUCTS)
#define NAME_HIDDEN 0x00020000 /* Not visible for inheritance */
#define NAME_PROTOTYPE 0x00010000 /* Defined by a prototype only */
#define NAME_UNDEFINED 0x00008000 /* Not defined yet */
#define NAME_TYPES_LOST 0x00004000 /* inherited, no save_types */
#else /* !USE_STRUCTS */
#define NAME_HIDDEN 0x00000800 /* Not visible for inheritance */
#define NAME_PROTOTYPE 0x00000400 /* Defined by a prototype only */
#define NAME_UNDEFINED 0x00000200 /* Not defined yet */
#define NAME_TYPES_LOST 0x00000100 /* inherited, no save_types */
#endif /* USE_STRUCTS */
#endif /* !__DRIVER_SOURCE__ */
/* Return value flag types for functionlist() and variable_list() */
#define RETURN_FUNCTION_NAME 0x01
#define RETURN_FUNCTION_FLAGS 0x02
#define RETURN_FUNCTION_TYPE 0x04
/* Additional return value flag types for functionlist() */
#define RETURN_FUNCTION_NUMARG 0x08
#define RETURN_FUNCTION_ARGTYPE 0x10 /* not implemented */
/* Additional return value flag types for variable_list() */
#define RETURN_VARIABLE_VALUE 0x08
/* Masks of the flag unions allowed for various efuns: */
#define RETURN_FUNCTION_MASK 0x0f /* functionlist() */
#define RETURN_VARIABLE_MASK 0x0f /* variable_list() */
/* Return value flag types for function_exists() */
#define FEXISTS_PROGNAME (0)
#define FEXISTS_FILENAME (1)
#define FEXISTS_LINENO (2)
#define FEXISTS_NUMARG (3)
#define FEXISTS_TYPE (4)
#define FEXISTS_FLAGS (5)
#define FEXISTS_ALL (3)
#endif /* LPC_FUNCTIONLIST_H */

26
mudlib/sys/idn.h Normal file
View file

@ -0,0 +1,26 @@
#ifndef LPC_IDN_H_
#define LPC_IDN_H_ 1
/* --- IDNA Constants ---
*/
/* idna_stringprep() profiles. */
#define STRINGPREP_NAMEPREP 1
#define STRINGPREP_SASLPREP 2
#define STRINGPREP_PLAIN 3
#define STRINGPREP_TRACE 4
#define STRINGPREP_KERBEROS5 5
#define STRINGPREP_XMPP_NODEPREP 6
#define STRINGPREP_XMPP_RESOURCEPREP 7
#define STRINGPREP_ISCSI 8
/* idna_stringprep() flags */
#define STRINGPREP_NO_NFKC_FLAG (1<<0)
#define STRINGPREP_NO_BIDI_FLAG (1<<1)
#define STRINGPREP_NO_UNASSIGNED_FLAG (1<<2)
#define STRINGPREP_FLAG_MAX (1<<2)
#endif

View file

@ -0,0 +1,9 @@
#ifndef LPC_INCLUDE_LIST_H
#define LPC_INCLUDE_LIST_H
/* Return value flag types for include_list() */
#define INCLIST_FLAT 0x00
#define INCLIST_TREE 0x01
#endif /* LPC_INCLUDE_LIST_H */

10
mudlib/sys/inherit_list.h Normal file
View file

@ -0,0 +1,10 @@
#ifndef LPC_INHERIT_LIST_H
#define LPC_INHERIT_LIST_H
/* Return value flag types for inherit_list() */
#define INHLIST_FLAT 0x00
#define INHLIST_TREE 0x01
#define INHLIST_TAG_VIRTUAL 0x02
#endif /* LPC_INHERIT_LIST_H */

18
mudlib/sys/input_to.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef LPC_INPUT_TO_H_
#define LPC_INPUT_TO_H_
/* Mode values recognized by the efun input_to() */
#define INPUT_NOECHO 1 /* Don't echo the next line typed */
#define INPUT_CHARMODE 2 /* Switch into/out of charmode */
#define INPUT_PROMPT 4 /* Use a custom prompt */
#define INPUT_NO_TELNET 8 /* Switch into/out of charmode on the driver
* side only.
*/
#define INPUT_APPEND 16 /* Append the input_to to the list of already
* pending input_to's.
*/
/* #define INPUT_BINARY 32 -- nice, but noone has coded it */
#define INPUT_IGNORE_BANG 128 /* Disallow the '!' escape */
#endif /* LPC_INPUT_TO_H_ */

68
mudlib/sys/lpctypes.h Normal file
View file

@ -0,0 +1,68 @@
#ifndef LPC_LPCTYPES_H
#define LPC_LPCTYPES_H
/* compile time types, from functionlist() */
#define TYPE_UNKNOWN 0 /* This type must be casted */
#define TYPE_NUMBER 1
#define TYPE_STRING 2
#define TYPE_VOID 3
#define TYPE_OBJECT 4
#define TYPE_MAPPING 5
#define TYPE_FLOAT 6
#define TYPE_ANY 7 /* Will match any type */
#define TYPE_CLOSURE 8
#define TYPE_SYMBOL 9
#define TYPE_QUOTED_ARRAY 10
#if defined(USE_STRUCTS) || defined(__LPC_STRUCTS__)
#define TYPE_STRUCT 11
#endif
#define TYPE_MOD_POINTER 0x0040 /* Pointer to a basic type */
/* runtime types, from typeof() */
#define T_INVALID 0x0
#define T_LVALUE 0x1
#define T_NUMBER 0x2
#define T_STRING 0x3
#define T_POINTER 0x4
#define T_OBJECT 0x5
#define T_MAPPING 0x6
#define T_FLOAT 0x7
#define T_CLOSURE 0x8
#define T_SYMBOL 0x9
#define T_QUOTED_ARRAY 0xa
#if defined(USE_STRUCTS) || defined(__LPC_STRUCTS__)
#define T_STRUCT 0xb
#endif
/* Closure types, stored as secondary type info */
#ifndef __DRIVER_SOURCE__
#define CLOSURE_LFUN 0 /* lfun in an object */
/* Code 1: currently unused, used to be CLOSURE_ALIEN_LFUN */
#define CLOSURE_IDENTIFIER 2 /* variable in this object */
#define CLOSURE_PRELIMINARY 3
/* Efun closure used in a static initialization */
#define CLOSURE_BOUND_LAMBDA 4 /* Bound unbound-lambda closure */
#define CLOSURE_LAMBDA 5 /* normal lambda closure */
#define CLOSURE_UNBOUND_LAMBDA 6 /* unbound lambda closure. */
#define CLOSURE_OPERATOR (0xe800)
#define CLOSURE_EFUN (0xf000)
#define CLOSURE_SIMUL_EFUN (0xf800)
#define CLOSURE_IS_LFUN(x) (((x)&~1) == 0)
#define CLOSURE_IS_IDENTIFIER(x) ((x) == CLOSURE_IDENTIFIER)
#define CLOSURE_IS_BOUND_LAMBDA(x) ((x) == CLOSURE_BOUND_LAMBDA)
#define CLOSURE_IS_LAMBDA(x) ((x) == CLOSURE_LAMBDA)
#define CLOSURE_IS_UNBOUND_LAMBDA(x) ((x) == CLOSURE_UNBOUND_LAMBDA)
#define CLOSURE_IS_SIMUL_EFUN(x) (((x) & 0xf800) == CLOSURE_SIMUL_EFUN)
#define CLOSURE_IS_EFUN(x) (((x) & 0xf800) == CLOSURE_EFUN)
#define CLOSURE_IS_OPERATOR(x) (((x) & 0xf800) == CLOSURE_OPERATOR)
#endif /* __DRIVER_SOURCE__ */
#endif /* LPC_LPCTYPES_H */

83
mudlib/sys/objectinfo.h Normal file
View file

@ -0,0 +1,83 @@
#ifndef LPC_OBJECTINFO_H_
#define LPC_OBJECTINFO_H_
/* Definition of argument values for object_info() and
* of the indices in the corresponding result arrays.
*/
/* Possible types of information requested from object_info()
*/
#define OINFO_BASIC 0
#define OINFO_POSITION 1
#define OINFO_MEMORY 2
/* Indices in the array resulting from OINFO_BASIC
*/
#define OIB_HEART_BEAT 0
#define OIB_IS_WIZARD 1
#define OIB_ENABLE_COMMANDS 2
#define OIB_CLONE 3
#define OIB_DESTRUCTED 4
#define OIB_SWAPPED 5
#define OIB_ONCE_INTERACTIVE 6
#define OIB_RESET_STATE 7
#define OIB_WILL_CLEAN_UP 8
#define OIB_LAMBDA_REFERENCED 9
#define OIB_SHADOW 10
#define OIB_REPLACED 11
#define OIB_TOTAL_LIGHT 12
#define OIB_NEXT_RESET 13
#define OIB_TIME_OF_REF 14
#define OIB_REF 15
#define OIB_GIGATICKS 16
#define OIB_TICKS 17
#define OIB_SWAP_NUM 18
#define OIB_PROG_SWAPPED 19
#define OIB_VAR_SWAPPED 20
#define OIB_NAME 21
#define OIB_LOAD_NAME 22
#define OIB_NEXT_ALL 23
#define OIB_PREV_ALL 24
#define OIB_NEXT_CLEANUP 25
#define OIB_MAX 26 /* Number of OIB_ result elements */
/* Indices in the array resulting from OINFO_POSITION
*/
#define OIP_NEXT 0
#define OIP_PREV 1
#define OIP_POS 2
#define OIP_MAX 3 /* Number of OIP_ result elements */
/* Indices in the array resulting from OINFO_MEMORY
*/
#define OIM_REF 0
#define OIM_NAME 1
#define OIM_PROG_SIZE 2
#define OIM_NUM_FUNCTIONS 3
#define OIM_SIZE_FUNCTIONS 4
#define OIM_NUM_VARIABLES 5
#define OIM_SIZE_VARIABLES 6
#define OIM_NUM_STRINGS 7
#define OIM_SIZE_STRINGS 8
#define OIM_SIZE_STRINGS_DATA 9
#define OIM_SIZE_STRINGS_TOTAL 10
#define OIM_NUM_INHERITED 11
#define OIM_SIZE_INHERITED 12
#define OIM_TOTAL_SIZE 13
#define OIM_DATA_SIZE 14
#define OIM_TOTAL_DATA_SIZE 15
#define OIM_NO_INHERIT 16
#define OIM_NO_CLONE 17
#define OIM_NO_SHADOW 18
#define OIM_NUM_INCLUDES 19
#define OIM_SHARE_VARIABLES 20
#define OIM_MAX 21 /* Number of OIM_ result elements */
#endif /* LPC_OBJECTINFO_H_ */

23
mudlib/sys/pgsql.h Normal file
View file

@ -0,0 +1,23 @@
#ifndef _PGSQL_H
#define _PGSQL_H
/* Definitions for the PostgreSQL efuns */
#define PGRES_EMPTY_QUERY 0 /* Unimplemented */
#define PGRES_COMMAND_OK 1
#define PGRES_TUPLES_OK 2
#define PGRES_COPY_OUT 3 /* Unimplemented */
#define PGRES_COPY_IN 4 /* Unimplemented */
#define PGRES_BAD_RESPONSE 5
#define PGRES_NONFATAL_ERROR 6
#define PGRES_FATAL_ERROR 7
#define PGRES_NOTICE 99
#define PGCONN_SUCCESS 100
#define PGCONN_FAILED 101
#define PGCONN_ABORTED 102
#define PG_RESULT_ARRAY 0
#define PG_RESULT_MAP 1
#endif

43
mudlib/sys/regexp.h Normal file
View file

@ -0,0 +1,43 @@
#ifndef LPC_REGEXP_H_
#define LPC_REGEXP_H_ 1
/* Definitions of regexp option values */
/* Not really an RE option, but used in conjunction with some RE functions: */
#define RE_GLOBAL 0x0001 /* Apply RE globally (if possible) */
/* Options supported by the old regexp package: */
#define RE_EXCOMPATIBLE 0x0002 /* RE is compatible with ex */
/* Options supported by the PCRE regexp package: */
#define RE_CASELESS 0x0004
#define RE_MULTILINE 0x0008
#define RE_DOTALL 0x0010
#define RE_EXTENDED 0x0020
#define RE_ANCHORED 0x0040
#define RE_DOLLAR_ENDONLY 0x0080
#define RE_NOTBOL 0x0100
#define RE_NOTEOL 0x0200
#define RE_UNGREEDY 0x0400
#define RE_NOTEMPTY 0x0800
#define RE_UTF8 0x1000
/* Options specific for regmatch(): */
#define RE_MATCH_SUBS 0x00100000 /* Return matched subexpressions */
/* Options specific for regexplode(): */
#define RE_OMIT_DELIM 0x00100000 /* Omit the delimiters */
/* Regexp package selection options: */
#define RE_TRADITIONAL 0x04000000
#define RE_PCRE 0x02000000
#define RE_PACKAGE_MASK (RE_TRADITIONAL | RE_PCRE)
#endif /* LPC_REGEXP_H_ */

24
mudlib/sys/rtlimits.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef LPC_RTLIMITS_H_
#define LPC_RTLIMITS_H_
/* Runtime limit index/tag values */
#define LIMIT_EVAL (0)
#define LIMIT_ARRAY (1)
#define LIMIT_MAPPING (2)
#define LIMIT_MAPPING_KEYS LIMIT_MAPPING
#define LIMIT_MAPPING_SIZE (3)
#define LIMIT_BYTE (4)
#define LIMIT_FILE (5)
#define LIMIT_CALLOUTS (6)
#define LIMIT_COST (7)
#define LIMIT_MAX (8) /* Number of recognized limits */
/* Special limit values */
#define LIMIT_UNLIMITED 0 /* No limit */
#define LIMIT_KEEP (-1) /* Keep the old limit setting */
#define LIMIT_DEFAULT (-2) /* Use the default setting */
#endif /* LPC_RTLIMITS_H_ */

10
mudlib/sys/sent.h Normal file
View file

@ -0,0 +1,10 @@
#ifndef LPC_SENT_H_
#define LPC_SENT_H_
#define SENT_PLAIN 0
#define SENT_SHORT_VERB 1
#define SENT_NO_SPACE 2
#define SENT_NO_VERB 3
#define SENT_MARKER 4
#endif

10
mudlib/sys/strings.h Normal file
View file

@ -0,0 +1,10 @@
#ifndef LPC_STRINGS_H_
#define LPC_STRINGS_H_ 1
/* 'where' argument values for trim() */
#define TRIM_LEFT 0x01
#define TRIM_RIGHT 0x02
#define TRIM_BOTH (TRIM_LEFT|TRIM_RIGHT)
#endif /* LPC_STRINGS_H_ */

38
mudlib/sys/struct_info.h Normal file
View file

@ -0,0 +1,38 @@
#ifndef LPC_STRUCTINFO_H_
#define LPC_STRUCTINFO_H_
#ifndef __DRIVER_SOURCE__
#include "lpctypes.h"
#endif
/* Definition of argument values for struct_info() and
* of the indices in the corresponding result arrays.
*/
/* Possible types of information requested from struct_info()
*/
#define SINFO_FLAT 0
#define SINFO_NESTED 1
/* Indices in the result array
*/
#define SI_NAME 0
#define SI_PROG_NAME 1
#define SI_PROG_ID 2
#define SI_BASE 3
#define SI_MEMBER 4
#define SI_MAX 5 /* Min Number of SI_ result elements */
/* Indices in the SI_MEMBER arrays
*/
#define SIM_NAME 0
#define SIM_TYPE 1
#define SIM_EXTRA 2
#define SIM_MAX 3 /* Number of SIM_ elements */
#endif /* LPC_STRUCTINFO_H_ */

217
mudlib/sys/telnet.h Normal file
View file

@ -0,0 +1,217 @@
#ifndef TELNET_H__
#define TELNET_H__ 1
/*
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#)telnet.h 5.7 (Berkeley) 11/14/89
*/
/*
* Definitions for the TELNET protocol.
*/
#define IAC 255 /* interpret as command: */
#define DONT 254 /* you are not to use option */
#define DO 253 /* please, you use option */
#define WONT 252 /* I won't use option */
#define WILL 251 /* I will use option */
#define SB 250 /* interpret as subnegotiation */
#define GA 249 /* you may reverse the line */
#define EL 248 /* erase the current line */
#define EC 247 /* erase the current character */
#define AYT 246 /* are you there */
#define AO 245 /* abort output--but let prog finish */
#define IP 244 /* interrupt process--permanently */
#define BREAK 243 /* break */
#define DM 242 /* data mark--for connect. cleaning */
#define NOP 241 /* nop */
#define SE 240 /* end sub negotiation */
#define EOR 239 /* end of record (transparent mode) */
#define ABORT 238 /* Abort process */
#define SUSP 237 /* Suspend process */
#define xEOF 236 /* End of file: EOF is already used... */
#define SYNCH 242 /* for telfunc calls */
#ifdef __DRIVER_SOURCE__
#ifdef TELCMDS
char *telcmds[] = {
"EOF", "SUSP", "ABORT", "EOR",
"SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
"EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC",
};
#define TELCMD_FIRST xEOF
#define TELCMD_LAST IAC
#define TELCMD_OK(x) ((x) <= TELCMD_LAST && (x) >= TELCMD_FIRST)
#define TELCMD(x) telcmds[(x)-TELCMD_FIRST]
#endif
#endif /* __DRIVER_SOURCE__ */
/* telnet options */
#define TELOPT_BINARY 0 /* 8-bit data path */
#define TELOPT_ECHO 1 /* echo */
#define TELOPT_RCP 2 /* prepare to reconnect */
#define TELOPT_SGA 3 /* suppress go ahead */
#define TELOPT_NAMS 4 /* approximate message size */
#define TELOPT_STATUS 5 /* give status */
#define TELOPT_TM 6 /* timing mark */
#define TELOPT_RCTE 7 /* remote controlled transmission and echo */
#define TELOPT_NAOL 8 /* negotiate about output line width */
#define TELOPT_NAOP 9 /* negotiate about output page size */
#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */
#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */
#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */
#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */
#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */
#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */
#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */
#define TELOPT_XASCII 17 /* extended ascic character set */
#define TELOPT_LOGOUT 18 /* force logout */
#define TELOPT_BM 19 /* byte macro */
#define TELOPT_DET 20 /* data entry terminal */
#define TELOPT_SUPDUP 21 /* supdup protocol */
#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */
#define TELOPT_SNDLOC 23 /* send location */
#define TELOPT_TTYPE 24 /* terminal type */
#define TELOPT_EOR 25 /* end or record */
#define TELOPT_TUID 26 /* TACACS user identification */
#define TELOPT_OUTMRK 27 /* output marking */
#define TELOPT_TTYLOC 28 /* terminal location number */
#define TELOPT_3270REGIME 29 /* 3270 regime */
#define TELOPT_X3PAD 30 /* X.3 PAD */
#define TELOPT_NAWS 31 /* window size */
#define TELOPT_TSPEED 32 /* terminal speed */
#define TELOPT_LFLOW 33 /* remote flow control */
#define TELOPT_LINEMODE 34 /* Linemode option */
#define TELOPT_XDISPLOC 35 /* X Display Location */
#define TELOPT_ENVIRON 36 /* Environment opt for Port ID */
#define TELOPT_AUTHENTICATION 37 /* authentication */
#define TELOPT_ENCRYPT 38 /* authentication */
#define TELOPT_NEWENV 39 /* Environment opt for Port ID */
#define TELOPT_STARTTLS 46 /* Transport Layer Security */
/* Inofficial, mud specific telnet options */
#define TELOPT_COMPRESS 85 /* Mud Compression Protocol, v.1 */
#define TELOPT_COMPRESS2 86 /* Mud Compression Protocol, v.2 */
#define TELOPT_MSP 90 /* Mud Sound Protocol */
#define TELOPT_MXP 91 /* Mud Extension Protocol */
#define TELOPT_EXOPL 255 /* extended-options-list */
#define NTELOPTS 256 /* was: (1+TELOPT_NEWENV) */
#ifdef __DRIVER_SOURCE__
#ifdef TELOPTS
char *telopts[NTELOPTS]
= { "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD"
, "NAME", "STATUS", "TIMING MARK", "RCTE"
, "NAOL", "NAOP", "NAOCRD", "NAOHTS"
, "NAOHTD", "NAOFFD", "NAOVTS", "NAOVTD"
, "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO"
, "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT", "SEND LOCATION"
, "TERMINAL TYPE", "END OF RECORD", "TACACS UID", "OUTPUT MARKING"
, "TTYLOC", "3270 REGIME", "X.3 PAD", "NAWS"
, "TSPEED", "LFLOW", "LINEMODE", "XDISPLOC"
, "ENVIRON", "AUTH", "ENCRYPT", "NEWENV"
, "TELOPT 40", "TELOPT 41", "TELOPT 42", "TELOPT 43"
, "TELOPT 44", "TELOPT 45", "STARTTLS", "TELOPT 47"
, "TELOPT 48", "TELOPT 49", "TELOPT 50", "TELOPT 51"
, "TELOPT 52", "TELOPT 53", "TELOPT 54", "TELOPT 55"
, "TELOPT 56", "TELOPT 57", "TELOPT 58", "TELOPT 59"
, "TELOPT 60", "TELOPT 61", "TELOPT 62", "TELOPT 63"
, "TELOPT 64", "TELOPT 65", "TELOPT 66", "TELOPT 67"
, "TELOPT 68", "TELOPT 69", "TELOPT 70", "TELOPT 71"
, "TELOPT 72", "TELOPT 73", "TELOPT 74", "TELOPT 75"
, "TELOPT 76", "TELOPT 77", "TELOPT 78", "TELOPT 79"
, "TELOPT 80", "TELOPT 81", "TELOPT 82", "TELOPT 83"
, "TELOPT 84", "MUD COMPRESS", "MUD COMPRESS2", "TELOPT 87"
, "TELOPT 88", "TELOPT 89", "MUD SOUND", "MUD EXTENSION"
};
#define TELOPT_FIRST TELOPT_BINARY
#define TELOPT_LAST TELOPT_MXP
#define TELOPT_OK(x) ((x) <= TELOPT_LAST && (x) >= TELOPT_FIRST)
#define TELOPT(x) telopts[(x)-TELOPT_FIRST]
#endif
#endif /* __DRIVER_SOURCE__ */
/* sub-option qualifiers */
#define TELQUAL_IS 0 /* option is... */
#define TELQUAL_SEND 1 /* send option */
/*
* LINEMODE suboptions
*/
#define LM_MODE 1
#define LM_FORWARDMASK 2
#define LM_SLC 3
#define MODE_EDIT 0x01
#define MODE_TRAPSIG 0x02
#define MODE_ACK 0x04
#define MODE_MASK (MODE_EDIT|MODE_TRAPSIG|MODE_ACK)
/* Not part of protocol, but needed to simplify things... */
#define MODE_FLOW 0x0100
#define MODE_ECHO 0x0200
#define MODE_INBIN 0x0400
#define MODE_OUTBIN 0x0800
#define MODE_FORCE 0x1000
#define SLC_SYNCH 1
#define SLC_BRK 2
#define SLC_IP 3
#define SLC_AO 4
#define SLC_AYT 5
#define SLC_EOR 6
#define SLC_ABORT 7
#define SLC_EOF 8
#define SLC_SUSP 9
#define SLC_EC 10
#define SLC_EL 11
#define SLC_EW 12
#define SLC_RP 13
#define SLC_LNEXT 14
#define SLC_XON 15
#define SLC_XOFF 16
#define SLC_FORW1 17
#define SLC_FORW2 18
#define NSLC 18
#define SLC_NAMES "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
"ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
"LNEXT", "XON", "XOFF", "FORW1", "FORW2"
#define SLC_NOSUPPORT 0
#define SLC_CANTCHANGE 1
#define SLC_VARIABLE 2
#define SLC_DEFAULT 3
#define SLC_LEVELBITS 0x03
#define SLC_FUNC 0
#define SLC_FLAGS 1
#define SLC_VALUE 2
#define SLC_ACK 0x80
#define SLC_FLUSHIN 0x40
#define SLC_FLUSHOUT 0x20
#endif /* TELNET_H__ */

18
mudlib/sys/time.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef LPC_TIME_H_
#define LPC_TIME_H_ 1
/* Indices into the array returned from gmtime() and localtime(). */
#define TM_SEC 0 /* Seconds (0..59) */
#define TM_MIN 1 /* Minutes (0..59) */
#define TM_HOUR 2 /* Hours (0..23) */
#define TM_MDAY 3 /* Day of the month (1..31) */
#define TM_MON 4 /* Month of the year (0..11) */
#define TM_YEAR 5 /* Year (e.g. 2001) */
#define TM_WDAY 6 /* Day of the week (Sunday = 0) */
#define TM_YDAY 7 /* Day of the year (0..365) */
#define TM_ISDST 8 /* TRUE: Daylight saving time */
#define TM_MAX 9 /* Number of entries in the array */
#endif /* LPC_TIME_H_ */

87
mudlib/sys/tls.h Normal file
View file

@ -0,0 +1,87 @@
#ifndef LPC_TLS_H
#define LPC_TLS_H
/* Field indices for the result of tls_query_connection_info() */
#define TLS_CIPHER 0
#define TLS_COMP 1
#define TLS_KX 2
#define TLS_MAC 3
#define TLS_PROT 4
#define TLS_SESSION 5
#define TLS_INFO_MAX 6 /* Total number of result fields */
/* Interpretation of the cipher information */
#define TLS_CIPHER_TABLE ({ \
"TLS_CIPHER_NONE", \
"TLS_CIPHER_NULL", \
"TLS_CIPHER_ARCFOUR_128", \
"TLS_CIPHER_3DES_CBC", \
"TLS_CIPHER_RIJNDAEL_128_CBC", \
"TLS_CIPHER_RIJNDAEL_256_CBC", \
"TLS_CIPHER_ARCFOUR_40" \
})
#define TLS_CIPHER_NAME(x) TLS_CIPHER_TABLE[(x)]
/* Interpretation of the key-exchange information */
#define TLS_KX_TABLE ({ \
"TLS_KX_NONE", \
"TLS_KX_RSA", \
"TLS_KX_DHE_DSS", \
"TLS_KX_DHE_RSA", \
"TLS_KX_ANON_DH", \
"TLS_KX_SRP", \
"TLS_KX_RSA_EXPORT", \
"TLS_KX_SRP_RSA", \
"TLS_KX_SRP_DSS" \
})
#define TLS_KX_NAME(x) TLS_KX_TABLE[(x)]
/* Interpretation of the MAC information */
#define TLS_MAC_TABLE ({ \
"TLS_MAC_NONE", \
"TLS_MAC_NULL", \
"TLS_MAC_MD5", \
"TLS_MAC_SHA" \
})
#define TLS_MAC_NAME(x) TLS_MAC_TABLE[(x)]
/* Interpretation of the compression information */
#define TLS_COMP_TABLE ({ \
"TLS_COMP_NONE", \
"TLS_COMP_NULL", \
"TLS_COMP_ZLIB", \
"TLS_COMP_LZO" \
})
#define TLS_COMP_NAME(x) TLS_COMP_TABLE[(x)]
/* Interpretation of the protocol information */
#define TLS_PROT_TABLE ({ \
"TLS_PROT_NONE", \
"TLS_PROT_SSL3", \
"TLS_PROT_TLS1" \
})
#define TLS_PROT_NAME(x) TLS_PROT_TABLE[(x)]
/* Recognized hash() algorithms (not all may be supported at runtime) */
#define TLS_HASH_SHA1 (1)
#define TLS_HASH_SHA224 (2)
#define TLS_HASH_SHA256 (3)
#define TLS_HASH_SHA384 (4)
#define TLS_HASH_SHA512 (5)
#define TLS_HASH_MD5 (6)
#define TLS_HASH_RIPEMD160 (7)
#endif /* LPC_TLS_H */

18
mudlib/sys/trace.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef LPC_TRACE_H_
#define LPC_TRACE_H_
/* Argument values for the trace() efun.
*/
#define TRACE_NOTHING 0 /* Stop tracing */
#define TRACE_CALL 1 /* Trace all lfun calls */
#define TRACE_CALL_OTHER 2 /* Trace inter-object calls */
#define TRACE_RETURN 4 /* Trace function returns */
#define TRACE_ARGS 8 /* Print function arguments and results */
#define TRACE_EXEC 16 /* Trace all executed instructions */
#define TRACE_HEART_BEAT 32 /* Trace heartbeat code */
#define TRACE_APPLY 64 /* Trace (internal) applies */
#define TRACE_OBJNAME 128 /* Print the object names */
#endif /* LPC_TRACE_H_ */

22
mudlib/sys/wizlist.h Normal file
View file

@ -0,0 +1,22 @@
#ifndef LPC_WIZLIST_H_
#define LPC_WIZLIST_H_ 1
/* Indices returned by wizlist_info()
*/
#define WL_NAME 0 /* Wizard name */
#define WL_COMMANDS 1 /* Number of commands executed */
#define WL_COST 2 /* Weighted evalcost spent on this wizard */
#define WL_GIGACOST 3 /* Weighted giga-evalcost spent on this wizard */
#define WL_TOTAL_COST 4 /* Total evalcost spent on this wizard */
#define WL_TOTAL_GIGACOST 5 /* Total giga-evalcost spent on this wizard */
#define WL_HEART_BEATS 6 /* Heartbeats spent on this wizard */
#define WL_CALL_OUT 7 /* unimplemented */
#define WL_ARRAY_TOTAL 8 /* Arrays accounted for */
#define WL_MAPPING_TOTAL 9 /* Mappings accounted for */
#define WL_STRUCT_TOTAL 10 /* Struct elements accounted for */
#define WL_EXTRA 11 /* Extra Wizinfo, if set */
#define WL_SIZE 12 /* Number of entries */
#endif /* LPC_WIZLIST_H_ */

1247
mudlib/telnetneg.c Normal file

File diff suppressed because it is too large Load diff

277
mudlib/telnetneg.h Normal file
View file

@ -0,0 +1,277 @@
//
// Wunderland Mudlib
//
// telnet.h -- Standard telnet definitions
//
// $Log: telnetneg.h,v $
// Revision 1.1.1.1 2006/07/10 02:42:09 lynx
// ldmud 3.3.714
//
// Revision 1.10 2002/12/02 17:31:56 Fiona
// sb_ttype und sb_xdisp
//
#ifndef __TELNET_H__
#define __TELNET_H__
// ******************** Telnet State Machine ********************
// Each option could be in one of the following four states. There
// is also a one element queue for each option. Mind that each option
// could have different states for the lokal and the remote system.
// Six bits of TS_STATE are used.
#define NO 0x00 // option is deactivated
#define YES 0x01 // option is activated
#define WANT_NO 0x02 // option is activated, negotiating to switch off
#define WANT_YES 0x03 // option is deactivated, negotiating to switch on
#define Q_EMPTY 0x00 // no entry in queue
#define Q_OPPOSITE 0x04 // request to toggle state in queue
#define REJECTED 0x08 // option denied, don't retry
// State and queue on the remote side (DO + DONT) (bits 0-3)
#define Q_REMOTE(x) ((x) & 0x03)
#define S_REMOTE(x, y) (((x) & ~0x03) | (y))
#define Q_REMOTEQ(x) ((x) & 0x04)
#define S_REMOTEQ(x, y) (((x) & ~0x04) | (y))
#define Q_REMOTER(x) ((x) & 0x08)
#define S_REMOTER(x, y) (((x) & ~0x08) | (y))
// State and queue on this side (WILL + WONT) (bits 4-7)
#define Q_LOCAL(x) (((x) & 0x30) >> 4)
#define S_LOCAL(x,y) (((x) & ~0x30) | ((y) << 4))
#define Q_LOCALQ(x) (((x) & 0x40) >> 4)
#define S_LOCALQ(x, y) (((x) & ~0x40) | ((y) << 4))
#define Q_LOCALR(x) (((x) & 0x80) >> 4)
#define S_LOCALR(x, y) (((x) & ~0x80) | ((y) << 4))
// Access to mapping ts
#define TS_STATE 0 // option state (yes, no, want yes, want no, Q)
#define TS_SB 1 // sb infos (option specific)
#define TS_R_AGREE 2 // preference or decision callback (remote state)
#define TS_L_AGREE 3 // preference or decision callback (local state)
#define TS_CB 4 // option state change callback (yes, no)
#define TS_SBCB 5 // option sb callback
#define TS_SIZE 6
// To have everything in one place we have one special key in ts
#define TS_EXTRA -1 // key
#define TSE_STATE 0 // input_to's INPUT_NOECHO and/or INPUT_CHARMODE
#define TSE_TELNETNEG 1 // client answered a negotiation
#define TSE_LOG 2 // negotiation log
// Bits used for the charmode and noecho state of the connection
// Bits 0 + 1 used for TSE_NOECHO (set for noecho mode)
// Bits 2 + 3 used for TSE_SGA_CHAR (set for charmode using SGA)
// Bits 4 + 5 used for TSE_LM_CHAR (set for charmode using LINEMODE)
// each representing the state with NO, YES, WANT_NO and WANT_YES
#define Q_TSE_NOECHO ((ts[TS_EXTRA, TSE_STATE]) & 0x03)
#define S_TSE_NOECHO(y) (ts[TS_EXTRA, TSE_STATE] = \
((ts[TS_EXTRA, TSE_STATE]) & ~0x03) | (y))
#define Q_TSE_SGA_CHAR (((ts[TS_EXTRA, TSE_STATE]) & 0x0c) >> 2)
#define S_TSE_SGA_CHAR(y) (ts[TS_EXTRA, TSE_STATE] = \
((ts[TS_EXTRA, TSE_STATE]) & ~0x0c) | ((y) << 2))
#define Q_TSE_LM_CHAR (((ts[TS_EXTRA, TSE_STATE]) & 0x30) >> 4)
#define S_TSE_LM_CHAR(y) (ts[TS_EXTRA, TSE_STATE] = \
((ts[TS_EXTRA, TSE_STATE]) & ~0x30) | ((y) << 4))
#ifdef NEED_PRIVATE_PROTOTYPES
#ifndef __TELNET_H_P_PROTO__
#define __TELNET_H_P_PROTO__
private int send(int* x);
private void tel_error(string err);
private void start_telnetneg();
private string telnet_to_text(int command, int option, int* args);
private void sb_ttype(int command, int option, int* optargs);
private void sb_xdisp(int command, int option, int* optargs);
private void sb_tspeed(int command, int option, int* optargs);
private void sb_env(int command, int option, int* optargs);
private void sb_naws(int command, int option, int* optargs);
private void sb_status(int command, int option, int* optargs);
private void sb_line(int command, int option, int* optargs);
private int neg_sga(int command, int option);
private int neg_echo(int command, int option);
private int neg_bin(int command, int option);
private int neg_tm(int command, int option);
private void start_sb(int command, int option);
private void start_eor(int command, int option);
private void start_lm(int command, int option);
private void cb_echo(int command, int option);
private void cb_sga(int command, int option);
static void modify_prompt(); // std/player/prompt.c
#endif
#endif // NEED_PRIVATE_PROTOTYPES
// ************ Definitions for the TELNET protocol *************
#define IAC 255 /* interpret as command: */
#define DONT 254 /* you are not to use option */
#define DO 253 /* please, you use option */
#define WONT 252 /* I won't use option */
#define WILL 251 /* I will use option */
#define SB 250 /* interpret as subnegotiation */
#define SE 240 /* end sub negotiation */
#define EOR 239 /* end of record (transparent mode) */
#define TELCMDS ({\
"EOR", "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",\
"EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC",\
})
/* backward starting with IAC == 255 */
#define TELCMD2STRING(x) (((256-x)<sizeof(TELCMDS))?TELCMDS[<(256-x)]:(""+x))
/* telnet options */
#define TELOPT_BINARY 0 /* 8-bit data path */
#define TELOPT_ECHO 1 /* echo */
#define TELOPT_RCP 2 /* prepare to reconnect */
#define TELOPT_SGA 3 /* suppress go ahead */
#define TELOPT_NAMS 4 /* approximate message size */
#define TELOPT_STATUS 5 /* give status */
#define TELOPT_TM 6 /* timing mark */
#define TELOPT_RCTE 7 /* remote controlled transmission and echo */
#define TELOPT_NAOL 8 /* negotiate about output line width */
#define TELOPT_NAOP 9 /* negotiate about output page size */
#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */
#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */
#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */
#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */
#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */
#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */
#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */
#define TELOPT_XASCII 17 /* extended ascic character set */
#define TELOPT_LOGOUT 18 /* force logout */
#define TELOPT_BM 19 /* byte macro */
#define TELOPT_DET 20 /* data entry terminal */
#define TELOPT_SUPDUP 21 /* supdup protocol */
#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */
#define TELOPT_SNDLOC 23 /* send location */
#define TELOPT_TTYPE 24 /* terminal type */
#define TELOPT_EOR 25 /* end or record */
#define TELOPT_TUID 26 /* TACACS user identification */
#define TELOPT_OUTMRK 27 /* output marking */
#define TELOPT_TTYLOC 28 /* terminal location number */
#define TELOPT_3270REGIME 29 /* 3270 regime */
#define TELOPT_X3PAD 30 /* X.3 PAD */
#define TELOPT_NAWS 31 /* window size */
#define TELOPT_TSPEED 32 /* terminal speed */
#define TELOPT_LFLOW 33 /* remote flow control */
#define TELOPT_LINEMODE 34 /* linemode negotiations */
#define TELOPT_XDISPLOC 35 /* X Display Location */
#define TELOPT_ENVIRON 36 /* Environment opt for Port ID */
#define TELOPT_AUTHENTICATION 37/* authentication */
#define TELOPT_ENCRYPT 38 /* authentication */
#define TELOPT_NEWENV 39 /* Environment opt for Port ID */
/* Inofficial, mud specific telnet options */
#define TELOPT_COMPRESS 85 /* Mud Compression Protocol, v.1 */
#define TELOPT_COMPRESS2 86 /* Mud Compression Protocol, v.2 */
#define TELOPT_MSP 90 /* Mud Sound Protocol */
#define TELOPT_MXP 91 /* Mud Extension Protocol */
#define TELOPT_EXOPL 255 /* extended-options-list */
#define NTELOPTS (1+TELOPT_NEWENV)
#define TELOPTS ({\
"BINARY", "ECHO", "RCP", "SGA", "NAME",\
"STATUS", "TM", "RCTE", "NAOL", "NAOP",\
"NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",\
"NAOVTD", "NAOLFD", "XASCII", "LOGOUT", "BM",\
"DET", "SUPDUP", "SUPDUP OUTPUT",\
"SENDLOC", "TTYPE", "EOR", \
"TACACS UID", "OUTPUT MARKING", "TTYLOC",\
"3270 REGIME", "X.3 PAD", "NAWS","TSPEED","LFLOW","LINEMODE",\
"XDISPLOC","ENVIRON","AUTHENTICATION","ENCRYPT","NEWENV",\
"TELOPT 40", "TELOPT 41", "TELOPT 42", "TELOPT 43",\
"TELOPT 44", "TELOPT 45", "TELOPT 46", "TELOPT 47",\
"TELOPT 48", "TELOPT 49", "TELOPT 50", "TELOPT 51",\
"TELOPT 52", "TELOPT 53", "TELOPT 54", "TELOPT 55",\
"TELOPT 56", "TELOPT 57", "TELOPT 58", "TELOPT 59",\
"TELOPT 60", "TELOPT 61", "TELOPT 62", "TELOPT 63",\
"TELOPT 64", "TELOPT 65", "TELOPT 66", "TELOPT 67",\
"TELOPT 68", "TELOPT 69", "TELOPT 70", "TELOPT 71",\
"TELOPT 72", "TELOPT 73", "TELOPT 74", "TELOPT 75",\
"TELOPT 76", "TELOPT 77", "TELOPT 78", "TELOPT 79",\
"TELOPT 80", "TELOPT 81", "TELOPT 82", "TELOPT 83",\
"TELOPT 84", "MCCP1", "MCCP2", "TELOPT 87",\
"TELOPT 88", "TELOPT 89", "MSP", "MEP",\
})
#define TELOPT2STRING(x) ((x<sizeof(TELOPTS))?TELOPTS[x]:(""+x))
/* sub-option qualifiers */
#define TELQUAL_IS 0 /* option is... */
#define TELQUAL_SEND 1 /* send option */
#define TELQUAL_INFO 2
#define TELQUAL2STRING(x) (x<3?({"IS","SEND","INFO"})[x]:""+x)
/*
* LINEMODE suboptions
*/
#define LM_MODE 1
#define LM_FORWARDMASK 2
#define LM_SLC 3
#define MODE_EDIT 0x01
#define MODE_TRAPSIG 0x02
#define MODE_ACK 0x04
#define MODE_SOFT_TAB 0x08
#define MODE_LIT_ECHO 0x10
#define MODE_MASK (MODE_EDIT|MODE_TRAPSIG|MODE_ACK|MODE_SOFT_TAB|MODE_LIT_ECHO)
#define SLC_SYNCH 1
#define SLC_BRK 2
#define SLC_IP 3
#define SLC_AO 4
#define SLC_AYT 5
#define SLC_EOR 6
#define SLC_ABORT 7
#define SLC_EOF 8
#define SLC_SUSP 9
#define SLC_EC 10
#define SLC_EL 11
#define SLC_EW 12
#define SLC_RP 13
#define SLC_LNEXT 14
#define SLC_XON 15
#define SLC_XOFF 16
#define SLC_FORW1 17
#define SLC_FORW2 18
#define SLC_MCL 19
#define SLC_MCR 20
#define SLC_MCWL 21
#define SLC_MCWR 22
#define SLC_MCBOL 23
#define SLC_MCEOL 24
#define SLC_INSRT 25
#define SLC_OVER 26
#define SLC_ECR 27
#define SLC_EWR 28
#define SLC_EBOL 29
#define SLC_EEOL 30
#define SLC_NAMES ({"0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
"ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
"LNEXT", "XON", "XOFF", "FORW1", "FORW2", \
"MCL", "MCR", "MCWL", "MCWR", "MCBOL", "MCEOL", \
"INSRT", "OVER", "ECR", "EWR", "EBOL", "EEOL"})
#define SLC2STRING(x) ((x)<sizeof(SLC_NAMES)?SLC_NAMES[x]:sprintf("%02x",x))
#define SLC_NOSUPPORT 0
#define SLC_CANTCHANGE 1
#define SLC_VARIABLE 2
#define SLC_DEFAULT 3
#define SLC_ACK 0x80
#define SLC_FLUSHIN 0x40
#define SLC_FLUSHOUT 0x20
#define SLC_LEVELBITS 0x03
#define SLC_FLAGNAME ({ "NOSUPPORT", "CANTCHANGE", "VARIABLE", "DEFAULT" })
#define ENV_VAR 0
#define ENV_VALUE 1
#define ENV_ESC 2
#define ENV_USERVAR 3
#endif

315
mudlib/test_master.c Normal file
View file

@ -0,0 +1,315 @@
/* Test Master.c
*
* Minimal master.c to provide a very rudimentary test of the gamedriver.
* To perform the test, cd to the directory this file is in and give the
* command
* driver -N -e -m. -Mtest_master.c -s-1 -sv-1 4242
* (this assumes that you called the gamedriver 'driver' and that it is
* in your searchpath).
* Once it's running, telnet to localhost, port 4242. You should be
* connected to the driver now and be able to enter commands.
* The command 'help' will list you the commands available.
*
* A second test consists of the simple command
* driver --version
* The driver shall just print the version and exit immediately.
*/
//---------------------------------------------------------------------------
void inaugurate_master (int arg)
// Initialise the master object.
// We have to set the uid hooks, otherwise we can't clone a login object.
{
set_driver_hook(2, unbound_lambda(({}), "uid"));
set_driver_hook(3, unbound_lambda(({}), "uid"));
set_driver_hook(10, "What?\n");
#ifdef NOECHO
set_driver_hook(13, "telnetneg");
set_driver_hook(14, "set_noecho");
#endif
}
//---------------------------------------------------------------------------
int old_flag;
void set_noecho(int flag)
{
if (flag & ~old_flag & 1)
{
write("sending IAC WILL ECHO\n");
binary_message(({ 0xff, 0xfb, 0x01 })); // IAC WILL ECHO
}
else if (old_flag & ~flag & 1)
{
write("sending IAC WONT ECHO\n");
binary_message(({ 0xff, 0xfc, 0x01 })); // IAC WONT ECHO
}
if (flag & ~old_flag & 2)
{
write("sending IAC WILL+DO SGA\n");
binary_message(({ 0xff, 0xfb, 0x03 })); // IAC WILL SGA
binary_message(({ 0xff, 0xfd, 0x03 })); // IAC DO SGA
}
else if (old_flag & ~flag & 2)
{
write("sending IAC WONT+DONT SGA\n");
binary_message(({ 0xff, 0xfc, 0x03 })); // IAC WONT SGA
binary_message(({ 0xff, 0xfe, 0x03 })); // IAC DONT SGA
}
old_flag = flag;
} /* set_noecho() */
void telnetneg(int a, int b, int* c)
{
// just ignore, should work with linux telnet
printf("got %d %d %O\n", a,b,c);
}
//---------------------------------------------------------------------------
string get_simul_efun ()
// Load the simul-efun object "/sefun" if existing and return its pathname.
{
object sefun;
if (!catch(sefun = load_object("/sefun")))
return object_name(sefun);
return 0;
}
//---------------------------------------------------------------------------
string get_master_uid()
// Return the master uid.
{
return " R O O T ";
}
//---------------------------------------------------------------------------
void flag (string arg)
// Evaluate an argument given as option '-f' to the driver.
{
debug_message(sprintf("%O: flag(%O)\n", this_object(), arg));
if (arg == "test")
{
/* Insert your test code here */
return;
}
if (arg == "gc")
{
garbage_collection();
return;
}
if (arg == "dhry")
{
limited( (: load_object("dhrystone")->main(1000) :) );
shutdown();
return;
}
if (arg == "dhry2")
{
limited( (: load_object("dhrystone2")->main(1000) :) );
shutdown();
return;
}
if (arg == "shutdown")
{
shutdown();
return;
}
write ("master: Unknown flag "+arg+"\n");
}
//---------------------------------------------------------------------------
mixed prepare_destruct (object obj)
// Prepare the destruction of the object.
{
debug_message(sprintf("%O: prepare_destruct(%O)\n", this_object(), obj));
return 0;
}
//---------------------------------------------------------------------------
object connect ()
// Handle the request for a new connection.
// We simply return a clone of ourself (we can't simply return this object
// unfortunately), the gamedriver will then call logon() here.
{
object obj;
debug_message(sprintf("%O: connect()\n", this_object()));
obj = clone_object(object_name(this_object()));
return obj;
}
//---------------------------------------------------------------------------
static nomask mixed logon ()
// A connection was successfully bound to this object.
// Print some status data and add the commands.
{
debug_message(sprintf("%O: logon()\n", this_object()));
write("\nLDMud " __VERSION__ "\n\n----------\n");
write(debug_info(4,0));
write("----------\n\n");
enable_commands();
add_action("f_help", "help");
add_action("f_shutdown", "shutdown");
add_action("f_echo", "echo");
add_action("f_flag", "flag");
add_action("f_gc", "gc");
add_action("f_upd", "upd");
add_action("f_quit", "quit");
add_action("f_charmode", "charmode");
set_combine_charset("abc");
return 1; // To verify that the connection was accepted.
}
//---------------------------------------------------------------------------
int f_help (string arg)
// The 'help' command.
{
debug_message(sprintf("%O: f_help()\n", this_object()));
write(
" help - Prints this message\n"
" shutdown - shuts down the driver\n"
" flag - passes the argument to the flag() function\n"
" echo - tests the input_to() function\n"
" gc - performes a garbage collection\n"
" upd - reloads the master object\n"
" quit - terminates the connection, but leaves the driver running\n"
);
return 1;
}
//---------------------------------------------------------------------------
int f_flag (string arg)
// The 'flag' command.
{
debug_message(sprintf("%O: f_flag()\n", this_object()));
flag(arg);
return 1;
}
//---------------------------------------------------------------------------
int f_gc (string arg)
// The 'gc' command.
{
write("Requested a garbage collection.\n");
garbage_collection();
return 1;
}
//---------------------------------------------------------------------------
int f_echo (string arg)
// The 'echo' command.
{
debug_message(sprintf("%O: f_echo()\n", this_object()));
input_to("echoline", 4, "Please enter a line: ");
return 1;
}
//---------------------------------------------------------------------------
void echoline (string text)
// The user entered some text. Echo it.
{
debug_message(sprintf("%O: echoline()\n", this_object()));
write("You entered: '"+text+"'\n");
}
//---------------------------------------------------------------------------
int f_charmode (string arg)
{
write("Entering charmode. Enter 'enough' to stop.\n");
input_to("charinput", 2);
return 1;
}
string in;
void charinput(string char)
{
string cmd;
printf(" Got %O (%s)\n", char
, implode(map(to_array(char), #'to_string),","));
if (!in)
in = char;
else if (!strlen(char) || char[0] == 13)
{
cmd = in;
in = char[1..];
}
else
{
in += char;
}
if (cmd !="enough")
input_to("charinput", 2);
else
write("Ok.\n");
} /* charinput() */
//---------------------------------------------------------------------------
int f_shutdown (string arg)
// The 'shutdown' command.
{
debug_message(sprintf("%O: f_shutdown()\n", this_object()));
write("Shutting down.\n");
shutdown();
return 1;
}
//---------------------------------------------------------------------------
int f_upd (string arg)
// The 'upd' command.
{
debug_message(sprintf("%O: f_upd()\n", this_object()));
write("Removing old master...\n");
destruct(find_object(__MASTER_OBJECT__));
write("Loading master again...\n");
load_object(__MASTER_OBJECT__);
write("...done.\n");
return 1;
}
//---------------------------------------------------------------------------
int f_quit (string arg)
// The 'quit' command.
{
debug_message(sprintf("%O: f_quit()\n", this_object()));
write("Bye-bye.\n");
destruct(this_object());
return 1;
}

14
mudlib/uni-crasher/README Normal file
View file

@ -0,0 +1,14 @@
This directory holds a LPC object which runs a stress test against the driver:
it calls random efuns with random arguments and keeps a log of what has been
called.
It was written for the Unitopia mudlib (and thusly uses some of their
simul-efuns). To use it, copy secure.inc into the secure/simul_efun
directory first.
crasher.c : the test object
crashleak.c: a variant of the crasher object looking for memory leaks.
secure.inc : a replacement for the original secure/simul_efun/secure.inc,
so that the security-sensitive functions can be tested, too.
Written by Andreas "Menaures" Klauer.

View file

@ -0,0 +1,831 @@
/*
crasher: Standardversion (Menaures 07.12.01)
ANLEITUNG:
1. Bei dem Define DEBUGGER den eigenen Real-Namen angeben
2. Define VERBOSE auskommentieren, falls nicht bereits so.
VERBOSE kann genutzt werden, wenn gesicherte Dateien einen
Crash ausloesen und die genaue Zeile gesucht wird.
(VERBOSE gibt vor jedem einzelnen Aufruf momentane
Datei und Zeile per debug_message aus).
3. Wenn bereits aufgenommene Dateien existieren, das EFuns und
Values-Array NICHT modifizieren, bzw. nicht die Positionen
der einzelnen Elemente aendern - sonst werden die aufgezeichneten
Dateien unbrauchbar. Ebenso koennen nach solchen Modifikationen
aufgenommene Dateien nicht mehr von alten Versionen des Crashers
abgespielt werden.
Wer andere Values / Closures haben moechte, modifiziere die
entsprechenden Arrays, speichere den Crasher unter einem anderen
Filenamen und mache einen eindeutigen Eintrag im Header...
record:
record(file) speichert Ausfuehrungsablaeufe in Dateien namens
file_xxxx, wobei xxxx eine Durchlaufnummer ist. Das Objekt
braucht fuer diese Dateien logischerweise Schreibrecht.
Die aufgenommenen Dateien werden nach ihrer Erstellung automatisch
ausgefuehrt. Fuehrt dies zu einem Crash, kann man das ganze einfach
nochmals abspielen.
replay:
replay(file) spielt aufgenommene Dateien ab, fuehrt sie also aus.
Dies ist dazu da, um Crashes, die dieses Objekt erzeugt, zu
reproduzieren. Statt file wird file_xxxx eingelesen, wobei xxxx
eine Durchlaufnummer ist.
execute_file:
Mit execute_file(file) kann man eine Datei gezielt ausfuehren.
Dazu gibt man den echten Dateinamen der Datei an, inklusive
Durchlaufnummer.
debug_query:
Mit debug_query(file, line) kann man abfragen, was in der Datei
file in Zeile line ausgefuehrt werden wuerde - also welche
Closure mit welchen Argumenten.
Hierzu muss der eigene Name als DEBUGGER definiert sein.
debug_exec:
Mit debug_exec(file, line) wird die angegebene Zeile in der
Datei ausgefuehrt. Dadurch kann gezielt festgestellt werden,
ob der einzelne Aufruf den Crash ausgeloest hat.
Crash-Grund finden:
Bringt der Crasher den Driver zum Absturz, zunaechst den Driver
neu starten und mit execute_file das zuletzt aufgenommene File
abspielen.
Bringt das den Driver zum Crash, den gleichen Vorgang mit
aktiviertem VERBOSE wiederholen, um die Zeilennummer herauszufinden.
Hat man erst einmal die Zeilennummer, laesst sich per debug_query
herausfinden, was ausgefuehrt werden, und mit debug_exec pruefen,
ob es wirklich der Ausloeser war.
Kann der Crash auf diese Weise nicht reproduziert werden, kann man
einmal versuchen, alle aufgenommenen Dateien mit replay abzuspielen;
fuehrt das zu keinem Crash, wurde der Crash nicht durch einen
bestimmten Aufruf (oder eine bestimmte Folge selbiger) ausgeloest,
sondern hat einen anderen Grund, der genauer untersucht werden muss.
*/
#include <math.h>
#define DEBUGGER "menaures"
#include <debug.h>
// #define VERBOSE // Aktivieren, wenn man die crashausloesende Zeile sucht
#define MAX_ARGS 5
#define DELAY 4
#define ITERATIONS 1000
mixed execute;
mixed efuns;
mixed values;
mixed names;
void record(string file);
void reset_all()
{
catch(
execute = 0,
( efuns =
({
#'Name,
#'[,
#'abs,
#'abs_path,
#'acos,
#'add_action,
#'add_dot_to_msg,
// #'add_verb,
// #'add_xverb,
#'all_environment,
#'all_inventory,
#'allocate,
// #'allocate_mapping,
#'and_bits,
#'apply,
#'arr_delete,
#'asin,
// #'assoc,
#'atan,
#'atan2,
#'attach_erq_demon,
#'auto_owner_search,
#'binary_message,
#'bind_lambda,
// #'break_point,
#'call_other,
#'call_out,
#'call_out_info,
#'call_resolved,
#'caller_stack,
#'caller_stack_depth,
#'capitalize,
#'cat,
#'catch,
#'ceil,
#'center,
#'clear_bit,
#'clock,
#'clone_object,
#'clonep,
// #'clones,
#'closurep,
#'command,
#'command_stack,
#'command_stack_depth,
#'cond_present,
#'convert_message,
#'convert_umlaute,
#'copies,
#'copy,
#'copy_bits,
#'copy_file,
// #'copy_mapping,
#'cos,
#'count_bits,
#'crypt,
#'ctime,
// #'db_affected_rows,
// #'db_close,
// #'db_coldefs,
// #'db_connect,
// #'db_conv_string,
// #'db_error,
// #'db_exec,
// #'db_fetch,
// #'db_handles,
// #'db_insert_id,
#'debug_info,
#'debug_message,
#'deep_copy,
#'deep_inventory,
#'deep_present,
#'dein,
#'deinem,
#'deinen,
#'deines,
#'dem,
#'den,
#'der,
#'des,
#'destruct,
#'diesem,
#'diesen,
#'dieser,
#'dieses,
#'disable_commands,
#'domain2map,
#'ed,
// #'efun308,
#'ein,
#'einem,
#'einen,
#'eines,
#'enable_commands,
#'environment,
#'er,
#'exec,
#'execute_command,
#'exp,
#'expand_define,
#'explode,
#'export_uid,
#'extern_call,
// #'extract,
// #'file_name,
#'file_path,
#'file_size,
#'file_time,
#'filter,
// #'filter_array,
#'filter_indices,
// #'filter_mapping,
#'filter_objects,
#'find_call_out,
#'find_living,
#'find_object,
#'find_player,
#'first_inventory,
#'floatp,
#'floor,
#'format_seconds,
#'format_vseconds,
#'funcall,
#'function_exists,
#'functionlist,
#'garbage_collection,
#'get_align_string,
#'get_dir,
#'get_error_file,
#'get_eval_cost,
#'get_extra_wizinfo,
#'get_genitiv,
#'get_type_info,
#'get_unique_string,
#'geteuid,
#'getuid,
#'gmtime,
#'heart_beat_info,
#'ihm,
#'ihn,
#'ihr,
#'ihrem,
#'ihren,
#'ihres,
#'implode,
#'inherit_list,
#'input_to,
// #'insert_alist,
#'interactive,
// #'intersect_alist,
#'intp,
#'invert_bits,
#'ist,
#'lambda,
#'last_bit,
#'last_instructions,
#'left,
#'limited,
#'liste,
#'living,
#'load_name,
#'load_object,
#'localtime,
#'log,
#'log_file,
#'lower_case,
#'m_allocate,
#'m_contains,
#'m_delete,
#'m_indices,
#'m_reallocate,
// #'m_sizeof,
#'m_values,
#'make_shared_string,
#'map,
#'map2domain,
// #'map_array,
#'map_indices,
// #'map_mapping,
#'map_object,
#'map_objects,
// #'mapping_contains,
#'mappingp,
#'max,
#'md5,
#'member,
// #'member_array,
#'min,
#'mixed2str,
#'mixed_to_closure,
#'mkdir,
#'mkmapping,
#'move_object,
#'negate,
#'next_bit,
#'next_inventory,
#'not_alone,
#'notify_fail,
#'object_info,
#'object_name,
#'object_time,
#'objectp,
#'or_bits,
// #'order_alist,
#'parse_com,
#'parse_com_error,
#'parse_com_error_string,
#'player_exists,
#'player_present,
#'playerp,
#'plural,
#'pointerp,
#'pol2xy,
#'pow,
#'present,
#'present_clone,
#'previous_object,
#'printf,
#'process_string,
#'program_name,
#'program_time,
#'query_actions,
// #'query_akkusativ,
#'query_command,
// #'query_dativ,
#'query_deklin,
#'query_deklin_adjektiv,
#'query_deklin_ein_adjektiv,
#'query_deklin_name,
// #'query_dekliniert,
#'query_editing,
// #'query_genitiv,
#'query_idle,
// #'query_imp_port,
#'query_input_pending,
#'query_ip_name,
#'query_ip_number,
#'query_limits,
#'query_living_name,
#'query_livings,
#'query_load_average,
#'query_mud_port,
#'query_notify_fail,
#'query_once_interactive,
#'query_pronom,
#'query_real_player_level,
#'query_shadowing,
#'query_snoop,
#'query_udp_port,
#'query_up_time,
#'query_verb,
#'quote,
#'raise_error,
#'random,
#'read_bytes,
#'read_file,
#'real_time_diff,
#'referencep,
#'regexp,
#'regexplode,
#'regreplace,
#'remove_action,
#'remove_call_out,
#'remove_input_to,
#'remove_interactive,
#'rename,
#'rename_object,
#'replace_program,
#'restore_object,
#'restore_value,
#'right,
#'rm,
#'rmdir,
#'round,
#'rusage,
#'save_object,
#'save_value,
#'say,
#'search_object,
#'sein,
#'seinem,
#'seinen,
#'seines,
#'send_erq,
// #'send_imp,
#'send_udp,
// #'set_auto_include_string,
#'set_bit,
#'set_buffer_size,
#'set_combine_charset,
#'set_connection_charset,
#'set_driver_hook,
#'set_environment,
#'set_extra_wizinfo,
#'set_extra_wizinfo_size,
#'set_heart_beat,
#'set_is_wizard,
#'set_light,
#'set_limits,
#'set_living_name,
#'set_modify_command,
#'set_next_reset,
#'set_prompt,
#'set_this_object,
#'set_this_player,
#'seteuid,
#'sgn,
#'shadow,
#'short_format_seconds,
#'short_format_vseconds,
#'shorttimestr,
#'shortvtimestr,
#'shout,
#'shutdown,
#'sin,
#'sizeof,
// #'slice_array,
#'snoop,
#'sort_array,
#'space,
#'sprintf,
#'sqrt,
#'sscanf,
#'str2int,
#'string_parser,
#'stringp,
#'strip,
#'strlen,
#'strstr,
#'substr,
// #'swap,
#'symbol_function,
#'symbol_variable,
#'symbolp,
#'sys_log,
#'tail,
#'tan,
#'tell_object,
#'tell_room,
#'terminal_colour,
#'test_bit,
#'this_interactive,
#'this_object,
#'this_player,
#'throw,
#'time,
#'time_to_vtime,
#'timestr,
#'to_array,
#'to_float,
#'to_int,
#'to_object,
#'to_string,
#'touch,
#'trace,
#'traceprefix,
#'transpose_array,
#'trim,
#'typeof,
#'unbound_lambda,
#'unique_array,
#'unmkmapping,
#'unshadow,
#'upper_case,
#'users,
#'utime,
#'vclock,
#'vtime,
#'vtime_to_time,
#'vtimestr,
#'walk_mapping,
#'wem,
#'wen,
#'wer,
#'wessen,
#'widthof,
#'wizardshellp,
#'wizlist_info,
#'wrap,
#'wrap_say,
#'write,
#'write_bytes,
#'write_file,
#'xor_bits,
#'xy2pol,
#',,
#'=,
#'+=,
#'-=,
#'&=,
#'|=,
#'^=,
#'<<=,
#'>>=,
#'>>>=,
#'*=,
#'%=,
#'/=,
#'?,
#'||,
#'&&,
#'|,
#'^,
#'&,
#'==,
#'!=,
#'>,
#'>=,
#'<,
#'<=,
#'<<,
#'>>,
#'>>>,
#'+,
#'-,
#'*,
#'%,
#'/,
#'++,
#'--,
#'negate,
#'!,
#'~,
#'({,
#'([,
#'[,
#'[<,
#'[..],
#'[..<],
#'[<..],
#'[<..<],
#'[..,
#'[<..,
#'({,
#'([,
}) ),
( values =
({
/* --- Integers: --- */
0,
1,
-1,
32,
-32,
40,
-40,
29292929,
-5050211,
__INT_MAX__,
__INT_MIN__,
/* --- Floats: --- */
0.0,
0.5,
-0.5,
55.5,
-55.5,
999999999999999999999999999999999999999999999.99,
-999999999999999999999999999999999999999999999.99,
/* --- Strings: --- */
"",
"foo bar",
"%d %q %T",
"0",
"",
" ",
"_",
"^^^^^^",
"#^# #^#",
" ^",
"^ ",
" - - - - ",
"? ? ? ? ? ? ????? ???? ??",
"°°°°°°°°°°°°°°°°°°°°°",
"\\/ "*32,
" !"*42,
/* --- Objekte: --- */
touch("/obj/fackel"),
touch("/obj/rucksack"),
touch("/obj/rope"),
touch("/secure/master"),
clone_object("/obj/schiff"),
clone_object("/obj/player"),
clone_object("/obj/tisch"),
/* --- Closures: --- */
(: :),
(: (: 1 :) :),
#'sizeof,
#'garbage_collection,
symbol_function("query_long", touch("/i/item")),
lambda( ({'x, 'y}), ({#'?, ({#'>, 'x, 'y}), 'x, 'y}) ),
unbound_lambda( ({'x}), ({#'==, 0, 'x}) ),
/* --- Arrays: --- */
({ }),
({ 0 }),
({ "" }),
({ ({ }) }),
({ ([ ]) }),
allocate(3000),
/* --- Mappings: --- */
([ ]),
([ (: :) ]),
m_allocate(5,5),
mkmapping(allocate(30), allocate(30, ({})), allocate(30, (:1:))),
}) )
); // catch
if(pointerp(values)) {
values += ({0,0,0});
apply((: values[<3] = $1 :), &execute);
apply((: values[<2] = $1 :), &values);
apply((: values[<1] = $1 :), &efuns);
}
while(remove_call_out("execute_file") != -1);
while(remove_call_out("do_replay") != -1);
while(remove_call_out("do_record") != -1);
seteuid(getuid());
}
int execute_file(string file)
{
int line;
string str;
mixed restore;
if(!stringp(file) || file_size(file) <= 0)
{
DEBUG("ERROR: Cannot execute "+file+": Invalid file.");
return 0;
}
DEBUG("Executing: "+file);
for(line = 0; (str=read_file(file, line, 2)) && strlen(str); line += 2)
{
restore = restore_value(str);
rm("/save/crash/LAST_EXEC");
write_file("/save/crash/LAST_EXEC",
save_value( ({file, line}) ));
#ifdef VERBOSE
debug_message("File: "+file+" Line: "+line+"\n");
#endif
debug_message(sprintf("REPLAY: %O %O -> %O %O\n", restore[0], restore[1], efuns[ restore[0] ], map( restore[1], (: values[$1] :) )));
catch(
apply( efuns[ restore[0] ],
map( restore[1], (: values[$1] :) ) )
);
}
return 1;
}
mixed query_values() { return values; }
int generate_file(string file)
{
int i, h, efun_index, * value_index;
if(!stringp(file) || !write_file(file, ""))
{
DEBUG("ERROR: Cannot write file: "+file);
debug_message(wrap("ERROR: Cannot write file: "+file));
seteuid(getuid());
record("/save/crash/"+(mixed2str(utime())-"({,})"));
return 0;
}
DEBUG("Recording: "+file);
for(i = ITERATIONS; i--; )
{
efun_index = random(sizeof(efuns));
value_index = ({});
for(h = random(MAX_ARGS+1); h--; )
{
value_index += ({ random(sizeof(values)) });
}
write_file(file, save_value( ({efun_index, value_index}) ));
}
return 1;
}
void replay(string file)
{
if (!file)
{
file = names[0];
names = names[1..];
}
DEBUG("Stopping all actions and starting REPLAY for: "+file);
reset_all();
execute = ({ #'call_out, "do_replay", DELAY, file, 1 });
// Um this_player etc. loszuwerden einen Reset-Hack ;o)
set_next_reset(DELAY);
}
static void do_replay(string file, int number)
{
if(execute_file(file + right(number, 5, "_0000")))
{
call_out("do_replay", DELAY, file, number+1);
}
else call_out("replay", DELAY, 0);
}
void record(string file)
{
DEBUG("Stopping all actions and starting RECORD for: "+file);
reset_all();
execute = ({ #'call_out, "do_record", DELAY, file, 1 });
// Um this_player etc. loszuwerden einen Reset-Hack ;o)
set_next_reset(DELAY);
}
static void do_record(string file, int number)
{
if(generate_file(file+right(number, 5, "_0000")))
{
call_out("execute_file", DELAY, file+right(number, 5, "_0000"));
call_out("do_record", DELAY*2, file, number+1);
}
}
void reset()
{
// Um this_player etc. loszuwerden einen Reset-Hack ;o)
if(execute)
{
apply(execute[0], execute[1..]);
execute = 0;
}
}
void debug_query(string file, int line)
{
mixed restore;
restore = restore_value(read_file(file, line, 2));
rm("/save/crash/TEMP");
write_file("/save/crash/TEMP",
sprintf("apply( %Q, %Q )", efuns[ restore[0] ],
map(restore[1], (: values[$1] :))));
({this_player()})->more("/save/crash/TEMP");
}
void debug_exec(string file, int line)
{
mixed restore;
restore = restore_value(read_file(file, line, 2));
catch(
apply( efuns[ restore[0] ], map(restore[1], (: values[$1] :)))
);
}
void create()
{
string str;
mixed strs;
reset_all();
str = read_file("/save/crash/LAST_EXEC");
if(str)
{
catch( apply( #'debug_query, restore_value(str) ),
write_file("/save/crash/CRASHERS",
"-"*80 + "\n"
+ read_file("/save/crash/TEMP")+ "\n" ) );
}
#if 0
strs = get_dir("/save/crash/1*");
foreach(str : strs)
{
rm("/save/crash/"+str);
}
#endif
#if 1
call_out("record", 4, "/save/crash/"+(mixed2str(utime())-"({,})"));
#else
names = ({
"/save/crash/crash1"
});
call_out("replay", 4, 0);
#endif
}
/* --- End of file. --- */

View file

@ -0,0 +1,686 @@
// This is for crash purposes only. Don't run it in a production MUD.
//
// It may still depend on some UNItopia stuff, I haven't tested it with other
// libs. If you're using the UNItopia Mudlib to run it, you have to remove all
// nomask simul efuns (empty the file /secure/simul_efun/secure.inc), and
// unlock all privilege violations in /secure/master/compiler_control.inc by
// adding return 1; of the function.
//
// ------------------------------------------------------------------
// File: crashleak.c
// Description: Try to crash the driver and/or find memory leaks
// by calling EFuns and Operators with random arguments.
// Based on my old crasher.c
// Author: Menaures@UNItopia (2004-07-17)
//
/* --- Documentation: --- */
/* --- Inherits: --- */
/* --- Includes: --- */
#include <rtlimits.h>
// Replace this with some kind of output if you
// want Debug-Messages
#define DEBUG(x) {}
/* --- Defines: --- */
// Undef the following if you're not interested in Memleaks
#define FIND_MEMORY_LEAKS
// Where shall we write our data to?
#define CRASHLEAK_DIR "/save/crashleak/"
// Where is the doc/efun directory of the driver package?
#define DOC_EFUN_DIR CRASHLEAK_DIR"doc/efun/"
#define FILE(x,y) (CRASHLEAK_DIR+l_time+"_"+sprintf("%'0'6d_%s", (y), (x)))
#define GC_FILE(x) FILE("GC_"+(x), ++filecounter)
#define RECORD_FILE(x) FILE("REC_"+(x), ++filecounter)
#define LEAK_FILE(x) FILE("LEAK_"+(x), ++filecounter)
#define LOG_FILE(x) FILE("LOG_"+(x), ++filecounter)
// How many calls shall we do per step?
#define CALLS_PER_STEP 1000
// How long to wait between steps?
// Careful, Memleak detection might not work for lower values!
#define STEP_PAUSE 4
// Sometimes objects get removed out of the values array.
// Do you want to reinitialize it every X steps?
// For maximum Memleak Find reliability, set to 1,
// which causes reinitialization in every step (halfing
// the speed)
#define REINIT_EVERY_N_STEPS 10
// This defines minimum and maximum number of arguments per
// function call. Recorded files may still be executed with
// old values if you change this.
#define MIN_PARAMS 0
#define MAX_PARAMS 15
// NOTE:
// When looking for Memleaks, only one step per PAUSE will be made.
// Thus, detecting all Memleaks of one real step will require
// a minimum of CALLS_PER_STEP*STEP_PAUSE time until the next step
// is done with full stress speed again. This is probably a long
// time, however: if there are few leaks, lower CALLS_PER_STEP
// will only add up to the time it takes to find one in the first
// place...
/* --- Global Variables: --- */
int l_time = time(); // Just as a unique number...
mixed * efun; // EFun- and Operator-Closures. Either #'foo or ({#'foo, min_param, max_param})
mixed * value; // Value-set which contains all Data Types.
int stepcounter; // For reinit after N steps.
int filecounter; // For file naming.
mixed * queue; // Queue, to have one call-out-loop instead of many
#ifdef FIND_MEMORY_LEAKS
mixed * leakage; // To track GCs and Execs for Leak detection.
#endif
/* --- Prototypes: --- */
void crash(string file, closure callback);
void leak(closure callback);
#ifdef FIND_MEMORY_LEAKS
void check_for_leak(string file, mixed * exec);
void step_by_step(string gc_file, string file, mixed * exec);
#endif
/* --- Functions: --- */
/* --- Queue --- */
// Basic Queue, mainly to prevent recursion problems.
// And to make call_out loops easier (we have more than one)
mixed * query_queue() { return queue; }
int push(int pos, varargs mixed * what)
{
if(!pointerp(queue))
{
queue = ({});
}
if(pos <= 0)
{
pos = sizeof(queue) + 1;
}
queue = queue[0..pos-2] + ({ what }) + queue[pos-1..];
}
int pop()
{
mixed q;
if(pointerp(queue) && sizeof(queue))
{
q = queue[0];
queue = queue[1..];
apply(q[0],q[1..]);
return sizeof(queue);
}
}
void step()
{
if(set_next_reset(0) > 300)
{
set_next_reset(150);
}
pop();
call_out(#'step, STEP_PAUSE);
}
/* --- Crashleak Initialization: --- */
// Just to provide some LFun Closures below...
string foo() { return "foo"; }
mixed bar(mixed x, mixed y, mixed z) { return ({z,y,x}); }
mixed query_efun() { return efun; }
void init_efun()
{
DEBUG("init_efun()");
// Generate list of all EFuns. /doc/efun/ is part of the driver package.
// If it isn't part of your mudlib directory, copy it somewhere in it
// and modify the path accordingly.
string * list = get_dir(DOC_EFUN_DIR"*") - ({".","..","[]"});
// Convert them to EFun closures using a restore_value hack.
efun = restore_value("#1:0\n({#e:"+implode(list, ",#e:")+",})\n");
// Kill unrecognized and dangerous EFuns.
efun -= ({0,
#'efun::set_driver_hook, // it makes the crasher stop running
#'efun::limited, // too much fun
#'efun::set_this_object, // poses problems
#'efun::garbage_collection, // Can't find no leaks otherwise
#'efun::shutdown, // Can't find no crashes otherwise
#'efun::set_limits}); // Messes things up naturally
// Add Operator closures. Have not found a way to generate this list
// automatically yet, so you might want to check if it's still up2date.
// See lex.c ~ approx line 1000 for a list (this one's of 2004/07/17).
efun +=
({ #'+= ,#'++ ,#'+ ,#'-= ,#'-- ,#'- ,#'*= ,#'* ,#'/=
,#'/ ,#'%= ,#'% ,#', ,#'^= ,#'^ ,#'|| ,#'||= ,#'|=
,#'| ,#'&& ,#'&&= ,#'&= ,#'& ,#'~ ,#'<= ,#'<<= ,#'<<
,#'< ,#'>= ,#'>>= ,#'>>>= ,#'>>> ,#'>> ,#'> ,#'== ,#'=
,#'!= ,#'! ,#'?! ,#'? ,#'[..] ,#'[..<] ,#'[<..]
,#'[<..<] ,#'[..>] ,#'[>..] ,#'[<..>]
,#'[>..<] ,#'[>..>] ,#'[.. ,#'[<..
,#'[>.. ,#'[,] ,#'[ ,#'[< ,#'[>
,#'({ ,#'([ ,#'-> ,#'(<
});
}
mixed query_values() { return value; }
struct Bar {
mixed four;
};
struct Foo {
int one, *two;
struct Bar three;
};
void init_value()
{
DEBUG("init_value()");
// The more values, the more variation, the better.
// Feel free to add stuff to this list. However, don't modify it
// on the fly, changing this array will make recorded files useless.
// Please refrain from using self-referencing structures unless you
// want to test the crash aspect only. Include self-referencing
// stuff inside #ifndef FIND_MEMORY_LEAKS #endif blocks only.
if(pointerp(value))
{
// Do some cleanup first:
map(value, (: objectp($1) && destruct($1) :));
}
value = 0;
value =
({
/* --- Integer: --- */
-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
-1000,1000,-50000,50000,-2000000,2000000,
__INT_MIN__+16,__INT_MAX__-16,__INT_MIN__,__INT_MAX__,
/* --- Float: --- */
0.0,0.001,-0.001,-0.5,0.5,0.99,-0.99,1.01,-1.01,
42.767,-42.767,1.0,2.0,3.0,-1.0,-2.0,-3.0,
to_float(__INT_MIN__), to_float(__INT_MAX__),
1.0e+100, -1.0e+100,
/* --- String: --- */
"", " ", " ", "!_!_", "_!_!",
"foo","bar","foo bar", "%d", "%Q", "0", "^^^^^^",
"#^# #^#", " ^",
"^ ", " - - - - ",
"? ? ? ? ? ? ????? ???? ??", "",
"\\/ "*32, " !"*42, "/", "/..",
"/a", "/d/", "/w/..",
"%#Q%#Q%#Q","%d%-=80s%%",
save_value(efun), save_object(),
/* --- Object: --- */
// This is mudlib specific, please provide some objects;
// Preferred are Blueprints, Clones, Objects with Environment,
// and Objects which have other objects inside (rooms).
//
// Note that random calls (for example to destruct()) might
// remove objects; so they should be reloaded here.
// A proper cleanup of old objects then would probably be good too.
load_object("/obj/fackel"), clone_object("/obj/fackel"),
load_object("/obj/player"), clone_object("/obj/player"),
load_object("/i/item/message"),
clone_object("/obj/rucksack"), clone_object("/obj/kurstafel"),
clone_object("/obj/wizard_shell"), clone_object("/secure/obj/login"),
load_object("/secure/obj/login"), load_object("/apps/error_db"),
load_object("/apps/plugin"), clone_object("/obj/zauberstab"),
load_object("/room/church"), load_object("/room/void"),
load_object("/room/hell"), load_object("/room/death/death"),
load_object("/room/rathaus/treppe"),
load_object("/room/rathaus/konferenz"),
load_object("/room/rathaus/forum"),
clone_object("/obj/monster"), clone_object("/obj/monster"),
clone_object("/obj/monster"), clone_object("/obj/monster"),
/* --- Closure: --- */
(: :), (: 1 :), (: 0 :), (: $2/$1 :),
#'efun::max, #'efun::input_to, #'efun::this_player,
#'efun::this_object, #'efun::call_out,
symbol_function("query_long", load_object("/i/item")),
symbol_function("query_real_name", load_object("/i/player/player")),
#'foo, #'bar,
function { return 2 * $1; },
function int (int a) { return 2 * a; },
function (int a) { return 2 * a; },
lambda( ({'x, 'y}), ({#'?, ({#'>, 'x, 'y}), 'x, 'y}) ),
unbound_lambda( ({'x}), ({#'==, 0, 'x}) ),
(: for(;;); :), (: while($1); :),
/* --- Array: --- */
({}), ({ ({}) }), ({ (: :) }), ({ 0 }), ({ 1 }),
({ "" }), ({ ([]) }), ({#'efun::min}),
allocate(5), allocate(10,1), allocate(query_limits(1)[LIMIT_ARRAY]),
({'x, 'y}), ({#'?, ({#'>, 'x, 'y}), 'x, 'y}),
({'x}), ({#'==, 0, 'x}),
/* --- Mapping: --- */
([:0]), ([:1]), ([:2]), (["a":"b"]),([([1]):({2,3})]),
mkmapping( ({1,2,3,4,5,6,7,8,9,10}), ({1,2,3,4,5,6,7,8,9,10}) ),
mkmapping( ({"1","2","3","4","5","6","7","8","9","10"}) ),
([ load_object("/apps/groups") ]),
([ #'efun::allocate ]),
/* --- Symbol / Quoted: --- */
'a, 'b, 'c, quote(allocate(10)),
'dont_know_what_this_is_supposed_to_be_it_sure_is_fun,
'whatever_floats_your_boat,
/* --- Struct: --- */
});
// --- Lets add some special values. ---
// Container inside Container inside...
object ob = clone_object("/obj/rucksack");
for(int i = 10; i--; )
{
object ob2 = clone_object("/obj/rucksack");
ob->move(ob2);
ob=ob2;
}
value += ({ob});
// Some random strings. Good for crashing, bad for debugging...
// So to make things reproducible, we generate them only once,
// and only load them afterwards. Delete the Savefile if you
// want new random strings.
string str;
if(str = read_file(CRASHLEAK_DIR"random_strings.o"))
{
value += restore_value(str);
}
else
{
string * random_strings = ({});
for(int i = 10; i--; )
{
int * arr;
arr = map(allocate(random(100)), (: random(256) :));
random_strings += ({ to_string(arr) });
}
// Save these strings so that we can reuse them next time.
write_file(CRASHLEAK_DIR"random_strings.o",
save_value(random_strings));
// Don't forget to add them to the values array...
value += random_strings;
}
// Structs
struct Bar foo = (<Bar> 10);
struct Foo bar = (<Foo> 1, ({"2",3}), (<Bar> 5));
value += ({foo,bar})*20;
}
mixed do_plot_efun(closure cl)
{
// DEBUG(sprintf("do_plot_efun(%#Q)",cl));
object ob = this_object();
int min_p = MIN_PARAMS;
int max_p = MAX_PARAMS;
for(int p = MAX_PARAMS; p >= MIN_PARAMS; p--)
{
string str = catch(apply(cl, allocate(p)); nolog);
// DEBUG(sprintf(" str -> %#Q", str));
if(str && strstr(str, "many arguments") != -1)
{
max_p--;
}
else if(str && strstr(str, "few arguments") != -1)
{
min_p++;
}
}
set_this_object(ob);
seteuid(0);
seteuid(getuid());
if(min_p != MIN_PARAMS || max_p != MAX_PARAMS)
{
return ({cl, min_p, max_p});
}
return cl;
}
void plot_efun()
{
DEBUG("plot_efun()");
efun = filter(efun, #'closurep);
efun = limited(#'map, ({10000000}), efun, #'do_plot_efun);
garbage_collection(GC_FILE("plot_efun"));
}
void init_crashleak(closure callback)
{
DEBUG("init_crashleak()");
// Sometimes init fails. Recall.
push(1, #'init_crashleak, callback);
string str;
if(str = catch(limited(#'init_efun, ({1000000})); publish))
{
debug_message("CRASHLEAK: init_efun failed:\n"+str+"\n");
return;
}
if(str = catch(limited(#'init_value, ({1000000})); publish))
{
debug_message("CRASHLEAK: init_value failed:\n"+str+"\n");
}
garbage_collection(GC_FILE("AFTER_INIT"));
// Del the old entry
queue = queue[1..];
push(0, callback);
// Determine EFun parameter counts next step.
push(1, #'plot_efun);
}
void crashleak()
{
DEBUG("crashleak()");
if(stepcounter++ == REINIT_EVERY_N_STEPS)
{
init_crashleak(#'crashleak);
stepcounter=0;
return;
}
#ifdef FIND_MEMORY_LEAKS
push(0, #'crash, RECORD_FILE("cl"), #'check_for_leak);
#else
push(0, #'crash, RECORD_FILE("cl"), #'crashleak);
#endif
}
/* --- Crash Execution: --- */
mixed * pick()
{
DEBUG("pick()");
mixed * erg = ({});
int f, p;
for(int i = CALLS_PER_STEP; i--; )
{
f = random(sizeof(efun));
if(closurep(efun[f]))
{
p = MIN_PARAMS + random(MAX_PARAMS-MIN_PARAMS);
}
else
{
p = efun[f][1] + random(efun[f][2]-efun[f][1]);
}
erg +=
({
// Pick EFun index.
({ random(sizeof(efun)),
// Pick p parameter indices.
map(allocate(p), (: random(sizeof(value)) :)),
// Will be replaced with a string later:
// (debugmessage of what was executed)
0
})
});
}
return erg;
}
varargs void exec(mixed * exec, int quiet)
{
DEBUG("exec()");
string file;
string text = "";
object ob = this_object();
debug_message("start_of_exec\n");
foreach(mixed * x : exec)
{
mixed f = efun[x[0]];
if(pointerp(f)) f=f[0];
mixed * v = map(x[1], (: value[$1] :));
string str = sprintf("%d %#Q\n", x[0],x[1]);
// Note: This chance affects arrays by reference. :-)
x[2] = str;
debug_message(sprintf("exec: %s",str));
set_this_object(ob);
seteuid(0);
seteuid(getuid());
catch(apply(f, v); reserve (max(get_eval_cost()/2,100000)), nolog);
if(get_eval_cost() < 100000)
{
break;
}
}
set_this_object(ob);
debug_message("end_of_exec\n");;
}
void crash(string file, closure callback)
{
DEBUG("crash()");
mixed * exec;
/* --- Pick what we will execute in this run: --- */
exec = limited(#'pick, ({1000000}));
/* --- Record it to the file. --- */
write_file(file, save_value(exec));
/* --- Execute it. --- */
limited(#'exec, ({1000000}), exec);
funcall(callback, file, exec);
}
/* --- Leak detection: --- */
int analyze(string gc_file)
{
DEBUG("analyze("+gc_file+")");
string s = read_file(gc_file);
if(!stringp(s))
{
debug_message(sprintf("CRASHLEAK: Could not read file %#Q (%#Q)!\n",gc_file,s));
return 0;
}
string * str = explode(s, "\n");
return sizeof(regexp(str, "freeing.*block"));
}
void leak_gc(string file, mixed * exec)
{
DEBUG("leak_gc( ["+sizeof(exec)+"] )");
string sbs = GC_FILE("sbs");
// GC.
garbage_collection(sbs);
// Note this file will be created later.
// Push.
push(1, #'step_by_step, sbs, file, exec);
// Execute.
limited(#'exec, ({1000000}), exec, 1);
}
void step_by_step(string gc_file, string file, mixed * exec)
{
DEBUG("step_by_step()");
// Okay. Binary search.
// Was there a leak?
if(analyze(gc_file))
{
// Whee! There was one. Let's see what we do.
// How many execs are there which might have caused the leak?
if(sizeof(exec) == 1)
{
// Only one? Okay, this is it then.
DEBUG("LEAK: "+exec[0][2]+"\n");
write_file(LEAK_FILE(explode(gc_file,"/")[<1]), exec[0][2]+"\n");
// We haven't done a GC, so we can pop:
call_out(#'pop, 0);
return;
}
// Okay. Do the first half now...
leak_gc(file, exec[..(sizeof(exec)/2)-1]);
// ...push the second half into the first queue, coz we can't do
// to garbage_collection() at once.
push(1, #'leak_gc, file, exec[(sizeof(exec)/2)..]);
}
else
{
// We haven't done a GC, so we can pop:
call_out(#'pop, 0);
}
// And wait...
}
void check_for_leak(string file, mixed * exec)
{
DEBUG("check_for_leak()");
string gc_file = GC_FILE("check_for_leak");
// Warning: This is actually executed at the end of the cycle,
// and not right now.
garbage_collection(gc_file);
// This means gc_file does not exist now yet.
// Check previous leakage (their gc_file exists now)
if(leakage && analyze(leakage[0]))
{
// We need to do a step by step further investigation
// of this exec to find which call exactly has caused
// the leak.
push(0, #'step_by_step, leakage[0], leakage[1], leakage[2]);
// Continue Crashing afterwards.
push(0, #'crashleak);
}
else
{
// nothing to do. continue crashing.
crashleak();
}
// Remember this leakage and test it in the next run.
leakage = ({gc_file,file,exec});
}
/* --- Applied LFuns: --- */
void reset()
{
if(sizeof(queue) <= 0)
{
push(0, #'init_crashleak, #'crashleak);
}
if(find_call_out(#'step) <= 0)
{
call_out(#'step, STEP_PAUSE);
}
}
void create()
{
DEBUG("create()");
garbage_collection(GC_FILE("AFTER_CREATE"));
reset();
}
/* --- End of file. --- */

View file

@ -0,0 +1,152 @@
// This file is part of UNItopia Mudlib.
// ----------------------------------------------------------------
// File: /secure/simul_efun/secure.inc
// Description: Security Funktionen / Gesperrte Funktionen
// Author: Freaky
// Modified by: Freaky (31.03.1999) set_environment, object_info hinzugefuegt
// Freaky (26.06.1999) command hinzugefuegt
//
// $Log: secure.inc,v $
// Revision 1.1.1.1 2006/07/10 02:42:07 lynx
// ldmud 3.3.714
//
// Revision 1.3 2001/01/30 23:59:01 sissi
// Bergeweise CVS Log Eintraege eingetragen.
// Hoffentlich nirgends doppelt und nirgends zu wenig.
//
#pragma strict_types
#pragma save_types
//
// Dieser File ist der einizge Teil der Simul Efun mit
// nomask simul_efun Privileg.
// (siehe /secure/master/compiler_control::privilege_violation())
//
/*
* Nur der Shutdown-Daemon darf die efun shutdown verwenden!
*/
#if 0
/*
* Gesperrte efuns
*/
#if __EFUN_DEFINED__(shutdown)
nomask void shutdown() {}
#endif
/*
#if __EFUN_DEFINED__(set_next_reset)
nomask int set_next_reset(int delay) {}
#endif
*/
#if __EFUN_DEFINED__(heart_beat_info)
nomask object *heart_beat_info() {}
#endif
#if __EFUN_DEFINED__(object_info)
nomask mixed *object_info(object ob, int what) {}
#endif
#if __EFUN_DEFINED__(debug_info)
nomask varargs mixed debug_info(int flag, mixed m) {}
#endif
#if __EFUN_DEFINED__(move_object)
nomask void move_object(object ob1, object ob2) {}
#endif
#if __EFUN_DEFINED__(set_this_player)
nomask void set_this_player(object ob) {}
#endif
#if __EFUN_DEFINED__(set_environment)
nomask void set_environment(object ob1, object ob2) {}
#endif
#if __EFUN_DEFINED__(efun308)
nomask void efun308(object ob1, object ob2) {}
#endif
#if __EFUN_DEFINED__(swap)
nomask void swap(object ob) {}
#endif
#if __EFUN_DEFINED__(break_point)
nomask void break_point() {}
#endif
#if __EFUN_DEFINED__(functionlist)
nomask mixed *functionlist(mixed ob, int flag) {}
#endif
#if __EFUN_DEFINED__(query_actions)
nomask mixed *query_actions(mixed ob, mixed flag) {}
#endif
#if __EFUN_DEFINED__(garbage_collection)
nomask void garbage_collection() {}
#endif
#if __EFUN_DEFINED__(command)
nomask int command(string str) {}
#endif
#if __EFUN_DEFINED__(last_instructions)
nomask varargs string *last_instructions(int len, int verbose) {}
#endif
#if __EFUN_DEFINED__(command_stack)
nomask mixed *command_stack() {}
#endif
#if __EFUN_DEFINED__(command_stack_depth)
nomask int command_stack_depth() {}
#endif
#if __EFUN_DEFINED__(set_buffer_size)
nomask int set_buffer_size(int size) {}
#endif
/*
#if __EFUN_DEFINED__(restore_value)
nomask mixed restore_value(string str) {}
#endif
#if __EFUN_DEFINED__(save_value)
nomask string save_value(mixed m) {}
#endif
*/
/*
#if __EFUN_DEFINED__(clones)
nomask varargs object *clones(mixed m, int i) {}
#endif
*/
#if __EFUN_DEFINED__(set_connection_charset)
nomask void set_connection_charset(mixed a, int i) {}
#endif
#if __EFUN_DEFINED__(binary_message)
nomask varargs int binary_message(mixed m, int i) {}
#endif
#if __EFUN_DEFINED__(query_ip_number)
nomask varargs string query_ip_number(object who)
{
return "0.0.0.0";
}
#endif
#if __EFUN_DEFINED__(query_ip_name)
nomask varargs string query_ip_name(object who)
{
return "leider.nicht.mehr.verfuegbar";
}
#endif
#endif