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