1 /* env.c
2  */
3 /* This software is copyrighted as detailed in the LICENSE file. */
4 
5 
6 #include "EXTERN.h"
7 #include "common.h"
8 #include "init.h"
9 #include "final.h"
10 #include "util.h"
11 #include "util2.h"
12 #include "INTERN.h"
13 #include "env.h"
14 #include "env.ih"
15 
16 #ifdef HAS_RES_INIT
17 #include <netinet/in.h>
18 #include <arpa/nameser.h>
19 #include <resolv.h>
20 #endif
21 
22 bool
env_init(tcbuf,lax)23 env_init(tcbuf, lax)
24 char* tcbuf;
25 bool_int lax;
26 {
27     bool fully_successful = TRUE;
28 
29     if ((homedir = getenv("HOME")) == NULL)
30 	homedir = getenv("LOGDIR");
31 
32     if ((tmpdir = getenv("TMPDIR")) == NULL)
33 	tmpdir = getval("TMP","/tmp");
34 
35     /* try to set loginName */
36     if (lax) {
37 	loginName = getenv("USER");
38 	if (!loginName)
39 	    loginName = getenv("LOGNAME");
40     }
41 #ifndef MSDOS
42     if (!lax || !loginName) {
43 	loginName = getlogin();
44 	if (loginName)
45 	    loginName = savestr(loginName);
46     }
47 #endif
48 
49     /* Set realName, and maybe set loginName and homedir (if NULL). */
50     if (!setusername(tcbuf)) {
51 	if (!loginName)
52 	    loginName = nullstr;
53 	if (!realName)
54 	    realName = nullstr;
55 	fully_successful = FALSE;
56     }
57     env_init2();
58 
59     /* set phostname to the hostname of our local machine */
60     if (!setphostname(tcbuf))
61 	fully_successful = FALSE;
62 
63 #ifdef SUPPORT_NNTP
64     {
65 	char* cp = getval("NETSPEED","5");
66 	if (*cp == 'f')
67 	    netspeed = 10;
68 	else if (*cp == 's')
69 	    netspeed = 1;
70 	else {
71 	    netspeed = atoi(cp);
72 	    if (netspeed < 1)
73 		netspeed = 1;
74 	}
75     }
76 #endif
77 
78     return fully_successful;
79 }
80 
81 static void
env_init2()82 env_init2()
83 {
84     if (dotdir)		/* Avoid running multiple times. */
85 	return;
86     if (!homedir)
87 	homedir = "/";
88     dotdir = getval("DOTDIR",homedir);
89     trndir = savestr(filexp(getval("TRNDIR",TRNDIR)));
90     lib = savestr(filexp(NEWSLIB));
91     rnlib = savestr(filexp(PRIVLIB));
92 }
93 
94 /* Set loginName to the user's login name and realName to the user's
95 ** real name.
96 */
97 bool
setusername(tmpbuf)98 setusername(tmpbuf)
99 char* tmpbuf;
100 {
101     char* s;
102     char* c;
103 
104 #ifdef HAS_GETPWENT
105     struct passwd* pwd;
106 
107     if (loginName == NULL)
108 	pwd = getpwuid(getuid());
109     else
110 	pwd = getpwnam(loginName);
111     if (!pwd)
112 	return 0;
113     if (!loginName)
114 	loginName = savestr(pwd->pw_name);
115     if (!homedir)
116 	homedir = savestr(pwd->pw_dir);
117     s = pwd->pw_gecos;
118 #else /* !HAS_GETPWENT */
119     int i;
120 
121     if (getpw(getuid(), tmpbuf+1) != 0)
122 	return 0;
123     if (!loginName) {
124 	cpytill(buf,tmpbuf+1,':');
125 	loginName = savestr(buf);
126     }
127     for (s = tmpbuf, i = GCOSFIELD-1; i; i--) {
128 	if (s)
129 	    s = index(s+1,':');
130     }
131     if (!s)
132 	return 0;
133     s = cpytill(tmpbuf,s+1,':');
134     if (!homedir) {
135 	cpytill(buf,s+1,':');
136 	homedir = savestr(buf);
137     }
138     s = tmpbuf;
139 #endif /* !HAS_GETPWENT */
140 #ifdef PASSNAMES
141 #ifdef BERKNAMES
142 #ifdef BERKJUNK
143     while (*s && !isalnum(*s) && *s != '&') s++;
144 #endif
145     if ((c = index(s, ',')) != NULL)
146 	*c = '\0';
147     if ((c = index(s, ';')) != NULL)
148 	*c = '\0';
149     s = cpytill(buf,s,'&');
150     if (*s == '&') {			/* whoever thought this one up was */
151 	c = buf + strlen(buf);		/* in the middle of the night */
152 	strcat(c,loginName);		/* before the morning after */
153 	strcat(c,s+1);
154 	if (islower(*c))
155 	    *c = toupper(*c);		/* gack and double gack */
156     }
157     realName = savestr(buf);
158 #else /* !BERKNAMES */
159     if ((c = index(s, '(')) != NULL)
160 	*c = '\0';
161     if ((c = index(s, '-')) != NULL)
162 	s = c;
163     realName = savestr(s);
164 #endif /* !BERKNAMES */
165 #else /* !PASSNAMES */
166     {
167 	FILE* fp;
168 	env_init2(); /* Make sure homedir/dotdir/etc. are set. */
169 	if ((fp = fopen(filexp(FULLNAMEFILE),"r")) != NULL) {
170 	    fgets(buf,sizeof buf,fp);
171 	    fclose(fp);
172 	    buf[strlen(buf)-1] = '\0';
173 	    realName = savestr(buf);
174 	}
175 	else
176 	    s = "PUT_YOUR_NAME_HERE";
177     }
178 #endif /* !PASSNAMES */
179 #ifdef HAS_GETPWENT
180     endpwent();
181 #endif
182     return 1;
183 }
184 
185 bool
setphostname(tmpbuf)186 setphostname(tmpbuf)
187 char* tmpbuf;
188 {
189     FILE* fp;
190     bool hostname_ok = TRUE;
191 
192     /* Find the local hostname */
193 
194 #ifdef HAS_GETHOSTNAME
195     gethostname(tmpbuf,TCBUF_SIZE);
196 #else
197 # ifdef HAS_UNAME
198     /* get sysname */
199     uname(&utsn);
200     strcpy(tmpbuf,utsn.nodename);
201 # else
202 #  ifdef PHOSTCMD
203     {
204 	FILE* popen();
205 	FILE* pipefp = popen(PHOSTCMD,"r");
206 
207 	if (pipefp == NULL) {
208 	    printf("Can't find hostname\n");
209 	    finalize(1);
210 	}
211 	fgets(tmpbuf,TCBUF_SIZE,pipefp);
212 	tmpbuf[strlen(tmpbuf)-1] = '\0';	/* wipe out newline */
213 	pclose(pipefp);
214     }
215 #  else
216     strcpy(tmpbuf, "!INVALID!");
217 #  endif /* PHOSTCMD */
218 # endif /* HAS_UNAME */
219 #endif /* HAS_GETHOSTNAME */
220     localhost = savestr(tmpbuf);
221 
222     /* Build the host name that goes in postings */
223 
224     phostname = PHOSTNAME;
225     if (FILE_REF(phostname) || *phostname == '~') {
226 	phostname = filexp(phostname);
227 	if ((fp = fopen(phostname,"r")) == NULL)
228 	    strcpy(tmpbuf,".");
229 	else {
230 	    fgets(tmpbuf,TCBUF_SIZE,fp);
231 	    fclose(fp);
232 	    phostname = tmpbuf + strlen(tmpbuf) - 1;
233 	    if (*phostname == '\n')
234 		*phostname = '\0';
235 	}
236     }
237     else
238 	strcpy(tmpbuf,phostname);
239 
240     if (*tmpbuf == '.') {
241 	if (tmpbuf[1] != '\0')
242 	    strcpy(buf,tmpbuf);
243 	else
244 	    *buf = '\0';
245 	strcpy(tmpbuf,localhost);
246 	strcat(tmpbuf,buf);
247     }
248 
249     if (!index(tmpbuf,'.')) {
250 	if (*tmpbuf)
251 	    strcat(tmpbuf, ".");
252 #ifdef HAS_RES_INIT
253 	if (!(_res.options & RES_INIT))
254 	    res_init();
255 	if (_res.defdname != NULL)
256 	    strcat(tmpbuf,_res.defdname);
257 	else
258 #endif
259 #ifdef HAS_GETDOMAINNAME
260 	if (getdomainname(buf,LBUFLEN) == 0)
261 	    strcat(tmpbuf,buf);
262 	else
263 #endif
264 	{
265 	    strcat(tmpbuf,"UNKNOWN.HOST");
266 	    hostname_ok = FALSE;
267 	}
268     }
269     phostname = savestr(tmpbuf);
270     return hostname_ok;
271 }
272 
273 char*
getval(nam,def)274 getval(nam,def)
275 char* nam;
276 char* def;
277 {
278     char* val;
279 
280     if ((val = getenv(nam)) == NULL || !*val)
281 	return def;
282     return val;
283 }
284 
285 static bool firstexport = TRUE;
286 extern char** environ;
287 
288 char*
export(nam,val)289 export(nam,val)
290 char* nam;
291 char* val;
292 {
293     int namlen = strlen(nam);
294     register int i=envix(nam,namlen);	/* where does it go? */
295 
296     if (!environ[i]) {			/* does not exist yet */
297 	if (firstexport) {		/* need we copy environment? */
298 	    int j;
299 #ifndef lint
300 	    char** tmpenv = (char**)	/* point our wand at memory */
301 		safemalloc((MEM_SIZE) (i+2) * sizeof(char*));
302 #else
303 	    char** tmpenv = NULL;
304 #endif /* lint */
305 
306 	    firstexport = FALSE;
307 	    for (j = 0; j < i; j++)	/* copy environment */
308 		tmpenv[j] = environ[j];
309 	    environ = tmpenv;		/* tell exec where it is now */
310 	}
311 #ifndef lint
312 	else
313 	    environ = (char**) saferealloc((char*) environ,
314 		(MEM_SIZE) (i+2) * sizeof(char*));
315 					/* just expand it a bit */
316 #endif /* lint */
317 	environ[i+1] = NULL;	/* make sure it's null terminated */
318     }
319     environ[i] = safemalloc((MEM_SIZE)(namlen + strlen(val) + 2));
320 					/* this may or may not be in */
321 					/* the old environ structure */
322     sprintf(environ[i],"%s=%s",nam,val);/* all that work just for this */
323     return environ[i] + namlen + 1;
324 }
325 
326 void
un_export(export_val)327 un_export(export_val)
328 char* export_val;
329 {
330     if (export_val[-1] == '=' && export_val[-2] != '_') {
331 	export_val[0] = export_val[-2];
332 	export_val[1] = '\0';
333 	export_val[-2] = '_';
334     }
335 }
336 
337 void
re_export(export_val,new_val,limit)338 re_export(export_val, new_val, limit)
339 char* export_val;
340 char* new_val;
341 int limit;
342 {
343     if (export_val[-1] == '=' && export_val[-2] == '_' && !export_val[1])
344 	export_val[-2] = export_val[0];
345     safecpy(export_val, new_val, limit+1);
346 }
347 
348 static int
envix(nam,len)349 envix(nam, len)
350 char* nam;
351 int len;
352 {
353     register int i;
354 
355     for (i = 0; environ[i]; i++) {
356 	if (strnEQ(environ[i],nam,len) && environ[i][len] == '=')
357 	    break;			/* strnEQ must come first to avoid */
358     }					/* potential SEGV's */
359     return i;
360 }
361 
362 #ifdef MSDOS
363 
364 char*
GetEnv(var)365 GetEnv(var)
366 char* var;
367 {
368 #undef getenv
369     char* s = getenv(var);
370     if (s && isalpha(*s) && s[1] == ':') {
371 	char* t = index(s,'\\');
372 	if (t) {
373 	    char ebuf[MAXDIR+32];
374 	    strcpy(ebuf,s);
375 	    t = ebuf + (t-s);
376 	    do {
377 		*t = '/';
378 	    } while ((t = index(t,'\\')) != NULL);
379 	    s = export(var,ebuf);
380 	}
381     }
382     return s;
383 }
384 #endif
385