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

int
main(int argc, char *argv[])
{
    char *username, *password, *encrypted, *p;
    struct passwd *pwd;
    struct spwd *spwd;
    size_t len;
    long lnmax;

    lnmax = sysconf(_SC_LOGIN_NAME_MAX);
    if (lnmax == -1)                    /* If limit is indeterminate */
        lnmax = 256;

    username = malloc(lnmax);
    if (username == NULL)
        errx(EXIT_FAILURE, "malloc");

    printf("Username: ");
    fflush(stdout);
    if (fgets(username, lnmax, stdin) == NULL)
        exit(EXIT_FAILURE);

    len = strlen(username);
    if (username[len - 1] == '\n')
        username[len - 1] = '\0';

    pwd = getpwnam(username);
    if (pwd == NULL)
        errx(EXIT_FAILURE, "could'nt get password record");

    /*
     * تابع
     * getspnam
     * در صورت خطا
     * errno
     * را ست نمی‌کند
     */
    spwd = getspnam(username);
    if (spwd == NULL)
        errx(EXIT_FAILURE, "getspnam. must be root?");

    if (spwd != NULL)
        pwd->pw_passwd = spwd->sp_pwdp;

    password = getpass("Password: ");
    encrypted = crypt(password, pwd->pw_passwd);
    for (p = password; *p != '\0'; )
        *p++ = '\0';

    if (encrypted == NULL)
        errx(EXIT_FAILURE, "crypt");

    if (strcmp(encrypted, pwd->pw_passwd) != 0) {
        fprintf(stderr, "Incorrect password: %s\n", spwd->sp_namp);
        exit(EXIT_FAILURE);
    }

    printf("Successfully authenticated: UID=%ld\n", (long) pwd->pw_uid);
    exit(EXIT_SUCCESS);
}
