From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Sergey Shilov Organization: DSTSZI To: community@altlinux.ru Subject: Re: [Comm] =?windows-1251?b?wu7v8O7xIO/u?= xinetd Date: Thu, 24 Mar 2005 10:59:16 +0000 User-Agent: KMail/1.6.2 References: <200503211041.45176.hsv@dstszi.gov.ua> In-Reply-To: MIME-Version: 1.0 Content-Disposition: inline Content-Type: text/plain; charset="windows-1251" Content-Transfer-Encoding: 8bit Message-Id: <200503241059.19387.hsv@dstszi.gov.ua> X-Antivirus: Dr.Web (R) for Mail Servers on mail3.dstszi.gov.ua host X-Antivirus-Code: 100000 X-Protected: : UNA Antivirus http://www.una.ua X-BeenThere: community@altlinux.ru X-Mailman-Version: 2.1.5 Precedence: list Reply-To: community@altlinux.ru List-Id: Mailing list for ALT Linux users List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 24 Mar 2005 08:58:55 -0000 Archived-At: List-Archive: List-Post: В сообщении от 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)); } } Воникает вполне резонный вопрос - примеры кода в некоторых ман страницах реально проверяются на работоспособность, или это известная часть знаменитого "метода проблемного обучения" для начинающих программистов? -- С уважением Сергей Шилов