1 #include "defs.h"
2 #include "readnews_error.h"
3 
4 /*
5  * string handling functions
6  */
7 char *
myalloc(size)8 myalloc(size)
9 int size;
10 {
11 	register char *cp;
12 
13 	if ((cp = malloc((unsigned) size)) == NIL(char))
14 		readnews_error("No more memory.");
15 	return cp;
16 }
17 
18 
19 char *
myrealloc(ptr,size)20 myrealloc(ptr, size)
21 char *ptr;
22 int size;
23 {
24 	register char *cp;
25 
26 	if ((cp = realloc(ptr, (unsigned) size)) == NIL(char))
27 		readnews_error("No more memory.");
28 	return cp;
29 }
30 
31 
32 char *
newstr(s)33 newstr(s)
34 const char *s;
35 {
36 	return strcpy(myalloc(strlen(s) + 1), s);
37 }
38 
39 
40 char *
newstr2(s1,s2)41 newstr2(s1, s2)
42 const char *s1, *s2;
43 {
44 	return strcat(strcpy(myalloc(strlen(s1) + strlen(s2) + 1), s1), s2);
45 }
46 
47 
48 char *
newstr3(s1,s2,s3)49 newstr3(s1, s2, s3)
50 const char *s1, *s2, *s3;
51 {
52 	return strcat(strcat(strcpy(myalloc(strlen(s1) + strlen(s2) + strlen(s3) +
53 	    1), s1), s2), s3);
54 }
55 
56 
57 char *
newstr4(s1,s2,s3,s4)58 newstr4(s1, s2, s3, s4)
59 const char *s1, *s2, *s3, *s4;
60 {
61 	return strcat(strcat(strcat(strcpy(myalloc(strlen(s1) + strlen(s2) +
62 	    strlen(s3) + strlen(s4) + 1), s1), s2), s3), s4);
63 }
64 
65 
66 char *
newstr5(s1,s2,s3,s4,s5)67 newstr5(s1, s2, s3, s4, s5)
68 const char *s1, *s2, *s3, *s4, *s5;
69 {
70 	return strcat(strcat(strcat(strcat(strcpy(myalloc(strlen(s1) + strlen(s2) +
71 	    strlen(s3) + strlen(s4) + strlen(s5) + 1), s1), s2), s3), s4), s5);
72 }
73 
74 
75 char *
newstr6(s1,s2,s3,s4,s5,s6)76 newstr6(s1, s2, s3, s4, s5, s6)
77 const char *s1, *s2, *s3, *s4, *s5, *s6;
78 {
79 	return strcat(strcat(strcat(strcat(strcat(strcpy(myalloc(strlen(s1) +
80 	    strlen(s2) + strlen(s3) + strlen(s4) + strlen(s5) + strlen(s6) + 1),
81 	     s1), s2), s3), s4), s5), s6);
82 }
83 
84 
85 char *
catstr(old,s)86 catstr(old, s)
87 char *old, *s;
88 {
89 	return strcat(myrealloc(old, strlen(old) + strlen(s) + 1), s);
90 }
91 
92 
93 char *
catstr2(old,s1,s2)94 catstr2(old, s1, s2)
95 char *old, *s1, *s2;
96 {
97 	return strcat(strcat(myrealloc(old, strlen(old) + strlen(s1) + strlen(s2) +
98 	    1), s1), s2);
99 }
100 
101 
102 /*
103  * Compare two newsgroups for equality.
104  * The first one may be a "meta" newsgroup.
105  */
106 static
ptrncmp(ng1,ng2)107 ptrncmp(ng1, ng2)
108 register char *ng1, *ng2;
109 {
110 
111 	while (1) {
112 		if (ng1[0] == 'a' && ng1[1] == 'l' && ng1[2] == 'l' && (ng1[3] ==
113 		    '\0' || ng1[3] == '.')) {
114 			if (ng1[3] == '\0')	/* "all" matches anything */
115 				return 1;
116 			while (*ng2 && *ng2 != '.')
117 				ng2++;
118 			if (*ng2 != '.')		/* "all." doesn't match "xx" */
119 				return 0;
120 			ng1 += 4, ng2++;
121 			continue;
122 		}
123 		while (*ng1 && *ng1 != '.' && *ng1 == *ng2)
124 			ng1++, ng2++;
125 		if (*ng1 == '.') {
126 			if (*ng2 != '.' && *ng2 != '\0')
127 				return 0;	/* "."'s don't line up */
128 			if (*ng2)
129 				ng2++;
130 			ng1++;			/* "."'s line up - keep going */
131 		} else if (*ng1 == '\0')
132 			return (*ng2 == '\0' || *ng2 == '.');
133 			/* full match or X matching X.thing */
134 		else
135 			return 0;
136 	}
137 	/* NOTREACHED */
138 }
139 
140 
141 
142 /*
143  * News group matching.
144  *
145  * nglist is a list of newsgroups.
146  * sublist is a list of subscriptions.
147  * sublist may have "meta newsgroups" in it.
148  * All fields are NGSEPCHAR separated.
149  *
150  * sublist uses "all" like shell uses "*", and "." like shell uses "/"
151  * if subscription X matches Y, it also matches Y.anything
152  */
153 int
readnews_ngmatch(nglist,sublist)154 readnews_ngmatch(nglist, sublist)
155 char *nglist, *sublist;
156 {
157 	register char *n, *s, *nd, *sd;
158 	register int rc;
159 
160 	rc = 0;
161 	n = nglist;
162 	while (*n && rc == 0) {
163 		if ((nd = strchr(n, NGSEPCHAR)))
164 			*nd = '\0';
165 		s = sublist;
166 		while (*s) {
167 			if ((sd = strchr(s, NGSEPCHAR)))
168 				*sd = '\0';
169 			if (*s != NEGCHAR)
170 				rc |= ptrncmp(s, n);
171 			else
172 				rc &= ~ptrncmp(s + 1, n);
173 			if (sd)
174 				*sd = NGSEPCHAR, s = sd + 1;
175 			else
176 				break;
177 		}
178 		if (nd)
179 			*nd = NGSEPCHAR, n = nd + 1;
180 		else
181 			break;
182 	}
183 	return rc;
184 }
185 
186 
187 /*
188  * open a file
189  */
190 FILE *
fopenf(name,mode)191 fopenf(name, mode)
192 char *name, *mode;
193 {
194 	register FILE	*f;
195 
196 	if ((f = fopen(name, mode)) == NULL)
197 		readnews_error("Can't %s %s", *mode == 'r' ? "open" : "create", name);
198 	return f;
199 }
200 
201 
202 /*
203  * replace all '.''s with '/'
204  */
205 char *
convg(s)206 convg(s)
207 char *s;
208 {
209 	register char *sav;
210 
211 	sav = s;
212 	while ((s = strchr(s, '.')))
213 		*s = '/';
214 	return sav;
215 }
216 
217 
218 /*
219  * get a line from stdin
220  * trim leading and trailing blanks
221  */
222 char *
mgets()223 mgets()
224 {
225 	register char *s;
226 	static char buf[BUFSIZ];
227 
228 	fflush(stdout);
229 	if (fgets(buf, sizeof(buf), stdin) == NULL) {
230 		(void) printf("\n");
231 		return NIL(char);
232 	}
233 	if ((s = strchr(buf, '\n')))
234 		while (isspace(*s) && s > buf)
235 			*s-- = '\0';
236 	else {
237 		(void) printf("Input line too long.\n");
238 		return NULL;
239 	}
240 	s = buf;
241 	while (isspace(*s))
242 		s++;
243 	return s;
244 }
245 
246 
247 /*
248  * apply the given function to each member in the newsgroup
249  */
250 /* VARARGS2 */
applyng(ng,func,arg1)251 applyng(ng, func, arg1)
252 register char *ng;
253 register int (*func)();
254 char *arg1;
255 {
256 	register char *delim;
257 	register int err;
258 
259 	err = 0;
260 	while (*ng) {
261 		if ((delim = strchr(ng, NGSEPCHAR)))
262 			*delim = '\0';
263 		err += (*func)(ng, arg1);
264 		if (delim)
265 			*delim = NGSEPCHAR, ng = delim + 1;
266 		else
267 			break;
268 	}
269 	return err;
270 }
271 
272 
273 /*
274  * generate a return address
275  */
276 char *
getretaddr(hp)277 getretaddr(hp)
278 header *hp;
279 {
280 	register char *ra;
281 
282 	extern char *exaddress();
283 
284 	if (hp->h_replyto)
285 		ra = exaddress(hp->h_replyto);
286 	else if (hp->h_from)
287 		ra = exaddress(hp->h_from);
288 	else
289 		ra = NIL(char);
290 	if (hp->h_path && !ra)
291 		ra = hp->h_path;
292 	return ra;
293 }
294 
295 
296 /*
297  * try and make a proper address
298  */
299 char *
exaddress(addr)300 exaddress(addr)
301 char *addr;
302 {
303 	register char *space, *dot, *at;
304 	register char *raddr;
305 	extern char mailvia[];
306 
307 	raddr = NIL(char);
308 	if (strcmp(mailvia, "<path>") == 0)
309 		return raddr;
310 	if ((space = strchr(addr, ' ')))
311 		*space = '\0';
312 	if (mailvia[0] != '\0' && (at = strchr(addr, '@')) != NULL) {
313 		*at = '\0';
314 		raddr = newstr5(mailvia, PSEPS, at + 1, PSEPS, addr);
315 		*at = '@';
316 	} else
317 		raddr = newstr(addr);
318 	if (space)
319 		*space = ' ';
320 	return raddr;
321 }
322 
323 
324 /*
325  * remove extra spaces, and insert separators if necessary in
326  * newsgroups specification
327  */
328 void
convgrps(sp)329 convgrps(sp)
330 register char *sp;
331 {
332 	register char *sep = NULL;
333 
334 	while (*sp) {
335 		if (sep)
336 			sp++;
337 		while (*sp && (isspace(*sp) || *sp == NGSEPCHAR))
338 			strcpy(sp, sp + 1);
339 		if (sep)
340 			*sep = (*sp ? NGSEPCHAR : '\0');
341 		while (*sp && !isspace(*sp) && *sp != NGSEPCHAR)
342 			sp++;
343 		sep = sp;
344 	}
345 }
346