Skip to content

Commit 22b1c8c

Browse files
maqeel75neel5481
authored andcommitted
Extracts domain name from FQDN, if fails then tries to read it from /etc/resolv.conf and finally fallback to getdomainname() with validation
1 parent 30fa675 commit 22b1c8c

File tree

2 files changed

+134
-11
lines changed

2 files changed

+134
-11
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ OBJS = \
4141
linux/network_info.o \
4242
linux/cpu_memory_by_process.o
4343

44-
HEADERS = system_stats.h
44+
HEADERS = system_stats.h misc.h
4545

4646
endif
4747

linux/os_info.c

Lines changed: 133 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@
1414
#include <unistd.h>
1515
#include <sys/utsname.h>
1616
#include <sys/sysinfo.h>
17+
#include <netdb.h>
18+
#include <sys/socket.h>
19+
#include <arpa/inet.h>
20+
#include <string.h>
1721

1822
bool total_opened_handle(int *total_handles);
23+
static bool get_dns_domain_name(const char *hostname, char *domain_name, size_t domain_size);
1924
void ReadOSInformations(Tuplestorestate *tupstore, TupleDesc tupdesc);
2025

2126
bool total_opened_handle(int *total_handles)
@@ -57,6 +62,120 @@ bool total_opened_handle(int *total_handles)
5762
return true;
5863
}
5964

65+
/*
66+
* get_dns_domain_name
67+
*
68+
* Attempts to retrieve the DNS domain name using multiple fallback strategies:
69+
* 1. Try DNS resolution to get FQDN, then extract domain
70+
* 2. Read from /etc/resolv.conf (domain or search directive)
71+
* 3. Fallback to getdomainname() with validation
72+
*
73+
* Returns true if domain name was found, false otherwise
74+
*/
75+
static bool get_dns_domain_name(const char *hostname, char *domain_name, size_t domain_size)
76+
{
77+
struct addrinfo hints, *info = NULL;
78+
bool found = false;
79+
char *dot_pos = NULL;
80+
81+
memset(domain_name, 0, domain_size);
82+
83+
/* Strategy 1: Try DNS resolution to get FQDN */
84+
memset(&hints, 0, sizeof(hints));
85+
hints.ai_family = AF_UNSPEC;
86+
hints.ai_socktype = SOCK_STREAM;
87+
hints.ai_flags = AI_CANONNAME;
88+
89+
if (getaddrinfo(hostname, NULL, &hints, &info) == 0 && info != NULL)
90+
{
91+
if (info->ai_canonname != NULL)
92+
{
93+
/* Look for first dot to extract domain from FQDN */
94+
dot_pos = strchr(info->ai_canonname, '.');
95+
if (dot_pos != NULL && strlen(dot_pos + 1) > 0)
96+
{
97+
/* Copy domain part (after first dot) */
98+
snprintf(domain_name, domain_size, "%s", dot_pos + 1);
99+
found = true;
100+
ereport(DEBUG1, (errmsg("domain name extracted from FQDN: %s", domain_name)));
101+
}
102+
}
103+
freeaddrinfo(info);
104+
}
105+
106+
/* Strategy 2: If DNS failed, try reading from /etc/resolv.conf */
107+
if (!found)
108+
{
109+
FILE *resolv_file = fopen("/etc/resolv.conf", "r");
110+
if (resolv_file != NULL)
111+
{
112+
char *line_buf = NULL;
113+
size_t line_buf_size = 0;
114+
ssize_t line_size;
115+
116+
while ((line_size = getline(&line_buf, &line_buf_size, resolv_file)) >= 0)
117+
{
118+
char *trimmed = str_trim(line_buf);
119+
120+
/* Check for "domain" directive (preferred) */
121+
if (strncmp(trimmed, "domain", 6) == 0)
122+
{
123+
char *domain_val = str_trim(trimmed + 6);
124+
if (strlen(domain_val) > 0)
125+
{
126+
snprintf(domain_name, domain_size, "%s", domain_val);
127+
found = true;
128+
ereport(DEBUG1, (errmsg("domain name from /etc/resolv.conf (domain): %s", domain_name)));
129+
break;
130+
}
131+
}
132+
/* Check for "search" directive (fallback) */
133+
else if (!found && strncmp(trimmed, "search", 6) == 0)
134+
{
135+
char *search_val = str_trim(trimmed + 6);
136+
/* Take first domain from search list */
137+
char *space = strchr(search_val, ' ');
138+
if (space != NULL)
139+
*space = '\0';
140+
141+
if (strlen(search_val) > 0)
142+
{
143+
snprintf(domain_name, domain_size, "%s", search_val);
144+
found = true;
145+
ereport(DEBUG1, (errmsg("domain name from /etc/resolv.conf (search): %s", domain_name)));
146+
}
147+
}
148+
}
149+
150+
if (line_buf != NULL)
151+
free(line_buf);
152+
fclose(resolv_file);
153+
}
154+
}
155+
156+
/* Strategy 3: Last resort - try getdomainname() with validation */
157+
if (!found)
158+
{
159+
char nis_domain[256];
160+
memset(nis_domain, 0, sizeof(nis_domain));
161+
162+
if (getdomainname(nis_domain, sizeof(nis_domain)) == 0)
163+
{
164+
/* Validate that it's not empty or "(none)" */
165+
if (strlen(nis_domain) > 0 &&
166+
strcmp(nis_domain, "(none)") != 0 &&
167+
strcmp(nis_domain, "localdomain") != 0)
168+
{
169+
snprintf(domain_name, domain_size, "%s", nis_domain);
170+
found = true;
171+
ereport(DEBUG1, (errmsg("domain name from getdomainname(): %s", domain_name)));
172+
}
173+
}
174+
}
175+
176+
return found;
177+
}
178+
60179
void ReadOSInformations(Tuplestorestate *tupstore, TupleDesc tupdesc)
61180
{
62181
struct utsname uts;
@@ -103,21 +222,25 @@ void ReadOSInformations(Tuplestorestate *tupstore, TupleDesc tupdesc)
103222

104223
/* Function used to get the host name of the system */
105224
if (gethostname(host_name, sizeof(host_name)) != 0)
225+
{
106226
ereport(DEBUG1,
107227
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
108228
errmsg("error while getting host name")));
109-
110-
/* Function used to get the domain name of the system */
111-
if (getdomainname(domain_name, sizeof(domain_name)) != 0)
112-
ereport(DEBUG1,
113-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
114-
errmsg("error while getting domain name")));
115-
116-
/*If hostname or domain name is empty, set the value to NULL */
117-
if (strlen(host_name) == 0)
118229
nulls[Anum_host_name] = true;
119-
if (strlen(domain_name) == 0)
230+
}
231+
else if (strlen(host_name) == 0)
232+
{
233+
nulls[Anum_host_name] = true;
234+
}
235+
236+
/* Get DNS domain name using multiple fallback strategies */
237+
if (!get_dns_domain_name(host_name, domain_name, sizeof(domain_name)))
238+
{
239+
/* All strategies failed, set to NULL */
120240
nulls[Anum_domain_name] = true;
241+
ereport(DEBUG1,
242+
(errmsg("unable to determine domain name from any source")));
243+
}
121244

122245
os_info_file = fopen(OS_INFO_FILE_NAME, "r");
123246

0 commit comments

Comments
 (0)