After hours of working, I've finally finished my first C log parsing program! (previously was a bash script, now it is C).
Although I think I've gotten most everything, I was just wondering if you saw any possible buffer/memory overflow dangers in the coding?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifndef max
#define max(a, b) ((a)>(b))? (a) : (b)
#endif
long GetFileSize(FILE *fp){
long fsize = 0;
fseek(fp,0,SEEK_END);
fsize = ftell(fp);
fseek(fp,0,SEEK_SET);//reset stream position!!
return fsize;
}
char *lastline(char *filepath){
FILE *fp;
char buff[4096+1];
int size,i;
long fsize;
if(NULL==(fp=fopen(filepath, "r"))){
printf("You have not died recently enough for any information to be recorded.");
return NULL;
}
fsize= -1L*GetFileSize(fp);
if(size=fseek(fp, max(fsize, -4096L), SEEK_END)){
perror("cannot seek");
exit(0);
}
size=fread(buff, sizeof(char), 4096, fp);
fclose(fp);
buff[size] = '\0';
i=size-1;
if(buff[i]=='\n'){
buff[i] = '\0';
}
while(i >=0 && buff[i] != '\n')
--i;
++i;
return strdup(&buff[i]);
}
int main(int argc, char *argv[], char *envp[]){
typedef char * string;
char *last;
char *name;
char field_x[128];
char field_y[128];
char field_z[128];
char field_world[128];
char field_cause[128];
char field_killer[128];
name = getenv("MCEXEC_PLAYERNAME");
char *filename;
char *p;
char *ispvp;
int i;
char *f;
char output[200] = {0x00};
int index = 0;
char field_year[128];
char field_month[128];
char field_mix[128];
char field_mix2[128];
char field_day[128];
char field_hour[128];
char field_minute[128];
char field_seconds[128];
char *hummonth;
int dmon;
int dy;
char *cause_string;
int x;
char *deathtype;
string dtypes[15] = { "unknown", "water", "fire", "explosion", "lava", "fall", "cactus", "creeper", "skeleton", "spider", "zombie", "pigzombie", "slime", "ghast", "suicide" };
string dstrings[15] = { "You died for unknown reasons", "You Drowned", "You were burnt to death", "You were blown to pieces", "You tried to swim in lava", "You fell to your death", "You tried to hug a cactus", "You were killed by a (more to this but not needed for this post)
string realm[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
filename = malloc(sizeof "/home/minecraft/freedonia/playerdata/deathlog-.txt" - 1 + strlen(name) + 1);
if (!filename) exit(EXIT_FAILURE);
snprintf(filename,4096,"/home/minecraft/freedonia/playerdata/deathlog-%s.txt",name);
last = lastline(filename);
if( last != NULL ) {
printf( "%s\n", last );
sscanf(last, "%*[^:]:%*[^:]:%*[^:]:%127[^:]:", field_x);
sscanf(last, "%*[^:]:%*[^:]:%*[^:]:%*[^:]:%127[^:]:", field_y);
sscanf(last, "%*[^:]:%*[^:]:%*[^:]:%*[^:]:%*[^:]:%127[^:]:", field_z);
sscanf(last, "%*[^:]:%*[^:]:%*[^:]:%*[^:]:%*[^:]:%*[^:]:%127[^:]:", field_world);
sscanf(last, "%*[^:]:%*[^:]:%*[^:]:%*[^:]:%*[^:]:%*[^:]:%*[^:]:%127[^:]:", field_cause);
sscanf(last, "%127[^ ] ", field_mix);
sscanf(field_mix, "%127[^-]-", field_year);
sscanf(field_mix, "%*[^-]-%127[^-]-", field_month);
sscanf(field_mix, "%*[^-]-%*[^-]-%127[^-]-", field_day);
sscanf(last, "%127[^:]:", field_mix2);
sscanf(field_mix2, "%*[^ ] %127[^ ] ", field_hour);
sscanf(last, "%*[^:]:%127[^:]:", field_minute);
sscanf(last, "%*[^:]:%*[^:]:%127[^:]:", field_seconds);
dmon = atoi(field_month);
hummonth = realm[dmon-1];
p = strchr(field_cause, '_');
printf( "X coord: %s\n", field_x);
printf( "Y coord: %s\n", field_y);
printf( "Z coord: %s\n", field_z);
printf( "World: %s\n", field_world);
printf( "Cause: %s\n", field_cause);
printf( "Year: %s\n", field_year );
printf( "Month: %s\n", field_month );
printf( "Day: %s\n", field_day );
printf( "Hour: %s\n", field_hour );
printf( "Minute: %s\n", field_minute );
printf( "Second: %s\n", field_seconds );
printf( "Human Month: %s\n", hummonth );
while (p != NULL) {
ispvp = "true";
sscanf(field_cause, "%*[^_]_%128[^_]_", field_killer);
printf( "Killer: %s\n", field_killer);
cause_string = malloc(sizeof "You were killed by §f\n" - 1 + strlen(field_killer) + 1);
snprintf(cause_string,128,"You were killed by §f%s\n",field_killer);
printf( "%s", cause_string);
p = NULL;
}
f = field_cause;
while( *f )
{
if (isalnum(*f) || *f == '_')
{
output[index++] = *f;
}
f++;
}
if (strcmp(ispvp,"true")!=0) {
for ( x = 0; x < 15; x++ ) {
deathtype = dtypes[x];
if (strcmp(field_cause,deathtype)==0) {
cause_string = dstrings[x];
printf( "%s\n", cause_string );
{break;}
}
}
}
dy = atoi(field_y);
if ( 0 > dy ) {
printf( "§eYou suffocated in the void §6at§f%s:%s §6on§f %s %s", field_hour, field_minute, hummonth, field_day );
printf("§6Coords: §f%s %s\n", field_x, field_z );
}
else if (strcmp(field_world,"normal")==0) {
printf("§e%s §6at§f%s:%s §6on§f %s %s\n", cause_string, field_hour, field_minute, hummonth, field_day );
printf("§6Coords: §f%s %s %s\n", field_x, field_y, field_z );
}
else if (strcmp(field_world,"normal")==0) {
printf("§e%s §6at§f%s:%s §6on§f %s %s\n", cause_string, field_hour, field_minute, hummonth, field_day );
printf("§6Coords: §f%s %s %s §6in the §fnether\n", field_x, field_y, field_z );
}
}
// printf("\"%s\"\n", last);
free(last);
return 0;
}