Advanced Programming in the UNIX Environment: Second Edition [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Advanced Programming in the UNIX Environment: Second Edition [Electronic resources] - نسخه متنی

W. Richard Stevens; Stephen A. Rago

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید



18.10. Canonical Mode


Section 18.3 that the following characters are interpreted as end of line in canonical mode: NL, EOL, EOL2, and EOF. Also, recall from Section 18.5 that if ICRNL is set and if IGNCR is not set, then the CR character also terminates a line, since it acts just like the NL character.

Realize that of these five line delimiters, one (EOF) is discarded by the terminal driver when it's processed. The other four are returned to the caller as the last character of the line.

  • The read also returns if a signal is caught and if the function is not automatically restarted (Section 10.5).



  • Examplegetpass Function

    We now show the function getpass, which reads a password of some type from the user at a terminal. This function is called by the login(1) and crypt(1) programs. To read the password, the function must turn off echoing, but it can leave the terminal in canonical mode, as whatever we type as the password forms a complete line. Chapter 3), but we would have to simulate the getc function using read.

  • We store only up to eight characters as the password. Any additional characters that are entered are ignored.


  • The program in Figure 18.18 calls getpass and prints what we enter to let us verify that the ERASE and KILL characters work (as they should in canonical mode).

    Whenever a program that calls getpass is done with the cleartext password, the program should zero it out in memory, just to be safe. If the program were to generate a core file that others might be able to read or if some other process were somehow able to read our memory, they might be able to read the cleartext password. (By "cleartext," we mean the password that we type at the prompt that is printed by getpass. Most UNIX system programs then modify this cleartext password into an "encrypted" password. The field pw_passwd in the password file, for example, contains the encrypted password, not the cleartext password.)


    Figure 18.17. Implementation of getpass function

    #include <signal.h>
    #include <stdio.h>
    #include <termios.h>
    #define MAX_PASS_LEN 8 /* max #chars for user to enter */
    char *
    getpass(const char *prompt)
    {
    static char buf[MAX_PASS_LEN + 1]; /* null byte at end */
    char *ptr;
    sigset_t sig, osig;
    struct termios ts, ots;
    FILE *fp;
    int c;
    if ((fp = fopen(ctermid(NULL), "r+")) == NULL)
    return(NULL);
    setbuf(fp, NULL);
    sigemptyset(&sig);
    sigaddset(&sig, SIGINT); /* block SIGINT */
    sigaddset(&sig, SIGTSTP); /* block SIGTSTP */
    sigprocmask(SIG_BLOCK, &sig, &osig); /* and save mask */
    tcgetattr(fileno(fp), &ts); /* save tty state */
    ots = ts; /* structure copy */
    ts.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
    tcsetattr(fileno(fp), TCSAFLUSH, &ts);
    fputs(prompt, fp);
    ptr = buf;
    while ((c = getc(fp)) != EOF && c != '\n')
    if (ptr < &buf[MAX_PASS_LEN])
    *ptr++ = c;
    *ptr = 0; /* null terminate */
    putc('\n', fp); /* we echo a newline */
    tcsetattr(fileno(fp), TCSAFLUSH, &ots); /* restore TTY state */
    sigprocmask(SIG_SETMASK, &osig, NULL); /* restore mask */
    fclose(fp); /* done with /dev/tty */
    return(buf);
    }


    Figure 18.18. Call the getpass function

    #include "apue.h"
    char *getpass(const char *);
    int
    main(void)
    {
    char *ptr;
    if ((ptr = getpass("Enter password:")) == NULL)
    err_sys("getpass error");
    printf("password: %s\n", ptr);
    /* now use password (probably encrypt it) ... */
    while (*ptr != 0)
    *ptr++ = 0; /* zero it out when we're done with it */
    exit(0);
    }


      / 369