Jordan Wills Jordan Wills - 3 months ago 16
C Question

strncmp proper usage

Here's the quick background: I've got a client and a server program that are communicating with each other over a Unix socket. When parsing the received messages on the server side, I am attempting to use strncmp to figure out what action to take.

The problem I'm having is figuring out exactly what to use for the length argument of strncmp. The reason this is being problematic is that some of my messages share a common prefix. For example, I have a message "getPrimary", which causes the server to respond with a primary server address, and a message "getPrimaryStatus", which causes the server to respond with the status of the primary server. My initial thought was to do the following:

if(strncmp(message,"getPrimary",strlen("getPrimary"))==0){
return foo;
}
else if(strncmp(message,"getPrimaryStatus",strlen("getPrimaryStatus"))==0){
return bar;
}


The problem with this is when I send the server "getPrimaryStatus", the code will always return foo because strncmp is not checking far enough in the string. I could pass in strlen(message) as the length argument to strncmp, but this seems to defeat the purpose of using strncmp, which is to prevent overflow in the case of unexpected input. I do have a static variable for the maximum message length I can read, but it seems like passing this in as the length is only making sure that if the message overflows, the effects are minimized.

I've come up with a few solutions, but they aren't very pretty, so I was wondering if there was a common way of dealing with this problem.

For reference, my current solutions are:
Order my if / else if statements in such a way that that any messages with common prefixes are checked in order of descending length (which seems like a really good way to throw a landmine in my code for anyone trying to add something to it later on).

Group my messages with common prefixes together and look for the suffix first:

if(strncmp(message,"getPrimary",strlen("getPrimary"))==0){
if(strncmp(message,"getPrimaryStatus",strlen("getPrimaryStatus"))==0){
return bar;
else
return foo;
}
}


But this just feels messy, especially since I have about 20 different possible messages that I'm handling.

Create an array of all the possible messages I have, add a function to my init sequence that will order the array by descending length, and have my code search through the elements of that list until it finds a match. This seems complicated and silly.

It seems like this should be a common enough issue that there ought to be a solution for it somewhere, but I haven't been able to find anything so far.

Thanks in advance for the help!

caf caf
Answer

Presuming that the string in message is supposed to be null-terminated, the only reason to use strncmp() here rather than strcmp() would be to be to prevent it looking beyond the end of message, in the case where message is not null-terminated.

As such, the n you pass to strncmp() should be the received size of message, which you ought to know (from the return value of the read() / recv() function that read the message).