1 /*
2  * news configuration inquiry
3  */
4 
5 #include <stdio.h>
6 #include <sys/types.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include "libc.h"
10 #include "news.h"
11 #include "config.h"
12 
13 #ifndef NULL
14 #define	NULL	0
15 #endif
16 
17 #ifndef NEWSCTL
18 /* =()<#define	NEWSCTL	"@<NEWSCTL>@">()= */
19 #define	NEWSCTL	"/etc/news"
20 #endif
21 #ifndef NEWSPATH
22 /* =()<#define	NEWSPATH	"@<NEWSPATH>@">()= */
23 #define	NEWSPATH	"/bin:/usr/bin:/usr/contrib/bin"
24 #endif
25 #ifndef NEWSARTS
26 /* =()<#define	NEWSARTS	"@<NEWSARTS>@">()= */
27 #define	NEWSARTS	"/var/news"
28 #endif
29 #ifndef NEWSBIN
30 /* =()<#define	NEWSBIN	"@<NEWSBIN>@">()= */
31 #define	NEWSBIN	"/usr/libexec/news"
32 #endif
33 #ifndef NEWSUMASK
34 /* =()<#define	NEWSUMASK	@<NEWSUMASK>@>()= */
35 #define	NEWSUMASK	022
36 #endif
37 #ifndef NEWSCONFIG
38 /* =()<#define	NEWSCONFIG	"@<NEWSCONFIG>@">()= */
39 #define	NEWSCONFIG	"/etc/news/bin/config"
40 #endif
41 
42 static char *pwd = NULL;	/* Current directory, NULL means unknown. */
43 static int dirsset = NO;	/* Have the following been set up? */
44 static const char *arts = NEWSARTS;
45 static const char *bin = NEWSBIN;
46 static const char *ctl = NEWSCTL;
47 static const char *path = NEWSPATH;
48 static int numask = NEWSUMASK;
49 static const char *nconfig = NEWSCONFIG;
50 #define	DIRS()	if (!dirsset) setdirs()
51 
52 extern char *getenv();
53 
54 /*
55  - setdirs - set up stuff from environment, for use by other functions
56  *
57  * Invokes user-supplied function unprivileged() if non-standard values used.
58  */
59 static void
setdirs()60 setdirs()
61 {
62 	register char *p;
63 	register int mask;
64 	register char *scan;
65 	register int ns = 0;
66 #	define	NONSTD(reason)	{ if (!ns) { unprivileged(reason); ns = 1; } }
67 
68 	if (dirsset)
69 		return;
70 
71 	p = getenv("NEWSARTS");
72 	if (p != NULL && !STREQ(p, arts)) {
73 		arts = p;
74 		NONSTD("NEWSARTS");
75 	}
76 
77 	p = getenv("NEWSCTL");
78 	if (p != NULL && !STREQ(p, ctl)) {
79 		ctl = p;
80 		NONSTD("NEWSCTL");
81 	}
82 
83 	p = getenv("NEWSPATH");
84 	if (p != NULL && !STREQ(p, path)) {
85 		path = p;
86 		NONSTD("NEWSPATH");
87 	}
88 
89 	p = getenv("NEWSBIN");
90 	if (p != NULL && !STREQ(p, bin)) {
91 		bin = p;
92 		NONSTD("NEWSBIN");
93 	}
94 
95 	p = getenv("NEWSUMASK");
96 	if (p != NULL) {
97 		mask = 0;
98 		for (scan = p; *scan != '\0'; scan++)
99 			if ('0' <= *scan && *scan <= '7' && mask <= 077)
100 				mask = (mask << 3) | (*scan - '0');
101 			else {	/* Garbage, ignore it. */
102 				mask = numask;
103 				break;			/* NOTE BREAK OUT */
104 			}
105 		if (mask != numask) {
106 			numask = mask;
107 			NONSTD("NEWSUMASK");
108 		}
109 	}
110 
111 	p = getenv("NEWSCONFIG");
112 	if (p != NULL && !STREQ(p, nconfig)) {
113 		nconfig = p;
114 		NONSTD("NEWSCONFIG");
115 	}
116 
117 	dirsset = YES;
118 }
119 
120 /*
121  - artfile - best pathname for a file in NEWSARTS
122  */
123 const char *
artfile(base)124 artfile(base)
125 const char *base;
126 {
127 	static char *artf = NULL;
128 
129 	DIRS();
130 
131 	if (base == NULL)	/* he just wants the directory */
132 		return (arts);
133 
134 	if (artf != NULL)
135 		free(artf);	/* toss old returned value */
136 	if (pwd != NULL && STREQ(pwd, arts))
137 		artf = strsave(base);
138 	else
139 		artf = str3save(arts, SFNDELIM, base);
140 
141 	return (artf);
142 }
143 
144 /*
145  - fullartfile - full pathname for a file in NEWSARTS
146  */
147 const char *
fullartfile(base)148 fullartfile(base)
149 const char *base;
150 {
151 	register const char *p;
152 	register char *pwdsave;
153 
154 	pwdsave = pwd;
155 	pwd = NULL;		/* fool artfile() into giving full path */
156 	p = artfile(base);
157 	pwd = pwdsave;
158 	return (p);
159 }
160 
161 /*
162  - ctlfile - full pathname for a file in NEWSCTL
163  */
164 const char *
ctlfile(base)165 ctlfile(base)
166 const char *base;
167 {
168 	static char *ctlf = NULL;
169 
170 	DIRS();
171 
172 	if (ctlf != NULL)
173 		free(ctlf);		/* toss old returned value */
174 
175 	if (base == NULL) {
176 		ctlf = NULL;
177 		return(ctl);
178 	} else {
179 		ctlf = str3save(ctl, SFNDELIM, base);
180 		return(ctlf);
181 	}
182 }
183 
184 /*
185  - binfile - full pathname for a file in NEWSBIN
186  */
187 const char *
binfile(base)188 binfile(base)
189 const char *base;
190 {
191 	static char *binf = NULL;
192 
193 	DIRS();
194 
195 	if (binf != NULL)
196 		free(binf);		/* toss old returned value */
197 
198 	if (base == NULL) {
199 		binf = NULL;
200 		return(bin);
201 	} else {
202 		binf = str3save(bin, SFNDELIM, base);
203 		return (binf);
204 	}
205 }
206 
207 /*
208  - cd - change to a directory, with checking
209  */
210 void
cd(dir)211 cd(dir)
212 const char *dir;
213 {
214 	if (pwd != NULL)
215 		free(pwd);
216 	if (chdir(dir) < 0)
217 		errunlock("cannot chdir(%s)", dir);
218 	pwd = strsave(dir);
219 }
220 
221 /*
222  - newspath - search path for normal system commands
223  */
224 const char *
newspath()225 newspath()
226 {
227 	DIRS();
228 	return(path);
229 }
230 
231 /*
232  - newsumask - suitable value of umask for news stuff
233  */
234 int
newsumask()235 newsumask()
236 {
237 	DIRS();
238 	return(numask);
239 }
240