diff -u -r -N --ignore-space-change driver-3.2.1@141/comm.h driver-321@141-mod/comm.h --- driver-3.2.1@141/comm.h Sat Jan 11 01:33:58 1997 +++ driver-321@141-mod/comm.h Sat Oct 10 20:33:00 1998 @@ -33,8 +33,8 @@ #if defined(SunOS4) || defined(atarist) SOCKET_T socket PROT((int, int, int)); int getpeername PROT((SOCKET_T, struct sockaddr *, int *)); -void shutdown PROT((SOCKET_T, int)); -int setsockopt PROT((SOCKET_T, int, int, char *, int)); +/*void shutdown PROT((SOCKET_T, int));*/ +/*int setsockopt PROT((SOCKET_T, int, int, char *, int));*/ int bind PROT((SOCKET_T, struct sockaddr *, int)); int listen PROT((SOCKET_T, int)); SOCKET_T accept PROT((SOCKET_T, struct sockaddr *, int *)); @@ -62,10 +62,13 @@ SOCKET_T socket; struct object *ob; /* Points to the associated object */ struct input_to *input_to; /* To be called with next input line ! */ + char *last_command; /* the last command executed by this player */ + int ansi; /* whether the player understands ANSI */ struct object *modify_command; struct svalue prompt; struct sockaddr_in addr; char closing; /* True when closing this socket. */ + unsigned char line_pos; /* pos on line, for 80 column wrap */ char do_close; /* This is to be closed down. */ char noecho; /* Don't echo lines * 0: unset 1:fresh 4:NAK, 5:ACK received */ diff -u -r -N --ignore-space-change driver-3.2.1@141/comm1.c driver-321@141-mod/comm1.c --- driver-3.2.1@141/comm1.c Mon Feb 16 17:30:22 1998 +++ driver-321@141-mod/comm1.c Fri Nov 12 23:02:50 1999 @@ -34,8 +34,9 @@ #endif #include "lint.h" #ifdef HAVE_FCNTL -#include +/*#include */ #endif +#include /* Kickaha added this */ #include "interpret.h" #include "comm.h" #include "object.h" @@ -44,6 +45,8 @@ #include "exec.h" #include "util/erq.h" +#include "secure/security.h" + #ifdef AMIGA #include "hosts/amiga/nsignal.h" #endif @@ -52,12 +55,17 @@ #include SOCKET_INC #endif +#define white_space(x) (x == ' ' || x == '\n' || x == '\t') + #ifndef EPROTO #define EPROTO EINTR #endif void telnet_neg PROT((struct interactive *)); +/*extern struct hostent *gethostbyname(char *);*/ /* Kickaha */ + +extern struct svalue const0; extern int d_flag; extern int current_time; extern int trace_level; @@ -365,14 +373,19 @@ int a1, a2, a3, a4, a5, a6, a7, a8, a9; #endif { - char buff[2130]; /* Kludgy! Hope this is enough ! */ + char buff[3000]; /* Kludgy! Hope this is enough ! */ + char buff3[2*3000+1]; struct interactive *ip; int n, chunk, length; + FILE *fil; + int from2, to2, last2; + int converted = 0; int min_length; int old_message_length; struct object *snooper; char *source, *end, *dest; int retries; + int filter_eol = 1; #ifdef __STDC__ va_list va; #endif @@ -492,6 +505,81 @@ c = ']'; } #endif + + /* Conversion of message to 80 column wrap -- Kickaha */ + + if (filter_eol) + { + bzero(buff3, 2*3000+1); + for (from2=0, to2=0, last2=0; to2=32 && source[from2]<127)) + { + if (source[from2] == '\t') ip->line_pos = (ip->line_pos/8+1)*8; + else + if (!isansi(source, from2, 1)) + (ip->line_pos)++; + } + from2++; + } // while (!white_space(source[from2]) && source[from2]) + if (ip->line_pos>=80 && ip->line_pos!=from2-last2) + { /* need to wrap, && white space somewhere in line */ + ip->line_pos = 0; + buff3[to2++] = '\r'; + buff3[to2++] = '\n'; + while (white_space(source[last2])) + last2++; + from2 = last2; + } + else + { + if (ip->line_pos>=80) /* need to wrap, line full of non-white spaces */ + from2 = last2+80-1; + while (last2=127)) + last2++; /* ignore */ + else + buff3[to2++] = source[last2++]; /* keep the same */ + } + if (ip->line_pos>=80) + { + buff3[to2++] = '\r'; + buff3[to2++] = '\n'; + ip->line_pos = 0; + } + else + { + if (source[from2] == '\n') + ip->line_pos = 0; + else + if (!isansi(source, from2, 1) && source[from2]) + (ip->line_pos)++; + from2++; + } + } + } + if (converted) + { + strncpy(buff, buff3, 3000); + source = buff; + if (to2 >= 2999) + source[2999] = '\0'; /* too long message */ + else + source[to2++] = '\0'; + chunk = to2; + } + } // if (filter_eol) /* conversion completed -- Kickaha */ + + do { char c; @@ -539,8 +627,8 @@ if (old_message_length) remove_flush_entry(ip); return; case EWOULDBLOCK: - fprintf(stderr, - "comm1: write EWOULDBLOCK. Message discarded.\n"); +/* fprintf(stderr, Kickaha + "comm1: write EWOULDBLOCK. Message discarded.\n"); */ if (old_message_length) remove_flush_entry(ip); /* ip->do_close = 1; -- LA */ return; @@ -557,7 +645,7 @@ fprintf(stderr, "comm1: write EHOSTUNREACH.\n"); break; case EPIPE: - fprintf(stderr, "comm1: write EPIPE detected\n"); +/* fprintf(stderr, "comm1: write EPIPE detected\n"); Kickaha */ break; default: fprintf(stderr, "comm1: write: unknown errno %d\n", errno); @@ -571,9 +659,9 @@ inet_packets++; inet_volume += n; #endif - if (n != chunk) +/* if (n != chunk) fprintf(stderr, "write socket: wrote %d, should be %d.\n", - n, chunk); + n, chunk); Kickaha */ dest = &ip->message_buf[0]; if (c) *dest++ = c; @@ -1072,6 +1160,7 @@ strcpy(buff, ip->text); command_giver = ip->ob; trace_level = ip->trace_level; + ip->line_pos = 0; /* they've hit cr, so their line pos is now 0 */ ip->tn_state = TS_DATA; telnet_neg(ip); /* if he is not in ed, dont let him issue another command @@ -1117,7 +1206,7 @@ extern int malloc_privilege; struct object *save = command_giver; - int i; + int i, j; struct interactive *interactive; int save_privilege; @@ -1141,6 +1230,11 @@ /* master might have used exec() */ ob = interactive->ob; } + if (interactive->last_command) + { + xfree(interactive->last_command); + interactive->last_command = 0; + } interactive->catch_tell_activ = 0; if (interactive->snoop_by) { if (O_GET_INTERACTIVE(interactive->snoop_by) && @@ -1187,6 +1281,12 @@ if (interactive->modify_command) { free_object(interactive->modify_command, "remove_interactive"); } + for (j=0; j<10; j++) /* Kickaha */ + { + struct interactive *ip; + + ip = O_GET_INTERACTIVE(ob); + } free_svalue(&interactive->prompt); free_svalue(&interactive->default_err_message); if (interactive->sent.ed_buffer || @@ -1367,7 +1467,7 @@ struct sockaddr_in *addr; int len; { - int i; + int i, j; char *p; #ifdef ACCESS_CONTROL @@ -1446,6 +1546,7 @@ new_interactive->prompt.x.string_type = STRING_CONSTANT; new_interactive->prompt.u.string = "> "; new_interactive->modify_command = 0; + new_interactive->line_pos = 0; new_interactive->closing = 0; new_interactive->do_close = 0; new_interactive->noecho = 0; @@ -1462,10 +1563,12 @@ new_interactive->ts_data = TS_DATA; new_interactive->snoop_on = 0; new_interactive->snoop_by = 0; + new_interactive->last_command = NULL; new_interactive->last_time = current_time; new_interactive->default_err_message.type = T_INVALID; new_interactive->trace_level = 0; new_interactive->trace_prefix = 0; + new_interactive->ansi = 0; /* Kickaha */ new_interactive->message_length=0; #ifdef PORTAL new_interactive->from_portal = 0; @@ -1527,6 +1630,9 @@ ob->sent = (struct sentence *)new_interactive; new_interactive->ob = ob; ob->flags |= O_ONCE_INTERACTIVE|O_SHADOW; + + new_interactive->sent.ed_buffer = 0; + new_interactive->line_pos = 0; master_ob->flags &= ~O_ONCE_INTERACTIVE; if (save_shadow->shadowing || save_shadow->shadowed_by || save_shadow->ed_buffer) @@ -1540,6 +1646,7 @@ } free_object(master_ob, "reconnect"); add_ref(ob, "new_player"); +// setuid_me((struct object *) 0, ob, GOD+2, 0); command_giver = ob; if (new_interactive->snoop_on) { new_interactive->snoop_on->snoop_by = ob; @@ -1755,6 +1885,20 @@ } } +void +save_all_players() /* Kickaha */ +{ + int i; + + for (i = 0; i < MAX_PLAYERS; i++) { + if (all_players[i] == 0) + continue; + command_giver = all_players[i]->ob; + CLEAR_EVAL_COST; + (void) apply("save_character", all_players[i]->ob, 0); + } +} + void set_prompt(str) char *str; { @@ -2531,6 +2675,16 @@ char *name; } iptable[IPSIZE] = { {0, 0}, }; +null_iptable() /* Kickaha */ +{ + int i; + for (i=0; i0) tmp=isansi(arr, i-1, 0); + if (tmp) return 1; + if (i>1) tmp=isansi(arr, i-2, 0); + if (tmp) return 1; + if (i>2) tmp=isansi(arr, i-3, 0); + if (tmp) return 1; + if (i>3) tmp=isansi(arr, i-4, 0); + if (tmp) return 1; + } + return 0; +} + + + diff -u -r -N --ignore-space-change driver-3.2.1@141/config.h driver-321@141-mod/config.h --- driver-3.2.1@141/config.h Sat Oct 26 15:37:52 1996 +++ driver-321@141-mod/config.h Wed Oct 14 20:50:02 1998 @@ -9,7 +9,7 @@ * are supplied should be placed in ERQ_DIR. If you want something * different, consider writing a wrapper program or shell script. */ -#define ERQ_DIR "/user/src/mud/erq" +#define ERQ_DIR "/export/home/mud/mud/src/erq" /* #define ACCESS_CONTROL if you want the driver to do any access control, * either using the old style ACCESS.DENY or the new ACCESS.ALLOW . @@ -23,6 +23,8 @@ */ #define ACCESS_RESTRICTED +#define DOMAINS_FILE "/export/home/mud/src/secure/domains" + /* Some configurations for this system. Needn't be changed if you don't use * the new access restriction system. */ @@ -35,7 +37,6 @@ */ /* #define ACCESS_LOG "access.allow.log" */ - /* * Define the maximum size of log files (in bytes). */ @@ -58,7 +59,7 @@ * * This time should be substantially longer than the swapping time. */ -#define TIME_TO_CLEAN_UP 5400 +#define TIME_TO_CLEAN_UP 3600 /* 1 hour */ /* * How long time until an unused object is swapped out. @@ -66,8 +67,8 @@ * Machine with few players and lot of memory: 10000 * Machine with infinite memory: 0 (never swap). */ -#define TIME_TO_SWAP 900 -#define TIME_TO_SWAP_VARIABLES 1800 +#define TIME_TO_SWAP 0 +#define TIME_TO_SWAP_VARIABLES 0 /* * How many seconds until an object is reset again. @@ -75,7 +76,7 @@ * No castles: 1800 (30 minutes) * >100 castles:10000 (almost 3 hours). */ -#define TIME_TO_RESET 3600 /* one hour */ +#define TIME_TO_RESET 7200 /* 120 minutes */ #define RESET_GRANULARITY 900 /* 15 minutes */ @@ -108,7 +109,7 @@ /* * Define what port number the game is to use. */ -#define PORTNO 7680 +#define PORTNO 4242 /* * Max number of local variables in a function. @@ -119,7 +120,7 @@ * If this is exceeded, the current function is halted. * ls() can take about 30000 for large directories. */ -#define MAX_COST 100000 +#define MAX_COST 1000000 /* to catch an eval_cost too big error in an object that called recursive * master functions, CATCH_RESERVED_COST should be greater than * MASTER_RESERVED_COST * 2. @@ -133,7 +134,7 @@ * periodically either, it's a good idea to place the swap file there. * The hostname will be appended to the filename defined here. */ -#define SWAP_FILE "LP_SWAP.3" +#define SWAP_FILE "/tmp/LP_SWAP.1" /* * This is the maximum array size allowed for one single array. @@ -143,7 +144,7 @@ /* * Maximum number of players in the game. */ -#define MAX_PLAYERS 40 +#define MAX_PLAYERS 50 /* * When uploading files, we want fast response; however, normal players @@ -165,8 +166,8 @@ #define RESERVED_MASTER_SIZE 50000 #define RESERVED_SYSTEM_SIZE 100000 -/* Define the size of the shared string hash table. This number needn't - * be prime, probably between 1000 and 30000; if you set it to about 1/5 +/* Define the size of the shared string hash table. This number needn't be + * a prime, probably between 1000 and 30000; if you set it to about 1/5 * of the number of distinct strings you have, you will get a hit ratio * (number of comparisons to find a string) very close to 1, as found strings * are automatically moved to the head of a hash chain. You will never @@ -239,7 +240,7 @@ /* Define MASTER_NAME if you want something different from "obj/master" resp. * "secure/master" as default. */ -/* #define MASTER_NAME "kernel/master" */ +#define MASTER_NAME "secure/master" /* * Define MAX_BYTE_TRANSFER to the number of bytes you allow to be read @@ -269,7 +270,7 @@ * with the -u### flag. Where ### is the portnumber for the udp port. * If undefined the -u flag will be ignored. */ -#define CATCH_UDP_PORT 4246 +#define CATCH_UDP_PORT 8889 #define UDP_SEND #define SET_BUFFER_SIZE_MAX 65536 diff -u -r -N --ignore-space-change driver-3.2.1@141/ed.c driver-321@141-mod/ed.c --- driver-3.2.1@141/ed.c Mon Feb 16 17:30:04 1998 +++ driver-321@141-mod/ed.c Sat Oct 10 20:33:04 1998 @@ -191,12 +192,13 @@ #define P_CUR_AUTOIND (ED_BUFFER->cur_autoindent) #define ED_BUFFER (current_ed_buffer) #define EXTERN_ED_BUFFER (O_GET_SHADOW(command_giver)->ed_buffer) +#define P_ED_OBJ (O_GET_INTERACTIVE(command_giver)->sent.ed_buffer->ed_object) static struct ed_buffer *current_ed_buffer; - static char inlin[MAXLINE]; static char *inptr; /* tty input buffer */ struct ed_buffer { + struct object *ed_object; /* for remote eds - confers file perms */ int diag; /* diagnostic-output? flag */ int truncflg; /* truncate long line flag */ int nonascii; /* count of non-ascii chars read */ diff -u -r -N --ignore-space-change driver-3.2.1@141/exec.h driver-321@141-mod/exec.h --- driver-3.2.1@141/exec.h Sat Oct 26 15:37:54 1996 +++ driver-321@141-mod/exec.h Sat Oct 10 20:33:04 1998 @@ -173,6 +173,7 @@ #define TYPE_QUOTED_ARRAY 11 #define TYPE_TERM 12 #define TYPEMAP_SIZE 13 +#define TYPE_ARRAY 14 /* Kickaha */ /* * These are or'ed in on top of the basic type. diff -u -r -N --ignore-space-change driver-3.2.1@141/func_spec driver-321@141-mod/func_spec --- driver-3.2.1@141/func_spec Sat Oct 26 15:37:54 1996 +++ driver-321@141-mod/func_spec Sat Oct 10 20:33:04 1998 @@ -99,7 +100,7 @@ push_rindexed_lvalue index_lvalue rindex_lvalue -index +indexx rindex const0 const1 @@ -135,6 +136,7 @@ range_lvalue aggregate extract2 +extract3 previous_object0 lambda_cconstant lambda_constant @@ -166,10 +168,13 @@ string clear_bit(string, int); object clone_object(string); int command(string, void|object); +object *contents(object default: F_THIS_OBJECT); +int cp(string, string); string crypt(string, string|int default: F_CONST0); string ctime(int default: F_TIME); object *deep_inventory(object default: F_THIS_OBJECT); -void destruct(object); +string describe_items(mixed *, string, void|int); /* Kickaha */ +int destruct(object); void disable_commands(); int ed(void|string, void|string); void enable_commands(); @@ -183,12 +188,16 @@ object find_object(string); string function_exists(string, object default: F_THIS_OBJECT); string implode(string *, string); +int index(mixed *|string,mixed,void|int); /* Kickaha */ int input_to(string, void|int, ...); mixed insert_alist(mixed, mixed, ...); int interactive(object default: F_THIS_OBJECT); mixed *intersect_alist(mixed *,mixed *); int intp(mixed); +int in_editor(object); /* Kickaha */ int living(object); +void localcmd(); +void log_file(string, string); string lower_case(string); mixed *get_dir(string, int default: F_CONST1); mixed *map_array(mixed *, string|closure, ...); @@ -204,22 +213,30 @@ object present(object|string, void|object); mixed *query_actions(object|string, int|object|string default: F_CONST1); string query_load_average(); +int query_malloced(); /* Kickaha */ +int query_su_level(object); /* Kickaha */ +string query_su_name(object); /* Kickaha */ +int query_valid_file(string,string); /* Kickaha */ string query_verb(); int random(int); string read_bytes(string, void|int, void|int); string read_file(string, void|int, void|int); int remove_call_out(string|closure); +/*int remove_shadow(void|object); */ /* Kickaha */ int rename(string, string); void replace_program(string); -int restore_object(string); +int restore_object(string, void|object); int rm(string); int rmdir(string); mixed *rusage(); -void save_object(string); +void save_object(string, void|object); void say(string|mixed *, void|object|object *); +void set_ansi(int); string set_bit(string, int); int set_heart_beat(int); int set_light(int); +int set_uid_file(string, int); +int set_uid_me(object, int, void|string); void set_this_object(object); int sizeof(mixed *|mapping); mixed *slice_array F_RANGE (mixed *,int,int); @@ -236,6 +253,7 @@ object this_player(); void throw(mixed); int time(); +string typeof(mixed); /* Kickaha */ mixed *unique_array(mixed *, string, mixed default: F_CONST0); object *users(); void write(mixed); @@ -378,7 +396,6 @@ void raise_error(string); int get_eval_cost(); void garbage_collection(); -int typeof(mixed); mixed get_type_info(mixed, int default: F_THIS_OBJECT); diff -u -r -N --ignore-space-change driver-3.2.1@141/interpret.c driver-321@141-mod/interpret.c --- driver-3.2.1@141/interpret.c Mon Feb 16 17:30:10 1998 +++ driver-321@141-mod/interpret.c Sat Oct 10 20:33:08 1998 @@ -5,8 +5,10 @@ #include #include #include +#include #include #include +/*#include */ #ifdef MARK #include #endif @@ -44,11 +46,13 @@ #define getrusage(a, b) syscall(SYS_GETRUSAGE, a, b) #endif +#include "secure/security.h" + #ifdef HAVE_GETRUSAGE /* Defined in machine.h */ #ifdef HAVE_SYS_RUSAGE_H /* solaris */ #include -#endif /* HAVE_SYS_RUSAGE */ +#endif /* solaris */ #include #ifdef sun extern int getpagesize(); @@ -61,6 +65,10 @@ #endif #endif /* HAVE_GETRUSAGE */ +/*void printf();*/ +int remove_one_sent(), query_malloc_total_alloced(); +char *strsub(); + #if defined(__GNUC__) && !defined(lint) && !defined(DEBUG) #define INLINE inline #else @@ -3400,6 +3409,26 @@ } break; } +/* CASE(F_REMOVE_SHADOW); + { + struct object *ob; + + ob = current_object; + GET_NUM_ARG + if (num_arg) { ob = sp->u.ob; pop_stack(); } + if (!ob || !ob->shadowing) + push_number(0); + else + { + if (ob->shadowed) + ob->shadowed->shadowing = ob->shadowing; + if (ob->shadowing) + ob->shadowing->shadowed = ob->shadowed; + ob->shadowing = ob->shadowed = 0; + push_object(ob); + } + break; + } */ CASE(F_POP_VALUE); pop_stack(); break; @@ -3661,7 +3689,7 @@ CASE(F_RINDEX_LVALUE); sp = rindex_lvalue(sp, pc); break; - CASE(F_INDEX); + CASE(F_INDEXX); /* * Fetch value of a variable. It is possible that it is a variable * that points to a destructed object. In that case, @@ -3856,6 +3884,27 @@ inter_pc = pc; /* apply_low() needs this */ sp = filter_mapping(sp, num_arg); break; + CASE(F_DESCRIBE_ITEMS); + { + char *str; + int live; + + assign_eval_cost(); + GET_NUM_ARG + + if (num_arg < 3) live = 0; + else { + if (sp->type != T_NUMBER) goto bad_arg_3; + live = sp->u.number; + pop_stack (); + } + TYPE_TEST2(sp, T_STRING) + str = describe_items(sp-1, sp->u.string, live); + pop_n_elems(2); + if (str) push_malloced_string (string_copy (str)); + else push_number(0); + break; + } CASE(F_MAPPINGP); { int i; @@ -4060,13 +4109,27 @@ break; } CASE(F_SAVE_OBJECT); + { + struct svalue *arg; assign_eval_cost(); - TYPE_TEST1(sp, T_STRING) + GET_NUM_ARG + arg = sp - num_arg + 1; + + TYPE_TEST1(arg, T_STRING) inter_sp = sp; inter_pc = pc; - save_object(current_object, sp->u.string); + + if (num_arg==2) + { + TYPE_TEST2(arg+1, T_OBJECT) + save_object((arg+1)->u.ob, arg->u.string); + pop_stack(); + } + else + save_object(current_object, arg->u.string); pop_stack(); break; + } CASE(F_FIND_OBJECT); { struct object *ob; @@ -4213,13 +4276,32 @@ CASE(F_RESTORE_OBJECT); { int i; + char tmp1[30], tmp2[30]; + struct svalue *arg; assign_eval_cost(); - TYPE_TEST1(sp, T_STRING) + + GET_NUM_ARG + arg = sp - num_arg + 1; + + TYPE_TEST1(arg, T_STRING) inter_sp = sp; inter_pc = pc; - i = restore_object(current_object, sp->u.string); - free_svalue(sp); + if (num_arg==2) TYPE_TEST2(arg+1, T_OBJECT) + + if (num_arg==2) + { + if (!O_GET_INTERACTIVE(arg[1].u.ob) && + sscanf(arg[0].u.string, "%ssecure%s", tmp1, tmp2)==2) + error("Restore_object(\"%s\") - not allowed to restore living!\n", + arg[0].u.string); + } + + if (num_arg==2) + i = restore_object((arg+1)->u.ob, arg->u.string); + else i = restore_object(current_object, arg->u.string); + free_svalue(arg); + pop_n_elems(num_arg-1); put_number(i); break; } @@ -4643,6 +4725,22 @@ } break; } + CASE(F_CONTENTS); + { + struct vector *vec; + TYPE_TEST1(sp, T_OBJECT) + inter_sp = sp; + inter_pc = pc; + vec = all_inventory(sp->u.ob); + free_object_svalue(sp); + if (vec == 0) { + put_number(0); + } else { + sp->type = T_POINTER; + sp->u.vec = vec; + } + break; + } CASE(F_DEEP_INVENTORY); { struct vector *vec; @@ -4702,6 +4800,10 @@ else push_object(previous_ob); break; + CASE(F_LOCALCMD); + print_local_commands(); + push_number(0); + break; #ifdef F_QUERY_ACTIONS CASE(F_QUERY_ACTIONS); { @@ -5456,6 +5558,15 @@ put_number(i); break; } + CASE(F_LOG_FILE); + if ((sp-1)->type != T_STRING) + error("Bad argument 1 to log_file()\n"); + if (sp->type != T_STRING) + error("Bad argument 2 to log_file()\n"); + log_file((sp-1)->u.string, sp->u.string); + pop_stack(); + pop_stack(); + break; /* Return first argument */ CASE(F_NOT); if (sp->type == T_NUMBER) { if (sp->u.number == 0) { @@ -5876,6 +5987,70 @@ break; } } + CASE(F_EXTRACT3); + { + int len, to, from; + struct svalue *arg; + + arg = sp - 1; + if (arg->type == T_STRING) { + char *res; + + len = _svalue_strlen((&arg[0])); + TYPE_TEST2(arg+1, T_NUMBER) + from = 0; + to = arg[1].u.number; + sp--; + if (from < 0) { + from = 0; + } + if (to >= len) + to = len-1; + if (to < from) { + pop_stack(); + push_constant_string(""); + break; + } + if (from >= len) { + pop_stack(); + push_constant_string(""); + break; + } + if (to == len-1) { + res = string_copy(arg->u.string + from); + free_string_svalue(sp); + put_malloced_string(res, sp); + break; + } + res = xalloc(to - from + 2); + strncpy(res, arg->u.string+from, to-from+1); + res[to-from+1] = '\0'; + free_string_svalue(sp); + put_malloced_string(res, sp); + break; + } + TYPE_TEST1(arg, T_POINTER) + { + struct vector *v, *res; + + TYPE_TEST2(arg+1, T_NUMBER) + v = arg->u.vec; + len = VEC_SIZE(v); + from = 0; + to = arg[1].u.number; + sp--; + if (from < 0) { + from = len + from; + } + if (to >= len) + to = len-1; +/* if (to<0) to = 0; */ + res = slice_array(v, from, to); + free_vector(v); + put_referenced_vector(res); + break; + } + } CASE(F_RANGE); { if (sp[-1].type != T_NUMBER) @@ -5913,7 +6088,7 @@ to = sp[0].u.number; if (to >= len) to = len-1; - if (to < from) { + if (to < from || to<0) { pop_n_elems(3); push_constant_string(""); break; @@ -6137,6 +6312,149 @@ } goto bad_arg_2; } + CASE (F_INDEX); + { + struct svalue *arg; + int from, i; + + GET_NUM_ARG + arg = sp-num_arg+1; + if (num_arg == 3) + { + if (arg[2].type != T_NUMBER) goto bad_arg_3; + from = arg[2].u.number; + } + else from = 0; + if (arg[0].type == T_POINTER) { + +#define UP_TO_SVP2(up) ( \ + (struct svalue *)( \ + ((char*)(up))- \ + ((char *)(&((struct svalue *)0)->u)-(char*) 0) \ + ) \ + ) + + struct vector *vec; + union u sp_u, *item_u_p; + int cnt; + + vec = arg[0].u.vec; + sp_u = arg[1].u; + item_u_p = &vec->item->u; + cnt = VEC_SIZE(vec); + if (from > cnt) from = cnt-1; + for(i=0; i= from;((char *)item_u_p) += sizeof(struct svalue) ) + { + if (UP_TO_SVP2(item_u_p)->type == T_STRING) + if (strcmp(sp_u.string, item_u_p->string) == 0) + break; + } + break; + } +#ifdef FLOATS + case T_FLOAT: + { + short exponent; + + exponent = arg[1].x.exponent; + for(; --cnt >= from; ((char *)item_u_p) += sizeof(struct svalue) + ) + { + if (sp_u.mantissa == item_u_p->mantissa) + if (exponent == UP_TO_SVP2(item_u_p)->x.exponent) + if (UP_TO_SVP2(item_u_p)->type == T_FLOAT) + break; + } + break; + } +#endif + case T_NUMBER: + if (!sp_u.number) { + struct svalue *svp; + short type; + + for(svp = UP_TO_SVP2(item_u_p); --cnt >= from; svp++) { + if ( (type = svp->type) == T_NUMBER) { + if ( !svp->u.number ) + break; + } else if (type == T_OBJECT) { + if (svp->u.ob->flags & O_DESTRUCTED) { + assign_svalue(svp, &const0); + break; + } + } + } + break; + } +#ifdef MAPPINGS + case T_MAPPING: +#endif + case T_OBJECT: case T_POINTER: + { + short type = arg[1].type; + + for(; --cnt >= from; ((char *)item_u_p) += sizeof(struct svalue) + ) + { + if (sp_u.number == item_u_p->number) + if (UP_TO_SVP2(item_u_p)->type == type) + break; + } + break; + } + default: + fatal("Bad type to member_array(): %d\n", arg[1].type); + } + if (cnt >= 0) { /* Return -1 for failure */ + cnt = VEC_SIZE(vec) - cnt - 1; + } + pop_stack(); + if (num_arg==3) pop_stack(); + free_svalue(&arg[0]); + put_number(cnt); + break; + } + if (arg[0].type == T_STRING) { + char *str, *str2, *str3; + int i; + + if (arg[1].type == T_NUMBER) + { + str = arg[0].u.string; + i = arg[1].u.number; + if (from > strlen(str)-1) from = strlen(str)-1; + str2 = i & ~0xff ? 0 : strchr(str+from, i); + i = str2 ? str2 - str : -1; + pop_stack(); + if (num_arg==3) pop_stack(); + free_svalue(&arg[0]); + put_number(i); + } + else if (arg[1].type == T_STRING) + { + str = arg[0].u.string; + str3 = arg[1].u.string; + if (from > strlen(str)-1) from = strlen(str)-1; + str2 = strstr(str+from, str3); + i = str2 ? str2 - str : -1; + pop_stack(); + if (num_arg==3) pop_stack(); + free_svalue(&arg[0]); + put_number(i); + } + else goto bad_arg_2; + break; + } + goto bad_arg_1; + } CASE (F_MEMBER); { if (sp[-1].type == T_POINTER) { @@ -6157,7 +6475,7 @@ str = sp_u.string; for(; --cnt >= 0; item_u_p += sizeof(struct svalue) ) { - if (UP_TO_SVP(item_u_p)->type == T_STRING) + if (UP_TO_SVP2(item_u_p)->type == T_STRING) if (strcmp( sp_u.string, ((union u*)item_u_p)->string @@ -6192,7 +6510,7 @@ struct svalue *svp; short type; - for(svp = UP_TO_SVP(item_u_p); --cnt >= 0; svp++) { + for(svp = UP_TO_SVP2(item_u_p); --cnt >= 0; svp++) { if ( (type = svp->type) == T_NUMBER) { if ( !svp->u.number ) break; @@ -6215,7 +6533,7 @@ for(; --cnt >= 0; item_u_p += sizeof(struct svalue) ) { if (sp_u.number == ((union u*)item_u_p)->number) - if (UP_TO_SVP(item_u_p)->type == type) + if (UP_TO_SVP2(item_u_p)->type == type) break; } break; @@ -6390,6 +6708,30 @@ sp->u.vec = v; break; } + CASE(F_TYPEOF); + { + char ret[20]; + switch(sp->type) + { + case T_NUMBER: + strcpy(ret, "int"); + break; + case T_OBJECT: + strcpy(ret, "object"); + break; + case T_STRING: + strcpy(ret, "string"); + break; + case T_POINTER: + strcpy(ret, "array"); + break; + default: + strcpy(ret, "unknown"); + } + pop_stack(); + push_string_malloced(ret); + break; + } CASE(F_ED); if (current_object->flags & O_DESTRUCTED) { /* could confuse the master... */ @@ -6438,13 +6780,15 @@ break; } CASE(F_DESTRUCT); + { assign_eval_cost(); TYPE_TEST1(sp, T_OBJECT) inter_sp = sp; inter_pc = pc; destruct_object(sp); - pop_stack(); + put_number(1); break; + } CASE(F_RANDOM); TYPE_TEST1(sp, T_NUMBER) if (sp->u.number <= 0) { @@ -6476,6 +6820,12 @@ if (sp[-1].type != T_STRING && sp[-1].type != T_POINTER) goto bad_arg_1; if ( sp->type == T_POINTER ) { + if (sp->u.vec->ref > 1) { + struct vector *vtmpp = + slice_array(sp->u.vec, 0, VEC_SIZE(sp->u.vec)-1); + say(sp-1, vtmpp); + free_vector(vtmpp); + } else say(sp-1, sp->u.vec); } else if (sp->type == T_OBJECT) { vtmp.v.item[0].type = T_NUMBER; @@ -6545,6 +6895,17 @@ pop_stack(); break; #endif /* F_SHOUT */ + CASE(F_SET_ANSI); + { + struct interactive *ip; + inter_sp = sp; + inter_pc = pc; + TYPE_TEST1(sp, T_NUMBER) + if (current_object && (ip=O_GET_INTERACTIVE(current_object))) + ip->ansi = sp->u.number; + pop_stack(); + break; + } CASE(F_SWITCH); { extern char* findstring PROT((char*)); @@ -6959,6 +7320,11 @@ } break; } + CASE(F_QUERY_MALLOCED); + { + push_number(query_malloc_total_alloced()); + break; + } CASE(F_RM); { int i; @@ -7009,7 +7375,6 @@ inter_sp = sp; TYPE_TEST1(sp, T_STRING) path = check_valid_path(sp->u.string, current_object, "mkdir", 1); - /* pop_stack(); see comment above... */ i = !(path == 0 || mkdir(path, 0770) == -1); free_svalue(sp); put_number(i); @@ -7025,7 +7390,6 @@ inter_sp = sp; TYPE_TEST1(sp, T_STRING) path = check_valid_path(sp->u.string, current_object, "rmdir", 1); - /* pop_stack(); rw - what the heck ??? */ i = !(path == 0 || rmdir(path) == -1); free_svalue(sp); put_number(i); @@ -7973,10 +8337,36 @@ put_number (0); break; } -#ifdef F_RENAME + CASE(F_CP); + { +/* + int ret; + struct svalue *arg = sp-1; + char *src, *dst; + + ret = copy_file((sp-1)->u.string, sp->u.string); + pop_n_elems(2); + push_number(ret); + break; +*/ + int i; + struct svalue *arg = sp-1; + + assign_eval_cost(); + inter_pc = pc; + inter_sp = sp; + TYPE_TEST1(sp-1, T_STRING) + TYPE_TEST2(sp, T_STRING) + i = copy_file((sp-1)->u.string, sp->u.string); + pop_n_elems(2); + push_number((i ? 1 : 0)); + break; + + } CASE(F_RENAME); { int i; + struct svalue *arg = sp-1; assign_eval_cost(); inter_pc = pc; @@ -7985,10 +8375,9 @@ TYPE_TEST2(sp, T_STRING) i = do_rename((sp-1)->u.string, sp->u.string); pop_n_elems(2); - push_number(i); + push_number((i ? 0 : 1)); break; } -#endif CASE(F_MAP_ARRAY); { struct vector *res; struct svalue *arg; @@ -8336,6 +8725,73 @@ pop_stack(); break; } + CASE(F_SET_UID_FILE); + { + struct svalue *arg = sp-1; + int ret; +// ret = set_file_su(arg[0].u.string, arg[1].u.number); + pop_n_elems(2); + push_number(ret); + break; + } + CASE(F_SET_UID_ME); + { + int ret; + struct svalue *arg; + + GET_NUM_ARG + arg = sp - num_arg + 1; + +// if (num_arg == 3) +// ret = setuid_me(current_object, arg[0].u.ob, +// arg[1].u.number, arg[2].u.string); +// else +// ret = setuid_me(current_object, arg[0].u.ob, +// arg[1].u.number, 0); + pop_n_elems(num_arg); + push_number(ret); + break; + } + CASE(F_QUERY_SU_LEVEL); + { + int ret; + ret = sp->u.ob->level; + pop_stack(); + push_number(ret); + break; + } + CASE(F_QUERY_SU_NAME); + { + char *ret; + ret = string_copy(sp->u.ob->su_name); + pop_stack(); + push_string_malloced(ret); + break; + } + CASE(F_QUERY_VALID_FILE); + { + int ret; + struct svalue *arg = sp-1; + + ret = 1; + pop_n_elems(2); + push_number(ret); + break; + } + + CASE(F_IN_EDITOR); + { + struct object *o; + struct interactive *ip; + int ret; + o = sp->u.ob; + ret = 0; + if (o->flags & O_DESTRUCTED) ret = 0; + if ((ip = O_GET_INTERACTIVE(o)) && ip->sent.ed_buffer) ret = 1; + pop_stack(); + push_number(ret); + break; + } #ifdef MAPPINGS CASE(F_MAP_INDEX); { @@ -9095,6 +9551,8 @@ { struct object *ob; + if (current_object->level < GOD) + error("swap(ob) - no permission.\n"); if (sp->type != T_OBJECT) goto xbad_arg_1; ob = sp->u.ob; if (ob != current_object) /* should also check csp */ @@ -9555,7 +10013,16 @@ } free_svalue(--sp); /* free key */ for (i = -num_arg + 1; ++i < 0; ) { - /* mapping must have been freed yet */ + /* get_map_lvalue() may return destructed objects. */ + /* TODO: Does this behaviour cause problems elsewhere, too? */ + if (T_OBJECT == item->type + && (O_DESTRUCTED & item->u.ob->flags)) + { + assign_svalue(sp[i].u.lvalue, &const0); + item++; + } + else + /* mapping must not have been freed yet */ assign_svalue(sp[i].u.lvalue, item++); free_svalue(&sp[i]); } @@ -9623,13 +10090,13 @@ extra_jobs_to_do = garbage_collect_to_do = 1; break; } - XCASE(F_TYPEOF); +/* XCASE(F_TYPEOF); { mp_int i = sp->type; free_svalue(sp); put_number(i); break; - } + } */ XCASE(F_GET_TYPE_INFO); { mp_int i, j; @@ -9754,9 +10221,9 @@ if (expected_stack && expected_stack != sp) { fatal("Bad stack after evaluation.\n\ sp: %lx expected: %lx\n\ -Instruction %d, num arg %d\n", +Instruction %d(%s), num arg %d\n", (long)sp, (long)expected_stack, - instruction + F_OFFSET, num_arg); + instruction + F_OFFSET, get_f_name(instruction), num_arg); } if (sp < fp + csp->num_local_variables - 1) { fatal("Bad stack after evaluation.\n\ @@ -9866,6 +10333,7 @@ struct program *progp; struct control_stack *save_csp; p_int ix; + int start, was_first; ob->time_of_ref = current_time; /* Used by the swapper */ /* @@ -11838,6 +12306,7 @@ } init_telopts(); master_ob = find_object(master_name); +// setuid_me((struct object *) 0, master_ob, GOD*2, 0); /* Kickaha */ if (current_object == &dummy_current_object_for_loads) { /* This might be due to the above assignment, or to setting * it in the backend. @@ -12111,7 +12580,7 @@ { bad_xefun_arg(2, sp); } - prompt = query_prompt(sp->u.ob); + prompt = (struct svalue *)query_prompt(sp->u.ob); free_object_svalue(sp); sp--; if (sp->type == T_STRING || sp->type == T_CLOSURE) { @@ -12285,6 +12755,42 @@ return sp; } +int +pstrcmp(p1, p2) + char **p1, **p2; +{ +char *t1, *t2; + t1 = *p1 + 5; /* ugly magic number attack! */ + t2 = *p2 + 5; + return strcmp(t1, t2); +} + +int +copy_file(src, dst) + char *src, *dst; +{ + FILE *src_f, *dst_f; + int c; + + if(!check_valid_path(src, current_object, "move_file", 0)) + return 0; + if(!check_valid_path(dst, current_object, "move_file", 1)) + return 0; + src_f = fopen(src, "r"); + if (src_f == 0) + return 0; + dst_f = fopen(dst, "w"); + if (dst_f == 0) { + fclose(src_f); + return 0; + } + while ((c = fgetc(src_f)) != EOF) + fputc(c, dst_f); + fclose(src_f); + fclose(dst_f); + return 1; +} + #ifdef F_DEBUG_INFO /* provide debugging information that can't be obtained by regular efuns */ struct svalue *f_debug_info(sp, num_arg) diff -u -r -N --ignore-space-change driver-3.2.1@141/lex.c driver-321@141-mod/lex.c --- driver-3.2.1@141/lex.c Mon Feb 16 17:30:24 1998 +++ driver-321@141-mod/lex.c Sat Oct 10 20:33:08 1998 @@ -42,7 +42,7 @@ struct lpc_predef_s *lpc_predefs=NULL; static INLINE int number PROT((int)); static INLINE int string PROT((char *)); -static void handle_define PROT((char *, int)); +static void handle_define PROT((char *)); static void add_define PROT((char *, int, char *)); #ifdef __GNUC__ /* old gcc versions, like on a NeXT, want it like this... */ static void add_permanent_define PROT((char *, int, char *, int)); @@ -117,6 +117,7 @@ static char *outp; static struct s_reswords reswords[] = { +{ "array", F_ARRAY, }, { "break", F_BREAK, }, { "case", F_CASE, }, { "catch", F_CATCH, }, @@ -1445,7 +1448,7 @@ if (strcmp("include", yytext) == 0) { handle_include(sp); } else {myfilbuf();if (strcmp("define", yytext) == 0) { - handle_define(sp, quote); + handle_define(sp); } else if (strcmp("if", yytext) == 0) { int cond; struct svalue sv; @@ -1883,7 +1886,7 @@ F_ADD, F_SUBTRACT, F_MULTIPLY, F_DIVIDE, F_MOD, F_LT, F_GT, F_EQ, F_GE, F_LE, F_NE, F_OR, F_XOR, F_LSH, F_RSH, - F_INDEX, F_RINDEX, F_EXTRACT2, + F_INDEXX, F_RINDEX, F_EXTRACT2, }; static short ternary_operators[] = { F_RANGE, F_NR_RANGE, F_RR_RANGE, F_RN_RANGE, @@ -1892,6 +1895,7 @@ for (i=0; inum_values); - if (m->num_values != 1 && old_written == bytes_written - buf_left) { - char *source, c; - - MY_PUTC(':') + i = m->condensed->string_size/sizeof(char *) + /* Kickaha, 15/5/1994 */ + m->condensed->misc_size/sizeof(struct svalue) + + (m->hash ? m->hash->used - m->hash->condensed_deleted : 0); source = number_buffer; - (void)sprintf(source, "%d", m->num_values); + (void)sprintf(source, "%d", i); c = *source++; do MY_PUTC(c) while (c = *source++); - } + MY_PUTC('|'); + walk_mapping(m, save_mapping_filter, (char *)(p_int)m->num_values); MY_PUTC(']') MY_PUTC(')') } @@ -302,7 +304,15 @@ pt = parameters->str; siz = 0; - if (!pt) return -1; + if (sscanf(pt, "%d", &siz) == 1) /* Kickaha, 15/5/1994 */ + { + parameters->str = ((char *)(strchr(pt, '|')))+1; + parameters->num_values = 1; /* May not be good ... */ + return siz; + } + else return -1; + +/* if (!pt) return -1; while (1) { switch (*pt) { case ']': @@ -330,8 +340,8 @@ do { pt = strchr(&pt[1],'\"'); if (!pt) return -1; - /* the quote is escaped if and only - * if the number of slashes is odd. */ + * the quote is escaped if and only + * if the number of slashes is odd. * for (backslashes = -1; pt[backslashes] == '\\'; backslashes--) ; } while ( !(backslashes & 1) ) ; pt++; @@ -365,7 +375,7 @@ pt++; if (!*pt) return -1; - /* fall through */ + * fall through * case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (pt[1] == '.') { @@ -380,7 +390,7 @@ if (!pt) return -1; pt++; } - /* fall through */ + * fall through * default: { pt = strpbrk(pt, ":;,"); @@ -410,7 +420,7 @@ } pt++; } - return -1; + return -1; */ } INLINE static int restore_mapping(svp, str) @@ -423,6 +433,7 @@ struct mapping *z; struct svalue key, *data; int i; + char *pt; struct rms_parameters tmp_par; int siz; @@ -432,6 +443,9 @@ *svp = const0; return 0; } + + *str = tmp_par.str; /* Kickaha, 15/5/1994 */ + z = allocate_mapping(siz, tmp_par.num_values); svp->type = T_MAPPING; svp->u.map = z; @@ -445,10 +459,21 @@ data = get_map_lvalue(z, &key, 1); free_svalue(&key); while (--i >= 0) { - if (!restore_svalue(data++, str, i ? ';' : ',' )) return 0; + if (!restore_svalue(data++, str, i ? ';' : ',' )) + { + printf("CHECK3\n"); + return 0; + } + } } + + pt = *str; + if (*pt++ != ']' || *pt++ != ')' ) { + free_mapping(z); + *svp = const0; + return 0; } - *str = tmp_par.str; + *str = pt; return 1; } @@ -551,12 +576,18 @@ { int i; struct svalue *val; - if ( recall_pointer( (char *)v ) ) - return; + char *source, c; +/* if ( recall_pointer( (char *)v ) ) + return; --- removed by Kickaha */ { L_PUTC_PROLOG L_PUTC('(') L_PUTC('{') + source = number_buffer; /* Kickaha */ + (void)sprintf(source, "%d", VEC_SIZE(v)); + c = *source++; + do L_PUTC(c) while (c = *source++); + L_PUTC('|'); L_PUTC_EPILOG } for (i = VEC_SIZE(v), val = v->item; --i >= 0; ) { @@ -692,6 +723,10 @@ if (ob->flags & O_DESTRUCTED) return; + if (ob->flags & O_SWAPPED) /* Kickaha */ + if (load_ob_from_swap(ob) < 0) + error("Out of memory\n"); + /* COMPAT_MODE stuff moved to master.c by amylaar * master.c will access current_object->prog->name instead of * current_prog->name , but then, this is probably better in COMPAT_MODE @@ -800,7 +835,15 @@ char *pt,*pt2; int siz,tsiz; - pt = *str; + if (sscanf(*str, "%d", &siz) == 1) /* Fetch size immediately */ + { /* Kickaha, 15/5/1994 */ + pt = strchr(*str, '|'); + *str = &pt[1]; + return siz; + } + else return -1; + +/* pt = *str; siz = 0; while ((pt) && (*pt)) { @@ -815,7 +858,7 @@ do { pt = strchr(&pt[1],'\"'); if (!pt) return -1; - /* the quote is escaped if and only if the number of slashes is odd. */ + * the quote is escaped if and only if the number of slashes is odd. * for (backslashes = -1; pt[backslashes] == '\\'; backslashes--) ; } while ( !(backslashes & 1) ) ; if (pt[1] != ',') return -1; @@ -823,7 +866,7 @@ pt += 2; } else if (pt[0] == '(') { - /* Lazy way of doing it, a bit inefficient */ + * Lazy way of doing it, a bit inefficient * struct rms_parameters tmp_par; tmp_par.str = pt + 2; @@ -858,7 +901,7 @@ pt = &pt2[1]; } } - return -1; + return -1; */ } INLINE static int restore_array(svp, str) @@ -875,6 +918,7 @@ *svp = const0; return 0; } + *str = end; /* Kickaha, 15/5/1994 */ v = allocate_array(siz); /* We need to do this now, so that the value can be used inside. */ @@ -1097,7 +1141,7 @@ int len; FILE *f; struct stat st; - struct variable *rover; + struct variable *rover = NULL; /* rover is used uninitialised, but var_rest is initialised instead. */ int var_rest, num_var; #ifndef MSDOS_FS @@ -1108,10 +1152,14 @@ struct discarded *next; } * dp = 0; - if (current_object != ob) - fatal("Bad argument to restore_object()\n"); +/* if (current_object != ob) + fatal("Bad argument to restore_object()\n"); Kickaha */ + if (ob->flags & O_DESTRUCTED) return 0; + if (ob->flags & O_SWAPPED) /* Kickaha */ + if (load_ob_from_swap(ob) < 0) + error("Out of memory\n"); file = check_valid_path(file, ob, "restore_object", 0); if (file == 0) @@ -1119,6 +1167,7 @@ len = strlen(file); name = alloca(len + (sizeof save_file_suffix)); + (void)strcpy(name, file); if (name[len-2] == '.' && name[len-1] == 'c') len -= 2; @@ -1129,10 +1178,12 @@ (void)fclose(f); return 0; } + if (st.st_size == 0) { (void)fclose(f); return 0; } + buff = alloca(st.st_size + 1); shared_restored_values = (struct svalue *) xalloc(sizeof(struct svalue)*256); @@ -1142,6 +1193,7 @@ var_rest = 0; old_format = 1; restored_host = -1; + while(1) { struct svalue *v; char *pt; @@ -1161,6 +1213,7 @@ continue; } } + (void)fclose(f); if (dp) do free_svalue(&dp->v); while (dp=dp->next); xfree((char*)shared_restored_values); @@ -1359,6 +1412,10 @@ */ *ob = NULL_object; ob->ref = 1; + ob->level = 0; /* Kickaha */ + ob->su_name = 0; /* Kickaha */ + ob->file_was_suid = 0; /* Kickaha */ + ob->sent = NULL; /* Kickaha */ #ifdef DEBUG ob->extra_num_variables = num_var; #endif diff -u -r -N --ignore-space-change driver-3.2.1@141/object.h driver-321@141-mod/object.h --- driver-3.2.1@141/object.h Mon Feb 16 17:30:04 1998 +++ driver-321@141-mod/object.h Sat Oct 10 20:33:10 1998 @@ -23,7 +23,6 @@ #define O_WILL_CLEAN_UP 0x200 /* clean_up will be called next time */ #define O_LAMBDA_REFERENCED 0x400 /* be careful with replace_program() */ #define O_SHADOW 0x800 - #define O_PROG_SWAPPED(ob) ((p_int)(ob)->prog & 1) #define O_VAR_SWAPPED(ob) ((p_int)(ob)->variables & 1) #define O_SWAP_NUM(ob) \ @@ -33,6 +32,7 @@ struct object { unsigned short flags; /* Bits or'ed together from above */ + char file_was_suid; /* Kickaha */ short total_light; int next_reset; /* Time of next reset of this object */ int time_of_ref; /* Time when last referenced. Used by swap */ @@ -40,7 +40,9 @@ #ifdef DEBUG p_int extra_ref; /* Used to check ref count. */ #endif + int level; /* capability based security - Kickaha */ struct program *prog; + char *su_name; /* playername for owner - Kickaha */ char *name; struct object *next_all, *next_inv, *next_hash; struct object *contains; diff -u -r -N --ignore-space-change driver-3.2.1@141/parse.c driver-321@141-mod/parse.c --- driver-3.2.1@141/parse.c Sat Oct 26 15:38:14 1996 +++ driver-321@141-mod/parse.c Sat Oct 10 20:33:10 1998 @@ -27,6 +27,24 @@ extern int tolower PROT((int)); #endif +#define KLUDGELEN 200 + +/* Some useful string macros +*/ +#define EQ(x,y) (strcmp(x,y)==0) +#define EQN(x,y) (strncmp(x,y,strlen(x))==0) +#define EMPTY(x) (strcmp(x,"")==0) + +#define QNPCFUNC "query_npc" /* Called in living to see if NPC */ +#define QNAMEFUNC "query_looks" /* Called in living to get name */ + /* Used to be query_name -- Kickaha */ +#define QLIVING "query_living" /* Called to see if living */ +extern int gDebug; +char *fixname PROT((struct object *,int,char *)); +char *add_num(), *plurfix(), *splitfix(), *artfix(), *pfix(); +struct object *get_object(); +struct svalue *make_number(); + #if defined(SUPPLY_PARSE_COMMAND) struct svalue find_living_closures[2] = { { T_INVALID }, { T_INVALID } }; @@ -292,12 +310,7 @@ */ -/* Some useful string macros -*/ -#define EQ(x,y) (strcmp(x,y)==0) -#define EQN(x,y) (strncmp(x,y,strlen(x))==0) -#define EMPTY(x) (strcmp(x,"")==0) - +#define KLUDGELEN 200 /* Function in LPC which returns a list of ids */ @@ -1685,15 +1698,326 @@ ----- describe: This code is obsolete ------ */ -#ifdef F_DESCRIBE char *describe_items (arr, func, live) struct svalue *arr; char *func; int live; { - return "Not supported in 3.0"; + + struct vector *p,*v1; + struct object *ob; + char *tmp; + int siz,num,cnt1,cnt2,nr; + char *fixname PROT((struct object *,int,char *)); + char *live_plurfix PROT((struct object *,int,char *)); + static char res[10*KLUDGELEN]; + +/* res = xalloc(10*KLUDGELEN); Kickaha */ + if (gDebug) fprintf(stderr,"Describing:"); + p=arr->u.vec; + if (VEC_SIZE(p)<1) return (char *)make_number(0); + if (!(siz=get_positive(&(p->item[0])))) return (char *)0; + strcpy(res,"@@@"); cnt1=1; cnt2=siz; nr=siz; + while (cnt1<=cnt2) { + if (p->item[cnt1].type!=T_POINTER) return res; + v1=p->item[cnt1].u.vec; + if (VEC_SIZE(v1)<2) return res; + num=get_positive(&v1->item[0]); + ob=get_object(&v1->item[1]); + if ((!num) || (!ob)) return res; + if (live) tmp=live_plurfix(ob,num,func); + else tmp=fixname(ob,num,func); + if (tmp!=(char *)0) + { + while (tmp[strlen(tmp)-1]==' ') tmp[strlen(tmp)-1]=0; + if (gDebug) fprintf(stderr,".%s.",tmp); + if (strlen(tmp)+strlen(res)>9*KLUDGELEN) { + strcat(res," among other things"); return res; + } + if (EQ("@@@",res)) strcpy(res,""); +/* if (siz == 1) strcat(res,tmp); + else if (siz == 2) { strcat(res,tmp); strcat(res," and "); } + else if (siz > 2) { strcat(res,tmp); strcat(res,", "); } */ +/* Kickaha */ + if (siz==cnt2) { strcat(res,tmp); } + else if (siz==1&&nr>1) { strcat(res," and ");strcat(res,tmp); } + else if (siz>=2&&nr>siz) { strcat(res,", ");strcat(res,tmp); } + else if (siz==2&&nr<=2) { strcat(res,tmp); } + else if (siz==1&&nr<=1) { strcat(res,tmp); } + } +/* else nr--; */ + cnt1++; siz--; + } + if (gDebug) fprintf(stderr,":\n",tmp); + if (EQ("@@@",res)) strcpy(res,""); + return res; +} + +int get_positive (v) + struct svalue *v; +{ + if (v->type!=T_NUMBER) return 0; + return v->u.number; +} + +struct object *get_object (v) + struct svalue *v; +{ + if (v->type!=T_OBJECT) return 0; + return v->u.ob; +} + +/* Fix the description of a living thing +*/ +char *live_plurfix (ob, ant, func) + struct object *ob; + int ant; + char *func; +{ + char *str,*name,tmp[KLUDGELEN]; + static char retval[2*KLUDGELEN]; + struct svalue *v; + + if (gDebug) fprintf(stderr,".live_plurfix.",tmp); + v=apply(QLIVING,ob,0); + if (!(v)) return fixname(ob,ant,func); + if ((v) && (v->type!=T_NUMBER)) return fixname(ob,ant,func); + v=apply(QNPCFUNC,ob,0); + if ((v) && (v->type==T_NUMBER) && (v->u.number)) return fixname(ob,ant,func); + if (ant==1) { + v=apply(QNAMEFUNC,ob,0); + if ((v) && (v->type==T_STRING)) + { + str=v->u.string; /* Kickaha */ + if (EQN("Someone",v->u.string)) return (char *)0; + } + else { + v=apply(func,ob,0); + if ((v) && (v->type==T_STRING)) str=v->u.string; + else { + return (char *)0; +/* strcpy(tmp,"shadow"); str=tmp; */ + } + } + strncpy(retval,str,2*KLUDGELEN-1); retval[2*KLUDGELEN-1]=0; + return retval; + } + else { + sprintf(tmp,"plural_%s",QNAMEFUNC); + v=apply(tmp,ob,0); + if ((v) && (v->type==T_STRING)) name=v->u.string; + else { + sprintf(tmp,"plural_%s",func); + v=apply(tmp,ob,0); + if ((v) && (v->type==T_STRING)) name=v->u.string; + else name=0; + } + if (name) { + strncpy(tmp,name,KLUDGELEN-1); tmp[KLUDGELEN-1]=0; /* Cry: Whaaaaah */ + return add_num(retval,tmp,ant); + } + strncpy(tmp,str,KLUDGELEN-1); tmp[KLUDGELEN-1]=0; /* Cry: Whaaaaah */ + return plurfix(retval,tmp,ant,0); + } +} + +/* Fix the descriptiom of a 'dead' object +*/ +char *fixname (ob, ant, func) + struct object *ob; + int ant; + char *func; +{ + char *str,*name,tmp[KLUDGELEN]; + static char retval[2*KLUDGELEN]; + struct svalue *v; + + if (gDebug) fprintf(stderr,".fixname."); + v=apply(func,ob,0); + if ((v) && (v->type==T_STRING)) str=v->u.string; + else str="shadow thing"; + if (ant>1) { + sprintf(tmp,"plural_%s",func); + v=apply(tmp,ob,0); + if ((v) && (v->type==T_STRING)) name=v->u.string; + else name=0; + if (name) { + strncpy(tmp,name,KLUDGELEN-1); tmp[KLUDGELEN-1]=0; /* Cry: Whaaaaah */ + return add_num(retval,tmp,ant); + } + } + strncpy(tmp,str,KLUDGELEN-1); tmp[KLUDGELEN-1]=0; /* Cry: Whaaaaah */ + if EQN("a ",tmp) return plurfix(retval,&tmp[2],ant,0); + else if EQN("an ",tmp) return plurfix(retval,&tmp[3],ant,0); + else if EQN("A ",tmp) return plurfix(retval,&tmp[2],ant,0); + else if EQN("An ",tmp) return plurfix(retval,&tmp[3],ant,0); + else if EQN("AN ",tmp) return plurfix(retval,&tmp[3],ant,0); + else if EQN("aN ",tmp) return plurfix(retval,&tmp[3],ant,0); + return plurfix(retval,tmp,ant,1); +} + +/* Add a prefix number in textform to the noun +*/ +char *add_num (dest, str, ant) + char *dest; + char *str; + int ant; +{ + strcpy(dest,""); + if (gDebug) fprintf(stderr,".splitfix."); + if (ant == 2) { + strcpy(dest,"two "); strcat(dest,str); + } + else if (ant == 3) { + strcpy(dest,"three "); strcat(dest,str); + } + else if (ant == 4) { + strcpy(dest,"four "); strcat(dest,str); + } + else if (ant < 8) { + strcpy(dest,"some "); strcat(dest,str); + } + else { + strcpy(dest,"many "); strcat(dest,str); + } + return dest; +} + +/* Fix the description into pluralform, used when no "plural_short" exists +*/ +char *plurfix (dest, str, ant, check) /* check -- Kickaha */ + char *dest; + char *str; + int ant; + int check; +{ + char tmp[KLUDGELEN]; + int itmp; + + if (gDebug) fprintf(stderr,".plurfix."); + if (sscanf(str,"%d",&itmp)) { + strcpy(dest,str); return dest; + } + if (ant == 1) { + if EQN("the ",str) { /* Kickaha */ + strcpy(dest,"the "); strcat(dest,splitfix(&str[4],ant)); return dest; + } + if EQN("The ",str) { /* Kickaha */ + strcpy(dest,"the "); strcat(dest,splitfix(&str[4],ant)); return dest; + } + if (check) /* Kickaha */ + { + strcpy(dest,splitfix(str,ant)); + return dest; + } + strcpy(dest,artfix(splitfix(str,ant))); + return dest; + } + else { + itmp=sscanf(str,"the %s",tmp); + if (!itmp) itmp=sscanf(str,"The %s",tmp); + if (!itmp) strcpy(tmp,str); + return add_num(dest,splitfix(str,ant),ant); + } +} + +/* Get the last word of the description and fix it to the right form +*/ +char *splitfix (str, ant) + char *str; + int ant; +{ + char *sp; + static char tmp[KLUDGELEN+10]; + char tmp2[KLUDGELEN+10]; + + strcpy(tmp2,str); sp=strrchr(tmp2,' '); /* sp => last word in desc */ + if (gDebug) fprintf(stderr,".splitfix."); + if (!sp) { /* Only 1 word in desc */ + strcpy(tmp,str); /*lowercase(tmp); Kickaha */ + if (ant>1) strcpy(tmp,pfix(tmp)); + return tmp; + } + else { + *sp=0; strcpy(tmp,&sp[1]); /* tmp2+" "+tmp is hole desc */ + } + if (ant>1) strcpy(tmp,pfix(tmp)); +/* lowercase(tmp); Kickaha */ + strcat(tmp2," "); strcat(tmp2,tmp); strcpy(tmp,tmp2); + return tmp; +} + +/* Add the correct article to a noun ( a or an ) +*/ +char *artfix (str) + char *str; +{ + static char tmp[KLUDGELEN+3]; + + if (gDebug) fprintf(stderr,".artfix."); + if (strchr("AEIOUaeiou",str[0])) { + strcpy(tmp,"an "); strcat(tmp,str); return tmp; + } + strcpy(tmp,"a "); strcat(tmp,str); return tmp; +} + +/* Change a noun in singularform to a noun in pluralform +*/ +char *pfix (str) + char *str; +{ + static char plur[KLUDGELEN+10]; + char *sp,*sp2; + int sl; + + sl=strlen(str); + if (sl<2) return strcpy(plur,str); + sp= &str[sl-1]; strcpy(plur,str); plur[sl-1]=0; + sp2= &str[sl-2]; + if (gDebug) fprintf(stderr,"To plural (%s) end(%s) begin(%s)\n",str,sp,plur); + if (EQ(sp,"s")) strcat(plur,"ses"); + else if (EQ(sp,"x")) strcat(plur,"xes"); + else if (EQ(sp,"h")) strcat(plur,"hes"); + else if (EQ(sp,"y")) strcat(plur,"ies"); + else if (EQ(sp2,"fe")) { + strcpy(plur,str); plur[sl-2]=0; strcat(plur,"ves"); + } + else if (EQ(str,"tooth")) strcpy(plur,"teeth"); + else if (EQ(str,"foot")) strcpy(plur,"feet"); + else if (EQ(str,"man")) strcpy(plur,"men"); + else if (EQ(str,"woman")) strcpy(plur,"women"); + else if (EQ(str,"children")) strcpy(plur,"child"); + else if (EQ(str,"sheep")) strcpy(plur,"sheep"); + else { + strcpy(plur,str); strcat(plur,"s"); + } + return plur; +} + +struct svalue * +make_number(n) + int n; +{ + struct svalue *ret; + + ret = (struct svalue *)xalloc(sizeof(struct svalue)); + ret->type = T_NUMBER; + ret->u.number = n; + return ret; +} + +struct svalue * +make_string(str) + char *str; +{ + struct svalue *ret; + + ret = (struct svalue *)xalloc(sizeof(struct svalue)); + ret->type = T_STRING; + ret->u.string = make_shared_string(str); + ret->x.string_type = STRING_SHARED; + return ret; } -#endif #ifdef F_PROCESS_STRING /* process_string diff -u -r -N --ignore-space-change driver-3.2.1@141/prolang.y driver-321@141-mod/prolang.y --- driver-3.2.1@141/prolang.y Mon Feb 16 17:29:50 1998 +++ driver-321@141-mod/prolang.y Sat Oct 10 20:33:10 1998 @@ -1711,6 +1711,7 @@ | F_MAPPING { $$ = TYPE_MAPPING; current_type = $$; }; %endif | F_VOID {$$ = TYPE_VOID; current_type = $$; } + | F_ARRAY {$$ = TYPE_ARRAY; current_type = $$; } | F_MIXED { $$ = TYPE_ANY; current_type = $$; } ; name_list: new_name @@ -3469,6 +3470,27 @@ $$.type = TYPE_ANY; } }; + | expr4 '[' F_RANGE expr0 ']' %prec '[' /* Kickaha */ + { +%line + $$.start = $1.start; + $$.code = -1; + ins_f_byte(F_EXTRACT3); + if (exact_types) { + int type; + + $$.type = type = $1.type & TYPE_MOD_MASK; + if ((type & TYPE_MOD_POINTER) == 0 && + type != TYPE_ANY && type != TYPE_STRING) + { + type_error("Bad type of argument used for range", type); + $$.type = TYPE_ANY; + } + type = $4.type & TYPE_MOD_MASK; + if (type != TYPE_ANY && type != TYPE_NUMBER) + type_error("Bad type of index", type); + } + }; | expr4 '[' '<' expr0 F_RANGE ']' %prec '[' { %line @@ -3812,7 +3834,7 @@ $$.start = $1.start; $$.end = CURRENT_PROGRAM_SIZE; $$.code = F_PUSH_INDEXED_LVALUE - F_OFFSET; - ins_f_byte(F_INDEX); + ins_f_byte(F_INDEXX); if ($3.type & TYPE_MOD_REFERENCE) yyerror("Reference used as index"); if (exact_types) { diff -u -r -N --ignore-space-change driver-3.2.1@141/simulate.c driver-321@141-mod/simulate.c --- driver-3.2.1@141/simulate.c Mon Feb 16 17:30:06 1998 +++ driver-321@141-mod/simulate.c Sat Oct 10 20:33:10 1998 @@ -69,7 +69,7 @@ #if ! defined (__GNUC__) || __GNUC__ < 2 || __GNUC__ == 2 && __GNUC_MINOR__ < 7 extern int lstat PROT((CONST char *, struct stat *)); #endif -extern int fchmod PROT((int, int)); +/*extern int fchmod PROT((int, int));*/ #endif #if defined(MSDOS) || defined(OS2) #define lstat stat @@ -336,7 +336,7 @@ while (--i > 0) { /* isdigit would need to check isascii first... */ if ( (c = *--p) < '0' || c > '9' ) { - if (c == '#' && name_length - i > 1) { + if (c == '@' && name_length - i > 1) { fprintf(stderr, "Illegal file to load: %s\n", name); error("Illegal file to load.\n"); } @@ -460,6 +460,7 @@ ob->name = string_copy(name); /* Shared string is no good here */ ob->prog = prog; ob->next_all = obj_list; +// init_object_su(ob, ob->name, ob->file_was_suid); /* Kickaha */ obj_list = ob; enter_object_hash(ob); /* add name to fast object lookup table */ @@ -609,6 +610,7 @@ new_ob->flags |= O_CLONE | ob->flags & ( O_APPROVED | O_WILL_CLEAN_UP ) ; new_ob->prog = ob->prog; reference_prog (ob->prog, "clone_object"); +// init_object_su(new_ob, ob->name, ob->file_was_suid); /* Kickaha */ #ifdef DEBUG if (!current_object) fatal("clone_object() from no current_object !\n"); @@ -1881,8 +1884,8 @@ if (path == 0) return 0; - if (start < 0) - return 0; +/* if (start < 0) + return 0; Kickaha */ f = fopen(path, "r"); if (f == 0) return 0; @@ -1890,6 +1893,15 @@ len = MAX_LINES; if (len > MAX_LINES) len = MAX_LINES; + if (start < 0) /* Kickaha */ + { + int lines; + lines = 0; + while (fgets(buff, sizeof buff, f) != 0) + lines++; + rewind(f); + start = lines-len+1; + } if (start == 0) start = 1; for (i=1; i < start + len; i++) { @@ -2107,7 +2119,6 @@ item->flags &= ~O_RESET_STATE; if (item->super) { int okey = 0; - if (item->sent) { void remove_environment_sent PROT((struct object *)); @@ -2149,6 +2160,7 @@ { struct object *ob; struct interactive *ip; + struct svalue *svp; if (sp->type != T_OBJECT) bad_xefun_arg(1, sp); @@ -2271,7 +2283,7 @@ if (buff[0] == '\0') return 0; clear_notify(); - if (special_parse(buff)) + if (O_GET_INTERACTIVE(command_giver) && special_parse(buff)) return 1; mark_sentence = alloc_sentence(); length = (int)(p_int)p; @@ -2309,9 +2321,11 @@ if (s->verb != shared_verb) continue; } else if (type == SENT_SHORT_VERB) { - int len; + int len, len2; len = strlen(s->verb); - if (strncmp(s->verb, buff, len) != 0) + len2 = strcspn(buff, " "); + if ((strncmp(s->verb, buff, len2) != 0 || len2short_verb) && + !(strcmp(s->verb,"")==0 && s->short_verb == 1)) continue; } else if (type == SENT_NO_SPACE) { int len; @@ -2871,13 +2885,29 @@ { struct interactive *ip; struct svalue *svp; - + int tmp, i; #ifdef DEBUG strncpy(debug_parse_buff, buff, sizeof debug_parse_buff); debug_parse_buff[sizeof debug_parse_buff - 1] = '\0'; #endif + if ((ip = O_GET_INTERACTIVE(command_giver)) != NULL && + ip->sent.type == SENT_INTERACTIVE) + { + if (strcmp(buff, "%%")==0) + { + if (ip->last_command) + strcpy(buff, ip->last_command); + } + else + { + if (ip->last_command) xfree(ip->last_command); + ip->last_command = xalloc(strlen(buff)+1); + strcpy(ip->last_command, buff); + } + } + if (!is_wizard_used || command_giver->flags & O_IS_WIZARD) { if (strcmp(buff, "malloc") == 0) { -#if defined(MALLOC_malloc) || defined(MALLOC_smalloc) +#if defined(MALLOC_malloc) || defined(MALLOC_smalloc) || defined(MALLOC_lmalloc) dump_malloc_data(); #endif #ifdef MALLOC_gmalloc @@ -2888,7 +2918,6 @@ #endif return 1; } - if (!is_wizard_used || command_giver->flags & O_IS_WIZARD) { if (strcmp(buff, "dumpallobj") == 0) { dumpstat(); return 1; @@ -3286,6 +3315,7 @@ int do_save_error; char *file, *malloced_error, *malloced_file = 0, *malloced_name = 0; char fixed_fmt[200]; + char *ffptr; mp_int line_number; #ifdef __STDC__ int a; @@ -3611,7 +3642,8 @@ void shutdowngame() { apply_master_ob("notify_shutdown", 0); ipc_remove(); - remove_all_players(); + save_all_players(); +/* remove_all_players(); */ remove_destructed_objects(); /*Will perform the remove_interactive calls*/ unlink_swap_file(); #ifdef DEALLOCATE_MEMORY_AT_SHUTDOWN @@ -4048,6 +4080,8 @@ pop_apply_value(); return 1; } + from = fr; + to = t; if(!strlen(to) && !strcmp(t, "/")) { to = (char *)alloca(3); sprintf(to, "./"); @@ -4067,12 +4101,12 @@ newto = (char *) alloca (strlen (to) + 1 + strlen (cp) + 1); sprintf (newto, "%s/%s", to, cp); - pop_apply_value(); +/* pop_apply_value(); Kickaha */ return do_move (from, newto); } else i = do_move (from, to); - pop_apply_value(); +/* pop_apply_value(); Kickaha */ return i; } #endif /* F_RENAME */ @@ -4384,3 +4418,75 @@ } return sp; } + +void log_file(file, str) + char *file, *str; +{ + FILE *f; + char file_name[100]; + struct stat st; + + sprintf(file_name, "/log/%s", file); +#ifdef COMPAT_MODE + if (/* strchr(file, '/') || */ file[0] == '.' || strlen(file) > 50 +#ifndef MSDOS + ) +#else + || !valid_msdos(file)) +#endif + error("Illegal file name to log_file(%s)\n", file); +#else + if (!check_valid_path(file_name, current_object->eff_user, "log_file", 1)) + return; +#endif + if (stat(file_name+1, &st) != -1 && st.st_size > MAX_LOG_SIZE) { + char file_name2[sizeof file_name + 4]; + sprintf(file_name2, "%s.old", file_name+1); + rename(file_name+1, file_name2); /* No panic if failure */ + } + f = fopen(file_name+1, "a"); /* Skip leading '/' */ + if (f == 0) + return; + fwrite(str, strlen(str), 1, f); + fclose(f); +} + +void print_local_commands() { + struct sentence *s; + + add_message("Current local commands:\n"); + for (s = command_giver->sent; s; s = s->next) + add_message("%s ", s->verb); + add_message("\n"); +} + +/* + * removes one sentence structure from player, which matches verb. + */ + +int remove_one_sent(ob, player, verb) +struct object *ob, *player; +char *verb; +{ + struct sentence **s; + + for (s = &player->sent; *s; ) + { + struct sentence *tmp; + + if ((*s)->ob == ob && strcmp((*s)->verb, verb) == 0) + { + if (d_flag > 1) + debug_message("--Unlinking sentence %s\n", (*s)->verb); + tmp = *s; + *s = tmp->next; + free_sentence(tmp); + return 1; + } + s = &((*s)->next); + } + return 0; +} + + + diff -u -r -N --ignore-space-change driver-3.2.1@141/smalloc.c driver-321@141-mod/smalloc.c --- driver-3.2.1@141/smalloc.c Mon Feb 16 17:30:06 1998 +++ driver-321@141-mod/smalloc.c Sat Oct 10 20:33:10 1998 @@ -1587,6 +1593,11 @@ return t; } +query_malloc_total_alloced() +{ + return large_alloc_stat.size*SINT-small_free_stat.size-unused_size; +} + /* * It is system dependent how sbrk() aligns data, so we simpy use brk() * to insure that we have enough. diff -u -r -N --ignore-space-change driver-3.2.1@141/sysmalloc.c driver-321@141-mod/sysmalloc.c --- driver-3.2.1@141/sysmalloc.c Sat Oct 26 15:38:18 1996 +++ driver-321@141-mod/sysmalloc.c Sat Oct 10 20:33:10 1998 @@ -2,3 +2,19 @@ * This is a dummy file, that will force the standard malloc * to be used. */ + +query_malloc_total_alloced() +{ + return 4242; +} + +note_malloced_block_ref(char *arg) +{ + +} +