summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt2
-rw-r--r--src/map/atcommand.c44
-rw-r--r--src/map/pc.c64
3 files changed, 76 insertions, 34 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 4c6450257..d215beadb 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -1,6 +1,8 @@
Date Added
2010/12/12
+ * Cleaned up MOTD reading (related r292 and r4552). [Ai4rei]
+ - Added a warning for common client crash caused by the sequence ' :' in MOTD.
* Fixed impossible condition in soundeffect script command (since athena-dev-2.1.1-mod1046, related r5841). [Ai4rei]
* Updates to the playBGM functionality (since r14335). [Ai4rei]
- Removed impossible condition in playBGM script command (from soundeffect).
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 6f008c3af..0c584223f 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -6862,26 +6862,36 @@ ACMD_FUNC(identify)
*------------------------------------------*/
ACMD_FUNC(gmotd)
{
- char buf[CHAT_SIZE_MAX];
- FILE *fp;
- nullpo_retr(-1, sd);
- if((fp = fopen(motd_txt, "r"))!=NULL){
- while(fgets(buf, sizeof(buf), fp) != NULL)
+ char buf[CHAT_SIZE_MAX];
+ size_t len;
+ FILE* fp;
+
+ if( ( fp = fopen(motd_txt, "r") ) != NULL )
+ {
+ while( fgets(buf, sizeof(buf), fp) )
+ {
+ if( buf[0] == '/' && buf[1] == '/' )
{
- int i;
- if (buf[0] == '/' && buf[1] == '/')
- continue;
- for(i=0; buf[i]; i++){
- if(buf[i]=='\r' || buf[i]=='\n'){
- buf[i]=0;
- break;
- }
- }
- intif_broadcast(buf, strlen(buf)+1, 0);
+ continue;
+ }
+
+ len = strlen(buf);
+
+ while( len && ( buf[len-1] == '\r' || buf[len-1] == '\n' ) )
+ {// strip trailing EOL characters
+ len--;
+ }
+
+ if( len )
+ {
+ buf[len] = 0;
+
+ intif_broadcast(buf, len+1, 0);
}
- fclose(fp);
}
- return 0;
+ fclose(fp);
+ }
+ return 0;
}
ACMD_FUNC(misceffect)
diff --git a/src/map/pc.c b/src/map/pc.c
index 065932636..018b392f1 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -61,7 +61,7 @@ struct fame_list taekwon_fame_list[MAX_FAME_LIST];
static unsigned short equip_pos[EQI_MAX]={EQP_ACC_L,EQP_ACC_R,EQP_SHOES,EQP_GARMENT,EQP_HEAD_LOW,EQP_HEAD_MID,EQP_HEAD_TOP,EQP_ARMOR,EQP_HAND_L,EQP_HAND_R,EQP_AMMO};
#define MOTD_LINE_SIZE 128
-char motd_text[MOTD_LINE_SIZE][256]; // Message of the day buffer [Valaris]
+static char motd_text[MOTD_LINE_SIZE][CHAT_SIZE_MAX]; // Message of the day buffer [Valaris]
struct duel duel_list[MAX_DUEL];
int duel_count = 0;
@@ -8141,30 +8141,60 @@ int pc_readdb(void)
// Read MOTD on startup. [Valaris]
int pc_read_motd(void)
{
- FILE *fp;
- int ln=0,i=0;
+ char* buf, * ptr;
+ unsigned int lines = 0, entries = 0;
+ size_t len;
+ FILE* fp;
+
+ // clear old MOTD
+ memset(motd_text, 0, sizeof(motd_text));
+
+ // read current MOTD
+ if( ( fp = fopen(motd_txt, "r") ) != NULL )
+ {
+ while( entries < MOTD_LINE_SIZE && fgets(motd_text[entries], sizeof(motd_text[entries]), fp) )
+ {
+ lines++;
+
+ buf = motd_text[entries];
- memset(motd_text,0,sizeof(motd_text));
- if ((fp = fopen(motd_txt, "r")) != NULL) {
- while ((ln < MOTD_LINE_SIZE) && fgets(motd_text[ln], sizeof(motd_text[ln])-1, fp) != NULL) {
- if(motd_text[ln][0] == '/' && motd_text[ln][1] == '/')
+ if( buf[0] == '/' && buf[1] == '/' )
+ {
continue;
- for(i=0; motd_text[ln][i]; i++) {
- if (motd_text[ln][i] == '\r' || motd_text[ln][i]== '\n') {
- if(i)
- motd_text[ln][i]=0;
- else
- motd_text[ln][0]=' ';
- ln++;
- break;
+ }
+
+ len = strlen(buf);
+
+ while( len && ( buf[len-1] == '\r' || buf[len-1] == '\n' ) )
+ {// strip trailing EOL characters
+ len--;
+ }
+
+ if( len )
+ {
+ buf[len] = 0;
+
+ if( ( ptr = strstr(buf, " :") ) != NULL && ptr-buf >= NAME_LENGTH )
+ {// crashes newer clients
+ ShowWarning("Found sequence '"CL_WHITE" :"CL_RESET"' on line '"CL_WHITE"%u"CL_RESET"' in '"CL_WHITE"%s"CL_RESET"'. This can cause newer clients to crash.\n", lines, motd_txt);
}
}
+ else
+ {// empty line
+ buf[0] = ' ';
+ buf[1] = 0;
+ }
+ entries++;
}
fclose(fp);
+
+ ShowStatus("Done reading '"CL_WHITE"%u"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", entries, motd_txt);
}
else
- ShowWarning("In function pc_read_motd() -> File '"CL_WHITE"%s"CL_RESET"' not found.\n", motd_txt);
-
+ {
+ ShowWarning("File '"CL_WHITE"%s"CL_RESET"' not found.\n", motd_txt);
+ }
+
return 0;
}