|
|
1.1 root 1: /*
2: * readnews - read news articles.
3: */
4:
5: #ifdef SCCSID
6: static char *SccsId = "@(#)readnews.c 2.33 10/15/87";
7: #endif /* SCCSID */
8:
9: #include "rparams.h"
10:
11: /*
12: * readnews - article reading program
13: */
14:
15: #ifndef SYSBUF
16: char SYSBUF[BUFSIZ]; /* to buffer std out */
17: #endif
18:
19: #define OPTION 0 /* pick up an option string */
20: #define STRING 1 /* pick up a string of arguments */
21:
22: struct timeb Now;
23:
24: int onsig(), cleanup();
25:
26: /*
27: * Authors:
28: * Matt Glickman ucbvax!glickman
29: * Mark Horton cbosg!mark
30: * Stephen Daniels duke!swd
31: * Tom Truscott duke!trt
32: */
33:
34: main(argc, argv)
35: int argc;
36: register char **argv;
37: {
38: register char *ptr; /* pointer to rest of buffer */
39: char *user = NULL, *home = NULL;
40: int optflag = FALSE, space = FALSE;
41: struct utsname ubuf;
42: char *myrc;
43:
44: /* set up defaults and initialize. */
45: pathinit();
46: mode = UNKNOWN;
47: header.title[0] = header.nbuf[0] = '\0';
48: coptbuf[0] = datebuf[0] = '\0';
49: uname(&ubuf);
50: strcpy(FROMSYSNAME, ubuf.nodename);
51:
52: savmask = umask(N_UMASK); /* set up mask */
53: uid = getuid();
54: gid = getgid();
55: duid = geteuid();
56: dgid = getegid();
57: (void) ftime(&Now);
58: /* give reasonable error message if SPOOL directory
59: * is unaccessable... usually means system administrator
60: * has "turned off" news reading...
61: */
62: #ifdef SERVER
63: if (open_server() < 0)
64: #else /* !SERVER */
65: if (access(SPOOL, 05))
66: #endif /* !SERVER */
67: {
68: fputs("News articles are not available at this time\n",stderr);
69: xxit(1);
70: }
71: #ifndef SHELL
72: if ((SHELL = getenv("SHELL")) == NULL)
73: SHELL = "/bin/sh";
74: #endif
75: /*
76: * IHCC forces the use of 'getuser()' to prevent forgery of articles
77: * by just changing $LOGNAME
78: * Note that this shouldn't matter in readnews, since inews
79: * does all the actual posting of news.
80: */
81: #ifndef IHCC
82: if ((user = getenv("USER")) == NULL)
83: user = getenv("LOGNAME");
84: if ((home = getenv("HOME")) == NULL)
85: home = getenv("LOGDIR");
86: #endif /* ! IHCC */
87: if (user == NULL || home == NULL)
88: getuser();
89: else {
90: username = AllocCpy(user);
91: (void) strcpy(header.path, username);
92: userhome = AllocCpy(home);
93: }
94:
95: if (!(MAILER = getenv("MAILER")))
96: MAILER = "mail"; /* was /bin/mail */
97:
98: #ifdef PAGE
99: if (myrc = getenv("PAGER"))
100: PAGER = AllocCpy(myrc);
101: else {
102: # ifdef IHCC
103: (void) sprintf(bfr, "%s/bin/%s", logdir(HOME), PAGE);
104: PAGER = AllocCpy(bfr);
105: # else /* !IHCC */
106: PAGER = PAGE;
107: # endif /* !IHCC */
108: }
109: #endif /* PAGE */
110:
111: if (ptr = getenv("NEWSOPTS"))
112: (void) strcpy(rcbuf, ptr);
113: else
114: *rcbuf = '\0';
115: if (*rcbuf) {
116: (void) strcat(rcbuf, " \1");
117: ptr = rcbuf;
118: while (*++ptr)
119: if (isspace(*ptr))
120: *ptr = '\0';
121: for (ptr = rcbuf; ; ptr++) {
122: if (!*ptr)
123: continue;
124: if (*ptr == '\1')
125: break;
126: if (++line > LINES)
127: xerror("Too many options.");
128: if ((rcline[line] = malloc((unsigned)(strlen(ptr) + 1))) == NULL)
129: xerror("Not enough memory.");
130: argvrc[line] = rcline[line];
131: (void) strcpy(rcline[line], ptr);
132: while (*ptr)
133: ptr++;
134: }
135: }
136: myrc = getenv("NEWSRC");
137: if (myrc == NULL) {
138: myrc = NEWSRC;
139: (void) sprintf(newsrc, "%s/%s", userhome, myrc);
140: } else {
141: (void) strcpy(newsrc, myrc);
142: }
143: if (access(newsrc, 0))
144: newrc(newsrc);
145: if ((rcfp = fopen(newsrc, "r")) != NULL) {
146: rcreadok = FALSE;
147: while (fgets(rcbuf, LBUFLEN, rcfp) != NULL) {
148: if (!(space = isspace(*rcbuf)))
149: optflag = FALSE;
150: if (!STRNCMP(rcbuf, "options ", 8))
151: optflag = TRUE;
152: if (optflag) {
153: (void) strcat(rcbuf, "\1");
154: if (space)
155: ptr = rcbuf - 1;
156: else
157: ptr = &rcbuf[7];
158: while (*++ptr)
159: if (isspace(*ptr))
160: *ptr = '\0';
161: if (space)
162: ptr = rcbuf;
163: else
164: ptr = &rcbuf[8];
165: for (; ; ptr++) {
166: if (!*ptr)
167: continue;
168: if (*ptr == '\1')
169: break;
170: if (++line > LINES)
171: xerror("Too many options.");
172: if ((rcline[line] = malloc((unsigned)(strlen(ptr) + 1))) == NULL)
173: xerror("Not enough memory.");
174: argvrc[line] = rcline[line];
175: (void) strcpy(rcline[line], ptr);
176: while (*ptr)
177: ptr++;
178: }
179: }
180: }
181: (void) fclose(rcfp);
182: rcreadok = TRUE;
183: }
184: if (line != -1) {
185: #ifdef DEBUG
186: register int i;
187: for (i = 0; i <= line; i++)
188: fprintf(stderr, "options: %s\n", rcline[i]);
189: #endif
190: process(line + 2, argvrc);
191: do {
192: #ifdef DEBUG
193: fprintf(stderr, "Freeing %d\n", line);
194: #endif
195: free(rcline[line]);
196: } while (line--);
197: }
198:
199: argv++;
200: (void) strcat(header.nbuf, ADMSUB);
201: process(argc, argv);
202: if (!nflag)
203: (void) sprintf(header.nbuf, "%s,%s", ADMSUB, DFLTSUB);
204: else {
205: char *p = rindex(header.nbuf, ',');
206: if (p && p[1] == '\0') /* strip of trailing NGDELIM */
207: *p ='\0';
208: }
209: lcase(header.nbuf);
210: makehimask(header.nbuf, "junk");
211: makehimask(header.nbuf, "control");
212: makehimask(header.nbuf, "test");
213:
214: setbuf(stdout, SYSBUF);
215: SigTrap = FALSE; /* true if a signal has been caught */
216: if (!pflag && !lflag && !eflag) {
217: (void) signal(SIGQUIT, SIG_IGN);
218: (void) signal(SIGHUP, cleanup);
219: (void) signal(SIGINT, onsig);
220: (void) signal(SIGPIPE, onsig);
221: } else {
222: if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
223: (void) signal(SIGQUIT, cleanup);
224: if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
225: (void) signal(SIGHUP, cleanup);
226: if (signal(SIGINT, SIG_IGN) != SIG_IGN)
227: (void) signal(SIGINT, cleanup);
228: }
229:
230: /*
231: * ALL of the command line has now been processed. (!)
232: */
233:
234: if (!*header.nbuf)
235: strcpy(header.nbuf, DFLTSUB);
236: if (sflag) {
237: printf("Subscription list: %s\n", header.nbuf);
238: xxit(0);
239: }
240: if (xflag)
241: line = -1;
242: rcfp = xfopen(newsrc, "r");
243: while (fgets(rcbuf, LBUFLEN, rcfp) != NULL) {
244: if (!nstrip(rcbuf))
245: xerror(".newsrc line too long");
246: if (++line >= LINES)
247: xerror("Too many .newsrc lines");
248: if ((rcline[line] = malloc((unsigned)(strlen(rcbuf) + 1))) == NULL)
249: xerror("Not enough memory");
250: (void) strcpy(rcline[line], rcbuf);
251: }
252: fclose(rcfp);
253:
254: if (SigTrap) {
255: if (SigTrap == SIGHUP || !rcreadok)
256: xxit(0);
257: fprintf(stdout, "Abort (n)? ");
258: (void) fflush(stdout);
259: if (gets(bfr) == NULL || *bfr == 'y' || *bfr == 'Y')
260: xxit(0);
261: SigTrap = FALSE;
262: }
263: #ifdef SERVER
264: if ((actfp = open_active()) == NULL)
265: xerror("Cannot open active newsgroups file");
266: strcpy(ACTIVE, active_name());
267: (void) fclose(actfp);
268: actfp = NULL;
269: #endif /* !SERVER */
270: sortactive();
271: actfp = xfopen(ACTIVE, "r");
272: #ifdef DEBUG
273: fprintf(stderr, "header.nbuf = %s\n", header.nbuf);
274: #endif /* DEBUG */
275: if (Kflag)
276: news++;
277: else {
278: switch (mode) {
279: case UNKNOWN:
280: readr();
281: break;
282: #ifdef TMAIL
283: case MAIL:
284: Mail();
285: break;
286: #endif /* TMAIL */
287: }
288: }
289:
290: cleanup(0);
291: /*NOTREACHED*/
292: }
293:
294: cleanup(signo)
295: {
296: extern short ospeed;
297:
298: (void) signal(SIGHUP, SIG_IGN);
299: (void) fflush(stdout);
300: if (news && !xflag && !lflag && !tflag) {
301: if (*groupdir && mode != MAIL)
302: updaterc();
303: writeoutrc();
304: }
305: /*
306: * stop vnews from clearing the screen if we're
307: * killed by a hangup
308: */
309: if (signo == SIGHUP)
310: ospeed = 0;
311: xxit(0);
312: }
313:
314: /*
315: * Write out the .newsrc file. It's already been cleaned up by sortactive()
316: * Take care that data is all written, and flushed, before we destroy the
317: * old copy.
318: */
319: writeoutrc()
320: {
321: FILE *wrcfp;
322: char aline[BUFLEN];
323: register int i;
324:
325: /* NEVER write it out if xflag */
326: if (xflag || !rcreadok)
327: return;
328:
329: (void) strcpy(aline, newsrc);
330: (void) strcat(aline, ".new");
331:
332: #ifdef VMS
333: (void) vmsdelete(aline);
334: #endif
335: wrcfp = xfopen(aline, "w");
336:
337: for (i = 0; i <= line; i++) {
338: if (rcline[i] != NULL)
339: if (fprintf(wrcfp, "%s\n", rcline[i]) < 0)
340: goto fouled;
341: }
342: if (fclose(wrcfp) < 0)
343: goto fouled;
344:
345: #ifdef VMS
346: (void) vmsdelete(newsrc);
347: #endif
348: if (rename(aline, newsrc) < 0)
349: xerror("Cannot rename %s to %s", aline, newsrc);
350: return;
351:
352: fouled:
353: xerror("Error writing new .newsrc file - no changes made\n");
354: return;
355: }
356:
357: /*
358: * Forbid newsgroup ng, unless he asked for it in nbuf.
359: */
360: makehimask(nbuf, ng)
361: char *nbuf, *ng;
362: {
363: if (!findex(nbuf, ng))
364: (void) sprintf(rindex(nbuf, '\0'), ",!%s", ng);
365: }
366:
367: /*
368: * Return true if the string searchfor is in string, but not if preceded by !.
369: */
370: findex(string, searchfor)
371: char *string, *searchfor;
372: {
373: register char first;
374: register char *p;
375:
376: first = *searchfor;
377: for (p=index(string, first); p; p = index(p+1, first)) {
378: if (((p==string) || (p[-1]!='!')) && STRNCMP(p, searchfor, strlen(searchfor)) == 0)
379: return TRUE;
380: }
381: return FALSE;
382: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.