[Comm] Вопрос по xinetd

Sergey Shilov =?iso-8859-1?q?hsv_=CE=C1_dstszi=2Egov=2Eua?=
Чт Мар 24 13:59:16 MSK 2005


В сообщении от 21 Март 2005 09:46 Eugene Ostapets написал(a):

> А слабо посмотреть в первоисточники? :)
Нееее, не слабо.
Но тут ...src.rpm однако :-)
> Чтение по диагонали telnetd.c дает ответ за 5 секунд - getnameinfo
Ага getpeername + getnameinfo. ;-)))

Но!

Как личность слегка обученная РТФМу попробовал сперва
man  getnameinfo
и, о чудо, узрел там магическое заклинание:
...
EXAMPLES
       The  following code tries to get the numeric hostname and service name,
       for a given socket address. Note that there is no  hardcoded  reference
       to a particular address family.

                struct sockaddr *sa;    /* input */
                char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];

                if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), sbuf,
                    sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0)
                        printf("host=%s, serv=%s\n", hbuf, sbuf);

       The  following  version  checks  if  the  socket  address has a reverse
       address mapping.

                struct sockaddr *sa;    /* input */
                char hbuf[NI_MAXHOST];

                if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf),
                    NULL, 0, NI_NAMEREQD))
                       printf("could not resolve hostname");
                else
                       printf("host=%s\n", hbuf);
...
попытка последовать "Букве зекона" увенчалась крахом с сообщением
о том, что у sa  (sockaddr) нету поля sa_len ... :-( и т.д.
Рабочий вариант решения задачи (да простят мне апологеты ГЦЦ недостойный стиль) 
выглядит примерно так:

void print_remote_info (void) {
    struct sockaddr_storage     addr;
    socklen_t                   addrlen;
    addrlen = sizeof(addr);
    char                        name[NI_MAXHOST];

    if (getpeername(fileno(stdin), (struct sockaddr*)&addr, &addrlen) == 0 ) {
        fprintf(stdout, "Connection handled on file descriptor %d ", fileno(stdin));
        if  ( getnameinfo( (struct sockaddr *)&addr, addrlen,
                         name, sizeof(name), NULL, 0, NI_NUMERICHOST) == 0 ) {
            fprintf(stdout, "IP %s ", ip);
        }
        else {
           fprintf(stderr, "getnameinfo error %s \n\r", strerror(errno));
 }
    }
    else {
          fprintf(stderr, "getpeername error %s \n\r", strerror(errno));
    }     
}

Воникает вполне резонный вопрос - примеры кода в некоторых ман страницах
реально проверяются на работоспособность, или это известная часть знаменитого
"метода проблемного обучения" для начинающих программистов?


-- 
С уважением
Сергей Шилов



Подробная информация о списке рассылки community