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