tin  2.6.1
About: TIN is a threaded NNTP and spool based UseNet newsreader.
  Fossies Dox: tin-2.6.1.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

header.c
Go to the documentation of this file.
1/*
2 * Project : tin - a Usenet reader
3 * Module : header.c
4 * Author : Urs Janssen <urs@tin.org>
5 * Created : 1997-03-10
6 * Updated : 2021-02-23
7 *
8 * Copyright (c) 1997-2022 Urs Janssen <urs@tin.org>
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 *
15 * 1. Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 *
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 *
22 * 3. Neither the name of the copyright holder nor the names of its
23 * contributors may be used to endorse or promote products derived from
24 * this software without specific prior written permission.
25 *
26 * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39#ifndef TIN_H
40# include "tin.h"
41#endif /* !TIN_H */
42#ifndef TNNTP_H
43# include "tnntp.h"
44#endif /* !TNNTP_H */
45
46static const char *get_full_name(void);
47static const char *get_user_name(void);
48
49
50/* find hostname */
51const char *
53 void)
54{
55 char *ptr;
56 static char hostname[MAXHOSTNAMELEN + 1]; /* need space for '\0' */
57
58 hostname[0] = '\0';
59
60#ifdef HAVE_GETHOSTNAME
61 gethostname(hostname, sizeof(hostname) - 1);
62#endif /* HAVE_GETHOSTNAME */
63#ifdef HAVE_SYS_UTSNAME_H
64 if (!*hostname)
65 my_strncpy(hostname, system_info.nodename, sizeof(hostname) - 1);
66#endif /* HAVE_SYS_UTSNAME_H */
67 if (!*hostname) {
68 if ((ptr = getenv("HOST")) != NULL)
69 my_strncpy(hostname, ptr, sizeof(hostname) - 1);
70 else {
71 if ((ptr = getenv("HOSTNAME")) != NULL)
72 my_strncpy(hostname, ptr, sizeof(hostname) - 1);
73 else
74 hostname[0] = '\0';
75 }
76 }
77 hostname[MAXHOSTNAMELEN] = '\0';
78 return hostname;
79}
80
81
82#ifdef DOMAIN_NAME
83/*
84 * find domainname - check DOMAIN_NAME
85 * TODO: check /etc/defaultdomain as a last resort?
86 */
87const char *
89 void)
90{
91 FILE *fp;
92 char *ptr;
93 char buff[MAXHOSTNAMELEN + 1];
94 static char domain[8192];
95
96 domain[0] = '\0';
97
98 if (strlen(DOMAIN_NAME))
99 strcpy(domain, DOMAIN_NAME);
100
101 if (domain[0] == '/' && domain[1]) {
102 /* read domainname from specified file */
103 if ((fp = fopen(domain, "r")) != NULL) {
104 while (fgets(buff, (int) sizeof(buff), fp) != NULL) {
105 if (buff[0] == '#' || buff[0] == '\n')
106 continue;
107
108 if ((ptr = strrchr(buff, '\n'))) {
109 *ptr = '\0';
110 strcpy(domain, buff);
111 }
112 }
113 if (domain[0] == '/') /* '/' is not allowed in domainames -> file was empty */
114 domain[0] = '\0';
115
116 fclose(fp);
117 } else
118 domain[0] = '\0';
119 }
120 domain[MAXHOSTNAMELEN + 1] = '\0';
121 return domain;
122}
123#endif /* DOMAIN_NAME */
124
125
126#ifdef HAVE_GETHOSTBYNAME
127# define MAXLINELEN 1024
128# define WS " \f\t\v"
129/* find FQDN - gethostbyaddr() */
130const char *
132 const char *host)
133{
134 char *domain;
135 char line[MAXLINELEN + 1];
136 char name[MAXHOSTNAMELEN + 1];
137 static char fqdn[1024];
138 struct hostent *hp;
139 struct in_addr in = {0};
140
141 *fqdn = '\0';
142 domain = NULL;
143 name[MAXHOSTNAMELEN] = '\0';
144
145 if (host) {
146 if (strchr(host, '.'))
147 return host;
148 my_strncpy(name, host, sizeof(name) - 1);
149 } else {
150# ifdef HAVE_GETHOSTNAME
151 if (gethostname(name, sizeof(name) - 1))
152# endif /* HAVE_GETHOSTNAME */
153 return NULL;
154 }
155
156# ifdef HAVE_INET_ADDR
157 if (*name >= '0' && *name <= '9') {
158 in_addr_t addr = inet_addr(name);
159
160 if ((hp = gethostbyaddr((char *) &addr, 4, AF_INET)))
161# ifdef HAVE_HOSTENT_H_ADDR_LIST
162 in.s_addr = (*hp->h_addr_list[0]);
163# else
164 in.s_addr = (*hp->h_addr);
165# endif /* HAVE_HOSTENT_H_ADDR_LIST */
166 return (hp && strchr(hp->h_name, '.') ? hp->h_name : inet_ntoa(in));
167 }
168# endif /* HAVE_INET_ADDR */
169 if ((hp = gethostbyname(name)) && !strchr(hp->h_name, '.'))
170# ifdef HAVE_HOSTENT_H_ADDR_LIST
171 if ((hp = gethostbyaddr(hp->h_addr_list[0], hp->h_length, hp->h_addrtype)))
172 in.s_addr = (*hp->h_addr_list[0]);
173# else
174 if ((hp = gethostbyaddr(hp->h_addr, hp->h_length, hp->h_addrtype)))
175 in.s_addr = (*hp->h_addr);
176# endif /* HAVE_HOSTENT_H_ADDR_LIST */
177 snprintf(fqdn, sizeof(fqdn), "%s", hp
178 ? strchr(hp->h_name, '.')
179 ? hp->h_name : inet_ntoa(in)
180 : "");
181
182 if (!*fqdn || (fqdn[strlen(fqdn) - 1] <= '9')) {
183 FILE *inf;
184
185 *fqdn = '\0';
186
187 if ((inf = fopen("/etc/resolv.conf", "r")) != NULL) {
188 char *eos;
189 int j;
190
191 while (fgets(line, MAXLINELEN, inf)) {
192 if (line[0] == '#' || line[0] == '\n')
193 continue;
194
195 line[MAXLINELEN] = '\0';
196
197 if ((eos = strpbrk(line, WS)) != NULL) {
198 if ((j = (int) (eos - line))) {
199 if (!strncmp(line, "domain", (size_t) j) || !strncmp(line, "search", (size_t) j)) {
200 domain = strtok(eos, WS);
201 break;
202 }
203 }
204 }
205 }
206 if (domain)
207 snprintf(fqdn, sizeof(fqdn), "%s.%s", name, strip_line(domain));
208
209 fclose(inf);
210 }
211 }
212 return fqdn;
213}
214#endif /* HAVE_GETHOSTBYNAME */
215
216
217/*
218 * Find username & fullname
219 */
220void
222 char *user_name,
223 char *full_name)
224{
225 const char *ptr;
226
227 user_name[0] = '\0';
228 full_name[0] = '\0';
229
230 if ((ptr = get_full_name()))
231 strcpy(full_name, ptr);
232 if ((ptr = get_user_name()))
233 strcpy(user_name, ptr);
234}
235
236
237static const char *
239 void)
240{
241 static char username[128];
242 struct passwd *pw;
243
244 username[0] = '\0';
245
246 if ((pw = getpwuid(getuid())) != NULL)
247 STRCPY(username, pw->pw_name);
248 else {
249 if (!*username)
251 }
252
253 return username;
254}
255
256
257static const char *
259 void)
260{
261 char *p;
262 static char fullname[128];
263#ifndef DONT_HAVE_PW_GECOS
264 char buf[128];
265 char tmp[128];
266 struct passwd *pw;
267#endif /* !DONT_HAVE_PW_GECOS */
268
269 fullname[0] = '\0';
270
271 if ((p = getenv("NAME")) != NULL) {
272 my_strncpy(fullname, p, sizeof(fullname) - 1);
273 return fullname;
274 }
275 if ((p = getenv("REALNAME")) != NULL) {
276 my_strncpy(fullname, p, sizeof(fullname) - 1);
277 return fullname;
278 }
279
280#ifndef DONT_HAVE_PW_GECOS
281 if ((pw = getpwuid(getuid())) != NULL) {
282 STRCPY(buf, pw->pw_gecos);
283 if ((p = strchr(buf, ',')))
284 *p = '\0';
285 if ((p = strchr(buf, '&'))) {
286 *p++ = '\0';
287 STRCPY(tmp, pw->pw_name);
288 if (*tmp && isalpha((int)(unsigned char) *tmp) && islower((int)(unsigned char) *tmp))
289 *tmp = (char) my_toupper((int) (unsigned char) *tmp);
290 snprintf(fullname, sizeof(fullname), "%s%s%s", buf, tmp, p);
291 } else
292 STRCPY(fullname, buf);
293 }
294#endif /* !DONT_HAVE_PW_GECOS */
295 return fullname;
296}
297
298
299/*
300 * FIXME to:
301 * char *build_from(full_name, user_name, domain_name)
302 */
303/*
304 * build From: in 'name <user@host.doma.in>' format
305 */
306void
308 char *from_name,
309 struct t_group *thisgrp)
310{
311 char *fromhost = domain_name;
312
313 if (thisgrp && *thisgrp->attribute->from != '\0') {
314 strcpy(from_name, thisgrp->attribute->from);
315 return;
316 }
317
318 sprintf(from_name, ((strpbrk(get_full_name(), "!()<>@,;:\\\".[]")) ? "\"%s\" <%s@%s>" : "%s <%s@%s>"), BlankIfNull(get_full_name()), BlankIfNull(get_user_name()), BlankIfNull(fromhost));
319
320#ifdef DEBUG
321 if (debug & DEBUG_MISC)
322 error_message(2, "FROM=[%s] USER=[%s] HOST=[%s] NAME=[%s]", BlankIfNull(from_name), BlankIfNull(get_user_name()), domain_name, BlankIfNull(get_full_name()));
323#endif /* DEBUG */
324}
325
326
327/*
328 * build_sender()
329 * returns *(Full_Name <user@fq.domainna.me>)
330 */
331#ifndef FORGERY
332char *
334 void)
335{
336 const char *ptr;
337 static char sender[8192];
338
339 sender[0] = '\0';
340
341 if ((ptr = get_full_name()))
342 snprintf(sender, sizeof(sender), ((strpbrk(ptr, "\".:;<>@[]()\\")) ? "\"%s\"" : "%s "), ptr);
343 if ((ptr = get_user_name())) {
344 snprintf(sender + strlen(sender), sizeof(sender) - strlen(sender), "<%s@", ptr);
345
346# ifdef HAVE_GETHOSTBYNAME
347 if ((ptr = get_fqdn(get_host_name())))
348# else
349 if ((ptr = get_host_name()))
350# endif /* HAVE_GETHOSTBYNAME */
351 snprintf(sender + strlen(sender), sizeof(sender) - strlen(sender), "%s>", ptr);
352 else
353 return NULL;
354 } else
355 return NULL;
356
357 return sender;
358}
359#endif /* !FORGERY */
#define DEBUG_MISC
Definition: debug.h:54
constext txt_error_passwd_missing[]
Definition: lang.c:262
char domain_name[]
Definition: init.c:75
unsigned short debug
Definition: debug.c:51
const char * get_host_name(void)
Definition: header.c:52
void get_user_info(char *user_name, char *full_name)
Definition: header.c:221
static const char * get_user_name(void)
Definition: header.c:238
void get_from_name(char *from_name, struct t_group *thisgrp)
Definition: header.c:307
static const char * get_full_name(void)
Definition: header.c:258
char * build_sender(void)
Definition: header.c:333
static char buf[16]
Definition: langinfo.c:50
char * strpbrk(const char *str1, const char *str2)
Definition: string.c:312
void error_message(unsigned int sdelay, const char *fmt,...)
Definition: screen.c:224
_Noreturn void tin_done(int ret, const char *fmt,...)
Definition: misc.c:562
char * strip_line(char *line)
Definition: misc.c:3644
const char * get_fqdn(const char *host)
const char * get_domain_name(void)
int my_toupper(int)
Definition: string.c:276
void my_strncpy(char *p, const char *q, size_t n)
Definition: string.c:196
const char * name
Definition: signal.c:117
char * from
Definition: tin.h:1631
Definition: tin.h:1816
struct t_attribute * attribute
Definition: tin.h:1834
#define STRCPY(dst, src)
Definition: tin.h:820
#define EXIT_FAILURE
Definition: tin.h:1302
#define _(Text)
Definition: tin.h:94
#define snprintf
Definition: tin.h:2464
#define BlankIfNull(p)
Definition: tin.h:2255
#define MAXHOSTNAMELEN
Definition: tnntp.h:114