There are several things to improve in the code before looking for buffer overflows:
Don't duplicate constant strings. E.g.
sizeof("You were killed by §f\n")and thensnprintf(..., "You were killed by §f\n", ...))Avoid raw constants (and duplicated) in the code. E.g.
char buff[4096+1]; ... fread(buff, sizeof(char), 4096, fp);In this case you can define a constant/macro for4096or just usesizeof(buff)infread(buff, sizeof(char), sizeof(buff)-1, fp);.In the code:
while(i >=0 && buff[i] != '\n') --i; ++i;The
++i;has a invalid indentation which can confuse the reader.Your macro
maxshould have some parenthesis to enclose the whole result:#define max(a, b) ( ((a)>(b))? (a) : (b) )Without those parenthesis a call like
(max(2,1)+3)will give you 2 (instead of 5).You've defined
stringtype liketypedef char * stringbut you're using thestringtype likeconst char*.You're calling several times
snprintffunction with an invalid 2nd argument (which is the same as callingsprintfdirectly). If you are creating a buffer with a specific size inmalloc, remember to use that size insnprintf().In
dmon = atoi(field_month); hummonth = realm[dmon-1];You should check the
dmonvalue before you use it to accessrealm[]array.
The atoi is generally deprecated, because it's not required to set errno -- when it returns a zero, you won't know why. You should use strtol and ensure that dmon has sensible value. If dmon is zero, then errno will indicate whether it was really zero, or was there an error. In this case simply checking dmon to be between 1 and 12 inclusive will do the trick, as the zero value is not allowed.
There are more things, but anyway, generally I would recommend you to create tiny functions to do specific tasks: instead of having mallocs/snprints/scanfs all mixed together, write functions with minimal objectives which you can ensure that they don't contain bugs/memory buffer overflow. Then you are safe to use them in your main() function.