[Sep 13 2007] - Rumble
  Changed binary search functions (real_xxxx, real_zone_by_thing), except real_shop. (thanks Neme)
  script_proto list freed when exiting without saving in oedit/medit/redit.  (thanks Neme)
  dg_olc.c, trigedit_save(): trig name and arg duping removed. (thanks Neme)
  genobj.c, update_all_obects(): object ID copied, no more 0 uid. (thanks Neme)
  CLEANUP_ALL in redit after saving a room.  (thanks Neme)
  new function in genolc.c: free_save_list(), called during shutdown.  (thanks Neme)
  Event_free_all() now frees all events. (thanks Neme)
  Fixed memory leak in perform_act(). (thanks Rhade)
  Changed NUM_BOARDS from 10 to 7 (the actual num of boards). (thanks Neme)
  Removed the Keywords option in hedit since they have to be in the body.
[Sep 12 2007] - Rumble
  Fixed crash bug caused by olist with no objects. (Thanks Rhade)
  Several changes made to compile clean on older versions of GCC. (Thanks Neme)
?Sep 10 2007] - Rumble
  Fixed items with rnum = NOTHING or NOBODY being changed to rnum = 0.  (Thanks Neme)
  Fixed memory leak in dg_olc.c trigedit save. (Thanks Neme)
[Sep 04 2007] - Rumble
  Changed CLSOLC to LVL_BUILDER.
  removed delete_doubledollar from do_say. (thanks Rhade)
[Sep 01 2007] - Rumble
  Made Puff a hidden mob since she is used on room entry trigs to do dg_cast.
  Fixed dg_affect to not add 1 to the desired affect duration.
  Fixed dg_affect to work with 128 bits.
This commit is contained in:
Rumble 2007-09-13 15:00:59 +00:00
parent f95bff93e5
commit 6c84a36236
54 changed files with 14481 additions and 14187 deletions

View file

@ -47,11 +47,11 @@ ACMD(do_say)
send_to_char(ch, "Yes, but WHAT do you want to say?\r\n");
else {
char buf[MAX_INPUT_LENGTH + 14], *msg;
struct char_data *vict;
snprintf(buf, sizeof(buf), "$n@n says, '%s@n'", argument);
msg = act(buf, FALSE, ch, 0, 0, TO_ROOM | DG_NO_TRIG);
struct char_data *vict;
for (vict = world[IN_ROOM(ch)].people; vict; vict = vict->next_in_room)
if (vict != ch && GET_POS(vict) > POS_SLEEPING)
add_history(vict, msg, HIST_SAY);
@ -59,7 +59,6 @@ ACMD(do_say)
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_NOREPEAT))
send_to_char(ch, "%s", CONFIG_OK);
else {
delete_doubledollar(argument);
sprintf(buf, "You say, '%s@n'", argument);
msg = act(buf, FALSE, ch, 0, 0, TO_CHAR | DG_NO_TRIG);
add_history(ch, msg, HIST_SAY);

View file

@ -1048,10 +1048,10 @@ ACMD(do_help)
space_to_minus(argument);
if ((mid = search_help(argument, GET_LEVEL(ch))) == NOWHERE) {
int i, found = 0;
send_to_char(ch, "There is no help on that word.\r\n");
mudlog(NRM, MAX(LVL_IMPL, GET_INVIS_LEV(ch)), TRUE,
"%s tried to get help on %s", GET_NAME(ch), argument);
int i, found = 0;
for (i = 0; i <= top_of_helpt; i++) {
if (help_table[i].min_level > GET_LEVEL(ch))
continue;
@ -1086,6 +1086,17 @@ ACMD(do_who)
int showclass = 0, short_list = 0, outlaws = 0;
int who_room = 0, showgroup = 0, showleader = 0;
struct {
char *disp;
int min_level;
int max_level;
int count; /* must always start as 0 */
} rank[] = {
{ "Immortals\r\n---------\r\n", LVL_IMMORT, LVL_IMPL, 0},
{ "Mortals\r\n-------\r\n", 1, LVL_IMMORT - 1, 0 },
{ "\n", 0, 0, 0 }
};
skip_spaces(&argument);
strcpy(buf, argument); /* strcpy: OK (sizeof: argument == buf) */
name_search[0] = '\0';
@ -1145,17 +1156,6 @@ ACMD(do_who)
}
}
struct {
char *disp;
int min_level;
int max_level;
int count; /* must always start as 0 */
} rank[] = {
{ "Immortals\r\n---------\r\n", LVL_IMMORT, LVL_IMPL, 0},
{ "Mortals\r\n-------\r\n", 1, LVL_IMMORT - 1, 0 },
{ "\n", 0, 0, 0 }
};
for (d = descriptor_list; d && !short_list; d = d->next) {
if (d->original)
tch = d->original;
@ -1733,6 +1733,95 @@ ACMD(do_toggle)
int toggle, tp, wimp_lev, result = 0, len = 0;
const char *types[] = { "off", "brief", "normal", "on", "\n" };
const struct {
char *command;
bitvector_t toggle; /* this needs changing once hashmaps are implemented */
char min_level;
char *disable_msg;
char *enable_msg;
} tog_messages[] = {
{"summonable", PRF_SUMMONABLE, 0,
"You are now safe from summoning by other players.\r\n",
"You may now be summoned by other players.\r\n"},
{"nohassle", PRF_NOHASSLE, LVL_IMMORT,
"Nohassle disabled.\r\n",
"Nohassle enabled.\r\n"},
{"brief", PRF_BRIEF, 0,
"Brief mode off.\r\n",
"Brief mode on.\r\n"},
{"compact", PRF_COMPACT, 0,
"Compact mode off.\r\n",
"Compact mode on.\r\n"},
{"notell", PRF_NOTELL, 0,
"You can now hear tells.\r\n",
"You are now deaf to tells.\r\n"},
{"noauction", PRF_NOAUCT, 0,
"You can now hear auctions.\r\n",
"You are now deaf to auctions.\r\n"},
{"noshout", PRF_NOSHOUT, 0,
"You can now hear shouts.\r\n",
"You are now deaf to shouts.\r\n"},
{"nogossip", PRF_NOGOSS, 0,
"You can now hear gossip.\r\n",
"You are now deaf to gossip.\r\n"},
{"nograts", PRF_NOGRATZ, 0,
"You can now hear gratz.\r\n",
"You are now deaf to gratz.\r\n"},
{"nowiz", PRF_NOWIZ, LVL_IMMORT,
"You can now hear the Wiz-channel.\r\n",
"You are now deaf to the Wiz-channel.\r\n"},
{"quest", PRF_QUEST, 0,
"Okay, you are part of the Quest.\r\n",
"You are no longer part of the Quest.\r\n"},
{"showvnums", PRF_SHOWVNUMS, LVL_IMMORT,
"You will no longer see the vnums.\r\n",
"You will now see the vnums.\r\n"},
{"norepeat", PRF_NOREPEAT, 0,
"You will now have your communication repeated.\r\n",
"You will no longer have your communication repeated.\r\n"},
{"holylight", PRF_HOLYLIGHT, LVL_IMMORT,
"HolyLight mode off.\r\n",
"HolyLight mode on.\r\n"},
{"slownameserver", 0, LVL_IMPL,
"Nameserver_is_slow changed to OFF; IP addresses will now be resolved.\r\n",
"Nameserver_is_slow changed to ON; sitenames will no longer be resolved.\r\n"},
{"autoexits", PRF_AUTOEXIT, 0,
"Autoexits disabled.\r\n",
"Autoexits enabled.\r\n"},
{"trackthru", 0, LVL_IMPL,
"Players can no longer track through doors.\r\n",
"Players can now track through doors.\r\n"},
{"clsolc", PRF_CLS, LVL_BUILDER,
"You will no longer clear screen in OLC.\r\n",
"You will now clear screen in OLC.\r\n"},
{"buildwalk", PRF_BUILDWALK, LVL_BUILDER,
"Buildwalk is now Off.\r\n",
"Buildwalk is now On.\r\n"},
{"afk", PRF_AFK, 0,
"AFK is now Off.\r\n",
"AFK is now On.\r\n"},
{"color", 0, 0, "\n", "\n"},
{"syslog", 0, LVL_IMMORT, "\n", "\n"},
{"wimpy", 0, 0, "\n", "\n"},
{"pagelength", 0, 0, "\n", "\n"},
{"autoloot", PRF_AUTOLOOT, 0,
"Autoloot disabled.\r\n",
"Autoloot enabled.\r\n"},
{"autogold", PRF_AUTOGOLD, 0,
"Autogold disabled.\r\n",
"Autogold enabled.\r\n"},
{"autosplit", PRF_AUTOSPLIT, 0,
"Autosplit disabled.\r\n",
"Autosplit enabled.\r\n"},
{"autosac", PRF_AUTOSAC, 0,
"Autosac disabled.\r\n",
"Autosac enabled.\r\n"},
{"autoassist", PRF_AUTOASSIST, 0,
"Autoassist disabled.\r\n",
"Autoassist enabled.\r\n"},
{"\n", 0, -1, "\n", "\n"} /* must be last */
};
if (IS_NPC(ch))
return;
@ -1839,95 +1928,6 @@ ACMD(do_toggle)
return;
}
const struct {
char *command;
bitvector_t toggle; /* this needs changing once hashmaps are implemented */
char min_level;
char *disable_msg;
char *enable_msg;
} tog_messages[] = {
{"summonable", PRF_SUMMONABLE, 0,
"You are now safe from summoning by other players.\r\n",
"You may now be summoned by other players.\r\n"},
{"nohassle", PRF_NOHASSLE, LVL_IMMORT,
"Nohassle disabled.\r\n",
"Nohassle enabled.\r\n"},
{"brief", PRF_BRIEF, 0,
"Brief mode off.\r\n",
"Brief mode on.\r\n"},
{"compact", PRF_COMPACT, 0,
"Compact mode off.\r\n",
"Compact mode on.\r\n"},
{"notell", PRF_NOTELL, 0,
"You can now hear tells.\r\n",
"You are now deaf to tells.\r\n"},
{"noauction", PRF_NOAUCT, 0,
"You can now hear auctions.\r\n",
"You are now deaf to auctions.\r\n"},
{"noshout", PRF_NOSHOUT, 0,
"You can now hear shouts.\r\n",
"You are now deaf to shouts.\r\n"},
{"nogossip", PRF_NOGOSS, 0,
"You can now hear gossip.\r\n",
"You are now deaf to gossip.\r\n"},
{"nograts", PRF_NOGRATZ, 0,
"You can now hear gratz.\r\n",
"You are now deaf to gratz.\r\n"},
{"nowiz", PRF_NOWIZ, LVL_IMMORT,
"You can now hear the Wiz-channel.\r\n",
"You are now deaf to the Wiz-channel.\r\n"},
{"quest", PRF_QUEST, 0,
"Okay, you are part of the Quest.\r\n",
"You are no longer part of the Quest.\r\n"},
{"showvnums", PRF_SHOWVNUMS, LVL_IMMORT,
"You will no longer see the vnums.\r\n",
"You will now see the vnums.\r\n"},
{"norepeat", PRF_NOREPEAT, 0,
"You will now have your communication repeated.\r\n",
"You will no longer have your communication repeated.\r\n"},
{"holylight", PRF_HOLYLIGHT, LVL_IMMORT,
"HolyLight mode off.\r\n",
"HolyLight mode on.\r\n"},
{"slownameserver", 0, LVL_IMPL,
"Nameserver_is_slow changed to OFF; IP addresses will now be resolved.\r\n",
"Nameserver_is_slow changed to ON; sitenames will no longer be resolved.\r\n"},
{"autoexits", PRF_AUTOEXIT, 0,
"Autoexits disabled.\r\n",
"Autoexits enabled.\r\n"},
{"trackthru", 0, LVL_IMPL,
"Players can no longer track through doors.\r\n",
"Players can now track through doors.\r\n"},
{"clsolc", PRF_CLS, LVL_BUILDER,
"You will no longer clear screen in OLC.\r\n",
"You will now clear screen in OLC.\r\n"},
{"buildwalk", PRF_BUILDWALK, LVL_BUILDER,
"Buildwalk is now Off.\r\n",
"Buildwalk is now On.\r\n"},
{"afk", PRF_AFK, 0,
"AFK is now Off.\r\n",
"AFK is now On.\r\n"},
{"color", 0, 0, "\n", "\n"},
{"syslog", 0, LVL_IMMORT, "\n", "\n"},
{"wimpy", 0, 0, "\n", "\n"},
{"pagelength", 0, 0, "\n", "\n"},
{"autoloot", PRF_AUTOLOOT, 0,
"Autoloot disabled.\r\n",
"Autoloot enabled.\r\n"},
{"autogold", PRF_AUTOGOLD, 0,
"Autogold disabled.\r\n",
"Autogold enabled.\r\n"},
{"autosplit", PRF_AUTOSPLIT, 0,
"Autosplit disabled.\r\n",
"Autosplit enabled.\r\n"},
{"autosac", PRF_AUTOSAC, 0,
"Autosac disabled.\r\n",
"Autosac enabled.\r\n"},
{"autoassist", PRF_AUTOASSIST, 0,
"Autoassist disabled.\r\n",
"Autoassist enabled.\r\n"},
{"\n", 0, -1, "\n", "\n"} /* must be last */
};
len = strlen(arg);
for (toggle = 0; *tog_messages[toggle].command != '\n'; toggle++)
if (!strncmp(arg, tog_messages[toggle].command, len))
@ -2149,10 +2149,11 @@ void free_history(struct char_data *ch, int type)
ACMD(do_history)
{
char arg[MAX_INPUT_LENGTH];
int type;
one_argument(argument, arg);
int type = search_block(arg, history_types, FALSE);
type = search_block(arg, history_types, FALSE);
if (!*arg || type < 0) {
int i;
@ -2184,12 +2185,14 @@ void add_history(struct char_data *ch, char *str, int type)
{
int i = 0;
char time_str[MAX_STRING_LENGTH], buf[MAX_STRING_LENGTH];
struct txt_block *tmp;
time_t ct;
if (IS_NPC(ch))
return;
struct txt_block *tmp = GET_HISTORY(ch, type);
time_t ct = time(0);
tmp = GET_HISTORY(ch, type);
ct = time(0);
strftime(time_str, sizeof(time_str), "%H:%M ", localtime(&ct));
sprintf(buf, "%s%s", time_str, str);

View file

@ -269,12 +269,12 @@ ACMD(do_flee)
was_fighting = FIGHTING(ch);
if (do_simple_move(ch, attempt, TRUE)) {
send_to_char(ch, "You flee head over heels.\r\n");
stop_fighting(ch);
stop_fighting(was_fighting);
if (was_fighting && !IS_NPC(ch)) {
if (was_fighting && !IS_NPC(ch)) {
loss = GET_MAX_HIT(was_fighting) - GET_HIT(was_fighting);
loss *= GET_LEVEL(was_fighting);
gain_exp(ch, -loss);
stop_fighting(ch);
stop_fighting(was_fighting);
}
} else {
act("$n tries to flee, but can't!", TRUE, ch, 0, 0, TO_ROOM);

View file

@ -85,7 +85,7 @@ ACMD(do_action)
if (action->char_auto)
send_to_char(ch, "%s\r\n", action->char_auto);
else
send_to_char(ch, "Erm, no.");
send_to_char(ch, "Erm, no.\r\n");
act(action->others_auto, action->hide, ch, 0, 0, TO_ROOM);
return;
}

View file

@ -8,7 +8,7 @@
* CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. *
**************************************************************************/
#define NUM_OF_BOARDS 10 /* change if needed! */
#define NUM_OF_BOARDS 7 /* change if needed! */
#define MAX_BOARD_MESSAGES 60 /* arbitrary -- change if needed */
#define MAX_MESSAGE_LENGTH 4096 /* arbitrary -- change if needed */

View file

@ -109,6 +109,7 @@ static bool fCopyOver; /* Are we booting in copyover mode? */
ush_int port;
socket_t mother_desc;
int log_this_messg;
char *last_act_message = NULL;
/* local functions */
RETSIGTYPE reread_wizlists(int sig);
@ -172,6 +173,7 @@ void board_clear_all(void);
void free_social_messages(void);
void free_invalid_list(void);
void free_command_list(void);
void free_save_list(void);
void load_config(void);
void new_hist_messg(struct descriptor_data *d, const char *msg);
#ifdef __CXREF__
@ -210,6 +212,10 @@ int main(int argc, char **argv)
int pos = 1;
const char *dir;
#ifdef MEMORY_DEBUG
zmalloc_init();
#endif
#if CIRCLE_GNU_LIBC_MEMORY_TRACK
mtrace(); /* This must come before any use of malloc(). */
#endif
@ -373,9 +379,13 @@ int main(int argc, char **argv)
free_social_messages(); /* act.social.c */
free_help_table(); /* db.c */
free_invalid_list(); /* ban.c */
free_save_list(); /* genolc.c */
free_strings(&config_info, OASIS_CFG); /* oasis_delete.c */
}
if (last_act_message)
free(last_act_message);
/* probably should free the entire config here.. */
free(CONFIG_CONFFILE);
@ -2402,7 +2412,7 @@ const char *ACTNULL = "<NULL>";
#define CHECK_NULL(pointer, expression) \
if ((pointer) == NULL) i = ACTNULL; else i = (expression);
/* higher-level communication: the act() function */
char *perform_act(const char *orig, struct char_data *ch, struct obj_data *obj,
void perform_act(const char *orig, struct char_data *ch, struct obj_data *obj,
const void *vict_obj, const struct char_data *to)
{
const char *i = NULL;
@ -2525,13 +2535,14 @@ char *perform_act(const char *orig, struct char_data *ch, struct obj_data *obj,
if ((IS_NPC(to) && dg_act_check) && (to != ch))
act_mtrigger(to, lbuf, ch, dg_victim, obj, dg_target, dg_arg);
return strdup(lbuf);
if (last_act_message)
free(last_act_message);
last_act_message = strdup(lbuf);
}
char *act(const char *str, int hide_invisible, struct char_data *ch,
struct obj_data *obj, const void *vict_obj, int type)
{
char *msg = NULL;
const struct char_data *to;
int to_sleeping;
@ -2556,14 +2567,18 @@ char *act(const char *str, int hide_invisible, struct char_data *ch,
REMOVE_BIT(type, DG_NO_TRIG);
if (type == TO_CHAR) {
if (ch && SENDOK(ch))
return perform_act(str, ch, obj, vict_obj, ch);
if (ch && SENDOK(ch)) {
perform_act(str, ch, obj, vict_obj, ch);
return last_act_message;
}
return NULL;
}
if (type == TO_VICT) {
if ((to = (const struct char_data *) vict_obj) != NULL && SENDOK(to))
return perform_act(str, ch, obj, vict_obj, to);
if ((to = (const struct char_data *) vict_obj) != NULL && SENDOK(to)) {
perform_act(str, ch, obj, vict_obj, to);
return last_act_message;
}
return NULL;
}
@ -2579,10 +2594,10 @@ char *act(const char *str, int hide_invisible, struct char_data *ch,
!ROOM_FLAGGED(IN_ROOM(i->character), ROOM_SOUNDPROOF)) {
sprintf(buf, "%s%s%s", CCYEL(i->character, C_NRM), str, CCNRM(i->character, C_NRM));
msg = perform_act(buf, ch, obj, vict_obj, i->character);
perform_act(buf, ch, obj, vict_obj, i->character);
}
}
return msg;
return last_act_message;
}
/* ASSUMPTION: at this point we know type must be TO_NOTVICT or TO_ROOM */
@ -2602,9 +2617,9 @@ char *act(const char *str, int hide_invisible, struct char_data *ch,
continue;
if (type != TO_ROOM && to == vict_obj)
continue;
msg = perform_act(str, ch, obj, vict_obj, to);
perform_act(str, ch, obj, vict_obj, to);
}
return msg;
return last_act_message;
}
/* Prefer the file over the descriptor. */

View file

@ -24,7 +24,7 @@ void send_to_range(room_vnum start, room_vnum finish, const char *messg, ...)
__attribute__ ((format (printf, 3, 4)));
void close_socket(struct descriptor_data *d);
char * perform_act(const char *orig, struct char_data *ch, struct obj_data *obj, const void *vict_obj, const struct char_data *to);
void perform_act(const char *orig, struct char_data *ch, struct obj_data *obj, const void *vict_obj, const struct char_data *to);
char * act(const char *str, int hide_invisible, struct char_data *ch, struct obj_data *obj, const void *vict_obj, int type);
#define TO_ROOM 1

View file

@ -2086,7 +2086,8 @@ void get_one_line(FILE *fl, char *buf)
buf[strlen(buf) - 1] = '\0'; /* take off the trailing \n */
}
void free_help(struct help_index_element *help) {
void free_help(struct help_index_element *help)
{
if (help->keywords)
free(help->keywords);
if (help->entry && !help->duplicate)
@ -2762,13 +2763,13 @@ void free_char(struct char_data *ch)
free(ch->player.long_descr);
if (ch->player.description)
free(ch->player.description);
if (ch->player_specials)
free(ch->player_specials);
for (i = 0; i < NUM_HIST; i++)
if (GET_HISTORY(ch, i))
free(GET_HISTORY(ch, i));
if (ch->player_specials)
free(ch->player_specials);
/* free script proto list */
free_proto_script(ch, MOB_TRIGGER);
@ -3052,21 +3053,21 @@ room_rnum real_room(room_vnum vnum)
bot = 0;
top = top_of_world;
if (world[bot].number > vnum || world[top].number < vnum)
return (NOWHERE);
/* perform binary search on world-table */
for (;;) {
while (bot<= top) {
mid = (bot + top) / 2;
if ((world + mid)->number == vnum)
return (mid);
if (bot > top)
return (NOWHERE);
if (top == 0)
return (NOWHERE);
if ((world + mid)->number > vnum)
top = mid - 1;
else
bot = mid + 1;
}
return (NOWHERE);
}
/* returns the real number of the monster with given virtual number */
@ -3077,21 +3078,22 @@ mob_rnum real_mobile(mob_vnum vnum)
bot = 0;
top = top_of_mobt;
/* quickly reject out-of-range vnums */
if (mob_index[bot].vnum > vnum || mob_index[top].vnum < vnum)
return (NOBODY);
/* perform binary search on mob-table */
for (;;) {
while (bot <= top) {
mid = (bot + top) / 2;
if ((mob_index + mid)->vnum == vnum)
return (mid);
if (bot > top)
return (NOBODY);
if (top == 0)
return (NOBODY);
if ((mob_index + mid)->vnum > vnum)
top = mid - 1;
else
bot = mid + 1;
}
return (NOBODY);
}
/* returns the real number of the object with given virtual number */
@ -3102,21 +3104,22 @@ obj_rnum real_object(obj_vnum vnum)
bot = 0;
top = top_of_objt;
/* quickly reject out-of-range vnums */
if (obj_index[bot].vnum > vnum || obj_index[top].vnum < vnum)
return (NOTHING);
/* perform binary search on obj-table */
for (;;) {
while (bot <= top) {
mid = (bot + top) / 2;
if ((obj_index + mid)->vnum == vnum)
return (mid);
if (bot > top)
return (NOTHING);
if (top == 0)
return (NOTHING);
if ((obj_index + mid)->vnum > vnum)
top = mid - 1;
else
bot = mid + 1;
}
return (NOTHING);
}
/* returns the real number of the zone with given virtual number */
@ -3127,21 +3130,21 @@ zone_rnum real_zone(zone_vnum vnum)
bot = 0;
top = top_of_zone_table;
if (zone_table[bot].number > vnum || zone_table[top].number < vnum)
return (NOWHERE);
/* perform binary search on zone-table */
for (;;) {
while (bot <= top) {
mid = (bot + top) / 2;
if ((zone_table + mid)->number == vnum)
return (mid);
if (bot > top)
return (NOWHERE);
if (top == 0)
return (NOWHERE);
if ((zone_table + mid)->number > vnum)
top = mid - 1;
else
bot = mid + 1;
}
return (NOWHERE);
}
/* Extend later to include more checks and add checks for unknown bitvectors. */

View file

@ -99,14 +99,6 @@ long event_time(struct event *event)
/* frees all events in the queue */
void event_free_all(void)
{
struct event *the_event;
while ((the_event = (struct event *) queue_head(event_q))) {
if (the_event->event_obj)
free(the_event->event_obj);
free(the_event);
}
queue_free(event_q);
}
@ -237,13 +229,19 @@ void queue_free(struct queue *q)
{
int i;
struct q_element *qe, *next_qe;
struct event *event;
for (i = 0; i < NUM_EVENT_QUEUES; i++)
for (qe = q->head[i]; qe; qe = next_qe) {
next_qe = qe->next;
if ((event = (struct event *) qe->data) != NULL) {
if (event->event_obj)
free(event->event_obj);
free(event);
}
free(qe);
}
free(q);
}
}

View file

@ -230,7 +230,7 @@ void do_dg_affect(void *go, struct script_data *sc, trig_data *trig,
/* add the affect */
af.type = SPELL_DG_AFFECT;
af.duration = duration;
af.duration = duration -1;
af.modifier = value;
if (type == APPLY_TYPE) {
@ -238,7 +238,7 @@ void do_dg_affect(void *go, struct script_data *sc, trig_data *trig,
af.bitvector = 0;
} else {
af.location = 0;
af.bitvector = (1<<i);
af.bitvector = (i);
}
affect_to_char(ch, &af);

View file

@ -513,11 +513,6 @@ void trigedit_save(struct descriptor_data *d)
new_index[rnum]->proto = proto;
trig_data_copy(proto, trig);
if (trig->name)
proto->name = strdup(trig->name);
if (trig->arglist)
proto->arglist = strdup(trig->arglist);
new_index[rnum + 1] = trig_index[rnum];
proto = trig_index[rnum]->proto;
@ -543,11 +538,6 @@ void trigedit_save(struct descriptor_data *d)
CREATE(proto, struct trig_data, 1);
new_index[rnum]->proto = proto;
trig_data_copy(proto, trig);
if (trig->name)
proto->name = strdup(trig->name);
if (trig->arglist)
proto->arglist = strdup(trig->arglist);
}
free(trig_index);
@ -557,7 +547,7 @@ void trigedit_save(struct descriptor_data *d)
/* HERE IT HAS TO GO THROUGH AND FIX ALL SCRIPTS/TRIGS OF HIGHER RNUM */
for (live_trig = trigger_list; live_trig; live_trig = live_trig->next_in_world)
GET_TRIG_RNUM(live_trig) += (GET_TRIG_RNUM(live_trig) > rnum);
GET_TRIG_RNUM(live_trig) += (GET_TRIG_RNUM(live_trig) != NOTHING && GET_TRIG_RNUM(live_trig) > rnum);
/* Update other trigs being edited. */
for (dsc = descriptor_list; dsc; dsc = dsc->next)

View file

@ -2625,25 +2625,26 @@ int script_driver(void *go_adress, trig_data *trig, int type, int mode)
/* returns the real number of the trigger with given virtual number */
trig_rnum real_trigger(trig_vnum vnum)
{
int bot = 0, mid;
int top = top_of_trigt-1;
trig_rnum bot, top, mid;
bot = 0;
top = top_of_trigt - 1;
if (!top_of_trigt || trig_index[bot]->vnum > vnum || trig_index[top]->vnum < vnum)
return (NOTHING);
/* perform binary search on trigger-table */
for (;;) {
while (bot <= top) {
mid = (bot + top) / 2;
/* Thanks to Derek Fisk for fixing this loop */
if (bot > top)
return (NOTHING);
if (trig_index[mid]->vnum == vnum)
return (mid);
if (top == 0)
return (NOTHING);
if (trig_index[mid]->vnum > vnum)
top = mid - 1;
else
bot = mid + 1;
}
return (NOTHING);
}
ACMD(do_tstat)

View file

@ -72,7 +72,7 @@ int add_mobile(struct char_data *mob, mob_vnum vnum)
/* Update live mobile rnums. */
for (live_mob = character_list; live_mob; live_mob = live_mob->next)
GET_MOB_RNUM(live_mob) += (GET_MOB_RNUM(live_mob) >= found);
GET_MOB_RNUM(live_mob) += (GET_MOB_RNUM(live_mob) != NOTHING && GET_MOB_RNUM(live_mob) >= found);
/* Update zone table. */
for (zone = 0; zone <= top_of_zone_table; zone++)
@ -83,7 +83,7 @@ int add_mobile(struct char_data *mob, mob_vnum vnum)
/* Update shop keepers. */
if (shop_index)
for (shop = 0; shop <= top_shop - top_shop_offset; shop++)
SHOP_KEEPER(shop) += (SHOP_KEEPER(shop) >= found);
SHOP_KEEPER(shop) += (SHOP_KEEPER(shop) != NOTHING && SHOP_KEEPER(shop) >= found);
add_to_save_list(zone_table[real_zone_by_thing(vnum)].number, SL_MOB);
return found;

View file

@ -65,6 +65,7 @@ int update_all_objects(struct obj_data *refobj)
*obj = *refobj;
/* Copy game-time dependent variables over. */
GET_ID(obj) = swap.id;
IN_ROOM(obj) = swap.in_room;
obj->carried_by = swap.carried_by;
obj->worn_by = swap.worn_by;
@ -96,7 +97,7 @@ obj_rnum adjust_objects(obj_rnum refpt)
/* Renumber live objects. */
for (obj = object_list; obj; obj = obj->next)
GET_OBJ_RNUM(obj) += (GET_OBJ_RNUM(obj) >= refpt);
GET_OBJ_RNUM(obj) += (GET_OBJ_RNUM(obj) != NOTHING && GET_OBJ_RNUM(obj) >= refpt);
/* Renumber zone table. */
for (zone = 0; zone <= top_of_zone_table; zone++) {
@ -374,15 +375,16 @@ int copy_object_main(struct obj_data *to, struct obj_data *from, int free_object
int delete_object(obj_rnum rnum)
{
obj_rnum i;
zone_rnum zrnum;
struct obj_data *obj, *tmp;
int shop, j;
int shop, j, zone, cmd_no;
if (rnum == NOTHING || rnum > top_of_objt)
return NOTHING;
obj = &obj_proto[rnum];
zone_rnum zrnum = real_zone_by_thing(GET_OBJ_VNUM(obj));
zrnum = real_zone_by_thing(GET_OBJ_VNUM(obj));
/* This is something you might want to read about in the logs. */
log("GenOLC: delete_object: Deleting object #%d (%s).", GET_OBJ_VNUM(obj), obj->short_description);
@ -443,7 +445,6 @@ int delete_object(obj_rnum rnum)
SHOP_PRODUCT(shop, j) -= (SHOP_PRODUCT(shop, j) > rnum);
/* Renumber zone table. */
int zone, cmd_no;
for (zone = 0; zone <= top_of_zone_table; zone++) {
for (cmd_no = 0; ZCMD(zone, cmd_no).command != 'S'; cmd_no++) {
switch (ZCMD(zone, cmd_no).command) {

View file

@ -189,6 +189,16 @@ int in_save_list(zone_vnum zone, int type)
return FALSE;
}
void free_save_list(void)
{
struct save_list_data *sld, *next_sld;
for (sld = save_list; sld; sld = next_sld) {
next_sld = sld->next;
free(sld);
}
}
/* Used from do_show(), ideally. */
ACMD(do_show_save_list)
{

View file

@ -27,8 +27,11 @@ zone_rnum real_zone_by_thing(room_vnum vznum)
bot = 0;
top = top_of_zone_table;
if (genolc_zone_bottom(bot) > vznum || zone_table[top].top < vznum)
return (NOWHERE);
/* perform binary search on zone-table */
for (;;) {
while (bot <= top) {
mid = (bot + top) / 2;
/* Upper/lower bounds of the zone. */
@ -37,13 +40,12 @@ zone_rnum real_zone_by_thing(room_vnum vznum)
if (low <= vznum && vznum <= high)
return mid;
if (bot >= top)
return NOWHERE;
if (low > vznum)
top = mid - 1;
else
bot = mid + 1;
}
return (NOWHERE);
}
zone_rnum create_new_zone(zone_vnum vzone_num, room_vnum bottom, room_vnum top, const char **error)

View file

@ -112,7 +112,7 @@ void hedit_setup_new(struct descriptor_data *d)
CREATE(OLC_HELP(d), struct help_index_element, 1);
OLC_HELP(d)->keywords = strdup(OLC_STORAGE(d));
OLC_HELP(d)->entry = strdup("This help file is unfinished.\r\n");
OLC_HELP(d)->entry = strdup("KEYWORDS\r\n\r\nThis help file is unfinished.\r\n");
OLC_HELP(d)->min_level = 0;
OLC_HELP(d)->duplicate = 0;
OLC_VAL(d) = 0;
@ -138,9 +138,9 @@ void hedit_save_internally(struct descriptor_data *d)
struct help_index_element *new_help_table = NULL;
if (OLC_ZNUM(d) > top_of_helpt) {
int i;
CREATE(new_help_table, struct help_index_element, top_of_helpt + 2);
int i;
for (i = 0; i <= top_of_helpt; i++)
new_help_table[i] = help_table[i];
new_help_table[++top_of_helpt] = *OLC_HELP(d);
@ -157,6 +157,7 @@ void hedit_save_to_disk(struct descriptor_data *d)
{
FILE *fp;
char buf1[MAX_STRING_LENGTH], index_name[READ_SIZE];
int i;
snprintf(index_name, sizeof(index_name), "%s%s", HLP_PREFIX, HELP_FILE);
if (!(fp = fopen(index_name, "w"))) {
@ -164,7 +165,6 @@ void hedit_save_to_disk(struct descriptor_data *d)
return;
}
int i;
for (i = 0; i <= top_of_helpt; i++) {
if (help_table[i].duplicate)
continue;
@ -192,13 +192,11 @@ void hedit_disp_menu(struct descriptor_data *d)
write_to_output(d,
"%s-- Help file editor\r\n"
"%s1%s) Keywords : %s%s\r\n"
"%s2%s) Entry :\r\n%s%s"
"%s3%s) Min Level : %s%d\r\n"
"%s1%s) Entry :\r\n%s%s"
"%s2%s) Min Level : %s%d\r\n"
"%sQ%s) Quit\r\n"
"Enter choice : ",
nrm,
grn, nrm, yel, OLC_HELP(d)->keywords,
grn, nrm, yel, OLC_HELP(d)->entry,
grn, nrm, yel, OLC_HELP(d)->min_level,
grn, nrm
@ -301,10 +299,6 @@ void hedit_parse(struct descriptor_data *d, char *arg)
}
break;
case '1':
write_to_output(d, "Enter keywords:-\r\n] ");
OLC_MODE(d) = HEDIT_KEYWORDS;
break;
case '2':
OLC_MODE(d) = HEDIT_ENTRY;
clear_screen(d);
send_editor_help(d);
@ -316,7 +310,7 @@ void hedit_parse(struct descriptor_data *d, char *arg)
string_write(d, &OLC_HELP(d)->entry, MAX_MESSAGE_LENGTH, 0, oldtext);
OLC_VAL(d) = 1;
break;
case '3':
case 'M':
write_to_output(d, "Enter min level : ");
OLC_MODE(d) = HEDIT_MIN_LEVEL;
break;

View file

@ -479,6 +479,7 @@ int format_text(char **ptr_string, int mode, struct descriptor_data *d, unsigned
int line_chars, cap_next = TRUE, cap_next_next = FALSE, color_chars = 0, i, pass_line = 0;
char *flow, *start = NULL, temp;
char formatted[MAX_STRING_LENGTH] = "";
char str[MAX_STRING_LENGTH];
/* Fix memory overrun. */
if (d->max_str > MAX_STRING_LENGTH) {
@ -490,7 +491,6 @@ int format_text(char **ptr_string, int mode, struct descriptor_data *d, unsigned
if ((flow = *ptr_string) == NULL)
return 0;
char str[MAX_STRING_LENGTH];
strcpy(str, flow);
for (i = 0; i < low - 1; i++) {

View file

@ -279,7 +279,7 @@ cpp_extern const struct command_info cmd_info[] = {
{ "close" , "cl" , POS_SITTING , do_gen_door , 0, SCMD_CLOSE },
{ "clear" , "cle" , POS_DEAD , do_gen_ps , 0, SCMD_CLEAR },
{ "cls" , "cls" , POS_DEAD , do_gen_ps , 0, SCMD_CLEAR },
{ "clsolc" , "clsolc" , POS_DEAD , do_gen_tog , 0, SCMD_CLS },
{ "clsolc" , "clsolc" , POS_DEAD , do_gen_tog , LVL_BUILDER, SCMD_CLS },
{ "consider" , "con" , POS_RESTING , do_consider , 0, 0 },
{ "commands" , "com" , POS_DEAD , do_commands , 0, SCMD_COMMANDS },
{ "compact" , "comp" , POS_DEAD , do_gen_tog , 0, SCMD_COMPACT },
@ -1193,8 +1193,10 @@ int perform_dupe_check(struct descriptor_data *d)
/* no target for switching into was found - allow login to continue */
if (!target) {
GET_PREF(d->character)= rand_number(1, 128000);
GET_HOST(d->character)= strdup(d->host);
GET_PREF(d->character) = rand_number(1, 128000);
if (GET_HOST(d->character))
free(GET_HOST(d->character));
GET_HOST(d->character) = strdup(d->host);
return 0;
}
@ -1340,7 +1342,7 @@ void nanny(struct descriptor_data *d, char *arg)
CREATE(d->character, struct char_data, 1);
clear_char(d->character);
CREATE(d->character->player_specials, struct player_special_data, 1);
GET_HOST(d->character) = strdup(d->host);
GET_HOST(d->character) = strdup(d->host);
d->character->desc = d;
}
if (!*arg)

View file

@ -263,7 +263,7 @@ char *read_delete(long recipient)
to = get_name_by_id(record_to_keep->recipient);
snprintf(buf, sizeof(buf),
" * * * * Midgaard Mail System * * * *\r\n"
" * * * * tbaMUD Mail System * * * *\r\n"
"Date: %s\r\n"
"To : %s\r\n"
"From: %s\r\n"

View file

@ -281,9 +281,9 @@ void medit_save_internally(struct descriptor_data *d)
/* Update keepers in shops being edited and other mobs being edited. */
for (dsc = descriptor_list; dsc; dsc = dsc->next) {
if (STATE(dsc) == CON_SEDIT)
S_KEEPER(OLC_SHOP(dsc)) += (S_KEEPER(OLC_SHOP(dsc)) >= new_rnum);
S_KEEPER(OLC_SHOP(dsc)) += (S_KEEPER(OLC_SHOP(dsc)) != NOTHING && S_KEEPER(OLC_SHOP(dsc)) >= new_rnum);
else if (STATE(dsc) == CON_MEDIT)
GET_MOB_RNUM(OLC_MOB(dsc)) += (GET_MOB_RNUM(OLC_MOB(dsc)) >= new_rnum);
GET_MOB_RNUM(OLC_MOB(dsc)) += (GET_MOB_RNUM(OLC_MOB(dsc)) != NOTHING && GET_MOB_RNUM(OLC_MOB(dsc)) >= new_rnum);
}
/* Update other people in zedit too. From: C.Raehl 4/27/99 */
@ -470,9 +470,14 @@ void medit_parse(struct descriptor_data *d, char *arg)
write_to_output(d, "Mobile saved to disk.\r\n");
} else
write_to_output(d, "Mobile saved to memory.\r\n");
/* FALL THROUGH */
cleanup_olc(d, CLEANUP_ALL);
return;
case 'n':
case 'N':
/* If not saving, we must free the script_proto list. We do so by
* assigning it to the edited mob and letting free_mobile in
* cleanup_olc handle it. */
OLC_MOB(d)->proto_script = OLC_SCRIPT(d);
cleanup_olc(d, CLEANUP_ALL);
return;
default:

View file

@ -152,6 +152,9 @@ void list_rooms(struct char_data *ch, zone_rnum rnum, room_vnum vmin, room_vnum
"Index VNum Room Name Exits\r\n"
"----- ------- ---------------------------------------- -----\r\n");
if (!top_of_world)
return;
for (i = 0; i <= top_of_world; i++) {
/** Check to see if this room is one of the ones needed to be listed. **/
@ -202,6 +205,9 @@ void list_mobiles(struct char_data *ch, zone_rnum rnum, mob_vnum vmin, mob_vnum
"Index VNum Mobile Name Level\r\n"
"----- ------- --------------------------------------------- -----\r\n");
if (!top_of_mobt)
return;
for (i = 0; i <= top_of_mobt; i++) {
if (mob_index[i].vnum >= bottom && mob_index[i].vnum <= top) {
counter++;
@ -238,6 +244,9 @@ void list_objects(struct char_data *ch, zone_rnum rnum, room_vnum vmin, room_vnu
"Index VNum Object Name Object Type\r\n"
"----- ------- -------------------------------------------- ----------------\r\n");
if (!top_of_objt)
return;
for (i = 0; i <= top_of_objt; i++) {
if (obj_index[i].vnum >= bottom && obj_index[i].vnum <= top) {
counter++;
@ -320,6 +329,9 @@ void list_zones(struct char_data *ch, zone_rnum rnum, zone_vnum vmin, zone_vnum
"VNum Zone Name Builder(s)\r\n"
"----- ------------------------------ --------------------------------------\r\n");
if (!top_of_zone_table)
return;
for (i = 0; i <= top_of_zone_table; i++) {
if (zone_table[i].number >= bottom && zone_table[i].number <= top) {
send_to_char(ch, "[%s%3d%s] %s%-*s %s%-1s%s\r\n",

View file

@ -711,10 +711,13 @@ void oedit_parse(struct descriptor_data *d, char *arg)
write_to_output(d, "Object saved to disk.\r\n");
} else
write_to_output(d, "Object saved to memory.\r\n");
/* Fall through. */
cleanup_olc(d, CLEANUP_ALL);
return;
case 'n':
case 'N':
/* If not saving, we must free the script_proto list. */
OLC_OBJ(d)->proto_script = OLC_SCRIPT(d);
free_proto_script(OLC_OBJ(d), OBJ_TRIGGER);
cleanup_olc(d, CLEANUP_ALL);
return;
case 'a': /* abort quit */

View file

@ -17,6 +17,7 @@
#include "pfdefaults.h"
#include "dg_scripts.h"
#include "comm.h"
#include "interpreter.h"
#define LOAD_HIT 0
#define LOAD_MANA 1
@ -258,7 +259,6 @@ int load_char(const char *name, struct char_data *ch)
GET_MOVE(ch) = PFDEF_MOVE;
GET_MAX_MOVE(ch) = PFDEF_MAXMOVE;
GET_OLC_ZONE(ch) = PFDEF_OLC;
GET_HOST(ch) = NULL;
GET_PAGE_LENGTH(ch) = PFDEF_PAGELENGTH;
GET_ALIASES(ch) = NULL;
SITTING(ch) = NULL;
@ -334,8 +334,12 @@ int load_char(const char *name, struct char_data *ch)
case 'H':
if (!strcmp(tag, "Hit ")) load_HMVS(ch, line, LOAD_HIT);
else if (!strcmp(tag, "Hite")) GET_HEIGHT(ch) = atoi(line);
else if (!strcmp(tag, "Host")) GET_HOST(ch) = strdup(line);
else if (!strcmp(tag, "Hrol")) GET_HITROLL(ch) = atoi(line);
else if (!strcmp(tag, "Host")) {
if (GET_HOST(ch))
free(GET_HOST(ch));
GET_HOST(ch) = strdup(line);
}
else if (!strcmp(tag, "Hrol")) GET_HITROLL(ch) = atoi(line);
else if (!strcmp(tag, "Hung")) GET_COND(ch, HUNGER) = atoi(line);
break;
@ -370,13 +374,22 @@ int load_char(const char *name, struct char_data *ch)
else if (!strcmp(tag, "Plyd")) ch->player.time.played = atoi(line);
else if (!strcmp(tag, "PfIn")) POOFIN(ch) = strdup(line);
else if (!strcmp(tag, "PfOt")) POOFOUT(ch) = strdup(line);
else if (!strcmp(tag, "Pref"))
sscanf(line, "%s %s %s %s", f1, f2, f3, f4);
PRF_FLAGS(ch)[0] = asciiflag_conv(f1);
PRF_FLAGS(ch)[1] = asciiflag_conv(f2);
PRF_FLAGS(ch)[2] = asciiflag_conv(f3);
PRF_FLAGS(ch)[3] = asciiflag_conv(f4);
break;
/* else if (!strcmp(tag, "Pref"))
sscanf(line, "%s %s %s %s", f1, f2, f3, f4);
PRF_FLAGS(ch)[0] = asciiflag_conv(f1);
PRF_FLAGS(ch)[1] = asciiflag_conv(f2);
PRF_FLAGS(ch)[2] = asciiflag_conv(f3);
PRF_FLAGS(ch)[3] = asciiflag_conv(f4);
*/
else if (!strcmp(tag, "Pref")) {
char *temp = line;
temp = one_argument(temp, line);
for (i = 0; *line && i < PR_ARRAY_MAX; i++) {
PRF_FLAGS(ch)[i] = asciiflag_conv(line);
temp = one_argument(temp, line);
}
}
break;
case 'Q':
if (!strcmp(tag, "Qstp")) GET_QUESTPOINTS(ch) = atoi(line);

View file

@ -483,12 +483,15 @@ void redit_parse(struct descriptor_data *d, char *arg)
write_to_output(d, "Room saved to disk.\r\n");
} else
write_to_output(d, "Room saved to memory.\r\n");
/* Do NOT free strings! Just the room structure. */
cleanup_olc(d, CLEANUP_STRUCTS);
/* Free everything. */
cleanup_olc(d, CLEANUP_ALL);
break;
case 'n':
case 'N':
/* Free everything up, including strings, etc. */
/* If not saving, we must free the script_proto list. We do so by
* assigning it to the edited room and letting free_room in
* cleanup_olc handle it. */
OLC_ROOM(d)->proto_script = OLC_SCRIPT(d);
cleanup_olc(d, CLEANUP_ALL);
break;
default:

View file

@ -5,8 +5,18 @@
* Version 2. Copyright 1996, 1998, 1999, 2000 Eric Murray. *
**************************************************************************/
/* local functions */
void zfree_special (int *, char *, int);
/*
** Zmalloc, a simple memory-allocation monitor.
**
** Copyright 1996,1998,1999,2000 Eric Murray, ericm@lne.com
** You may make free use of this code but please give me credit.
** Documentation: http://www.lne.com/ericm/zmalloc
*
* Usage: to enable call zmalloc_init() at the very start of your
* program to open the logfile and call zmalloc_check() at the end
* to display memory leaks and free all allocated mem.
* See the main() test function at the bottom for an example.
*/
/* protect our calloc() and free() calls from recursive redefinition: */
#define ZMALLOC_H
@ -14,8 +24,9 @@ void zfree_special (int *, char *, int);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/* #define NO_MEMORY_PADDING */
//#define NO_MEMORY_PADDING
#ifndef NO_MEMORY_PADDING
static unsigned char beginPad[4] = {
@ -25,238 +36,236 @@ static unsigned char endPad[4] = {
0xde, 0xad, 0xde, 0xad };
#endif
extern int errno;
FILE * zfd;
FILE *zfd = NULL;
typedef struct meminfo {
struct meminfo *next;
int size; /* number of bytes malloced */
long addr; /* address of memory returned */
unsigned char *addr; /* address of memory returned */
int frees; /* number of times that 'free' was called on this memory */
char *file; /* file where malloc was called */
int line; /* line in the code where malloc was called */
} meminfo;
static meminfo memlist;
/* -1 not checked yet, 0 = no zmalloc, 1 = zmalloc */
int zmallocstatus = -1;
static meminfo *memlist = NULL;
/*
* 0 = only end summary
* 1 = show errors
* 2 = errors with dumps
* 3 = all of the above plus all mallocs/frees
*/
int zmalloclogging = 2;
/* functions: */
int getzmallocstatus(void);
int * zmalloc(int len,char * file,int line);
void zfree_special(int * what, char * file,int line);
void zfree(int * what, char * file,int line);
unsigned char *zmalloc(int len, char *file, int line);
unsigned char *zrealloc(unsigned char *what, int len, char *file, int line);
void zdump(meminfo *m);
void zfree(unsigned char *what, char *file, int line);
char *zstrdup(const char *src, char *file, int line);
void zmalloc_check( void );
void zmalloc_init(void);
void zmalloc_check(void);
void pad_check(meminfo *m);
void zmalloc_free_list(meminfo *m);
/* a chopped down version that works */
int getzmallocstatus()
{
if (zmallocstatus == -1) {
zfd = fopen("test.log","w+");
zmallocstatus = 1;
}
return(zmallocstatus);
void zmalloc_init(void) {
zfd = fopen("zmalloc.log","w+");
}
int * zmalloc(int len,char * file,int line)
void zdump(meminfo *m)
{
unsigned char * ret;
#define MAX_ZDUMP_SIZE 32
const unsigned char *hextab = (unsigned char *)"0123456789ABCDEF";
unsigned char hexline[37], ascline[17], *hexp, *ascp, *inp;
int len, c = 1;
if (m->addr == NULL || m->size <= 0)
return;
hexp = hexline;
ascp = ascline;
inp = m->addr;
len = (m->size > MAX_ZDUMP_SIZE ? MAX_ZDUMP_SIZE : m->size);
for ( ; len > 0; len--, inp++, c++) {
*(hexp++) = hextab[(int) (*inp & 0xF0) >> 4]; /* high 4 bit */
*(hexp++) = hextab[(int) (*inp & 0x0F)]; /* low 4 bit */
if (c % 4 == 0) *(hexp++) = ' ';
*(ascp++) = isprint(*inp) ? *inp : '.';
if (c % 16 == 0 || len <= 1) {
*hexp = '\0';
*ascp = '\0';
fprintf(zfd, " %-40.40s%s\n", hexline, ascline);
hexp = hexline;
ascp = ascline;
}
}
fprintf(zfd, "\n");
}
unsigned char *zmalloc(int len, char *file, int line)
{
unsigned char *ret;
meminfo *m;
if (!zmallocstatus) {
/* zmalloc turned off */
ret = (unsigned char *)calloc(1,len);
return((int *)ret);
}
#ifndef NO_MEMORY_PADDING
ret = (unsigned char *)calloc(1,len + sizeof(beginPad) + sizeof(endPad));
ret = (unsigned char *) calloc(1, len + sizeof(beginPad) + sizeof(endPad));
#else
ret = (unsigned char *)calloc(1,len);
ret = (unsigned char *) calloc(1, len);
#endif
if (!ret)
if (!ret) {
fprintf(zfd,"zmalloc: malloc FAILED");
return NULL;
}
#ifndef NO_MEMORY_PADDING
/* insert begin and end padding to detect buffer under/overruns: */
memcpy(ret,beginPad,sizeof(beginPad));
memcpy(ret, beginPad, sizeof(beginPad));
ret += sizeof(beginPad); /* make ret skip begin pad */
memcpy(ret + len,endPad,sizeof(endPad));
memcpy(ret + len, endPad, sizeof(endPad));
#endif
if (getzmallocstatus() > 1)
if (zmalloclogging > 2)
fprintf(zfd,"zmalloc: 0x%4.4x %d bytes %s:%d\n",(int)ret,len,file,line);
m = (meminfo *)calloc(1,sizeof(meminfo));
m = (meminfo *) calloc(1, sizeof(meminfo));
if (!m) {
fprintf(zfd,"zmalloc: FAILED mem alloc for zmalloc struct... bailing!\n");
return((int*)0);
return NULL;
}
m->next = &memlist;
m->addr = (long)ret;
m->size = (int)len;
m->file = (char *)strdup(file);
m->addr = ret;
m->size = len;
m->frees = 0;
m->file = strdup(file);
if (!m->file) {
fprintf(zfd,"zmalloc: FAILED mem alloc for zmalloc struct... bailing!\n");
return((int*)0);
free(m);
return NULL;
}
m->line = line;
return((int *)ret);
m->next = memlist;
memlist = m;
return (ret);
}
void zfree_special(int * what, char * file,int line)
unsigned char *zrealloc(unsigned char *what, int len, char *file, int line)
{
meminfo *m, *old;
unsigned char *addr;
int gotit = 0;
unsigned char *ret;
meminfo *m;
if (what == 0) {
fprintf(zfd,"zmalloc: Null pointer free'd: %s:%d\n", file, line);
return;
}
if (what) {
for (m = memlist; m; m = m->next) {
if (m->addr == what) {
#ifndef NO_MEMORY_PADDING
ret = (unsigned char *) realloc(what - sizeof(beginPad), len + sizeof(beginPad) + sizeof(endPad));
#else
ret = (unsigned char *) realloc(what, len);
#endif
if (!ret) {
fprintf(zfd,"zrealloc: FAILED for 0x%4.4x %d bytes mallocd at %s:%d,\n"
" %d bytes reallocd at %s:%d.\n",
(int)m->addr, m->size, m->file, m->line, len, file, line);
if (zmalloclogging > 1) zdump(m);
return NULL;
}
#ifndef NO_MEMORY_PADDING
/* insert begin and end padding to detect buffer under/overruns: */
memcpy(ret, beginPad, sizeof(beginPad));
ret += sizeof(beginPad); /* make ret skip begin pad */
memcpy(ret + len, endPad, sizeof(endPad));
#endif
if (zmalloclogging > 2)
fprintf(zfd,"zrealloc: 0x%4.4x %d bytes mallocd at %s:%d, %d bytes reallocd at %s:%d.\n",
(int)m->addr, m->size, m->file, m->line, len, file, line);
if (!getzmallocstatus()) {
free(what);
} else {
/* look up allocated mem in list: */
old = m = &memlist;
if (m == (meminfo *)0) {
/* no memlist */
free(what);
} else {
for(; m ; m = m->next) {
if (m->addr == (long)what) {
/* got it. Print it if verbose: */
addr = (unsigned char *)m->addr;
fprintf(zfd,"zmalloc: Freed 0x%4.4x %d bytes mallocd@%s:%d\n",
(int)addr,m->size,m->file,m->line);
fprintf(zfd," free'd from %s:%d\n",
file, line);
/* check the padding: */
pad_check(m);
/* note that we freed the memory */
m->frees++;
/* check to see if it was freed > once */
if (m->frees > 1) {
fprintf(zfd," ERR: multiple frees! 0x%4.4x %d bytes: %s:%d\n",
(int)addr, m->size, m->file, m->line);
fprintf(zfd," free'd from %s:%d\n",
file, line);
}
gotit++;
if (!m)
break;
}
}
if (!gotit && m) {
fprintf(zfd,"zmalloc: ERR: Freed unallocated memory");
fprintf(zfd," @0x%4.4x %d bytes %s:%d\n",
(int)what,m->size,m->file,m->line);
}
else if (gotit > 1) {
/* this shouldn't happen, eh? */
fprintf(zfd," ERR: Multiply-allocd memory!\n");
m->addr = ret;
m->size = len;
if (m->file) free(m->file);
m->file = strdup(file);
m->line = line;
/* could continue the loop to check for multiply-allocd memory */
/* but that's highly improbable so lets just return instead. */
return (ret);
}
}
}
/* NULL or invalid pointer given */
fprintf(zfd,"zrealloc: invalid pointer 0x%4.4x, %d bytes to realloc at %s:%d.\n",
(int)what, len, file, line);
return (zmalloc(len, file, line));
}
void zfree(int * what, char * file,int line)
/* doesn't actually free memory */
void zfree(unsigned char *what, char *file, int line)
{
meminfo *m, *old;
unsigned char *addr;
meminfo *m;
int gotit = 0;
if (what == 0) {
fprintf(zfd,"zmalloc: Null pointer free'd: %s:%d\n", file, line);
if (!what) {
fprintf(zfd,"zfree: ERR: Null pointer free'd: %s:%d.\n", file, line);
return;
}
if (!getzmallocstatus()) {
free(what);
} else {
/* look up allocated mem in list: */
old = m = &memlist;
if (m == (meminfo *)0) {
/* no memlist */
free(what);
} else {
for(; m ; m = m->next) {
if (m->addr == (long)what) {
/* got it. Print it if verbose: */
addr = (unsigned char *)m->addr;
if (getzmallocstatus() > 1)
fprintf(zfd,"zmalloc: Freed 0x%4.4x %d bytes mallocd@%s:%d\n",
(int)addr,m->size,m->file,m->line);
/* check the padding: */
pad_check(m);
/* note that we freed the memory */
m->frees++;
/* check to see if it was freed > once */
if (m->frees > 1) {
fprintf(zfd," ERR: multiple frees! 0x%4.4x %d bytes: %s:%d\n",
(int)addr, m->size, m->file, m->line);
fprintf(zfd," free'd from %s:%d\n",
file, line);
}
gotit++;
if (!m)
break;
}
/* look up allocated mem in list: */
for (m = memlist; m; m = m->next) {
if (m->addr == what) {
/* got it. Print it if verbose: */
if (zmalloclogging > 2) {
fprintf(zfd,"zfree: Freed 0x%4.4x %d bytes mallocd at %s:%d, freed at %s:%d\n",
(int)m->addr, m->size, m->file, m->line, file, line);
}
if (!gotit && m) {
fprintf(zfd,"zmalloc: ERR: Freed unallocated memory");
fprintf(zfd," @0x%4.4x %d bytes %s:%d\n",
(int)what,m->size,m->file,m->line);
}
else if (gotit > 1) {
/* this shouldn't happen, eh? */
fprintf(zfd," ERR: Multiply-allocd memory!\n");
/* check the padding: */
pad_check(m);
/* note that we freed the memory */
m->frees++;
/* check to see if it was freed > once */
if (m->frees > 1) {
fprintf(zfd,"zfree: ERR: multiple frees! 0x%4.4x %d bytes\n"
" mallocd at %s:%d, freed at %s:%d.\n",
(int)m->addr, m->size, m->file, m->line, file, line);
if (zmalloclogging > 1) zdump(m);
}
gotit++;
}
} /* for.. */
if (!gotit) {
fprintf(zfd,"zfree: ERR: attempt to free unallocated memory 0x%4.4x at %s:%d.\n",
(int)what, file, line);
}
if (gotit > 1) {
/* this shouldn't happen, eh? */
fprintf(zfd,"zfree: ERR: Multiply-allocd memory 0x%4.4x.\n", (int)what);
}
}
/* zstrdup */
char *zstrdup(const char *src, char *file, int line)
{
char *result;
#ifndef NO_MEMORY_STRDUP
if (!getzmallocstatus()) {
result = (char*)malloc(strlen(src) + 1);
if (result == (char*)0)
return (char*)0;
strcpy(result, src); /* strcpy ok, size checked above */
return result;
} else {
result = (char*)zmalloc(strlen(src) + 1, file, line);
if (result == (char*)0)
return (char*)0;
strcpy(result, src);
return result;
}
char *result;
#ifndef NO_MEMORY_STRDUP
result = (char*)zmalloc(strlen(src) + 1, file, line);
if (!result)
return NULL;
strcpy(result, src);
return result;
#else
result = (char*)malloc(strlen(src) + 1);
if (result == (char*)0)
return (char*)0;
strcpy(result, src); /* strcpy ok, size checked above */
return result;
result = (char*)malloc(strlen(src) + 1);
if (!result)
return NULL;
strcpy(result, src); /* strcpy ok, size checked above */
return result;
#endif
}
void zmalloc_check()
{
meminfo *m;
@ -264,124 +273,124 @@ void zmalloc_check()
int total_leak = 0;
int num_leaks = 0;
if (getzmallocstatus() > 0) {
/* look up allocated mem in list: */
for(m = &memlist; m ; m = m->next) {
if (m->addr != 0 && m->frees <= 0) {
fprintf(zfd,"zmalloc: UNfreed memory 0x%4.4x %d bytes mallocd at %s:%d\n",
(int)m->addr,m->size,m->file,m->line);
fprintf(zfd, "\n------------ Checking leaks ------------\n\n");
/* look up allocated mem in list: */
for(m = memlist; m; m = m->next) {
if (m->addr != 0 && m->frees <= 0) {
fprintf(zfd,"zmalloc: UNfreed memory 0x%4.4x %d bytes mallocd at %s:%d\n",
(int)m->addr, m->size, m->file, m->line);
if (zmalloclogging > 1) zdump(m);
/* check padding on un-freed memory too: */
pad_check(m);
/* check padding on un-freed memory too: */
pad_check(m);
total_leak += m->size;
num_leaks ++;
}
}
if (total_leak) {
if (total_leak > 10000)
admonishemnt = "you must work for Microsoft.";
else if (total_leak > 5000)
admonishemnt = "you should be ashamed!";
else if (total_leak > 2000)
admonishemnt = "you call yourself a programmer?";
else if (total_leak > 1000)
admonishemnt = "the X consortium has a job for you...";
else
admonishemnt = "close, but not there yet.";
fprintf(zfd,"zmalloc: %d leaks totalling %d bytes... %s\n",num_leaks,total_leak,
admonishemnt);
}
else {
fprintf(zfd,"zmalloc: Congratulations: leak-free code!\n");
total_leak += m->size;
num_leaks++;
}
}
if (total_leak) {
if (total_leak > 10000)
admonishemnt = "you must work for Microsoft.";
else if (total_leak > 5000)
admonishemnt = "you should be ashamed!";
else if (total_leak > 2000)
admonishemnt = "you call yourself a programmer?";
else if (total_leak > 1000)
admonishemnt = "the X consortium has a job for you...";
else
admonishemnt = "close, but not there yet.";
fprintf(zfd,"zmalloc: %d leaks totalling %d bytes... %s\n",
num_leaks, total_leak, admonishemnt);
}
else {
fprintf(zfd,"zmalloc: Congratulations: leak-free code!\n");
}
/* free up our own internal list */
zmalloc_free_list(&memlist);
zmalloc_free_list(memlist);
if (zfd) {
fflush(zfd);
fclose(zfd);
}
}
void pad_check(meminfo *m)
{
#ifndef NO_MEMORY_PADDING
unsigned char *addr = (unsigned char *)m->addr;
/* check the padding: */
if (memcmp((int *)(addr - sizeof(beginPad)),
beginPad, sizeof(beginPad)) != 0)
fprintf(zfd," ERR: beginPad was modified!\n");
if (memcmp((int *)(addr + m->size),endPad,
sizeof(endPad)) != 0)
fprintf(zfd," ERR: endPad was modified!\n");
if (memcmp(m->addr - sizeof(beginPad), beginPad, sizeof(beginPad)) != 0) {
fprintf(zfd,"pad_check: ERR: beginPad was modified! (mallocd@ %s:%d)\n", m->file, m->line);
if (zmalloclogging > 1) zdump(m);
}
if (memcmp(m->addr + m->size, endPad, sizeof(endPad)) != 0) {
fprintf(zfd,"pad_check: ERR: endPad was modified! (mallocd@ %s:%d)\n", m->file, m->line);
if (zmalloclogging > 1) zdump(m);
}
#endif
}
void zmalloc_free_list(meminfo *m)
{
meminfo *old;
for( m = m->next ; m ; ) {
old = m;
m = m->next;
free(old->file);
free(old);
meminfo *next_m;
for (; m; m = next_m) {
next_m = m->next;
#ifndef NO_MEMORY_PADDING
if (m->addr) free(m->addr - sizeof(beginPad));
#else
if (m->addr) free(m->addr);
#endif
if (m->file) free(m->file);
free(m);
}
}
#ifdef ZTEST
#undef ZMALLOC_H
#include "zmalloc.h"
main()
int main()
{
unsigned char * tmp;
unsigned char * shit;
zmalloc_init();
printf("Testing Zmalloc.\n");
printf("Malloc test..");
printf("You should see no error here.\n");
tmp = (unsigned char*)malloc(200);
free(tmp);
/* You should see no error here. */
shit = (unsigned char*)malloc(200);
free(shit);
printf("Free free mem test...\n");
printf("You should see an ERR: multiple frees here\n");
tmp = (unsigned char*)malloc(200);
free(tmp);
free(tmp);
/* Multiple frees test */
shit = (unsigned char*)malloc(200);
strcpy(shit, "This should show up in the dump but truncated to MAX_ZDUMP_SIZE chars");
free(shit);
free(shit);
/*
fprintf(zfd,"\nFree unallocated mem test \n");
tmp += 4;
free(tmp);
*/
/* Free unallocated mem test */
shit += 4;
free(shit);
printf("Unfreed mem test...\n");
printf("You should see an \"UNfreed mem at line %d\" (at end) because of this\n",__LINE__+1);
tmp = (unsigned char*)malloc(200);
/* Unfreed mem test... You should see "UNfreed mem at line 370" (at end) because of this */
shit = (unsigned char*)malloc(200);
strcpy(shit, "This is unfreed memory!");
printf("Buffer overrun test 1...\n");
printf("You should see an ERR:endPad here\n");
tmp = (unsigned char*)malloc(200);
tmp[200] = 0xfa;
free(tmp);
/* Buffer overrun test... You should see an ERR:endPad here */
shit = (unsigned char*)malloc(200);
shit[202] = 0xbb;
free(shit);
printf("Buffer overrun test 2...\n");
printf("You should see an ERR:endPad here\n");
tmp = (unsigned char*)malloc(200);
tmp[215] = 0xbb;
free(tmp);
/* Buffer underrun test... You should see an ERR:beginPad here */
shit = (unsigned char*)malloc(200);
shit[-3] = 0x0f;
free(shit);
printf("Buffer underrun test 1...\n");
printf("You should see an ERR:beginPad here\n");
tmp = (unsigned char*)malloc(200);
tmp[-10] = 0x0f;
free(tmp);
printf("Buffer underrun test 2...\n");
printf("You should see an ERR:beginPad here\n");
tmp = (unsigned char*)malloc(200);
tmp[-1] = 0x00;
free(tmp);
/* Free NULL pointer test... */
shit = NULL;
free(shit);
printf("Test completed. See zmalloc.log for the messages.\n");
zmalloc_check();
exit(0);

View file

@ -1,22 +1,32 @@
/**************************************************************************
* File: zmalloc.h Part of tbaMUD *
* Usage: A simple memory allocation monitor, header. *
* *
* Version 1.1 Copyright 1996, 1998, 1999, 2000 Eric Murray. *
* File: zmalloc.h Part of tbaMUD *
* Usage: A simple memory allocation monitor, header. *
* *
* Version 1.1 Copyright 1996, 1998, 1999, 2000 Eric Murray. *
**************************************************************************/
/*
** Zmalloc, a simple memory-allocation monitor.
**
** Copyright 1996 Eric Murray, ericm@lne.com
** You may make free use of this code but please give me credit.
** Documentation: http://www.lne.com/ericm/zmalloc
*/
#ifndef ZMALLOC_H
#define ZMALLOC_H
int *zmalloc(int, char *, int);
void zfree(int *, char *, int);
int zmalloc_check();
char *zstrdup(const char*, char*, int);
unsigned char *zmalloc(int, char *, int);
unsigned char *zrealloc(unsigned char *, int, char *, int);
void zfree(unsigned char *, char *, int);
void zmalloc_init(void);
void zmalloc_check(void);
char *zstrdup(const char *, char *, int);
#define malloc(x) zmalloc((x),__FILE__,__LINE__)
#define calloc(n,x) zmalloc((n*x),__FILE__,__LINE__)
#define free(x) zfree((int *)(x),__FILE__,__LINE__)
#undef strdup
#define strdup(x) zstrdup((x), __FILE__, __LINE__)
#define malloc(x) zmalloc((x),__FILE__,__LINE__)
#define calloc(n,x) zmalloc((n*x),__FILE__,__LINE__)
#define realloc(r,x) zrealloc((unsigned char *)(r),(x),__FILE__,__LINE__)
#define free(x) zfree((unsigned char *)(x),__FILE__,__LINE__)
#undef strdup
#define strdup(x) zstrdup((x), __FILE__, __LINE__)
#endif /* ZMALLOC_H */