Subject: bin/34750: string handling cleanup for rogue(6)
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <dholland@eecs.harvard.edu>
List: netbsd-bugs
Date: 10/07/2006 23:55:02
>Number: 34750
>Category: bin
>Synopsis: string handling cleanup for rogue(6)
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sat Oct 07 23:55:02 +0000 2006
>Originator: David A. Holland <dholland@eecs.harvard.edu>
>Release: NetBSD 4.99.1 (patches against 20061007)
>Organization:
Harvard EECS
>Environment:
System: NetBSD tanaqui 4.99.1 NetBSD 4.99.1 (TANAQUI) #5: Mon Aug 14 16:58:44 EDT 2006 dholland@tanaqui:/usr/src/sys/arch/i386/compile/TANAQUI i386
Architecture: i386
Machine: i386
>Description:
rogue has a lot of dodgy string handling. The worst (and the
glaringly exploitable) has already been fixed; this patch gets
rid of sprintf, unchecked strcpy, and so forth, and also
cleans up the score file handling.
It's not a security fix (AFAIK) but is a security prudence fix.
Something like that.
The patch is rather large, unfortunately.
>How-To-Repeat:
-
>Fix:
Index: hit.c
===================================================================
RCS file: /cvsroot/src/games/rogue/hit.c,v
retrieving revision 1.7
diff -u -r1.7 hit.c
--- hit.c 7 Aug 2003 09:37:37 -0000 1.7
+++ hit.c 7 Oct 2006 23:11:51 -0000
@@ -56,7 +56,7 @@
#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 @@
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 @@
}
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 @@
}
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,16 @@
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++;
+ if (ds[i] == '/') {
+ i++;
+ }
for (j = 0; j < n; j++) {
if (r) {
@@ -197,9 +203,6 @@
total += d;
}
}
- if (ds[i] == '/') {
- i++;
- }
}
return(total);
}
@@ -208,7 +211,7 @@
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 +219,14 @@
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 +319,7 @@
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 +347,7 @@
while (!is_direction(ch = rgetchar(), &d)) {
sound_bell();
if (first_miss) {
- message("direction?", 0);
+ messagef(0, "direction?");
first_miss = 0;
}
}
@@ -355,7 +361,7 @@
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 +471,7 @@
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;
}
}
Index: init.c
===================================================================
RCS file: /cvsroot/src/games/rogue/init.c,v
retrieving revision 1.13
diff -u -r1.13 init.c
--- init.c 7 Aug 2003 09:37:38 -0000 1.13
+++ init.c 7 Oct 2006 23:11:51 -0000
@@ -96,7 +96,8 @@
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 @@
did_int = 1;
} else {
check_message();
- message("interrupt", 1);
+ messagef(1, "interrupt");
}
md_heed_signals();
}
@@ -341,6 +342,7 @@
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 @@
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);
}
}
Index: inventory.c
===================================================================
RCS file: /cvsroot/src/games/rogue/inventory.c,v
retrieving revision 1.10
diff -u -r1.10 inventory.c
--- inventory.c 14 May 2006 03:15:50 -0000 1.10
+++ inventory.c 7 Oct 2006 23:11:51 -0000
@@ -53,6 +53,7 @@
*
*/
+#include <stdarg.h>
#include "rogue.h"
boolean is_wood[WANDS];
@@ -216,43 +217,56 @@
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 @@
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 @@
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 @@
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 @@
return(0);
}
check_message();
- message(com_id_tab[i].com_desc, 0);
+ messagef(0, "%s", com_id_tab[i].com_desc);
return(1);
}
@@ -395,18 +409,16 @@
(ch == '\002')) {
char until[18], buf[DCOLS];
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 @@
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,243 @@
{
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
-get_desc(obj, desc)
+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, ...)
+{
+ 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, 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 +700,8 @@
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 +712,8 @@
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 +721,7 @@
single_inv(ichar)
short ichar;
{
- short ch;
+ short ch, ch2;
char desc[DCOLS];
object *obj;
@@ -654,15 +731,12 @@
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 +768,13 @@
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 +784,8 @@
{
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 +854,5 @@
}
}
check_message();
- sprintf(buf, "'%c': %s", ch, id);
- message(buf, 0);
+ messagef(0, "'%c': %s", ch, id);
}
Index: level.c
===================================================================
RCS file: /cvsroot/src/games/rogue/level.c,v
retrieving revision 1.7
diff -u -r1.7 level.c
--- level.c 7 Aug 2003 09:37:38 -0000 1.7
+++ level.c 7 Oct 2006 23:11:52 -0000
@@ -769,8 +769,8 @@
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 @@
}
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 @@
{
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 @@
int e;
boolean promotion;
{
- char mbuf[40];
short new_exp;
short i, hp;
@@ -832,8 +831,7 @@
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 @@
void
show_average_hp()
{
- char mbuf[80];
float real_average;
float effective_average;
@@ -885,9 +882,8 @@
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
Index: machdep.c
===================================================================
RCS file: /cvsroot/src/games/rogue/machdep.c,v
retrieving revision 1.14
diff -u -r1.14 machdep.c
--- machdep.c 24 Apr 2006 19:00:30 -0000 1.14
+++ machdep.c 7 Oct 2006 23:11:52 -0000
@@ -456,7 +456,7 @@
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_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 @@
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
Index: message.c
===================================================================
RCS file: /cvsroot/src/games/rogue/message.c,v
retrieving revision 1.10
diff -u -r1.10 message.c
--- message.c 7 Aug 2003 09:37:38 -0000 1.10
+++ message.c 7 Oct 2006 23:11:52 -0000
@@ -55,6 +55,7 @@
#include <signal.h>
#include <termios.h>
+#include <stdarg.h>
#include "rogue.h"
char msgs[NMESSAGES][DCOLS] = {"", "", "", "", ""};
@@ -63,6 +64,9 @@
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 @@
}
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(' ');
@@ -103,6 +107,19 @@
}
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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);
@@ -312,37 +323,21 @@
}
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; j<DCOLS; j++) {
buf[j] = mvinch(i, j);
- if (!found_non_blank) {
- if ((buf[j] != ' ') || (j == 0)) {
- buf[j + ((j == 0) ? 0 : 1)] = 0;
- found_non_blank = 1;
- }
- }
}
+ /*buf[DCOLS] = 0; -- redundant */
+ for (j=DCOLS; j>0 && buf[j-1]==' '; j--);
+ buf[j] = 0;
+
fputs(buf, fp);
putc('\n', fp);
}
Index: monster.c
===================================================================
RCS file: /cvsroot/src/games/rogue/monster.c,v
retrieving revision 1.11
diff -u -r1.11 monster.c
--- monster.c 30 Mar 2006 04:10:04 -0000 1.11
+++ monster.c 7 Oct 2006 23:11:53 -0000
@@ -709,7 +709,7 @@
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 @@
{
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;
Index: move.c
===================================================================
RCS file: /cvsroot/src/games/rogue/move.c,v
retrieving revision 1.8
diff -u -r1.8 move.c
--- move.c 14 May 2006 03:15:50 -0000 1.8
+++ move.c 7 Oct 2006 23:11:53 -0000
@@ -66,7 +66,7 @@
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 @@
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 @@
}
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 @@
} 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 @@
while (!is_direction(ch = rgetchar(), &d)) {
sound_bell();
if (first_miss) {
- message("direction? ", 0);
+ messagef(0, "direction? ");
first_miss = 0;
}
}
@@ -382,19 +378,19 @@
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 @@
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 @@
}
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 @@
}
if (haste_self) {
if (!(--haste_self)) {
- message("you feel yourself slowing down", 0);
+ messagef(0, "you feel yourself slowing down");
}
}
heal();
Index: object.c
===================================================================
RCS file: /cvsroot/src/games/rogue/object.c,v
retrieving revision 1.10
diff -u -r1.10 object.c
--- object.c 30 Mar 2006 04:27:24 -0000 1.10
+++ object.c 7 Oct 2006 23:11:53 -0000
@@ -80,36 +80,36 @@
};
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_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 @@
obj = obj->next_object;
}
if (!obj) {
- message("object_at(): inconsistent", 1);
+ messagef(1, "object_at(): inconsistent");
}
}
return(obj);
@@ -637,7 +637,7 @@
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 @@
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 @@
}
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 @@
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);
}
Index: pack.c
===================================================================
RCS file: /cvsroot/src/games/rogue/pack.c,v
retrieving revision 1.7
diff -u -r1.7 pack.c
--- pack.c 7 Aug 2003 09:37:39 -0000 1.7
+++ pack.c 7 Oct 2006 23:11:54 -0000
@@ -110,18 +110,18 @@
*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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{
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)) {
Index: play.c
===================================================================
RCS file: /cvsroot/src/games/rogue/play.c,v
retrieving revision 1.6
diff -u -r1.6 play.c
--- play.c 7 Aug 2003 09:37:39 -0000 1.6
+++ play.c 7 Oct 2006 23:11:54 -0000
@@ -67,7 +67,7 @@
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 @@
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 @@
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 @@
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;
}
}
Index: ring.c
===================================================================
RCS file: /cvsroot/src/games/rogue/ring.c,v
retrieving revision 1.6
diff -u -r1.6 ring.c
--- ring.c 7 Aug 2003 09:37:39 -0000 1.6
+++ ring.c 7 Oct 2006 23:11:54 -0000
@@ -77,28 +77,28 @@
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 @@
}
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 @@
}
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 @@
} 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 @@
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 @@
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);
}
}
Index: rogue.h
===================================================================
RCS file: /cvsroot/src/games/rogue/rogue.h,v
retrieving revision 1.17
diff -u -r1.17 rogue.h
--- rogue.h 15 Feb 2005 12:54:50 -0000 1.17
+++ rogue.h 7 Oct 2006 23:11:55 -0000
@@ -515,14 +515,14 @@
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_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 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];
Index: room.c
===================================================================
RCS file: /cvsroot/src/games/rogue/room.c,v
retrieving revision 1.9
diff -u -r1.9 room.c
--- room.c 2 Apr 2006 00:13:29 -0000 1.9
+++ room.c 7 Oct 2006 23:11:55 -0000
@@ -60,7 +60,7 @@
#define NOPTS 7
-struct option {
+const struct option {
const char *prompt;
boolean is_bool;
char **strval;
@@ -84,15 +84,15 @@
},
{
"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 = 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 @@
int i;
{
const char *s;
- struct option *opt = &options[i];
+ const struct option *opt = &options[i];
opt_erase(i);
@@ -642,7 +647,7 @@
opt_erase(i)
int i;
{
- struct option *opt = &options[i];
+ const struct option *opt = &options[i];
mvaddstr(i, 0, opt->prompt);
clrtoeol();
Index: save.c
===================================================================
RCS file: /cvsroot/src/games/rogue/save.c,v
retrieving revision 1.10
diff -u -r1.10 save.c
--- save.c 17 Mar 2006 23:04:01 -0000 1.10
+++ save.c 7 Oct 2006 23:11:55 -0000
@@ -64,12 +64,12 @@
{
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 @@
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 @@
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 @@
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 @@
{
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;
}
Index: score.c
===================================================================
RCS file: /cvsroot/src/games/rogue/score.c,v
retrieving revision 1.11
diff -u -r1.11 score.c
--- score.c 7 Aug 2003 09:37:40 -0000 1.11
+++ score.c 7 Oct 2006 23:11:56 -0000
@@ -62,7 +62,10 @@
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 @@
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 @@
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 @@
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 @@
quit(from_intrpt)
boolean from_intrpt;
{
- char buf[128];
+ char buf[DCOLS];
short i, orow, ocol;
boolean mc;
@@ -173,7 +179,7 @@
}
}
check_message();
- message("really quit?", 1);
+ messagef(1, "really quit?");
if (rgetchar() != 'y') {
md_heed_signals();
check_message();
@@ -194,17 +200,157 @@
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); x<len-1; x++) {
+ str[x] = ' ';
+ }
+ str[len-1] = 0;
+}
+
+static
+void
+unpad_spaces(str)
+ char *str;
+{
+ size_t x;
+ for (x=strlen(str); x>0 && 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 @@
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<numscores; i++) {
+ if (!strcmp(scores[i].username, login_name)) {
+ /* found our score */
+ if (rogue.gold < scores[i].gold) {
+ /* we didn't do as well as last time */
+ score_only = 1;
+ } else {
+ /* we did better; mark entry for removal */
+ found_player = i;
}
+ break;
}
}
+
+ /* Remove a superseded entry, if any. */
if (found_player != -1) {
- ne--;
- for (i = found_player; i < ne; i++) {
- (void) strcpy(scores[i], scores[i+1]);
- (void) strcpy(n_names[i], n_names[i+1]);
+ numscores--;
+ for (i = found_player; i < numscores; i++) {
+ scores[i] = scores[i+1];
}
}
+
+ /* If we're going to insert ourselves, do it now */
if (!score_only) {
- for (i = 0; i < ne; i++) {
- x = 5;
- while (scores[i][x] == ' ') {
- x++;
- }
- s = lget_number(scores[i] + x);
- if (rogue.gold >= 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 @@
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 @@
if (rogue.gold > MAX_GOLD) {
rogue.gold = MAX_GOLD;
}
- message("", 0);
+ messagef(0, "%s", ""); /* gcc objects to just "" */
}
int
@@ -504,23 +641,6 @@
}
}
-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;
@@ -557,33 +677,6 @@
}
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;
const char *buf;
@@ -598,6 +691,6 @@
sf_error()
{
md_lock(0);
- message("", 1);
+ messagef(1, "%s", ""); /* gcc objects to just "" */
clean_up("sorry, score file is out of order");
}
Index: spec_hit.c
===================================================================
RCS file: /cvsroot/src/games/rogue/spec_hit.c,v
retrieving revision 1.5
diff -u -r1.5 spec_hit.c
--- spec_hit.c 7 Aug 2003 09:37:40 -0000 1.5
+++ spec_hit.c 7 Oct 2006 23:11:56 -0000
@@ -100,12 +100,12 @@
}
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 @@
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 @@
}
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 @@
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 @@
}
}
}
- (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 @@
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 @@
object *monster;
{
short sting_chance = 35;
- char msg[80];
if ((rogue.str_current <= 3) || sustain_strength) {
return;
@@ -411,9 +406,8 @@
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 @@
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 @@
m_confuse(monster)
object *monster;
{
- char msg[80];
-
if (!rogue_can_see(monster->row, monster->col)) {
return(0);
}
@@ -483,8 +475,8 @@
}
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);
}
Index: throw.c
===================================================================
RCS file: /cvsroot/src/games/rogue/throw.c,v
retrieving revision 1.7
diff -u -r1.7 throw.c
--- throw.c 30 Mar 2006 05:04:22 -0000 1.7
+++ throw.c 7 Oct 2006 23:11:56 -0000
@@ -67,7 +67,7 @@
while (!is_direction(dir = rgetchar(), &d)) {
sound_bell();
if (first_miss) {
- message("direction? ", 0);
+ messagef(0, "direction? ");
first_miss = 0;
}
}
@@ -81,11 +81,11 @@
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 @@
}
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 @@
{
object *new_weapon, *monster;
short i = 0;
- char msg[80];
boolean found = 0;
short mch, dch;
unsigned short mon;
@@ -257,10 +256,9 @@
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);
}
}
Index: trap.c
===================================================================
RCS file: /cvsroot/src/games/rogue/trap.c,v
retrieving revision 1.6
diff -u -r1.6 trap.c
--- trap.c 7 Aug 2003 09:37:40 -0000 1.6
+++ trap.c 7 Oct 2006 23:11:56 -0000
@@ -99,7 +99,7 @@
}
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 @@
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 @@
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 @@
}
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 @@
{
short dir, row, col, d, t;
- message("direction? ", 0);
+ messagef(0, "direction? ");
while (!is_direction(dir = rgetchar(), &d)) {
sound_bell();
@@ -208,9 +208,9 @@
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 @@
shown++;
if (dungeon[row][col] & TRAP) {
t = trap_at(row, col);
- message(trap_strings[t*2], 1);
+ messagef(1, "%s",
+ trap_strings[t*2]);
}
}
}
Index: use.c
===================================================================
RCS file: /cvsroot/src/games/rogue/use.c,v
retrieving revision 1.6
diff -u -r1.6 use.c
--- use.c 7 Aug 2003 09:37:40 -0000 1.6
+++ use.c 7 Oct 2006 23:11:57 -0000
@@ -70,7 +70,6 @@
quaff()
{
short ch;
- char buf[80];
object *obj;
ch = pack_letter("quaff what?", POTION);
@@ -79,17 +78,16 @@
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 @@
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 @@
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 @@
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 @@
{
short ch;
object *obj;
- char msg[DCOLS];
ch = pack_letter("read what?", SCROL);
@@ -193,17 +190,16 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
short ch;
short moves;
object *obj;
- char buf[70];
ch = pack_letter("eat what?", FOOD);
@@ -406,24 +399,23 @@
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 @@
}
}
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 @@
{
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 @@
mv_mons();
}
md_sleep(1);
- message(you_can_move_again, 0);
+ messagef(0, "%s", you_can_move_again);
}
void
@@ -564,7 +556,7 @@
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 @@
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
Index: zap.c
===================================================================
RCS file: /cvsroot/src/games/rogue/zap.c,v
retrieving revision 1.6
diff -u -r1.6 zap.c
--- zap.c 7 Aug 2003 09:37:40 -0000 1.6
+++ zap.c 7 Oct 2006 23:11:57 -0000
@@ -69,7 +69,7 @@
while (!is_direction(dir = rgetchar(), &d)) {
sound_bell();
if (first_miss) {
- message("direction? ", 0);
+ messagef(0, "direction? ");
first_miss = 0;
}
}
@@ -83,15 +83,15 @@
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 @@
FLAMES | IMITATES | CONFUSES | SEEKS_GOLD | HOLDS));
break;
case DO_NOTHING:
- message("nothing happens", 0);
+ messagef(0, "nothing happens");
break;
}
}
@@ -230,17 +230,18 @@
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 @@
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 @@
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 @@
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 @@
} 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 @@
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 @@
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;