John Fawcett:
> for an inexistent user for strings up to 31 chars. From 32 chars onwards
> instead of returning not found it retuns EINVAL (invalid argument).
> 
> ./test AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
> Not found
> ./test AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
> getpwnam_r: Invalid argument

Perhaps they want programs to call sysconf(_SC_LOGIN_NAME_MAX)
(note that the result includes the null terminator).

        Wietse

#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

int     main(int argc, char *argv[])
{
    struct passwd pwd;
    struct passwd *result;
    char   *buf;
    size_t  bufsize;
    int     s;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s username\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
    if (bufsize == -1)                          /* Value was indeterminate */
        bufsize = 16384;                        /* Should be more than enough */

    buf = malloc(bufsize);
    if (buf == NULL) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    /* _SC_LOGIN_NAME_MAX includes the null terminator */
    if (strlen(argv[1]) >= sysconf(_SC_LOGIN_NAME_MAX)) {
        fprintf(stderr, "warning: name exceeds _SC_LOGIN_NAME_MAX\n");
        result = 0;
        s = 0;
    } else {
        s = getpwnam_r(argv[1], &pwd, buf, bufsize, &result);
    }
    if (result == NULL) {
        if (s == 0)
            printf("Not found\n");
        else {
            errno = s;
            perror("getpwnam_r");
        }
        exit(EXIT_FAILURE);
    }
    printf("Name: %s; UID: %ld\n", pwd.pw_gecos, (long) pwd.pw_uid);
    free(buf);
    exit(EXIT_SUCCESS);
}

Reply via email to