I am trying to make simple C program which checks a Linux password file line-by-line searching for the line beginning with a username supplied by a command line argument. Each line consists of several tokens delimited by a colon. The first token is the username, the 2nd is irrelevant, the 3rd is a user id (UID) number which needs to be printed, and the 4th token is the group id number (GID) which also needs to be printed.
Using a few print tests and searching online for solutions, I think my token variable remains NULL after assigning it to my first strtok call (printf of the token at this point prints nothing). Then, the NULL token is compared, using strcmp, to the username which produces the segmentation fault error. If my analysis thus far is correct (which it may very well not be since I am new to C), how can I avoid/fix this problem and why is this happening?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
FILE *pwfile;
char *userName;
char buf[1024];
const char s[2] = ":";
char *token;
int ch, number_of_lines = 0;
int i;
if(argc != 2)
{
perror("must supply a user name");
return -1;
}
pwfile = fopen("/home/c2467/passwd", "r");
if( pwfile == NULL)
{
perror( "error opening password file" );
return -1;
}
userName = argv[1];
do//loop to determine number of lines in the file
{
ch = fgetc(pwfile);
if(ch == '\n')
number_of_lines++;
} while (ch != EOF);
if(ch != '\n' && number_of_lines != 0)
{
number_of_lines++;
}
for (i = 0; i <= number_of_lines; i++)//iterates through lines of file
{
fgets(buf, 1024, pwfile);//stores line into buf
if (ferror(pwfile) != 0)//tests error indicator for given stream
{
perror("fgets error");
return 1;
}
if (feof(pwfile) == 0)//checks if at end of file
{
break;
}
token = strtok( buf, s);//stores first token of current line in file
if( strcmp(token, userName) == 0 )//compares token to user name entered
{
token = strtok( NULL, s);//Jumps to 2nd token in line, which is irrelevant so do nothing
token = strtok( NULL, s);//Jumps to 3rd token which is UID number
printf( "UID: %s\n", token );
token = strtok( NULL, s);//Jumps to 4th token which is GID number
printf( "GID: %s\n", token );
break;
}
}
fclose(pwfile);
return 0;
}