From 1c987590202c8ca8dec65a88afd1d73328d55b39 Mon Sep 17 00:00:00 2001 From: dholland Date: Thu, 27 Dec 2007 23:52:59 +0000 Subject: Comprehensive (or at least extensive) string handling cleanup for rogue. This patch dates (mostly) back to 2002; the critical parts of it were handled back then by security-officer. As far as I know, there's nothing exploitable fixed herein. A slightly earlier version of this patch was reviewed by Christian Biere when I filed it as PR 34750. --- rogue/hit.c | 58 ++++--- rogue/init.c | 13 +- rogue/inventory.c | 427 ++++++++++++++++++++++++++++++--------------------- rogue/level.c | 24 ++- rogue/machdep.c | 29 ++-- rogue/message.c | 89 +++++------ rogue/monster.c | 8 +- rogue/move.c | 46 +++--- rogue/object.c | 116 +++++++------- rogue/pack.c | 96 ++++++------ rogue/play.c | 22 +-- rogue/ring.c | 46 +++--- rogue/rogue.h | 13 +- rogue/room.c | 21 ++- rogue/save.c | 28 ++-- rogue/score.c | 451 ++++++++++++++++++++++++++++++++---------------------- rogue/spec_hit.c | 38 ++--- rogue/throw.c | 22 ++- rogue/trap.c | 23 +-- rogue/use.c | 123 +++++++-------- rogue/zap.c | 47 +++--- 21 files changed, 953 insertions(+), 787 deletions(-) (limited to 'rogue') diff --git a/rogue/hit.c b/rogue/hit.c index 33db6447..6bc74437 100644 --- a/rogue/hit.c +++ b/rogue/hit.c @@ -1,4 +1,4 @@ -/* $NetBSD: hit.c,v 1.7 2003/08/07 09:37:37 agc Exp $ */ +/* $NetBSD: hit.c,v 1.8 2007/12/27 23:52:59 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)hit.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: hit.c,v 1.7 2003/08/07 09:37:37 agc Exp $"); +__RCSID("$NetBSD: hit.c,v 1.8 2007/12/27 23:52:59 dholland Exp $"); #endif #endif /* not lint */ @@ -56,7 +56,7 @@ __RCSID("$NetBSD: hit.c,v 1.7 2003/08/07 09:37:37 agc Exp $"); #include "rogue.h" object *fight_monster = 0; -char hit_message[80] = ""; +char hit_message[HIT_MESSAGE_SIZE] = ""; void mon_hit(monster) @@ -86,16 +86,13 @@ mon_hit(monster) if (!rand_percent(hit_chance)) { if (!fight_monster) { - sprintf(hit_message + strlen(hit_message), - "the %s misses", mn); - message(hit_message, 1); + messagef(1, "%sthe %s misses", hit_message, mn); hit_message[0] = 0; } return; } if (!fight_monster) { - sprintf(hit_message + strlen(hit_message), "the %s hit", mn); - message(hit_message, 1); + messagef(1, "%sthe %s hit", hit_message, mn); hit_message[0] = 0; } if (!(monster->m_flags & STATIONARY)) { @@ -139,7 +136,8 @@ rogue_hit(monster, force_hit) } if (!rand_percent(hit_chance)) { if (!fight_monster) { - (void) strcpy(hit_message, "you miss "); + (void) strlcpy(hit_message, "you miss ", + sizeof(hit_message)); } goto RET; } @@ -152,7 +150,8 @@ rogue_hit(monster, force_hit) } if (mon_damage(monster, damage)) { /* still alive? */ if (!fight_monster) { - (void) strcpy(hit_message, "you hit "); + (void) strlcpy(hit_message, "you hit ", + sizeof(hit_message)); } } RET: check_gold_seeker(monster); @@ -186,9 +185,20 @@ get_damage(ds, r) while (ds[i]) { n = get_number(ds+i); - while (ds[i++] != 'd') ; + while ((ds[i] != 'd') && ds[i]) { + i++; + } + if (ds[i] == 'd') { + i++; + } + d = get_number(ds+i); - while ((ds[i] != '/') && ds[i]) i++; + while ((ds[i] != '/') && ds[i]) { + i++; + } + if (ds[i] == '/') { + i++; + } for (j = 0; j < n; j++) { if (r) { @@ -197,9 +207,6 @@ get_damage(ds, r) total += d; } } - if (ds[i] == '/') { - i++; - } } return(total); } @@ -208,7 +215,7 @@ int get_w_damage(obj) const object *obj; { - char new_damage[12]; + char new_damage[32]; int tmp_to_hit, tmp_damage; int i = 0; @@ -216,10 +223,16 @@ get_w_damage(obj) return(-1); } tmp_to_hit = get_number(obj->damage) + obj->hit_enchant; - while (obj->damage[i++] != 'd') ; + while ((obj->damage[i] != 'd') && obj->damage[i]) { + i++; + } + if (obj->damage[i] == 'd') { + i++; + } tmp_damage = get_number(obj->damage + i) + obj->d_enchant; - sprintf(new_damage, "%dd%d", tmp_to_hit, tmp_damage); + snprintf(new_damage, sizeof(new_damage), "%dd%d", + tmp_to_hit, tmp_damage); return(get_damage(new_damage, 1)); } @@ -312,8 +325,7 @@ mon_damage(monster, damage) fight_monster = 0; cough_up(monster); mn = mon_name(monster); - sprintf(hit_message+strlen(hit_message), "defeated the %s", mn); - message(hit_message, 1); + messagef(1, "%sdefeated the %s", hit_message, mn); hit_message[0] = 0; add_exp(monster->kill_exp, 1); take_from_pack(monster, &level_monsters); @@ -341,7 +353,7 @@ fight(to_the_death) while (!is_direction(ch = rgetchar(), &d)) { sound_bell(); if (first_miss) { - message("direction?", 0); + messagef(0, "direction?"); first_miss = 0; } } @@ -355,7 +367,7 @@ fight(to_the_death) c = mvinch(row, col); if (((c < 'A') || (c > 'Z')) || (!can_move(rogue.row, rogue.col, row, col))) { - message("I see no monster there", 0); + messagef(0, "I see no monster there"); return; } if (!(fight_monster = object_at(&level_monsters, row, col))) { @@ -465,7 +477,7 @@ s_con_mon(monster) if (con_mon) { monster->m_flags |= CONFUSED; monster->moves_confused += get_rand(12, 22); - message("the monster appears confused", 0); + messagef(0, "the monster appears confused"); con_mon = 0; } } diff --git a/rogue/init.c b/rogue/init.c index e50769f5..51a09752 100644 --- a/rogue/init.c +++ b/rogue/init.c @@ -1,4 +1,4 @@ -/* $NetBSD: init.c,v 1.14 2007/12/15 19:44:43 perry Exp $ */ +/* $NetBSD: init.c,v 1.15 2007/12/27 23:53:00 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)init.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: init.c,v 1.14 2007/12/15 19:44:43 perry Exp $"); +__RCSID("$NetBSD: init.c,v 1.15 2007/12/27 23:53:00 dholland Exp $"); #endif #endif /* not lint */ @@ -96,7 +96,8 @@ init(argc, argv) if ((!pn) || (strlen(pn) >= MAX_OPT_LEN)) { clean_up("Hey! Who are you?"); } - (void) strcpy(login_name, pn); + /* LOGIN_NAME_SIZE == MAX_OPT_LEN now, but just in case... */ + (void) strlcpy(login_name, pn, sizeof(login_name)); do_args(argc, argv); do_opts(); @@ -238,7 +239,7 @@ onintr(dummy) did_int = 1; } else { check_message(); - message("interrupt", 1); + messagef(1, "interrupt"); } md_heed_signals(); } @@ -341,6 +342,7 @@ env_get_value(s, e, add_blank) break; } } + /* note: edit_opts() in room.c depends on this being the right size */ *s = md_malloc(MAX_OPT_LEN + 2); if (*s == NULL) clean_up("out of memory"); @@ -357,9 +359,10 @@ init_str(str, dflt) const char *dflt; { if (!(*str)) { + /* note: edit_opts() in room.c depends on this size */ *str = md_malloc(MAX_OPT_LEN + 2); if (*str == NULL) clean_up("out of memory"); - (void) strcpy(*str, dflt); + (void) strlcpy(*str, dflt, MAX_OPT_LEN + 2); } } diff --git a/rogue/inventory.c b/rogue/inventory.c index 1439de99..0fcfe85f 100644 --- a/rogue/inventory.c +++ b/rogue/inventory.c @@ -1,4 +1,4 @@ -/* $NetBSD: inventory.c,v 1.10 2006/05/14 03:15:50 christos Exp $ */ +/* $NetBSD: inventory.c,v 1.11 2007/12/27 23:53:00 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)inventory.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: inventory.c,v 1.10 2006/05/14 03:15:50 christos Exp $"); +__RCSID("$NetBSD: inventory.c,v 1.11 2007/12/27 23:53:00 dholland Exp $"); #endif #endif /* not lint */ @@ -53,6 +53,7 @@ __RCSID("$NetBSD: inventory.c,v 1.10 2006/05/14 03:15:50 christos Exp $"); * */ +#include #include "rogue.h" boolean is_wood[WANDS]; @@ -216,43 +217,56 @@ inventory(pack, mask) unsigned short mask; { object *obj; - short i = 0, j, maxlen = 0, n; - char descs[MAX_PACK_COUNT+1][DCOLS]; + short i = 0, j; + size_t maxlen = 0, n; short row, col; + struct { + short letter; + short sepchar; + char desc[DCOLS]; + char savebuf[DCOLS+8]; + } descs[MAX_PACK_COUNT+1]; + + obj = pack->next_object; if (!obj) { - message("your pack is empty", 0); + messagef(0, "your pack is empty"); return; } while (obj) { if (obj->what_is & mask) { - descs[i][0] = ' '; - descs[i][1] = obj->ichar; - descs[i][2] = ((obj->what_is & ARMOR) && obj->is_protected) + descs[i].letter = obj->ichar; + descs[i].sepchar = ((obj->what_is & ARMOR) && obj->is_protected) ? '}' : ')'; - descs[i][3] = ' '; - get_desc(obj, descs[i]+4); - if ((n = strlen(descs[i])) > maxlen) { + get_desc(obj, descs[i].desc, sizeof(descs[i].desc)); + n = strlen(descs[i].desc) + 4; + if (n > maxlen) { maxlen = n; } - i++; + i++; + /*assert(i<=MAX_PACK_COUNT);*/ } obj = obj->next_object; } - (void) strcpy(descs[i++], press_space); if (maxlen < 27) maxlen = 27; + if (maxlen > DCOLS-2) maxlen = DCOLS-2; col = DCOLS - (maxlen + 2); - for (row = 0; ((row < i) && (row < DROWS)); row++) { - if (row > 0) { - for (j = col; j < DCOLS; j++) { - descs[row-1][j-col] = mvinch(row, j); - } - descs[row-1][j-col] = 0; + for (row = 0; ((row <= i) && (row < DROWS)); row++) { + for (j = col; j < DCOLS; j++) { + descs[row].savebuf[j-col] = mvinch(row, j); + } + descs[row].savebuf[j-col] = 0; + if (row < i) { + mvprintw(row, col, " %c%c %s", + descs[row].letter, descs[row].sepchar, + descs[row].desc); + } + else { + mvaddstr(row, col, press_space); } - mvaddstr(row, col, descs[row]); clrtoeol(); } refresh(); @@ -261,8 +275,8 @@ inventory(pack, mask) move(0, 0); clrtoeol(); - for (j = 1; ((j < i) && (j < DROWS)); j++) { - mvaddstr(j, col, descs[j-1]); + for (j = 1; ((j <= i) && (j < DROWS)); j++) { + mvaddstr(j, col, descs[j].savebuf); } } @@ -274,7 +288,7 @@ id_com() while (ch != CANCEL) { check_message(); - message("Character you want help for (* for all):", 0); + messagef(0, "Character you want help for (* for all):"); refresh(); ch = getchar(); @@ -334,7 +348,7 @@ MORE: if (!pr_com_id(ch)) { if (!pr_motion_char(ch)) { check_message(); - message("unknown character", 0); + messagef(0, "unknown character"); } } ch = CANCEL; @@ -353,7 +367,7 @@ pr_com_id(ch) return(0); } check_message(); - message(com_id_tab[i].com_desc, 0); + messagef(0, "%s", com_id_tab[i].com_desc); return(1); } @@ -393,20 +407,18 @@ pr_motion_char(ch) (ch == '\031') || (ch == '\016') || (ch == '\002')) { - char until[18], buf[DCOLS]; + const char *until; int n = 0; /* XXX: GCC */ - if (ch <= '\031') { ch += 96; - (void) strcpy(until, "until adjascent"); + until = " until adjacent"; } else { ch += 32; - until[0] = '\0'; + until = ""; } (void) get_com_id(&n, ch); - sprintf(buf, "run %s %s", com_id_tab[n].com_desc + 8, until); check_message(); - message(buf, 0); + messagef(0, "run %s%s", com_id_tab[n].com_desc + 8, until); return(1); } else { return(0); @@ -422,9 +434,10 @@ mix_colors() for (i = 0; i <= 32; i++) { j = get_rand(0, (POTIONS - 1)); k = get_rand(0, (POTIONS - 1)); - memcpy(t, id_potions[j].title, MAX_ID_TITLE_LEN); - memcpy(id_potions[j].title, id_potions[k].title, MAX_ID_TITLE_LEN); - memcpy(id_potions[k].title, t, MAX_ID_TITLE_LEN); + strlcpy(t, id_potions[j].title, sizeof(t)); + strlcpy(id_potions[j].title, id_potions[k].title, + sizeof(id_potions[j].title)); + strlcpy(id_potions[k].title, t, sizeof(id_potions[k].title)); } } @@ -433,181 +446,246 @@ make_scroll_titles() { short i, j, n; short sylls, s; + size_t maxlen = sizeof(id_scrolls[0].title); for (i = 0; i < SCROLS; i++) { sylls = get_rand(2, 5); - (void) strcpy(id_scrolls[i].title, "'"); + (void) strlcpy(id_scrolls[i].title, "'", maxlen); for (j = 0; j < sylls; j++) { s = get_rand(1, (MAXSYLLABLES-1)); - (void) strcat(id_scrolls[i].title, syllables[s]); + (void) strlcat(id_scrolls[i].title, syllables[s], + maxlen); } + /* trim trailing space */ n = strlen(id_scrolls[i].title); - (void) strcpy(id_scrolls[i].title+(n-1), "' "); + id_scrolls[i].title[n-1] = 0; + + (void) strlcat(id_scrolls[i].title, "' ", maxlen); + } +} + +struct sbuf { + char *buf; + size_t maxlen; +}; + +static void sbuf_init __P((struct sbuf *s, char *buf, size_t maxlen)); +static void sbuf_addstr __P((struct sbuf *s, const char *str)); +static void sbuf_addf __P((struct sbuf *s, const char *fmt, ...)); +static void desc_count __P((struct sbuf *s, int n)); +static void desc_called __P((struct sbuf *s, const object *)); + +static +void +sbuf_init(s, buf, maxlen) + struct sbuf *s; + char *buf; + size_t maxlen; +{ + s->buf = buf; + s->maxlen = maxlen; + /*assert(maxlen>0);*/ + s->buf[0] = 0; +} + +static +void +sbuf_addstr(s, str) + struct sbuf *s; + const char *str; +{ + strlcat(s->buf, str, s->maxlen); +} + +static void sbuf_addf(struct sbuf *s, const char *fmt, ...) + __attribute__((__format__(__printf__, 2, 3))); + +static +void +sbuf_addf(struct sbuf *s, const char *fmt, ...) +{ + va_list ap; + size_t initlen; + + initlen = strlen(s->buf); + va_start(ap, fmt); + vsnprintf(s->buf+initlen, s->maxlen-initlen, fmt, ap); + va_end(ap); +} + +static +void +desc_count(s, n) + struct sbuf *s; + int n; +{ + if (n == 1) { + sbuf_addstr(s, "an "); + } else { + sbuf_addf(s, "%d ", n); } } +static +void +desc_called(s, obj) + struct sbuf *s; + const object *obj; +{ + struct id *id_table; + + id_table = get_id_table(obj); + sbuf_addstr(s, name_of(obj)); + sbuf_addstr(s, "called "); + sbuf_addstr(s, id_table[obj->which_kind].title); +} + void -get_desc(obj, desc) +get_desc(obj, desc, desclen) const object *obj; char *desc; + size_t desclen; { const char *item_name; struct id *id_table; - char more_info[32]; - short i; + struct sbuf db; + unsigned short objtype_id_status; if (obj->what_is == AMULET) { - (void) strcpy(desc, "the amulet of Yendor "); + (void) strlcpy(desc, "the amulet of Yendor ", desclen); return; } - item_name = name_of(obj); if (obj->what_is == GOLD) { - sprintf(desc, "%d pieces of gold", obj->quantity); + snprintf(desc, desclen, "%d pieces of gold", obj->quantity); return; } - if (obj->what_is != ARMOR) { - if (obj->quantity == 1) { - (void) strcpy(desc, "a "); - } else { - sprintf(desc, "%d ", obj->quantity); + item_name = name_of(obj); + id_table = get_id_table(obj); + if (wizard || id_table == NULL) { + objtype_id_status = IDENTIFIED; + } + else { + objtype_id_status = id_table[obj->which_kind].id_status; + } + if (obj->what_is & (WEAPON | ARMOR | WAND | RING)) { + if (obj->identified) { + objtype_id_status = IDENTIFIED; } } - if (obj->what_is == FOOD) { + + sbuf_init(&db, desc, desclen); + + switch (obj->what_is) { + case FOOD: if (obj->which_kind == RATION) { if (obj->quantity > 1) { - sprintf(desc, "%d rations of ", obj->quantity); + sbuf_addf(&db, + "%d rations of %s", obj->quantity, + item_name); } else { - (void) strcpy(desc, "some "); + sbuf_addf(&db, "some %s", item_name); } } else { - (void) strcpy(desc, "a "); + sbuf_addf(&db, "an %s", item_name); } - (void) strcat(desc, item_name); - goto ANA; - } - id_table = get_id_table(obj); - - if (wizard) { - goto ID; - } - if (obj->what_is & (WEAPON | ARMOR | WAND | RING)) { - goto CHECK; - } - - switch(id_table[obj->which_kind].id_status) { - case UNIDENTIFIED: -CHECK: - switch(obj->what_is) { - case SCROL: - (void) strcat(desc, item_name); - (void) strcat(desc, "entitled: "); - (void) strcat(desc, id_table[obj->which_kind].title); - break; - case POTION: - (void) strcat(desc, id_table[obj->which_kind].title); - (void) strcat(desc, item_name); - break; - case WAND: - case RING: - if (obj->identified || - (id_table[obj->which_kind].id_status == IDENTIFIED)) { - goto ID; - } - if (id_table[obj->which_kind].id_status == CALLED) { - goto CALL; - } - (void) strcat(desc, id_table[obj->which_kind].title); - (void) strcat(desc, item_name); - break; - case ARMOR: - if (obj->identified) { - goto ID; - } - (void) strcpy(desc, id_table[obj->which_kind].title); - break; - case WEAPON: - if (obj->identified) { - goto ID; - } - (void) strcat(desc, name_of(obj)); - break; + break; + case SCROL: + desc_count(&db, obj->quantity); + if (objtype_id_status==UNIDENTIFIED) { + sbuf_addstr(&db, item_name); + sbuf_addstr(&db, "entitled: "); + sbuf_addstr(&db, id_table[obj->which_kind].title); + } else if (objtype_id_status==CALLED) { + desc_called(&db, obj); + } else { + sbuf_addstr(&db, item_name); + sbuf_addstr(&db, id_table[obj->which_kind].real); } break; - case CALLED: -CALL: switch(obj->what_is) { - case SCROL: - case POTION: - case WAND: - case RING: - (void) strcat(desc, item_name); - (void) strcat(desc, "called "); - (void) strcat(desc, id_table[obj->which_kind].title); - break; + case POTION: + desc_count(&db, obj->quantity); + if (objtype_id_status==UNIDENTIFIED) { + sbuf_addstr(&db, id_table[obj->which_kind].title); + sbuf_addstr(&db, item_name); + } else if (objtype_id_status==CALLED) { + desc_called(&db, obj); + } else { + sbuf_addstr(&db, item_name); + sbuf_addstr(&db, id_table[obj->which_kind].real); } break; - case IDENTIFIED: -ID: switch(obj->what_is) { - case SCROL: - case POTION: - (void) strcat(desc, item_name); - (void) strcat(desc, id_table[obj->which_kind].real); - break; - case RING: - if (wizard || obj->identified) { - if ((obj->which_kind == DEXTERITY) || - (obj->which_kind == ADD_STRENGTH)) { - sprintf(more_info, "%s%d ", ((obj->class > 0) ? "+" : ""), - obj->class); - (void) strcat(desc, more_info); - } - } - (void) strcat(desc, item_name); - (void) strcat(desc, id_table[obj->which_kind].real); - break; - case WAND: - (void) strcat(desc, item_name); - (void) strcat(desc, id_table[obj->which_kind].real); + case WAND: + desc_count(&db, obj->quantity); + if (objtype_id_status==UNIDENTIFIED) { + sbuf_addstr(&db, id_table[obj->which_kind].title); + sbuf_addstr(&db, item_name); + } else if (objtype_id_status==CALLED) { + desc_called(&db, obj); + } else { + sbuf_addstr(&db, item_name); + sbuf_addstr(&db, id_table[obj->which_kind].real); if (wizard || obj->identified) { - sprintf(more_info, "[%d]", obj->class); - (void) strcat(desc, more_info); + sbuf_addf(&db, "[%d]", obj->class); } - break; - case ARMOR: - sprintf(desc, "%s%d ", ((obj->d_enchant >= 0) ? "+" : ""), - obj->d_enchant); - (void) strcat(desc, id_table[obj->which_kind].title); - sprintf(more_info, "[%d] ", get_armor_class(obj)); - (void) strcat(desc, more_info); - break; - case WEAPON: - sprintf(desc+strlen(desc), "%s%d,%s%d ", - ((obj->hit_enchant >= 0) ? "+" : ""), obj->hit_enchant, - ((obj->d_enchant >= 0) ? "+" : ""), obj->d_enchant); - (void) strcat(desc, name_of(obj)); - break; } break; - } -ANA: - if (!strncmp(desc, "a ", 2)) { - if (is_vowel(desc[2])) { - for (i = strlen(desc) + 1; i > 1; i--) { - desc[i] = desc[i-1]; + case RING: + desc_count(&db, obj->quantity); + if (objtype_id_status==UNIDENTIFIED) { + sbuf_addstr(&db, id_table[obj->which_kind].title); + sbuf_addstr(&db, item_name); + } else if (objtype_id_status==CALLED) { + desc_called(&db, obj); + } else { + if ((wizard || obj->identified) && + (obj->which_kind == DEXTERITY || + obj->which_kind == ADD_STRENGTH)) { + sbuf_addf(&db, "%+d ", obj->class); } - desc[1] = 'n'; + sbuf_addstr(&db, item_name); + sbuf_addstr(&db, id_table[obj->which_kind].real); + } + break; + case ARMOR: + /* no desc_count() */ + if (objtype_id_status==UNIDENTIFIED) { + sbuf_addstr(&db, id_table[obj->which_kind].title); + } else { + sbuf_addf(&db, "%+d %s[%d] ", obj->d_enchant, + id_table[obj->which_kind].title, + get_armor_class(obj)); + } + break; + case WEAPON: + desc_count(&db, obj->quantity); + if (objtype_id_status==UNIDENTIFIED) { + sbuf_addstr(&db, name_of(obj)); + } else { + sbuf_addf(&db, "%+d,%+d %s", + obj->hit_enchant, obj->d_enchant, + name_of(obj)); } + break; } + if (obj->in_use_flags & BEING_WIELDED) { - (void) strcat(desc, "in hand"); + sbuf_addstr(&db, "in hand"); } else if (obj->in_use_flags & BEING_WORN) { - (void) strcat(desc, "being worn"); + sbuf_addstr(&db, "being worn"); } else if (obj->in_use_flags & ON_LEFT_HAND) { - (void) strcat(desc, "on left hand"); + sbuf_addstr(&db, "on left hand"); } else if (obj->in_use_flags & ON_RIGHT_HAND) { - (void) strcat(desc, "on right hand"); + sbuf_addstr(&db, "on right hand"); + } + + if (!strncmp(db.buf, "an ", 3)) { + if (!is_vowel(db.buf[3])) { + memmove(db.buf+2, db.buf+3, strlen(db.buf+3)+1); + db.buf[1] = ' '; + } } } @@ -625,7 +703,8 @@ get_wand_and_ring_materials() j = get_rand(0, WAND_MATERIALS-1); } while (used[j]); used[j] = 1; - (void) strcpy(id_wands[i].title, wand_materials[j]); + (void) strlcpy(id_wands[i].title, wand_materials[j], + sizeof(id_wands[i].title)); is_wood[i] = (j > MAX_METAL); } for (i = 0; i < GEMS; i++) { @@ -636,7 +715,8 @@ get_wand_and_ring_materials() j = get_rand(0, GEMS-1); } while (used[j]); used[j] = 1; - (void) strcpy(id_rings[i].title, gems[j]); + (void) strlcpy(id_rings[i].title, gems[j], + sizeof(id_rings[i].title)); } } @@ -644,7 +724,7 @@ void single_inv(ichar) short ichar; { - short ch; + short ch, ch2; char desc[DCOLS]; object *obj; @@ -654,15 +734,12 @@ single_inv(ichar) return; } if (!(obj = get_letter_object(ch))) { - message("no such item.", 0); + messagef(0, "no such item."); return; } - desc[0] = ch; - desc[1] = ((obj->what_is & ARMOR) && obj->is_protected) ? '}' : ')'; - desc[2] = ' '; - desc[3] = 0; - get_desc(obj, desc+3); - message(desc, 0); + ch2 = ((obj->what_is & ARMOR) && obj->is_protected) ? '}' : ')'; + get_desc(obj, desc, sizeof(desc)); + messagef(0, "%c%c %s", ch, ch2, desc); } struct id * @@ -694,13 +771,13 @@ inv_armor_weapon(is_weapon) if (rogue.weapon) { single_inv(rogue.weapon->ichar); } else { - message("not wielding anything", 0); + messagef(0, "not wielding anything"); } } else { if (rogue.armor) { single_inv(rogue.armor->ichar); } else { - message("not wearing anything", 0); + messagef(0, "not wearing anything"); } } } @@ -710,9 +787,8 @@ id_type() { const char *id; int ch; - char buf[DCOLS]; - message("what do you want identified?", 0); + messagef(0, "what do you want identified?"); ch = rgetchar(); @@ -781,6 +857,5 @@ id_type() } } check_message(); - sprintf(buf, "'%c': %s", ch, id); - message(buf, 0); + messagef(0, "'%c': %s", ch, id); } diff --git a/rogue/level.c b/rogue/level.c index ecf10468..5d9da622 100644 --- a/rogue/level.c +++ b/rogue/level.c @@ -1,4 +1,4 @@ -/* $NetBSD: level.c,v 1.7 2003/08/07 09:37:38 agc Exp $ */ +/* $NetBSD: level.c,v 1.8 2007/12/27 23:53:00 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)level.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: level.c,v 1.7 2003/08/07 09:37:38 agc Exp $"); +__RCSID("$NetBSD: level.c,v 1.8 2007/12/27 23:53:00 dholland Exp $"); #endif #endif /* not lint */ @@ -769,8 +769,8 @@ put_player(nr) rn = get_room_number(rogue.row, rogue.col); wake_room(rn, 1, rogue.row, rogue.col); if (new_level_message) { - message(new_level_message, 0); - new_level_message = 0; + messagef(0, "%s", new_level_message); + new_level_message = NULL; } mvaddch(rogue.row, rogue.col, rogue.fchar); } @@ -783,12 +783,12 @@ drop_check() } if (dungeon[rogue.row][rogue.col] & STAIRS) { if (levitate) { - message("you're floating in the air!", 0); + messagef(0, "you're floating in the air!"); return(0); } return(1); } - message("I see no way down", 0); + messagef(0, "I see no way down"); return(0); } @@ -797,11 +797,11 @@ check_up() { if (!wizard) { if (!(dungeon[rogue.row][rogue.col] & STAIRS)) { - message("I see no way up", 0); + messagef(0, "I see no way up"); return(0); } if (!has_amulet()) { - message("your way is magically blocked", 0); + messagef(0, "your way is magically blocked"); return(0); } } @@ -820,7 +820,6 @@ add_exp(e, promotion) int e; boolean promotion; { - char mbuf[40]; short new_exp; short i, hp; @@ -832,8 +831,7 @@ add_exp(e, promotion) rogue.exp_points = MAX_EXP + 1; } for (i = rogue.exp+1; i <= new_exp; i++) { - sprintf(mbuf, "welcome to level %d", i); - message(mbuf, 0); + messagef(0, "welcome to level %d", i); if (promotion) { hp = hp_raise(); rogue.hp_current += hp; @@ -873,7 +871,6 @@ hp_raise() void show_average_hp() { - char mbuf[80]; float real_average; float effective_average; @@ -885,9 +882,8 @@ show_average_hp() effective_average = (float) (rogue.hp_max - INIT_HP) / (rogue.exp - 1); } - sprintf(mbuf, "R-Hp: %.2f, E-Hp: %.2f (!: %d, V: %d)", real_average, + messagef(0, "R-Hp: %.2f, E-Hp: %.2f (!: %d, V: %d)", real_average, effective_average, extra_hp, less_hp); - message(mbuf, 0); } void diff --git a/rogue/machdep.c b/rogue/machdep.c index 200b7d96..747eae0a 100644 --- a/rogue/machdep.c +++ b/rogue/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.14 2006/04/24 19:00:30 snj Exp $ */ +/* $NetBSD: machdep.c,v 1.15 2007/12/27 23:53:00 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)machdep.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: machdep.c,v 1.14 2006/04/24 19:00:30 snj Exp $"); +__RCSID("$NetBSD: machdep.c,v 1.15 2007/12/27 23:53:00 dholland Exp $"); #endif #endif /* not lint */ @@ -456,7 +456,7 @@ md_lock(l) setegid(egid); if ((fd = open(_PATH_SCOREFILE, O_RDONLY)) < 1) { setegid(gid); - message("cannot lock score file", 0); + messagef(0, "cannot lock score file"); return; } setegid(gid); @@ -472,10 +472,13 @@ md_lock(l) /* md_shell(): * * This function spawns a shell for the user to use. When this shell is - * terminated, the game continues. Since this program may often be run - * setuid to gain access to privileged files, care is taken that the shell - * is run with the user's REAL user id, and not the effective user id. - * The effective user id is restored after the shell completes. + * terminated, the game continues. + * + * It is important that the game not give the shell the privileges the + * game uses to access the scores file. This version of the game runs + * with privileges low by default; only the saved gid (if setgid) or uid + * (if setuid) will be privileged, but that privilege is discarded by + * exec(). */ void @@ -483,11 +486,19 @@ md_shell(shell) const char *shell; { int w; + pid_t pid; - if (!fork()) { + pid = fork(); + switch (pid) { + case -1: + break; + case 0: execl(shell, shell, (char *) 0); + _exit(255); + default: + waitpid(pid, &w, 0); + break; } - wait(&w); } #endif diff --git a/rogue/message.c b/rogue/message.c index 3e30e046..46327720 100644 --- a/rogue/message.c +++ b/rogue/message.c @@ -1,4 +1,4 @@ -/* $NetBSD: message.c,v 1.10 2003/08/07 09:37:38 agc Exp $ */ +/* $NetBSD: message.c,v 1.11 2007/12/27 23:53:00 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)message.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: message.c,v 1.10 2003/08/07 09:37:38 agc Exp $"); +__RCSID("$NetBSD: message.c,v 1.11 2007/12/27 23:53:00 dholland Exp $"); #endif #endif /* not lint */ @@ -55,6 +55,7 @@ __RCSID("$NetBSD: message.c,v 1.10 2003/08/07 09:37:38 agc Exp $"); #include #include +#include #include "rogue.h" char msgs[NMESSAGES][DCOLS] = {"", "", "", "", ""}; @@ -63,6 +64,9 @@ boolean msg_cleared = 1, rmsg = 0; char hunger_str[HUNGER_STR_LEN] = ""; const char *more = "-more-"; +static void message __P((const char *, boolean)); + +static void message(msg, intrpt) const char *msg; @@ -86,7 +90,7 @@ message(msg, intrpt) } if (!rmsg) { imsg = (imsg + 1) % NMESSAGES; - (void) strcpy(msgs[imsg], msg); + (void) strlcpy(msgs[imsg], msg, sizeof(msgs[imsg])); } mvaddstr(MIN_ROW-1, 0, msg); addch(' '); @@ -102,6 +106,19 @@ message(msg, intrpt) } } +void +messagef(boolean intrpt, const char *fmt, ...) +{ + va_list ap; + char buf[DCOLS]; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + message(buf, intrpt); +} + void remessage(c) short c; @@ -132,9 +149,10 @@ check_message() } int -get_input_line(prompt, insert, buf, if_cancelled, add_blank, do_echo) +get_input_line(prompt, insert, buf, buflen, if_cancelled, add_blank, do_echo) const char *prompt, *insert; char *buf; + size_t buflen; const char *if_cancelled; boolean add_blank; boolean do_echo; @@ -147,14 +165,14 @@ get_input_line(prompt, insert, buf, if_cancelled, add_blank, do_echo) if (insert[0]) { mvaddstr(0, n + 1, insert); - (void) strcpy(buf, insert); - i = strlen(insert); + (void) strlcpy(buf, insert, buflen); + i = strlen(buf); move(0, (n + i + 1)); refresh(); } while (((ch = rgetchar()) != '\r') && (ch != '\n') && (ch != CANCEL)) { - if ((ch >= ' ') && (ch <= '~') && (i < MAX_TITLE_LENGTH-2)) { + if ((ch >= ' ') && (ch <= '~') && (i < buflen-2)) { if ((ch != ' ') || (i > 0)) { buf[i++] = ch; if (do_echo) { @@ -239,9 +257,7 @@ print_stats(stat_mask) mvaddstr(row, 0, "Level: "); } /* max level taken care of in make_level() */ - sprintf(buf, "%d", cur_level); - mvaddstr(row, 7, buf); - pad(buf, 2); + mvprintw(row, 7, "%-2d", cur_level); } if (stat_mask & STAT_GOLD) { if (label) { @@ -250,9 +266,7 @@ print_stats(stat_mask) if (rogue.gold > MAX_GOLD) { rogue.gold = MAX_GOLD; } - sprintf(buf, "%ld", rogue.gold); - mvaddstr(row, 16, buf); - pad(buf, 6); + mvprintw(row, 16, "%-6ld", rogue.gold); } if (stat_mask & STAT_HP) { if (label) { @@ -262,9 +276,9 @@ print_stats(stat_mask) rogue.hp_current -= (rogue.hp_max - MAX_HP); rogue.hp_max = MAX_HP; } - sprintf(buf, "%d(%d)", rogue.hp_current, rogue.hp_max); - mvaddstr(row, 27, buf); - pad(buf, 8); + snprintf(buf, sizeof(buf), "%d(%d)", + rogue.hp_current, rogue.hp_max); + mvprintw(row, 27, "%-8s", buf); } if (stat_mask & STAT_STRENGTH) { if (label) { @@ -274,10 +288,9 @@ print_stats(stat_mask) rogue.str_current -= (rogue.str_max - MAX_STRENGTH); rogue.str_max = MAX_STRENGTH; } - sprintf(buf, "%d(%d)", (rogue.str_current + add_strength), - rogue.str_max); - mvaddstr(row, 41, buf); - pad(buf, 6); + snprintf(buf, sizeof(buf), "%d(%d)", + (rogue.str_current + add_strength), rogue.str_max); + mvprintw(row, 41, "%-6s", buf); } if (stat_mask & STAT_ARMOR) { if (label) { @@ -286,9 +299,7 @@ print_stats(stat_mask) if (rogue.armor && (rogue.armor->d_enchant > MAX_ARMOR)) { rogue.armor->d_enchant = MAX_ARMOR; } - sprintf(buf, "%d", get_armor_class(rogue.armor)); - mvaddstr(row, 53, buf); - pad(buf, 2); + mvprintw(row, 53, "%-2d", get_armor_class(rogue.armor)); } if (stat_mask & STAT_EXP) { if (label) { @@ -300,9 +311,9 @@ print_stats(stat_mask) if (rogue.exp > MAX_EXP_LEVEL) { rogue.exp = MAX_EXP_LEVEL; } - sprintf(buf, "%d/%ld", rogue.exp, rogue.exp_points); - mvaddstr(row, 61, buf); - pad(buf, 11); + snprintf(buf, sizeof(buf), "%d/%ld", + rogue.exp, rogue.exp_points); + mvprintw(row, 61, "%-11s", buf); } if (stat_mask & STAT_HUNGER) { mvaddstr(row, 73, hunger_str); @@ -311,38 +322,22 @@ print_stats(stat_mask) refresh(); } -void -pad(s, n) - const char *s; - short n; -{ - short i; - - for (i = strlen(s); i < n; i++) { - addch(' '); - } -} - void save_screen() { FILE *fp; short i, j; char buf[DCOLS+2]; - boolean found_non_blank; if ((fp = fopen("rogue.screen", "w")) != NULL) { for (i = 0; i < DROWS; i++) { - found_non_blank = 0; - for (j = (DCOLS - 1); j >= 0; j--) { + for (j=0; j0 && buf[j-1]==' '; j--); + buf[j] = 0; + fputs(buf, fp); putc('\n', fp); } diff --git a/rogue/monster.c b/rogue/monster.c index 7fe5d699..bca5eb1c 100644 --- a/rogue/monster.c +++ b/rogue/monster.c @@ -1,4 +1,4 @@ -/* $NetBSD: monster.c,v 1.11 2006/03/30 04:10:04 jnemeth Exp $ */ +/* $NetBSD: monster.c,v 1.12 2007/12/27 23:53:00 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)monster.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: monster.c,v 1.11 2006/03/30 04:10:04 jnemeth Exp $"); +__RCSID("$NetBSD: monster.c,v 1.12 2007/12/27 23:53:00 dholland Exp $"); #endif #endif /* not lint */ @@ -709,7 +709,7 @@ create_monster() wake_up(monster); } } else { - message("you hear a faint cry of anguish in the distance", 0); + messagef(0, "you hear a faint cry of anguish in the distance"); } } @@ -851,7 +851,7 @@ aggravate() { object *monster; - message("you hear a high pitched humming noise", 0); + messagef(0, "you hear a high pitched humming noise"); monster = level_monsters.next_monster; diff --git a/rogue/move.c b/rogue/move.c index df8f452a..91adf0f1 100644 --- a/rogue/move.c +++ b/rogue/move.c @@ -1,4 +1,4 @@ -/* $NetBSD: move.c,v 1.8 2006/05/14 03:15:50 christos Exp $ */ +/* $NetBSD: move.c,v 1.9 2007/12/27 23:53:00 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)move.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: move.c,v 1.8 2006/05/14 03:15:50 christos Exp $"); +__RCSID("$NetBSD: move.c,v 1.9 2007/12/27 23:53:00 dholland Exp $"); #endif #endif /* not lint */ @@ -66,7 +66,7 @@ one_move_rogue(dirch, pickup) short row, col; object *obj; char desc[DCOLS]; - short n, status, d = 0; /* XXX: GCC */ + short status, d = 0; /* XXX: GCC */ row = rogue.row; col = rogue.col; @@ -83,9 +83,9 @@ one_move_rogue(dirch, pickup) if (being_held || bear_trap) { if (!(dungeon[row][col] & MONSTER)) { if (being_held) { - message("you are being held", 1); + messagef(1, "you are being held"); } else { - message("you are still stuck in the bear trap", 0); + messagef(0, "you are still stuck in the bear trap"); (void) reg_move(); } return(MOVE_FAILED); @@ -135,9 +135,10 @@ one_move_rogue(dirch, pickup) } if (pickup && !levitate) { if ((obj = pick_up(row, col, &status)) != NULL) { - get_desc(obj, desc); + get_desc(obj, desc, sizeof(desc)); if (obj->what_is == GOLD) { free_object(obj); + messagef(1, "%s", desc); goto NOT_IN_PACK; } } else if (!status) { @@ -148,17 +149,12 @@ one_move_rogue(dirch, pickup) } else { MOVE_ON: obj = object_at(&level_objects, row, col); - (void) strcpy(desc, "moved onto "); - get_desc(obj, desc+11); + get_desc(obj, desc, sizeof(desc)); + messagef(1, "moved onto %s", desc); goto NOT_IN_PACK; } - n = strlen(desc); - desc[n] = '('; - desc[n+1] = obj->ichar; - desc[n+2] = ')'; - desc[n+3] = 0; + messagef(1, "%s(%c)", desc, obj->ichar); NOT_IN_PACK: - message(desc, 1); (void) reg_move(); return(STOPPED_ON_SOMETHING); } @@ -326,7 +322,7 @@ move_onto() while (!is_direction(ch = rgetchar(), &d)) { sound_bell(); if (first_miss) { - message("direction? ", 0); + messagef(0, "direction? "); first_miss = 0; } } @@ -382,19 +378,19 @@ check_hunger(msg_only) boolean fainted = 0; if (rogue.moves_left == HUNGRY) { - (void) strcpy(hunger_str, "hungry"); - message(hunger_str, 0); + (void) strlcpy(hunger_str, "hungry", sizeof(hunger_str)); + messagef(0, "%s", hunger_str); print_stats(STAT_HUNGER); } if (rogue.moves_left == WEAK) { - (void) strcpy(hunger_str, "weak"); - message(hunger_str, 1); + (void) strlcpy(hunger_str, "weak", sizeof(hunger_str)); + messagef(1, "%s", hunger_str); print_stats(STAT_HUNGER); } if (rogue.moves_left <= FAINT) { if (rogue.moves_left == FAINT) { - (void) strcpy(hunger_str, "faint"); - message(hunger_str, 1); + (void) strlcpy(hunger_str, "faint", sizeof(hunger_str)); + messagef(1, "%s", hunger_str); print_stats(STAT_HUNGER); } n = get_rand(0, (FAINT - rogue.moves_left)); @@ -403,13 +399,13 @@ check_hunger(msg_only) if (rand_percent(40)) { rogue.moves_left++; } - message("you faint", 1); + messagef(1, "you faint"); for (i = 0; i < n; i++) { if (coin_toss()) { mv_mons(); } } - message(you_can_move_again, 1); + messagef(1, you_can_move_again); } } if (msg_only) { @@ -482,7 +478,7 @@ reg_move() } if (levitate) { if (!(--levitate)) { - message("you float gently to the ground", 1); + messagef(1, "you float gently to the ground"); if (dungeon[rogue.row][rogue.col] & TRAP) { trap_player(rogue.row, rogue.col); } @@ -490,7 +486,7 @@ reg_move() } if (haste_self) { if (!(--haste_self)) { - message("you feel yourself slowing down", 0); + messagef(0, "you feel yourself slowing down"); } } heal(); diff --git a/rogue/object.c b/rogue/object.c index 8d9e1a36..0ceb339e 100644 --- a/rogue/object.c +++ b/rogue/object.c @@ -1,4 +1,4 @@ -/* $NetBSD: object.c,v 1.10 2006/03/30 04:27:24 jnemeth Exp $ */ +/* $NetBSD: object.c,v 1.11 2007/12/27 23:53:00 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)object.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: object.c,v 1.10 2006/03/30 04:27:24 jnemeth Exp $"); +__RCSID("$NetBSD: object.c,v 1.11 2007/12/27 23:53:00 dholland Exp $"); #endif #endif /* not lint */ @@ -80,36 +80,36 @@ fighter rogue = { }; struct id id_potions[POTIONS] = { -{100, "blue \0 ", "of increase strength ", 0}, -{250, "red \0 ", "of restore strength ", 0}, -{100, "green \0 ", "of healing ", 0}, -{200, "grey \0 ", "of extra healing ", 0}, - {10, "brown \0 ", "of poison ", 0}, -{300, "clear \0 ", "of raise level ", 0}, - {10, "pink \0 ", "of blindness ", 0}, - {25, "white \0 ", "of hallucination ", 0}, -{100, "purple \0 ", "of detect monster ", 0}, -{100, "black \0 ", "of detect things ", 0}, - {10, "yellow \0 ", "of confusion ", 0}, - {80, "plaid \0 ", "of levitation ", 0}, -{150, "burgundy \0 ", "of haste self ", 0}, -{145, "beige \0 ", "of see invisible ", 0} +{100, "blue ", "of increase strength ", 0}, +{250, "red ", "of restore strength ", 0}, +{100, "green ", "of healing ", 0}, +{200, "grey ", "of extra healing ", 0}, + {10, "brown ", "of poison ", 0}, +{300, "clear ", "of raise level ", 0}, + {10, "pink ", "of blindness ", 0}, + {25, "white ", "of hallucination ", 0}, +{100, "purple ", "of detect monster ", 0}, +{100, "black ", "of detect things ", 0}, + {10, "yellow ", "of confusion ", 0}, + {80, "plaid ", "of levitation ", 0}, +{150, "burgundy ", "of haste self ", 0}, +{145, "beige ", "of see invisible ", 0} }; struct id id_scrolls[SCROLS] = { -{505, " ", "of protect armor ", 0}, -{200, " ", "of hold monster ", 0}, -{235, " ", "of enchant weapon ", 0}, -{235, " ", "of enchant armor ", 0}, -{175, " ", "of identify ", 0}, -{190, " ", "of teleportation ", 0}, - {25, " ", "of sleep ", 0}, -{610, " ", "of scare monster ", 0}, -{210, " ", "of remove curse ", 0}, - {80, " ", "of create monster ",0}, - {25, " ", "of aggravate monster ",0}, -{180, " ", "of magic mapping ", 0}, - {90, " ", "of confuse monster ", 0} +{505, "", "of protect armor ", 0}, +{200, "", "of hold monster ", 0}, +{235, "", "of enchant weapon ", 0}, +{235, "", "of enchant armor ", 0}, +{175, "", "of identify ", 0}, +{190, "", "of teleportation ", 0}, + {25, "", "of sleep ", 0}, +{610, "", "of scare monster ", 0}, +{210, "", "of remove curse ", 0}, + {80, "", "of create monster ",0}, + {25, "", "of aggravate monster ",0}, +{180, "", "of magic mapping ", 0}, + {90, "", "of confuse monster ", 0} }; struct id id_weapons[WEAPONS] = { @@ -134,31 +134,31 @@ struct id id_armors[ARMORS] = { }; struct id id_wands[WANDS] = { - {25, " ", "of teleport away ",0}, - {50, " ", "of slow monster ", 0}, - {8, " ", "of invisibility ",0}, - {55, " ", "of polymorph ",0}, - {2, " ", "of haste monster ",0}, - {20, " ", "of magic missile ",0}, - {20, " ", "of cancellation ",0}, - {0, " ", "of do nothing ",0}, - {35, " ", "of drain life ",0}, - {20, " ", "of cold ",0}, - {20, " ", "of fire ",0} + {25, "", "of teleport away ",0}, + {50, "", "of slow monster ", 0}, + {8, "", "of invisibility ",0}, + {55, "", "of polymorph ",0}, + {2, "", "of haste monster ",0}, + {20, "", "of magic missile ",0}, + {20, "", "of cancellation ",0}, + {0, "", "of do nothing ",0}, + {35, "", "of drain life ",0}, + {20, "", "of cold ",0}, + {20, "", "of fire ",0} }; struct id id_rings[RINGS] = { - {250, " ", "of stealth ",0}, - {100, " ", "of teleportation ", 0}, - {255, " ", "of regeneration ",0}, - {295, " ", "of slow digestion ",0}, - {200, " ", "of add strength ",0}, - {250, " ", "of sustain strength ",0}, - {250, " ", "of dexterity ",0}, - {25, " ", "of adornment ",0}, - {300, " ", "of see invisible ",0}, - {290, " ", "of maintain armor ",0}, - {270, " ", "of searching ",0}, + {250, "", "of stealth ",0}, + {100, "", "of teleportation ", 0}, + {255, "", "of regeneration ",0}, + {295, "", "of slow digestion ",0}, + {200, "", "of add strength ",0}, + {250, "", "of sustain strength ",0}, + {250, "", "of dexterity ",0}, + {25, "", "of adornment ",0}, + {300, "", "of see invisible ",0}, + {290, "", "of maintain armor ",0}, + {270, "", "of searching ",0}, }; void @@ -257,7 +257,7 @@ object_at(pack, row, col) obj = obj->next_object; } if (!obj) { - message("object_at(): inconsistent", 1); + messagef(1, "object_at(): inconsistent"); } } return(obj); @@ -637,7 +637,7 @@ alloc_object() obj = free_list; free_list = free_list->next_object; } else if (!(obj = (object *) md_malloc(sizeof(object)))) { - message("cannot allocate object, saving game", 0); + messagef(0, "cannot allocate object, saving game"); save_into_file(error_file); clean_up("alloc_object: save failed"); } @@ -739,10 +739,10 @@ c_object_for_wizard() max = 0; if (pack_count((object *) 0) >= MAX_PACK_COUNT) { - message("pack full", 0); + messagef(0, "pack full"); return; } - message("type of object?", 0); + messagef(0, "type of object?"); while (r_index("!?:)]=/,\033", (ch = rgetchar()), 0) == -1) { sound_bell(); @@ -788,7 +788,7 @@ c_object_for_wizard() } if ((ch != ',') && (ch != ':')) { GIL: - if (get_input_line("which kind?", "", buf, "", 0, 1)) { + if (get_input_line("which kind?", "", buf, sizeof(buf), "", 0, 1)) { wk = get_number(buf); if ((wk >= 0) && (wk <= max)) { obj->which_kind = (unsigned short) wk; @@ -804,7 +804,7 @@ GIL: return; } } - get_desc(obj, buf); - message(buf, 0); + get_desc(obj, buf, sizeof(buf)); + messagef(0, "%s", buf); (void) add_to_pack(obj, &rogue.pack, 1); } diff --git a/rogue/pack.c b/rogue/pack.c index 5619d247..ee091384 100644 --- a/rogue/pack.c +++ b/rogue/pack.c @@ -1,4 +1,4 @@ -/* $NetBSD: pack.c,v 1.7 2003/08/07 09:37:39 agc Exp $ */ +/* $NetBSD: pack.c,v 1.8 2007/12/27 23:53:00 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)pack.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: pack.c,v 1.7 2003/08/07 09:37:39 agc Exp $"); +__RCSID("$NetBSD: pack.c,v 1.8 2007/12/27 23:53:00 dholland Exp $"); #endif #endif /* not lint */ @@ -110,18 +110,18 @@ pick_up(row, col, status) *status = 1; if (levitate) { - message("you're floating in the air!", 0); + messagef(0, "you're floating in the air!"); return((object *) 0); } obj = object_at(&level_objects, row, col); if (!obj) { - message("pick_up(): inconsistent", 1); + messagef(1, "pick_up(): inconsistent"); return(obj); } if ( (obj->what_is == SCROL) && (obj->which_kind == SCARE_MONSTER) && obj->picked_up) { - message("the scroll turns to dust as you pick it up", 0); + messagef(0, "the scroll turns to dust as you pick it up"); dungeon[row][col] &= (~OBJECT); vanish(obj, 0, &level_objects); *status = 0; @@ -138,7 +138,7 @@ pick_up(row, col, status) return(obj); /* obj will be free_object()ed in caller */ } if (pack_count(obj) >= MAX_PACK_COUNT) { - message("pack too full", 1); + messagef(1, "pack too full"); return((object *) 0); } dungeon[row][col] &= ~(OBJECT); @@ -156,29 +156,29 @@ drop() char desc[DCOLS]; if (dungeon[rogue.row][rogue.col] & (OBJECT | STAIRS | TRAP)) { - message("there's already something there", 0); + messagef(0, "there's already something there"); return; } if (!rogue.pack.next_object) { - message("you have nothing to drop", 0); + messagef(0, "you have nothing to drop"); return; } if ((ch = pack_letter("drop what?", ALL_OBJECTS)) == CANCEL) { return; } if (!(obj = get_letter_object(ch))) { - message("no such item.", 0); + messagef(0, "no such item."); return; } if (obj->in_use_flags & BEING_WIELDED) { if (obj->is_cursed) { - message(curse_message, 0); + messagef(0, "%s", curse_message); return; } unwield(rogue.weapon); } else if (obj->in_use_flags & BEING_WORN) { if (obj->is_cursed) { - message(curse_message, 0); + messagef(0, "%s", curse_message); return; } mv_aquatars(); @@ -186,7 +186,7 @@ drop() print_stats(STAT_ARMOR); } else if (obj->in_use_flags & ON_EITHER_HAND) { if (obj->is_cursed) { - message(curse_message, 0); + messagef(0, "%s", curse_message); return; } un_put_on(obj); @@ -205,9 +205,8 @@ drop() take_from_pack(obj, &rogue.pack); } place_at(obj, rogue.row, rogue.col); - (void) strcpy(desc, "dropped "); - get_desc(obj, desc+8); - message(desc, 0); + get_desc(obj, desc, sizeof(desc)); + messagef(0, "dropped %s", desc); (void) reg_move(); } @@ -257,7 +256,9 @@ next_avail_ichar() } obj = rogue.pack.next_object; while (obj) { - ichars[(obj->ichar - 'a')] = 1; + if (obj->ichar >= 'a' && obj->ichar <= 'z') { + ichars[(obj->ichar - 'a')] = 1; + } obj = obj->next_object; } for (i = 0; i < 26; i++) { @@ -283,12 +284,12 @@ pack_letter(prompt, mask) unsigned short tmask = mask; if (!mask_pack(&rogue.pack, mask)) { - message("nothing appropriate", 0); + messagef(0, "nothing appropriate"); return(CANCEL); } for (;;) { - message(prompt, 0); + messagef(0, "%s", prompt); for (;;) { ch = rgetchar(); @@ -320,19 +321,18 @@ take_off() if (rogue.armor) { if (rogue.armor->is_cursed) { - message(curse_message, 0); + messagef(0, "%s", curse_message); } else { mv_aquatars(); obj = rogue.armor; unwear(rogue.armor); - (void) strcpy(desc, "was wearing "); - get_desc(obj, desc+12); - message(desc, 0); + get_desc(obj, desc, sizeof(desc)); + messagef(0, "was wearing %s", desc); print_stats(STAT_ARMOR); (void) reg_move(); } } else { - message("not wearing any", 0); + messagef(0, "not wearing any"); } } @@ -344,7 +344,7 @@ wear() char desc[DCOLS]; if (rogue.armor) { - message("your already wearing some", 0); + messagef(0, "you're already wearing some"); return; } ch = pack_letter("wear what?", ARMOR); @@ -353,17 +353,16 @@ wear() return; } if (!(obj = get_letter_object(ch))) { - message("no such item.", 0); + messagef(0, "no such item."); return; } if (obj->what_is != ARMOR) { - message("you can't wear that", 0); + messagef(0, "you can't wear that"); return; } obj->identified = 1; - (void) strcpy(desc, "wearing "); - get_desc(obj, desc + 8); - message(desc, 0); + get_desc(obj, desc, sizeof(desc)); + messagef(0, "wearing %s", desc); do_wear(obj); print_stats(STAT_ARMOR); (void) reg_move(); @@ -396,7 +395,7 @@ wield() char desc[DCOLS]; if (rogue.weapon && rogue.weapon->is_cursed) { - message(curse_message, 0); + messagef(0, "%s", curse_message); return; } ch = pack_letter("wield what?", WEAPON); @@ -405,22 +404,20 @@ wield() return; } if (!(obj = get_letter_object(ch))) { - message("No such item.", 0); + messagef(0, "No such item."); return; } if (obj->what_is & (ARMOR | RING)) { - sprintf(desc, "you can't wield %s", + messagef(0, "you can't wield %s", ((obj->what_is == ARMOR) ? "armor" : "rings")); - message(desc, 0); return; } if (obj->in_use_flags & BEING_WIELDED) { - message("in use", 0); + messagef(0, "in use"); } else { unwield(rogue.weapon); - (void) strcpy(desc, "wielding "); - get_desc(obj, desc + 9); - message(desc, 0); + get_desc(obj, desc, sizeof(desc)); + messagef(0, "wielding %s", desc); do_wield(obj); (void) reg_move(); } @@ -458,18 +455,20 @@ call_it() return; } if (!(obj = get_letter_object(ch))) { - message("no such item.", 0); + messagef(0, "no such item."); return; } if (!(obj->what_is & (SCROL | POTION | WAND | RING))) { - message("surely you already know what that's called", 0); + messagef(0, "surely you already know what that's called"); return; } id_table = get_id_table(obj); - if (get_input_line("call it:","",buf,id_table[obj->which_kind].title,1,1)) { + if (get_input_line("call it:", "", buf, sizeof(buf), + id_table[obj->which_kind].title, 1, 1)) { id_table[obj->which_kind].id_status = CALLED; - (void) strcpy(id_table[obj->which_kind].title, buf); + (void) strlcpy(id_table[obj->which_kind].title, buf, + sizeof(id_table[obj->which_kind].title)); } } @@ -565,23 +564,18 @@ kick_into_pack() { object *obj; char desc[DCOLS]; - short n, stat; + short stat; if (!(dungeon[rogue.row][rogue.col] & OBJECT)) { - message("nothing here", 0); + messagef(0, "nothing here"); } else { if ((obj = pick_up(rogue.row, rogue.col, &stat)) != NULL) { - get_desc(obj, desc); + get_desc(obj, desc, sizeof(desc)); if (obj->what_is == GOLD) { - message(desc, 0); + messagef(0, "%s", desc); free_object(obj); } else { - n = strlen(desc); - desc[n] = '('; - desc[n+1] = obj->ichar; - desc[n+2] = ')'; - desc[n+3] = 0; - message(desc, 0); + messagef(0, "%s(%c)", desc, obj->ichar); } } if (obj || (!stat)) { diff --git a/rogue/play.c b/rogue/play.c index c94f6e81..0ede8ad7 100644 --- a/rogue/play.c +++ b/rogue/play.c @@ -1,4 +1,4 @@ -/* $NetBSD: play.c,v 1.6 2003/08/07 09:37:39 agc Exp $ */ +/* $NetBSD: play.c,v 1.7 2007/12/27 23:53:00 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)play.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: play.c,v 1.6 2003/08/07 09:37:39 agc Exp $"); +__RCSID("$NetBSD: play.c,v 1.7 2007/12/27 23:53:00 dholland Exp $"); #endif #endif /* not lint */ @@ -67,7 +67,7 @@ play_level() for (;;) { interrupted = 0; if (hit_message[0]) { - message(hit_message, 1); + messagef(1, "%s", hit_message); hit_message[0] = 0; } if (trap_door) { @@ -214,7 +214,7 @@ CH: throw(); break; case 'v': - message("rogue-clone: Version III. (Tim Stoehr was here), tektronix!zeus!tims", 0); + messagef(0, "rogue-clone: Version III. (Tim Stoehr was here), tektronix!zeus!tims"); break; case 'Q': quit(0); @@ -246,28 +246,28 @@ CH: if (wizard) { inventory(&level_objects, ALL_OBJECTS); } else { - message(unknown_command, 0); + messagef(0, "%s", unknown_command); } break; case '\023': if (wizard) { draw_magic_map(); } else { - message(unknown_command, 0); + messagef(0, "%s", unknown_command); } break; case '\024': if (wizard) { show_traps(); } else { - message(unknown_command, 0); + messagef(0, "%s", unknown_command); } break; case '\017': if (wizard) { show_objects(); } else { - message(unknown_command, 0); + messagef(0, "%s", unknown_command); } break; case '\001': @@ -277,21 +277,21 @@ CH: if (wizard) { c_object_for_wizard(); } else { - message(unknown_command, 0); + messagef(0, "%s", unknown_command); } break; case '\015': if (wizard) { show_monsters(); } else { - message(unknown_command, 0); + messagef(0, "%s", unknown_command); } break; case 'S': save_game(); break; default: - message(unknown_command, 0); + messagef(0, "%s", unknown_command); break; } } diff --git a/rogue/ring.c b/rogue/ring.c index 8971f14c..321fd493 100644 --- a/rogue/ring.c +++ b/rogue/ring.c @@ -1,4 +1,4 @@ -/* $NetBSD: ring.c,v 1.6 2003/08/07 09:37:39 agc Exp $ */ +/* $NetBSD: ring.c,v 1.7 2007/12/27 23:53:00 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)ring.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: ring.c,v 1.6 2003/08/07 09:37:39 agc Exp $"); +__RCSID("$NetBSD: ring.c,v 1.7 2007/12/27 23:53:00 dholland Exp $"); #endif #endif /* not lint */ @@ -77,28 +77,28 @@ put_on_ring() object *ring; if (r_rings == 2) { - message("wearing two rings already", 0); + messagef(0, "wearing two rings already"); return; } if ((ch = pack_letter("put on what?", RING)) == CANCEL) { return; } if (!(ring = get_letter_object(ch))) { - message("no such item.", 0); + messagef(0, "no such item."); return; } if (!(ring->what_is & RING)) { - message("that's not a ring", 0); + messagef(0, "that's not a ring"); return; } if (ring->in_use_flags & (ON_LEFT_HAND | ON_RIGHT_HAND)) { - message("that ring is already being worn", 0); + messagef(0, "that ring is already being worn"); return; } if (r_rings == 1) { ch = (rogue.left_ring ? 'r' : 'l'); } else { - message(left_or_right, 0); + messagef(0, "%s", left_or_right); do { ch = rgetchar(); } while ((ch != CANCEL) && (ch != 'l') && (ch != 'r') && (ch != '\n') && @@ -110,7 +110,7 @@ put_on_ring() } if (((ch == 'l') && rogue.left_ring)||((ch == 'r') && rogue.right_ring)) { check_message(); - message("there's already a ring on that hand", 0); + messagef(0, "there's already a ring on that hand"); return; } if (ch == 'l') { @@ -120,8 +120,8 @@ put_on_ring() } ring_stats(1); check_message(); - get_desc(ring, desc); - message(desc, 0); + get_desc(ring, desc, sizeof(desc)); + messagef(0, "%s", desc); (void) reg_move(); } @@ -160,7 +160,7 @@ remove_ring() } else if (!rogue.left_ring && rogue.right_ring) { right = 1; } else { - message(left_or_right, 0); + messagef(0, "%s", left_or_right); do { ch = rgetchar(); } while ((ch != CANCEL) && (ch != 'l') && (ch != 'r') && @@ -174,22 +174,21 @@ remove_ring() if (rogue.left_ring) { ring = rogue.left_ring; } else { - message(no_ring, 0); + messagef(0, "%s", no_ring); } } else { if (rogue.right_ring) { ring = rogue.right_ring; } else { - message(no_ring, 0); + messagef(0, "%s", no_ring); } } if (ring->is_cursed) { - message(curse_message, 0); + messagef(0, "%s", curse_message); } else { un_put_on(ring); - (void) strcpy(buf, "removed "); - get_desc(ring, buf + 8); - message(buf, 0); + get_desc(ring, buf, sizeof(buf)); + messagef(0, "removed %s", buf); (void) reg_move(); } } @@ -257,23 +256,22 @@ inv_rings() char buf[DCOLS]; if (r_rings == 0) { - message("not wearing any rings", 0); + messagef(0, "not wearing any rings"); } else { if (rogue.left_ring) { - get_desc(rogue.left_ring, buf); - message(buf, 0); + get_desc(rogue.left_ring, buf, sizeof(buf)); + messagef(0, "%s", buf); } if (rogue.right_ring) { - get_desc(rogue.right_ring, buf); - message(buf, 0); + get_desc(rogue.right_ring, buf, sizeof(buf)); + messagef(0, "%s", buf); } } if (wizard) { - sprintf(buf, "ste %d, r_r %d, e_r %d, r_t %d, s_s %d, a_s %d, reg %d, r_e %d, s_i %d, m_a %d, aus %d", + messagef(0, "ste %d, r_r %d, e_r %d, r_t %d, s_s %d, a_s %d, reg %d, r_e %d, s_i %d, m_a %d, aus %d", stealthy, r_rings, e_rings, r_teleport, sustain_strength, add_strength, regeneration, ring_exp, r_see_invisible, maintain_armor, auto_search); - message(buf, 0); } } diff --git a/rogue/rogue.h b/rogue/rogue.h index d8a60966..64747981 100644 --- a/rogue/rogue.h +++ b/rogue/rogue.h @@ -1,4 +1,4 @@ -/* $NetBSD: rogue.h,v 1.17 2005/02/15 12:54:50 jsm Exp $ */ +/* $NetBSD: rogue.h,v 1.18 2007/12/27 23:53:00 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -515,14 +515,14 @@ void freeze(object *); int get_armor_class(const object *); int get_com_id(int *, short); int get_damage(const char *, boolean); -void get_desc(const object *, char *); +void get_desc(const object *, char *, size_t); int get_dir(short, short, short, short); void get_dir_rc(short, short *, short *, short); char get_dungeon_char(short, short); int get_exp_level(long); void get_food(object *, boolean); int get_hit_chance(const object *); -int get_input_line(const char *, const char *, char *, const char *, boolean, boolean); +int get_input_line(const char *, const char *, char *, size_t, const char *, boolean, boolean); char get_mask_char(unsigned short); int get_number(const char *); boolean get_oth_room(short, short *, short *); @@ -597,7 +597,9 @@ void md_lock(boolean); void md_shell(const char *); void md_sleep(int); void md_slurp(void); -void message(const char *, boolean); +/*void message(const char *, boolean);*/ +void messagef(boolean, const char *, ...) + __attribute__((__format__(__printf__, 2, 3))); void mix_colors(void); void mix_random_rooms(void); int mon_can_go(const object *, int, int); @@ -759,7 +761,8 @@ extern boolean see_invisible; extern boolean sustain_strength; extern boolean trap_door; extern boolean wizard; -extern char hit_message[]; +#define HIT_MESSAGE_SIZE 80 +extern char hit_message[HIT_MESSAGE_SIZE]; #define HUNGER_STR_LEN 8 extern char hunger_str[HUNGER_STR_LEN]; extern char login_name[MAX_OPT_LEN]; diff --git a/rogue/room.c b/rogue/room.c index 3ea1dd4a..f81106bd 100644 --- a/rogue/room.c +++ b/rogue/room.c @@ -1,4 +1,4 @@ -/* $NetBSD: room.c,v 1.9 2006/04/02 00:13:29 christos Exp $ */ +/* $NetBSD: room.c,v 1.10 2007/12/27 23:53:01 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)room.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: room.c,v 1.9 2006/04/02 00:13:29 christos Exp $"); +__RCSID("$NetBSD: room.c,v 1.10 2007/12/27 23:53:01 dholland Exp $"); #endif #endif /* not lint */ @@ -60,7 +60,7 @@ boolean rooms_visited[MAXROOMS]; #define NOPTS 7 -struct option { +const struct option { const char *prompt; boolean is_bool; char **strval; @@ -84,15 +84,15 @@ struct option { }, { "Name (\"name\"): ", - 0, &nick_name + 0, &nick_name, (boolean *) 0 }, { "Fruit (\"fruit\"): ", - 0, &fruit + 0, &fruit, (boolean *) 0 }, { "Save file (\"file\"): ", - 0, &save_file + 0, &save_file, (boolean *) 0 } }; @@ -602,6 +602,11 @@ CH: ch = rgetchar(); } while ((ch != '\012') && (ch != '\015') && (ch != '\033')); if (j != 0) { + /* + * We rely on the option string being + * allocated to hold MAX_OPT_LEN+2 + * bytes. This is arranged in init.c. + */ (void) strcpy(*(options[i].strval), buf); } opt_show(i); @@ -626,7 +631,7 @@ opt_show(i) int i; { const char *s; - struct option *opt = &options[i]; + const struct option *opt = &options[i]; opt_erase(i); @@ -642,7 +647,7 @@ void opt_erase(i) int i; { - struct option *opt = &options[i]; + const struct option *opt = &options[i]; mvaddstr(i, 0, opt->prompt); clrtoeol(); diff --git a/rogue/save.c b/rogue/save.c index 06e14b75..9e91bae1 100644 --- a/rogue/save.c +++ b/rogue/save.c @@ -1,4 +1,4 @@ -/* $NetBSD: save.c,v 1.10 2006/03/17 23:04:01 abs Exp $ */ +/* $NetBSD: save.c,v 1.11 2007/12/27 23:53:01 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)save.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: save.c,v 1.10 2006/03/17 23:04:01 abs Exp $"); +__RCSID("$NetBSD: save.c,v 1.11 2007/12/27 23:53:01 dholland Exp $"); #endif #endif /* not lint */ @@ -64,12 +64,12 @@ save_game() { char fname[64]; - if (!get_input_line("file name?", save_file, fname, "game not saved", - 0, 1)) { + if (!get_input_line("file name?", save_file, fname, sizeof(fname), + "game not saved", 0, 1)) { return; } check_message(); - message(fname, 0); + messagef(0, "%s", fname); save_into_file(fname); } @@ -89,20 +89,25 @@ save_into_file(sfile) len = strlen(hptr) + strlen(sfile); name_buffer = md_malloc(len); if (name_buffer == NULL) { - message("out of memory for save file name", 0); + messagef(0, + "out of memory for save file name"); sfile = error_file; } else { (void) strcpy(name_buffer, hptr); (void) strcat(name_buffer, sfile+1); sfile = name_buffer; } + /* + * Note: name_buffer gets leaked. But it's small, + * and in the common case we're about to exit. + */ } } if (((fp = fopen(sfile, "w")) == NULL) || ((file_id = md_get_file_id(sfile)) == -1)) { if (fp) fclose(fp); - message("problem accessing the save file", 0); + messagef(0, "problem accessing the save file"); return; } md_ignore_signals(); @@ -160,7 +165,7 @@ restore(fname) FILE *fp; struct rogue_time saved_time, mod_time; char buf[4]; - char tbuf[40]; + char tbuf[MAX_OPT_LEN]; int new_file_id, saved_file_id; fp = NULL; @@ -351,10 +356,13 @@ read_string(s, fp, len) short n; r_read(fp, (char *) &n, sizeof(short)); - if (n > len) + if (n<=0 || (size_t)(unsigned short)n > len) { clean_up("read_string: corrupt game file"); + } r_read(fp, s, n); xxxx(s, n); + /* ensure null termination */ + s[n-1] = 0; } void @@ -389,7 +397,7 @@ r_write(fp, buf, n) { if (!write_failed) { if (fwrite(buf, sizeof(char), n, fp) != (size_t)n) { - message("write() failed, don't know why", 0); + messagef(0, "write() failed, don't know why"); sound_bell(); write_failed = 1; } diff --git a/rogue/score.c b/rogue/score.c index 070329a4..bb6b5461 100644 --- a/rogue/score.c +++ b/rogue/score.c @@ -1,4 +1,4 @@ -/* $NetBSD: score.c,v 1.11 2003/08/07 09:37:40 agc Exp $ */ +/* $NetBSD: score.c,v 1.12 2007/12/27 23:53:01 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)score.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: score.c,v 1.11 2003/08/07 09:37:40 agc Exp $"); +__RCSID("$NetBSD: score.c,v 1.12 2007/12/27 23:53:01 dholland Exp $"); #endif #endif /* not lint */ @@ -62,7 +62,10 @@ killed_by(monster, other) const object *monster; short other; { - char buf[128]; + const char *mechanism = "killed by something unknown (?)"; + char mechanism_buf[128]; + const char *article; + char message_buf[128]; md_ignore_signals(); @@ -73,32 +76,35 @@ killed_by(monster, other) if (other) { switch(other) { case HYPOTHERMIA: - (void) strcpy(buf, "died of hypothermia"); + mechanism = "died of hypothermia"; break; case STARVATION: - (void) strcpy(buf, "died of starvation"); + mechanism = "died of starvation"; break; case POISON_DART: - (void) strcpy(buf, "killed by a dart"); + mechanism = "killed by a dart"; break; case QUIT: - (void) strcpy(buf, "quit"); + mechanism = "quit"; break; case KFIRE: - (void) strcpy(buf, "killed by fire"); + mechanism = "killed by fire"; break; } } else { - (void) strcpy(buf, "Killed by "); if (is_vowel(m_names[monster->m_char - 'A'][0])) { - (void) strcat(buf, "an "); + article = "an"; } else { - (void) strcat(buf, "a "); + article = "a"; } - (void) strcat(buf, m_names[monster->m_char - 'A']); + snprintf(mechanism_buf, sizeof(mechanism_buf), + "Killed by %s %s", + article, m_names[monster->m_char - 'A']); + mechanism = mechanism_buf; } - (void) strcat(buf, " with "); - sprintf(buf+strlen(buf), "%ld gold", rogue.gold); + snprintf(message_buf, sizeof(message_buf), + "%s with %ld gold", mechanism, rogue.gold); + if ((!other) && (!no_skull)) { clear(); mvaddstr(4, 32, "__---------__"); @@ -118,11 +124,11 @@ killed_by(monster, other) mvaddstr(18, 31, "\\_ _/"); mvaddstr(19, 33, "~---------~"); center(21, nick_name); - center(22, buf); + center(22, message_buf); } else { - message(buf, 0); + messagef(0, "%s", message_buf); } - message("", 0); + messagef(0, "%s", ""); /* gcc objects to just "" */ put_scores(monster, other); } @@ -143,8 +149,8 @@ win() mvaddstr(17, 11, "Congratulations, you have been admitted to the"); mvaddstr(18, 11, "Fighters' Guild. You return home, sell all your"); mvaddstr(19, 11, "treasures at great profit and retire into comfort."); - message("", 0); - message("", 0); + messagef(0, "%s", ""); /* gcc objects to just "" */ + messagef(0, "%s", ""); /* gcc objects to just "" */ id_all(); sell_pack(); put_scores((object *) 0, WIN); @@ -154,7 +160,7 @@ void quit(from_intrpt) boolean from_intrpt; { - char buf[128]; + char buf[DCOLS]; short i, orow, ocol; boolean mc; @@ -173,7 +179,7 @@ quit(from_intrpt) } } check_message(); - message("really quit?", 1); + messagef(1, "really quit?"); if (rgetchar() != 'y') { md_heed_signals(); check_message(); @@ -194,17 +200,157 @@ quit(from_intrpt) killed_by((object *) 0, QUIT); } +/* + * The score file on disk is up to ten entries of the form + * score block [80 bytes] + * nickname block [30 bytes] + * + * The score block is to be parsed as follows: + * bytes 0-1 Rank (" 1" to "10") + * bytes 2-4 space padding + * bytes 5-15 Score/gold + * byte 15 up to a ':' Login name + * past the ':' Death mechanism + * + * The nickname block is an alternate name to be printed in place of the + * login name. Both blocks are supposed to contain a null-terminator. + */ + +struct score_entry { + long gold; + char username[80]; + char death[80]; + char nickname[30]; +}; + +#define NUM_SCORE_ENTRIES 10 + +static void pad_spaces __P((char *, size_t)); +static void unpad_spaces(char *); +static int read_score_entry __P((struct score_entry *, FILE *)); +static void write_score_entry __P((const struct score_entry *, int, FILE *)); +static void make_score __P((struct score_entry *, const object *, int)); + + +static +void +pad_spaces(str, len) + char *str; + size_t len; +{ + size_t x; + for (x=strlen(str); x0 && str[x-1]==' '; x--); + str[x] = 0; +} + +static +int +read_score_entry(se, fp) + struct score_entry *se; + FILE *fp; +{ + char score_block[80]; + char nickname_block[30]; + size_t n, x; + + n = fread(score_block, 1, sizeof(score_block), fp); + if (n==0) { + /* EOF */ + return 0; + } + if (n != sizeof(score_block)) { + sf_error(); + } + + n = fread(nickname_block, 1, sizeof(nickname_block), fp); + if (n != sizeof(nickname_block)) { + sf_error(); + } + + xxxx(score_block, sizeof(score_block)); + xxxx(nickname_block, sizeof(nickname_block)); + + /* Ensure null termination */ + score_block[sizeof(score_block)-1] = 0; + nickname_block[sizeof(nickname_block)-1] = 0; + + /* If there are other nulls in the score block, file is corrupt */ + if (strlen(score_block)!=sizeof(score_block)-1) { + sf_error(); + } + /* but this is NOT true of the nickname block */ + + /* quash trailing spaces */ + unpad_spaces(score_block); + unpad_spaces(nickname_block); + + for (x=5; score_block[x] == ' '; x++); + se->gold = lget_number(score_block+x); + + for (x=15; score_block[x] != 0 && score_block[x] != ':'; x++); + if (score_block[x] == 0) { + sf_error(); + } + score_block[x++] = 0; + strlcpy(se->username, score_block+15, sizeof(se->username)); + + strlcpy(se->death, score_block+x, sizeof(se->death)); + strlcpy(se->nickname, nickname_block, sizeof(se->nickname)); + + return 1; +} + +static +void +write_score_entry(se, rank, fp) + const struct score_entry *se; + int rank; + FILE *fp; +{ + char score_block[80]; + char nickname_block[30]; + + /* avoid writing crap to score file */ + memset(score_block, 0, sizeof(score_block)); + memset(nickname_block, 0, sizeof(nickname_block)); + + snprintf(score_block, sizeof(score_block), + "%2d %6ld %s: %s", + rank+1, se->gold, se->username, se->death); + strlcpy(nickname_block, se->nickname, sizeof(nickname_block)); + + /* pad blocks out with spaces */ + pad_spaces(score_block, sizeof(score_block)); + /*pad_spaces(nickname_block, sizeof(nickname_block)); -- wrong! */ + + xxxx(score_block, sizeof(score_block)); + xxxx(nickname_block, sizeof(nickname_block)); + + fwrite(score_block, 1, sizeof(score_block), fp); + fwrite(nickname_block, 1, sizeof(nickname_block), fp); +} + void put_scores(monster, other) const object *monster; short other; { - short i, n, rank = 10, x, ne = 0, found_player = -1; - char scores[10][82]; - char n_names[10][30]; - char buf[128]; + short i, rank=-1, found_player = -1, numscores = 0; + struct score_entry scores[NUM_SCORE_ENTRIES]; + const char *name; FILE *fp; - long s; boolean dopause = score_only; md_lock(1); @@ -213,180 +359,172 @@ put_scores(monster, other) if ((fp = fopen(_PATH_SCOREFILE, "r+")) == NULL && (fp = fopen(_PATH_SCOREFILE, "w+")) == NULL) { setegid(gid); - message("cannot read/write/create score file", 0); + messagef(0, "cannot read/write/create score file"); sf_error(); } setegid(gid); rewind(fp); (void) xxx(1); - for (i = 0; i < 10; i++) { - if (((n = fread(scores[i], sizeof(char), 80, fp)) < 80) && (n != 0)) { - sf_error(); - } else if (n != 0) { - xxxx(scores[i], 80); - if ((n = fread(n_names[i], sizeof(char), 30, fp)) < 30) { - sf_error(); - } - xxxx(n_names[i], 30); - } else { + for (numscores = 0; numscores < NUM_SCORE_ENTRIES; numscores++) { + if (read_score_entry(&scores[numscores], fp) == 0) { break; } - ne++; - if ((!score_only) && (found_player == -1)) { - if (!name_cmp(scores[i]+15, login_name)) { - x = 5; - while (scores[i][x] == ' ') { - x++; - } - s = lget_number(scores[i] + x); - if (rogue.gold < s) { - score_only = 1; - } else { - found_player = i; - } + } + + /* Search the score list. */ + for (i=0; i= s) { + /* if we aren't better than anyone, add at end. */ + rank = numscores; + + /* Otherwise, find our slot. */ + for (i = 0; i < numscores; i++) { + if (rogue.gold >= scores[i].gold) { rank = i; break; } } - if (ne == 0) { - rank = 0; - } else if ((ne < 10) && (rank == 10)) { - rank = ne; - } - if (rank < 10) { - insert_score(scores, n_names, nick_name, rank, ne, - monster, other); - if (ne < 10) { - ne++; + + if (rank < NUM_SCORE_ENTRIES) { + /* Open up a slot */ + for (i = numscores; i > rank; i--) { + scores[i] = scores[i-1]; } + numscores++; + + /* Put our info in the slot */ + make_score(&scores[rank], monster, other); } + + /* Now rewrite the score file */ + + md_ignore_signals(); rewind(fp); + (void) xxx(1); + + for (i = 0; i < numscores; i++) { + write_score_entry(&scores[i], i, fp); + } } + md_lock(0); + fclose(fp); + + /* Display the scores */ clear(); mvaddstr(3, 30, "Top Ten Rogueists"); mvaddstr(8, 0, "Rank Score Name"); - md_ignore_signals(); - - (void) xxx(1); - - for (i = 0; i < ne; i++) { + for (i = 0; i < numscores; i++) { if (i == rank) { standout(); } - if (i == 9) { - scores[i][0] = '1'; - scores[i][1] = '0'; + + if (scores[i].nickname[0]) { + name = scores[i].nickname; } else { - scores[i][0] = ' '; - scores[i][1] = i + '1'; - } - nickize(buf, scores[i], n_names[i]); - mvaddstr(i+10, 0, buf); - if (rank < 10) { - xxxx(scores[i], 80); - fwrite(scores[i], sizeof(char), 80, fp); - xxxx(n_names[i], 30); - fwrite(n_names[i], sizeof(char), 30, fp); + name = scores[i].username; } + + mvprintw(i+10, 0, "%2d %6ld %s: %s", + i+1, scores[i].gold, name, scores[i].death); + if (i == rank) { standend(); } } - md_lock(0); refresh(); - fclose(fp); - message("", 0); + messagef(0, "%s", ""); /* gcc objects to just "" */ if (dopause) { - message("", 0); + messagef(0, "%s", ""); } clean_up(""); } +static void -insert_score(scores, n_names, n_name, rank, n, monster, other) - char scores[][82]; - char n_names[][30]; - const char *n_name; - short rank, n; +make_score(se, monster, other) + struct score_entry *se; const object *monster; int other; { - short i; - char buf[128]; + const char *death = "bolts from the blue (?)"; + const char *hasamulet; + char deathbuf[80]; - if (n > 0) { - for (i = n; i > rank; i--) { - if ((i < 10) && (i > 0)) { - (void) strcpy(scores[i], scores[i-1]); - (void) strcpy(n_names[i], n_names[i-1]); - } - } - } - sprintf(buf, "%2d %6ld %s: ", rank+1, (long)rogue.gold, - login_name); + se->gold = rogue.gold; + strlcpy(se->username, login_name, sizeof(se->username)); if (other) { switch(other) { case HYPOTHERMIA: - (void) strcat(buf, "died of hypothermia"); + death = "died of hypothermia"; break; case STARVATION: - (void) strcat(buf, "died of starvation"); + death = "died of starvation"; break; case POISON_DART: - (void) strcat(buf, "killed by a dart"); + death = "killed by a dart"; break; case QUIT: - (void) strcat(buf, "quit"); + death = "quit"; break; case WIN: - (void) strcat(buf, "a total winner"); + death = "a total winner"; break; case KFIRE: - (void) strcat(buf, "killed by fire"); + death = "killed by fire"; break; } } else { - (void) strcat(buf, "killed by "); - if (is_vowel(m_names[monster->m_char - 'A'][0])) { - (void) strcat(buf, "an "); + const char *mn, *article; + + mn = m_names[monster->m_char - 'A']; + if (is_vowel(mn[0])) { + article = "an"; } else { - (void) strcat(buf, "a "); + article = "a"; } - (void) strcat(buf, m_names[monster->m_char - 'A']); - } - sprintf(buf+strlen(buf), " on level %d ", max_level); - if ((other != WIN) && has_amulet()) { - (void) strcat(buf, "with amulet"); + + snprintf(deathbuf, sizeof(deathbuf), + "killed by %s %s", article, mn); + death = deathbuf; } - for (i = strlen(buf); i < 79; i++) { - buf[i] = ' '; + + if (other != WIN && has_amulet()) { + hasamulet = " with amulet"; + } else { + hasamulet = ""; } - buf[79] = 0; - (void) strcpy(scores[rank], buf); - (void) strcpy(n_names[rank], n_name); + + snprintf(se->death, sizeof(se->death), "%s on level %d%s", + death, max_level, hasamulet); + + strlcpy(se->nickname, nick_name, sizeof(se->nickname)); } boolean @@ -419,9 +557,8 @@ sell_pack() rogue.gold += val; if (row < DROWS) { - sprintf(buf, "%5d ", val); - get_desc(obj, buf+11); - mvaddstr(row++, 0, buf); + get_desc(obj, buf, sizeof(buf)); + mvprintw(row++, 0, "%5d %s", val, buf); } } obj = obj->next_object; @@ -430,7 +567,7 @@ sell_pack() if (rogue.gold > MAX_GOLD) { rogue.gold = MAX_GOLD; } - message("", 0); + messagef(0, "%s", ""); /* gcc objects to just "" */ } int @@ -504,23 +641,6 @@ id_all() } } -int -name_cmp(s1, s2) - char *s1; - const char *s2; -{ - short i = 0; - int r; - - while(s1[i] != ':') { - i++; - } - s1[i] = 0; - r = strcmp(s1, s2); - s1[i] = ':'; - return(r); -} - void xxxx(buf, n) char *buf; @@ -556,33 +676,6 @@ xxx(st) return(r); } -void -nickize(buf, score, n_name) - char *buf; - const char *score, *n_name; -{ - short i = 15, j; - - if (!n_name[0]) { - (void) strcpy(buf, score); - } else { - (void) strncpy(buf, score, 16); - - while (score[i] != ':') { - i++; - } - - (void) strcpy(buf+15, n_name); - j = strlen(buf); - - while (score[i]) { - buf[j++] = score[i++]; - } - buf[j] = 0; - buf[79] = 0; - } -} - void center(row, buf) short row; @@ -598,6 +691,6 @@ void sf_error() { md_lock(0); - message("", 1); + messagef(1, "%s", ""); /* gcc objects to just "" */ clean_up("sorry, score file is out of order"); } diff --git a/rogue/spec_hit.c b/rogue/spec_hit.c index 423f7416..9e842511 100644 --- a/rogue/spec_hit.c +++ b/rogue/spec_hit.c @@ -1,4 +1,4 @@ -/* $NetBSD: spec_hit.c,v 1.5 2003/08/07 09:37:40 agc Exp $ */ +/* $NetBSD: spec_hit.c,v 1.6 2007/12/27 23:53:01 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)spec_hit.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: spec_hit.c,v 1.5 2003/08/07 09:37:40 agc Exp $"); +__RCSID("$NetBSD: spec_hit.c,v 1.6 2007/12/27 23:53:01 dholland Exp $"); #endif #endif /* not lint */ @@ -100,12 +100,12 @@ rust(monster) } if ((rogue.armor->is_protected) || maintain_armor) { if (monster && (!(monster->m_flags & RUST_VANISHED))) { - message("the rust vanishes instantly", 0); + messagef(0, "the rust vanishes instantly"); monster->m_flags |= RUST_VANISHED; } } else { rogue.armor->d_enchant--; - message("your armor weakens", 0); + messagef(0, "your armor weakens"); print_stats(STAT_ARMOR); } } @@ -127,7 +127,7 @@ freeze(monster) if (freeze_percent > 10) { monster->m_flags |= FREEZING_ROGUE; - message("you are frozen", 1); + messagef(1, "you are frozen"); n = get_rand(4, 8); for (i = 0; i < n; i++) { @@ -139,7 +139,7 @@ freeze(monster) } killed_by((object *)0, HYPOTHERMIA); } - message(you_can_move_again, 1); + messagef(1, you_can_move_again); monster->m_flags &= (~FREEZING_ROGUE); } } @@ -160,7 +160,7 @@ steal_gold(monster) amount = rogue.gold; } rogue.gold -= amount; - message("your purse feels lighter", 0); + messagef(0, "your purse feels lighter"); print_stats(STAT_GOLD); disappear(monster); } @@ -205,13 +205,12 @@ steal_item(monster) } } } - (void) strcpy(desc, "she stole "); if (obj->what_is != WEAPON) { t = obj->quantity; obj->quantity = 1; } - get_desc(obj, desc+10); - message(desc, 0); + get_desc(obj, desc, sizeof(desc)); + messagef(0, "she stole %s", desc); obj->quantity = ((obj->what_is != WEAPON) ? t : 1); @@ -363,16 +362,13 @@ boolean check_imitator(monster) object *monster; { - char msg[80]; - if (monster->m_flags & IMITATES) { wake_up(monster); if (!blind) { mvaddch(monster->row, monster->col, get_dungeon_char(monster->row, monster->col)); check_message(); - sprintf(msg, "wait, that's a %s!", mon_name(monster)); - message(msg, 1); + messagef(1, "wait, that's a %s!", mon_name(monster)); } return(1); } @@ -400,7 +396,6 @@ sting(monster) object *monster; { short sting_chance = 35; - char msg[80]; if ((rogue.str_current <= 3) || sustain_strength) { return; @@ -411,9 +406,8 @@ sting(monster) sting_chance -= (6 * ((rogue.exp + ring_exp) - 8)); } if (rand_percent(sting_chance)) { - sprintf(msg, "the %s's bite has weakened you", - mon_name(monster)); - message(msg, 0); + messagef(0, "the %s's bite has weakened you", + mon_name(monster)); rogue.str_current--; print_stats(STAT_STRENGTH); } @@ -450,7 +444,7 @@ drain_life() n = get_rand(1, 3); /* 1 Hp, 2 Str, 3 both */ if ((n != 2) || (!sustain_strength)) { - message("you feel weaker", 0); + messagef(0, "you feel weaker"); } if (n != 2) { rogue.hp_max--; @@ -472,8 +466,6 @@ boolean m_confuse(monster) object *monster; { - char msg[80]; - if (!rogue_can_see(monster->row, monster->col)) { return(0); } @@ -483,8 +475,8 @@ m_confuse(monster) } if (rand_percent(55)) { monster->m_flags &= (~CONFUSES); - sprintf(msg, "the gaze of the %s has confused you", mon_name(monster)); - message(msg, 1); + messagef(1, "the gaze of the %s has confused you", + mon_name(monster)); cnfs(); return(1); } diff --git a/rogue/throw.c b/rogue/throw.c index 1531bb46..0312503c 100644 --- a/rogue/throw.c +++ b/rogue/throw.c @@ -1,4 +1,4 @@ -/* $NetBSD: throw.c,v 1.7 2006/03/30 05:04:22 jnemeth Exp $ */ +/* $NetBSD: throw.c,v 1.8 2007/12/27 23:53:01 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)throw.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: throw.c,v 1.7 2006/03/30 05:04:22 jnemeth Exp $"); +__RCSID("$NetBSD: throw.c,v 1.8 2007/12/27 23:53:01 dholland Exp $"); #endif #endif /* not lint */ @@ -67,7 +67,7 @@ throw() while (!is_direction(dir = rgetchar(), &d)) { sound_bell(); if (first_miss) { - message("direction? ", 0); + messagef(0, "direction? "); first_miss = 0; } } @@ -81,11 +81,11 @@ throw() check_message(); if (!(weapon = get_letter_object(wch))) { - message("no such item.", 0); + messagef(0, "no such item."); return; } if ((weapon->in_use_flags & BEING_USED) && weapon->is_cursed) { - message(curse_message, 0); + messagef(0, curse_message); return; } row = rogue.row; col = rogue.col; @@ -142,15 +142,15 @@ throw_at_monster(monster, weapon) } t = weapon->quantity; weapon->quantity = 1; - sprintf(hit_message, "the %s", name_of(weapon)); + snprintf(hit_message, HIT_MESSAGE_SIZE, "the %s", name_of(weapon)); weapon->quantity = t; if (!rand_percent(hit_chance)) { - (void) strcat(hit_message, "misses "); + (void) strlcat(hit_message, "misses ", HIT_MESSAGE_SIZE); return(0); } s_con_mon(monster); - (void) strcat(hit_message, "hit "); + (void) strlcat(hit_message, "hit ", HIT_MESSAGE_SIZE); (void) mon_damage(monster, damage); return(1); } @@ -207,7 +207,6 @@ flop_weapon(weapon, row, col) { object *new_weapon, *monster; short i = 0; - char msg[80]; boolean found = 0; short mch, dch; unsigned short mon; @@ -257,10 +256,9 @@ flop_weapon(weapon, row, col) t = weapon->quantity; weapon->quantity = 1; - sprintf(msg, "the %svanishes as it hits the ground", - name_of(weapon)); + messagef(0, "the %svanishes as it hits the ground", + name_of(weapon)); weapon->quantity = t; - message(msg, 0); } } diff --git a/rogue/trap.c b/rogue/trap.c index 9ef133bc..e0987cb0 100644 --- a/rogue/trap.c +++ b/rogue/trap.c @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.6 2003/08/07 09:37:40 agc Exp $ */ +/* $NetBSD: trap.c,v 1.7 2007/12/27 23:53:01 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)trap.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: trap.c,v 1.6 2003/08/07 09:37:40 agc Exp $"); +__RCSID("$NetBSD: trap.c,v 1.7 2007/12/27 23:53:01 dholland Exp $"); #endif #endif /* not lint */ @@ -99,7 +99,7 @@ trap_player(row, col) } dungeon[row][col] &= (~HIDDEN); if (rand_percent(rogue.exp + ring_exp)) { - message("the trap failed", 1); + messagef(1, "the trap failed"); return; } switch(t) { @@ -108,7 +108,7 @@ trap_player(row, col) new_level_message = trap_strings[(t*2)+1]; break; case BEAR_TRAP: - message(trap_strings[(t*2)+1], 1); + messagef(1, "%s", trap_strings[(t*2)+1]); bear_trap = get_rand(4, 7); break; case TELE_TRAP: @@ -116,7 +116,7 @@ trap_player(row, col) tele(); break; case DART_TRAP: - message(trap_strings[(t*2)+1], 1); + messagef(1, "%s", trap_strings[(t*2)+1]); rogue.hp_current -= get_damage("1d6", 1); if (rogue.hp_current <= 0) { rogue.hp_current = 0; @@ -131,11 +131,11 @@ trap_player(row, col) } break; case SLEEPING_GAS_TRAP: - message(trap_strings[(t*2)+1], 1); + messagef(1, "%s", trap_strings[(t*2)+1]); take_a_nap(); break; case RUST_TRAP: - message(trap_strings[(t*2)+1], 1); + messagef(1, "%s", trap_strings[(t*2)+1]); rust((object *) 0); break; } @@ -191,7 +191,7 @@ id_trap() { short dir, row, col, d, t; - message("direction? ", 0); + messagef(0, "direction? "); while (!is_direction(dir = rgetchar(), &d)) { sound_bell(); @@ -208,9 +208,9 @@ id_trap() if ((dungeon[row][col] & TRAP) && (!(dungeon[row][col] & HIDDEN))) { t = trap_at(row, col); - message(trap_strings[t*2], 0); + messagef(0, "%s", trap_strings[t*2]); } else { - message("no trap there", 0); + messagef(0, "no trap there"); } } @@ -269,7 +269,8 @@ search(n, is_auto) shown++; if (dungeon[row][col] & TRAP) { t = trap_at(row, col); - message(trap_strings[t*2], 1); + messagef(1, "%s", + trap_strings[t*2]); } } } diff --git a/rogue/use.c b/rogue/use.c index 2e74fcea..904680b2 100644 --- a/rogue/use.c +++ b/rogue/use.c @@ -1,4 +1,4 @@ -/* $NetBSD: use.c,v 1.6 2003/08/07 09:37:40 agc Exp $ */ +/* $NetBSD: use.c,v 1.7 2007/12/27 23:53:01 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)use.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: use.c,v 1.6 2003/08/07 09:37:40 agc Exp $"); +__RCSID("$NetBSD: use.c,v 1.7 2007/12/27 23:53:01 dholland Exp $"); #endif #endif /* not lint */ @@ -70,7 +70,6 @@ void quaff() { short ch; - char buf[80]; object *obj; ch = pack_letter("quaff what?", POTION); @@ -79,17 +78,16 @@ quaff() return; } if (!(obj = get_letter_object(ch))) { - message("no such item.", 0); + messagef(0, "no such item."); return; } if (obj->what_is != POTION) { - message("you can't drink that", 0); + messagef(0, "you can't drink that"); return; } switch(obj->which_kind) { case INCREASE_STRENGTH: - message("you feel stronger now, what bulging muscles!", - 0); + messagef(0, "you feel stronger now, what bulging muscles!"); rogue.str_current++; if (rogue.str_current > rogue.str_max) { rogue.str_max = rogue.str_current; @@ -97,14 +95,14 @@ quaff() break; case RESTORE_STRENGTH: rogue.str_current = rogue.str_max; - message("this tastes great, you feel warm all over", 0); + messagef(0, "this tastes great, you feel warm all over"); break; case HEALING: - message("you begin to feel better", 0); + messagef(0, "you begin to feel better"); potion_heal(0); break; case EXTRA_HEALING: - message("you begin to feel much better", 0); + messagef(0, "you begin to feel much better"); potion_heal(1); break; case POISON: @@ -114,27 +112,27 @@ quaff() rogue.str_current = 1; } } - message("you feel very sick now", 0); + messagef(0, "you feel very sick now"); if (halluc) { unhallucinate(); } break; case RAISE_LEVEL: rogue.exp_points = level_points[rogue.exp - 1]; - message("you suddenly feel much more skillful", 0); + messagef(0, "you suddenly feel much more skillful"); add_exp(1, 1); break; case BLINDNESS: go_blind(); break; case HALLUCINATION: - message("oh wow, everything seems so cosmic", 0); + messagef(0, "oh wow, everything seems so cosmic"); halluc += get_rand(500, 800); break; case DETECT_MONSTER: show_monsters(); if (!(level_monsters.next_monster)) { - message(strange_feeling, 0); + messagef(0, "%s", strange_feeling); } break; case DETECT_OBJECTS: @@ -143,29 +141,29 @@ quaff() show_objects(); } } else { - message(strange_feeling, 0); + messagef(0, "%s", strange_feeling); } break; case CONFUSION: - message((halluc ? "what a trippy feeling" : - "you feel confused"), 0); + messagef(0, (halluc ? "what a trippy feeling" : + "you feel confused")); cnfs(); break; case LEVITATION: - message("you start to float in the air", 0); + messagef(0, "you start to float in the air"); levitate += get_rand(15, 30); being_held = bear_trap = 0; break; case HASTE_SELF: - message("you feel yourself moving much faster", 0); + messagef(0, "you feel yourself moving much faster"); haste_self += get_rand(11, 21); if (!(haste_self % 2)) { haste_self++; } break; case SEE_INVISIBLE: - sprintf(buf, "hmm, this potion tastes like %sjuice", fruit); - message(buf, 0); + messagef(0, "hmm, this potion tastes like %sjuice", + fruit); if (blind) { unblind(); } @@ -185,7 +183,6 @@ read_scroll() { short ch; object *obj; - char msg[DCOLS]; ch = pack_letter("read what?", SCROL); @@ -193,17 +190,16 @@ read_scroll() return; } if (!(obj = get_letter_object(ch))) { - message("no such item.", 0); + messagef(0, "no such item."); return; } if (obj->what_is != SCROL) { - message("you can't read that", 0); + messagef(0, "you can't read that"); return; } switch(obj->which_kind) { case SCARE_MONSTER: - message("you hear a maniacal laughter in the distance", - 0); + messagef(0, "you hear a maniacal laughter in the distance"); break; case HOLD_MONSTER: hold_monster(); @@ -211,11 +207,10 @@ read_scroll() case ENCH_WEAPON: if (rogue.weapon) { if (rogue.weapon->what_is == WEAPON) { - sprintf(msg, "your %sglow%s %sfor a moment", - name_of(rogue.weapon), - ((rogue.weapon->quantity <= 1) ? "s" : ""), - get_ench_color()); - message(msg, 0); + messagef(0, "your %sglow%s %sfor a moment", + name_of(rogue.weapon), + ((rogue.weapon->quantity <= 1) ? "s" : ""), + get_ench_color()); if (coin_toss()) { rogue.weapon->hit_enchant++; } else { @@ -224,23 +219,22 @@ read_scroll() } rogue.weapon->is_cursed = 0; } else { - message("your hands tingle", 0); + messagef(0, "your hands tingle"); } break; case ENCH_ARMOR: if (rogue.armor) { - sprintf(msg, "your armor glows %sfor a moment", - get_ench_color()); - message(msg, 0); + messagef(0, "your armor glows %sfor a moment", + get_ench_color()); rogue.armor->d_enchant++; rogue.armor->is_cursed = 0; print_stats(STAT_ARMOR); } else { - message("your skin crawls", 0); + messagef(0, "your skin crawls"); } break; case IDENTIFY: - message("this is a scroll of identify", 0); + messagef(0, "this is a scroll of identify"); obj->identified = 1; id_scrolls[obj->which_kind].id_status = IDENTIFIED; idntfy(); @@ -249,22 +243,22 @@ read_scroll() tele(); break; case SLEEP: - message("you fall asleep", 0); + messagef(0, "you fall asleep"); take_a_nap(); break; case PROTECT_ARMOR: if (rogue.armor) { - message( "your armor is covered by a shimmering gold shield",0); + messagef(0, "your armor is covered by a shimmering gold shield"); rogue.armor->is_protected = 1; rogue.armor->is_cursed = 0; } else { - message("your acne seems to have disappeared", 0); + messagef(0, "your acne seems to have disappeared"); } break; case REMOVE_CURSE: - message((!halluc) ? + messagef(0, (!halluc) ? "you feel as though someone is watching over you" : - "you feel in touch with the universal oneness", 0); + "you feel in touch with the universal oneness"); uncurse_all(); break; case CREATE_MONSTER: @@ -274,13 +268,13 @@ read_scroll() aggravate(); break; case MAGIC_MAPPING: - message("this scroll seems to have a map on it", 0); + messagef(0, "this scroll seems to have a map on it"); draw_magic_map(); break; case CON_MON: con_mon = 1; - sprintf(msg, "your hands glow %sfor a moment", get_ench_color()); - message(msg, 0); + messagef(0, "your hands glow %sfor a moment", + get_ench_color()); break; } if (id_scrolls[obj->which_kind].id_status != CALLED) { @@ -378,8 +372,8 @@ AGAIN: return; } if (!(obj = get_letter_object(ch))) { - message("no such item, try again", 0); - message("", 0); + messagef(0, "no such item, try again"); + messagef(0, "%s", ""); /* gcc objects to just "" */ check_message(); goto AGAIN; } @@ -388,8 +382,8 @@ AGAIN: id_table = get_id_table(obj); id_table[obj->which_kind].id_status = IDENTIFIED; } - get_desc(obj, desc); - message(desc, 0); + get_desc(obj, desc, sizeof(desc)); + messagef(0, "%s", desc); } void @@ -398,7 +392,6 @@ eat() short ch; short moves; object *obj; - char buf[70]; ch = pack_letter("eat what?", FOOD); @@ -406,24 +399,23 @@ eat() return; } if (!(obj = get_letter_object(ch))) { - message("no such item.", 0); + messagef(0, "no such item."); return; } if (obj->what_is != FOOD) { - message("you can't eat that", 0); + messagef(0, "you can't eat that"); return; } if ((obj->which_kind == FRUIT) || rand_percent(60)) { moves = get_rand(950, 1150); if (obj->which_kind == RATION) { - message("yum, that tasted good", 0); + messagef(0, "yum, that tasted good"); } else { - sprintf(buf, "my, that was a yummy %s", fruit); - message(buf, 0); + messagef(0, "my, that was a yummy %s", fruit); } } else { moves = get_rand(750, 950); - message("yuk, that food tasted awful", 0); + messagef(0, "yuk, that food tasted awful"); add_exp(2, 1); } rogue.moves_left /= 3; @@ -459,11 +451,11 @@ hold_monster() } } if (mcount == 0) { - message("you feel a strange sense of loss", 0); + messagef(0, "you feel a strange sense of loss"); } else if (mcount == 1) { - message("the monster freezes", 0); + messagef(0, "the monster freezes"); } else { - message("the monsters around you freeze", 0); + messagef(0, "the monsters around you freeze"); } } @@ -515,14 +507,14 @@ unhallucinate() { halluc = 0; relight(); - message("everything looks SO boring now", 1); + messagef(1, "everything looks SO boring now"); } void unblind() { blind = 0; - message("the veil of darkness lifts", 1); + messagef(1, "the veil of darkness lifts"); relight(); if (halluc) { hallucinate(); @@ -555,7 +547,7 @@ take_a_nap() mv_mons(); } md_sleep(1); - message(you_can_move_again, 0); + messagef(0, "%s", you_can_move_again); } void @@ -564,7 +556,7 @@ go_blind() short i, j; if (!blind) { - message("a cloak of darkness falls around you", 0); + messagef(0, "a cloak of darkness falls around you"); } blind += get_rand(500, 800); @@ -610,11 +602,8 @@ cnfs() void unconfuse() { - char msg[80]; - confused = 0; - sprintf(msg, "you feel less %s now", (halluc ? "trippy" : "confused")); - message(msg, 1); + messagef(1, "you feel less %s now", (halluc ? "trippy" : "confused")); } void diff --git a/rogue/zap.c b/rogue/zap.c index 73279c0f..312de30c 100644 --- a/rogue/zap.c +++ b/rogue/zap.c @@ -1,4 +1,4 @@ -/* $NetBSD: zap.c,v 1.6 2003/08/07 09:37:40 agc Exp $ */ +/* $NetBSD: zap.c,v 1.7 2007/12/27 23:53:01 dholland Exp $ */ /* * Copyright (c) 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)zap.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: zap.c,v 1.6 2003/08/07 09:37:40 agc Exp $"); +__RCSID("$NetBSD: zap.c,v 1.7 2007/12/27 23:53:01 dholland Exp $"); #endif #endif /* not lint */ @@ -69,7 +69,7 @@ zapp() while (!is_direction(dir = rgetchar(), &d)) { sound_bell(); if (first_miss) { - message("direction? ", 0); + messagef(0, "direction? "); first_miss = 0; } } @@ -83,15 +83,15 @@ zapp() check_message(); if (!(wand = get_letter_object(wch))) { - message("no such item.", 0); + messagef(0, "no such item."); return; } if (wand->what_is != WAND) { - message("you can't zap with that", 0); + messagef(0, "you can't zap with that"); return; } if (wand->class <= 0) { - message("nothing happens", 0); + messagef(0, "nothing happens"); } else { wand->class--; row = rogue.row; col = rogue.col; @@ -198,7 +198,7 @@ zap_monster(monster, kind) FLAMES | IMITATES | CONFUSES | SEEKS_GOLD | HOLDS)); break; case DO_NOTHING: - message("nothing happens", 0); + messagef(0, "nothing happens"); break; } } @@ -230,17 +230,18 @@ wizardize() if (wizard) { wizard = 0; - message("not wizard anymore", 0); + messagef(0, "not wizard anymore"); } else { - if (get_input_line("wizard's password:", "", buf, "", 0, 0)) { + if (get_input_line("wizard's password:", "", buf, sizeof(buf), + "", 0, 0)) { (void) xxx(1); xxxx(buf, strlen(buf)); if (!strncmp(buf, "\247\104\126\272\115\243\027", 7)) { wizard = 1; score_only = 1; - message("Welcome, mighty wizard!", 0); + messagef(0, "Welcome, mighty wizard!"); } else { - message("sorry", 0); + messagef(0, "sorry"); } } } @@ -281,7 +282,6 @@ bounce(ball, dir, row, col, r) short ball, dir, row, col, r; { short orow, ocol; - char buf[DCOLS]; const char *s; short i, ch, new_dir = -1, damage; static short btime; @@ -298,8 +298,7 @@ bounce(ball, dir, row, col, r) s = "ice"; } if (r > 1) { - sprintf(buf, "the %s bounces", s); - message(buf, 0); + messagef(0, "the %s bounces", s); } orow = row; ocol = col; @@ -336,8 +335,8 @@ bounce(ball, dir, row, col, r) wake_up(monster); if (rand_percent(33)) { - sprintf(buf, "the %s misses the %s", s, mon_name(monster)); - message(buf, 0); + messagef(0, "the %s misses the %s", s, + mon_name(monster)); goto ND; } if (ball == FIRE) { @@ -352,14 +351,14 @@ bounce(ball, dir, row, col, r) } else { damage = (monster->hp_to_kill / 2) + 1; } - sprintf(buf, "the %s hits the %s", s, mon_name(monster)); - message(buf, 0); + messagef(0, "the %s hits the %s", s, + mon_name(monster)); (void) mon_damage(monster, damage); } else { damage = -1; if (!(monster->m_flags & FREEZES)) { if (rand_percent(33)) { - message("the monster is frozen", 0); + messagef(0, "the monster is frozen"); monster->m_flags |= (ASLEEP | NAPPING); monster->nap_length = get_rand(3, 6); } else { @@ -369,15 +368,14 @@ bounce(ball, dir, row, col, r) damage = -2; } if (damage != -1) { - sprintf(buf, "the %s hits the %s", s, mon_name(monster)); - message(buf, 0); + messagef(0, "the %s hits the %s", s, + mon_name(monster)); (void) mon_damage(monster, damage); } } } else if ((row == rogue.row) && (col == rogue.col)) { if (rand_percent(10 + (3 * get_armor_class(rogue.armor)))) { - sprintf(buf, "the %s misses", s); - message(buf, 0); + messagef(0, "the %s misses", s); goto ND; } else { damage = get_rand(3, (3 * rogue.exp)); @@ -385,10 +383,9 @@ bounce(ball, dir, row, col, r) damage = (damage * 3) / 2; damage -= get_armor_class(rogue.armor); } - sprintf(buf, "the %s hits", s); rogue_damage(damage, (object *) 0, ((ball == FIRE) ? KFIRE : HYPOTHERMIA)); - message(buf, 0); + messagef(0, "the %s hits", s); } } else { short nrow, ncol; -- cgit v1.2.3-56-ge451