7

我正在尝试在 ANSI C (Linux) 中以编程方式检索主机的本地域后缀。例如:我的机器是ironside.0ffnet.net,我想检索“0ffnet.net”。

我已经看到许多帖子通过使用 getnameinfo() 和 getaddrinfo() 来解决这个问题,但是这些函数似乎从 /etc/hosts 文件中提取它们的信息,以获取机器本地的任何接口地址。

如果我的机器通过 DHCP 分配了一个地址(和相应的域后缀),则 /etc/hosts 文件不会更新,而是将此信息存储在 /etc/resolv.conf 例如:

dfex@ironside:~/hush$cat /etc/resolv.conf 
domain 0ffnet.net
search 0ffnet.net
nameserver 139.130.4.4

因此,getnameinfo() 和 getaddrinfo() 都使用 /etc/hosts 信息简单地返回机器的主机名,不带后缀,如下所示:

dfex@ironside:~/hush$ cat /etc/hosts
::1             ironside localhost6.localdomain6 localhost6
127.0.1.1       ironside
127.0.0.1       localhost
::1             localhost ip6-localhost ip6-loopback

有谁知道一个函数可以在不诉诸 system() 调用的情况下提取这些信息?我一直在梳理 Beej 的指南,但没有取得多大成功。

4

3 回答 3

2

我将不得不将这个问题分开并分别回答各个部分。首先是标题问题。

DHCP 域

真正知道 DHCP 客户端从 DHCP 服务器接收到什么的唯一方法是读取客户端留下的文件/var/lib/dhcp。如果有其他东西控制了resolv.conf.

“我的主机的本地域后缀”

主机可能属于多个域,也可能不属于任何域,这使得这个概念很难定义。resolv.conf指定将搜索您正在解析的主机名的域;当应用于您自己的主机名时,没有基本保证搜索会成功。

任何!解析器搜索列表是我真正想要的。我如何得到它?

调用res_init然后查看_res.dnsrch和/或_res.defdname。或者解析resolv.conf自己;这是一种非常简单且稳定的格式。

那么 getdomainname() 有什么用呢?

它适用于您可能不想要的 NIS(YP)。

于 2012-09-01T22:29:26.883 回答
1

您可以尝试使用:

int getdomainname(char *name, size_t len);

尝试运行这个程序:

#include <unistd.h>
#include <stdio.h>

int main()
{
 char buf[255];
 getdomainname(buf, 255);
 printf("Domain: %s\n", buf);
 return 0; 
}

编辑:

不,经过多次尝试,我怀疑您将不得不使用系统调用和丑陋的 C 解析器(在其中使用 AWKpopen会使这段代码更短一些)。

这段代码似乎对我有用:

#include <stdio.h>
#include <string.h>

int main()
{
 char buf[255];
 const char reqhostname[255] = "ENTER_YOUR_HOSTNAME_HERE";

 FILE *fd;
 char readbuf[255];
 char *pch;
 int token_counter = 0;

 memset(buf, 0, 255);
 strcat(buf, "host ");
 strcat(buf, reqhostname);
 fd = popen(buf, "r");
 fgets(readbuf, 255, fd);
 printf("Host returned: %s\n", readbuf);
 pclose(fd);

 pch = strtok(readbuf, " ");
 while (pch != NULL)
   {
        strcpy(buf, pch);
        break;
   }

 memset(buf2, 0, 255);
 pch = strtok(buf, ".");
 while (pch != NULL)
   {
        pch = strtok(NULL, ".");
        if (pch == NULL)
           {
                memset(buf, 0, 255);
                strncpy(buf, buf2, strlen(buf2) - 1);
                break;
           }
        token_counter++;
        strcat(buf2, pch);
        strcat(buf2, ".");
   }

 printf("Domain: %s\n", buf);

 return 0;
}
于 2012-09-01T11:54:10.823 回答
1

感谢@alan-curry,它确实为我指明了正确的方向。对于其他为此苦苦挣扎的人, res_init 绝对是要走的路。这是获取本地域后缀的快速方法:

#include <stdio.h>
#include <resolv.h>

int main (int argc, char *argv[]) {

res_init();

printf ("Default domain: %s\n", _res.defdname);
return 0;
}
于 2012-09-02T10:33:50.117 回答