Retrieving last string on each line from a file

There’s a function in sv_ccmds.c called SV_RehashBans_f() which loads saved bans from a file. I copied the code over and converted it into in a mute function. Everything is working fine, except that I save the playername to the end of each line, and I’m unable to retrieve it.

I can retrieve the IP, subnet, and expiration integer fine. But, not the name.

Here’s the relevent code I have:

if((filelen = FS_SV_FOpenFileRead(filepath, &readfrom)) >= 0) {
                if(filelen < 2) {
                        // Don’t bother if file is too short.
                        FS_FCloseFile(readfrom);
                        return;
                }

curpos = textbuf = Z_Malloc(filelen);
                filelen = FS_Read(textbuf, filelen, readfrom);
                FS_FCloseFile(readfrom);
                endpos = textbuf + filelen;

for(index = 0; index < SERVER_MAXMUTES && curpos + 2 < endpos; index++) {
                        // find the end of the address string
                        for(maskpos = curpos + 0; maskpos < endpos && *maskpos != ’ '; maskpos++);
                        if(maskpos + 1 >= endpos) { break; }
                        *maskpos = ‘\0’;
                        maskpos++;

// find the end of the subnet specifier
                        for(maskpos = curpos ; maskpos < endpos && *maskpos != ’ '; maskpos++);
                        if(NET_StringToAdr(curpos + 0, &serverMutes[index].ip, NA_UNSPEC)) {
                                serverMutes[index].subnet = atoi(maskpos);
                                if(serverMutes[index].ip.type == NA_IP && (serverMutes[index].subnet < 1 || serverMutes[index].subnet > 32)) { serverMutes[index].subnet = 32; }
                        }
                        *maskpos = ‘\0’;
                        maskpos++;

for(newlinepos = maskpos; newlinepos < endpos && *newlinepos != ’ '; newlinepos++);
                        if(newlinepos >= endpos) { break; }
                        serverMutes[index].expiration = atoi(maskpos);
                        maskpos = ‘\0’;
                        maskpos++;
///////////////////////////////////////////////////////////////////////////////////////////////
This is the part I’m having trouble with below:
  ///////////////////////////////////////////////////////////////////////////////////////////////
newlinepos++;
                        for(newlinepos = maskpos; newlinepos <= endpos && newlinepos != ‘\n’; newlinepos++);
                        if(newlinepos >= endpos) { break; }
                        serverMutes[index].name = maskpos;
                        Com_Printf( “DEBUG: %s\n”, maskpos );

*newlinepos = ‘\0’;
                        curpos = newlinepos + 1;
                }

Here’s two example lines from my mute.dat file:

21.23.33.42 32 1406612718 TestName1                                                                                            
24.23.133.42 32 1406454556 Test Name 2

Here’s the output from the Com_Printf a few lines above:

NAME: 406612718 TestName1
24.23.133.42 32 1406454556 Test Name 2
�J
NAME: 406454556 Test Name 2
�J

I think you need to save the location of start of name which is in “newlinepos” instead of using maskpos which points to 2nd character in mask.

///////////////////////////////////////////////////////////////////////////////////////////////
//This is the part I'm having trouble with below:
///////////////////////////////////////////////////////////////////////////////////////////////
                        newlinepos++;
                        // NOTE: "newlinepos" now points to start of name, so save it!
                        curpos = newlinepos;

                        for(/* nothing */; newlinepos <= endpos && *newlinepos != '\n'; newlinepos++);
                        if(newlinepos >= endpos) { break; }
                        *newlinepos = '\0'; // remove the newline before printing message

                        serverMutes[index].name = curpos; // use saved address
                        Com_Printf( "DEBUG: %s\n", serverMutes[index].name );

                        curpos = newlinepos + 1;
                }

Also, you should probably make serverMutes[*].name be an array instead of a pointer. The pointer will be invalid after you free textbuf.

In serverMutes
char name[36];

Replace
serverMutes[index].name = curpos;
with
Q_strncpyz( serverMutes[index].name, curpos, sizeof ( serverMutes[0].name ) );