clinuxpasswd

Compare two passwd structures


I have a problem which I have narrowed down as much as I can imagine. I want to count the lines in /etc/passwd two times. One time as a reference and one time to detect any change.

I initialize one passwd structure and count the number of entries in it. I then call setpwent(). After I have done that i initialize a second passwd struct, note that I have added a sleep call so it is enough time to add another user. Problem is that the new struct is identical to the first one even though I have added a new user and initialized a new struct after it has been added. So no difference.

#include <stdio.h>
#include <pwd.h>
#include <unistd.h>
int main()
{
    for(;;)
    {
        struct passwd *i;
        int y = 0;
        while((i = getpwent()) != NULL)
            y++;
        printf("Lines : %d\n", y);
        setpwent();
        sleep(30);
        struct passwd *j;
        int x = 0;
        while((j = getpwent()) != NULL)
            x++;
        printf("Lines : %d\n", x);
        setpwent();
    }
}

Solution

  • You're using getpwent(), which upon first call reads the /etc/passwd file and parses it internally, providing you all the entries. After that, when you do setpwent(), you are merely resetting an internal pointer that keeps track of already parsed entries. When you do getpwent() again after setpwent(), the /etc/passwd file will not be accessed a second time, as the information has already ben parsed.

    If you want to force getpwent() to re-open and parse /etc/passwd every time, you should call endpwent() first. Replace the calls to setpwent() with endpwent() and you'll be good to go.


    From the manual page:

    The setpwent() function rewinds to the beginning of the password database.

    The endpwent() function is used to close the password database after all processing has been performed.