|
|
1.1 ! root 1: /* ! 2: * recnews [to newsgroup] [from user] [approved by] ! 3: * ! 4: * Process a news article which has been mailed to some group like msgs. ! 5: * Such articles are in normal mail format and have never seen the insides ! 6: * of netnews. If the "to newsgroup" is included, the article is posted ! 7: * to this newsgroup instead of trying to intuit it from the headers. ! 8: * If the "from user" is included, the return address is forged to look ! 9: * like that user instead of what getuid or a from line says. ! 10: * ! 11: * It is recommended that you always include the to newsgroup, since the ! 12: * intuition code is flakey and out of date. The from user is probably ! 13: * appropriate for arpanet mailing lists being funnelled at ucbvax but ! 14: * not otherwise. Sample lines in /usr/lib/aliases (if you run delivermail): ! 15: * worldnews: "|/usr/lib/news/recnews net.general" ! 16: * Allows you to mail to worldnews rather than using inews. ! 17: * Intended for humans to mail to. ! 18: * post-unix-wizards: "|/usr/lib/news/recnews fa.unix-wizards unix-wizards" ! 19: * Causes mail to post-unix-wizards to be fed into fa.unix-wizards ! 20: * and the return address forged as unix-wizards on the local ! 21: * machine. post-unix-wizards (on the local machine) should ! 22: * be part of the master mailing list somewhere (on a different ! 23: * machine.) ! 24: * in-gamemasters: "|/usr/lib/news/recnews mail.gamemasters '' news" ! 25: * ! 26: * Recnews is primarily useful in remote places on the usenet which collect ! 27: * mail from mailing lists and funnel them into the network. It is also ! 28: * useful if you like to send mail to some user instead of invoking ! 29: * inews -t .. -n .. when you want to submit an article. (Many mailers give ! 30: * you nice facilities like editing the message.) It is not, however, ! 31: * essential to use recnews to be able to join usenet. ! 32: * ! 33: * WARNING: recnews disables the "recording" check - it has to because ! 34: * by the time inews is run, it's in the background and too late to ! 35: * ask permission. If you depend heavily on recordings you probably ! 36: * should not allow recnews (and thus the mail interface) to be used. ! 37: * ! 38: * 1) We leave the from line alone. Just escape the double quotes, but let the ! 39: * mailer do the rest. ! 40: * 2) We give precedence to "From:" over "From " or ">From " in determining ! 41: * who the article is really from. ! 42: * Modifications by rad@tek ! 43: * ! 44: * [email protected]: add third argument to cause inews to be invoked with -a, ! 45: * for use with local groups for mailing lists with 2.11. ! 46: */ ! 47: ! 48: #ifdef SCCSID ! 49: static char *SccsId = "@(#)recnews.c 2.14 10/15/87"; ! 50: #endif /* SCCSID */ ! 51: ! 52: #include "params.h" ! 53: ! 54: /* ! 55: * Note: we assume there are 2 kinds of hosts using recnews: ! 56: * Those that have delivermail (and hence this program will never ! 57: * have to deal with more than one message at a time) and those on the arpanet ! 58: * that do not (and hence all messages end with a sentinel). It is ! 59: * supposed that regular v7 type systems without delivermail or some ! 60: * other automatic forwarding device will just use rnews. We do ! 61: * not attempt to tell where a message ends on all systems due to the ! 62: * different conventions in effect. (This COULD be fixed, I suppose.) ! 63: */ ! 64: ! 65: /* ! 66: * Kinds of lines in a message. ! 67: */ ! 68: #define FROM 001 /* From line */ ! 69: #define SUBJ 002 /* Subject */ ! 70: #define TO 003 /* To (newgroup based on this) */ ! 71: #define BLANK 004 /* blank line */ ! 72: #define EOM 005 /* End of message (4 ctrl A's) */ ! 73: #define HEADER 006 /* any unrecognized header */ ! 74: #define TEXT 007 /* anything unrecognized */ ! 75: #define INCLUSIVE 010 /* newsgroup is already in header */ ! 76: ! 77: /* ! 78: * Possible states program can be in. ! 79: */ ! 80: #define SKIPPING 0100 /* In header of message */ ! 81: #define READING 0200 /* In body of message */ ! 82: ! 83: #define BFSZ 250 ! 84: ! 85: #define EOT '\004' ! 86: ! 87: char from[BFSZ]; /* mailing address for replies */ ! 88: char sender[BFSZ]; /* mailing address of author, if different */ ! 89: char to[BFSZ]; /* Destination of mail (msgs, etc) */ ! 90: char subject[BFSZ]; /* subject of message */ ! 91: char newsgroup[BFSZ]; /* newsgroups of message */ ! 92: char approved[BFSZ]; /* Approved: */ ! 93: int fromset; /* from passed on command line */ ! 94: char cmdbuf[BFSZ]; /* command to popen */ ! 95: ! 96: extern char *strcat(), *strcpy(), *index(); ! 97: extern FILE *popen(); ! 98: char *any(); ! 99: ! 100: main(argc, argv) ! 101: int argc; ! 102: char **argv; ! 103: { ! 104: char buf[BFSZ], inews[BFSZ]; ! 105: register char *p, *q; ! 106: register FILE *pipe = NULL; ! 107: register int state; ! 108: ! 109: /* build inews command */ ! 110: #ifdef LOGDIR ! 111: sprintf(inews, "%s/%s/%s", logdir(HOME), LIBDIR, "inews"); ! 112: #else ! 113: sprintf(inews, "%s/%s", LIBDIR, "inews"); ! 114: #endif ! 115: ! 116: if (argc > 1) ! 117: strcpy(to, argv[1]); ! 118: if (argc > 2) ! 119: strcpy(from, argv[2]); ! 120: if (argc > 3 && *argv[3]) { ! 121: sprintf(approved,"-a %s", argv[3]); ! 122: } ! 123: ! 124: /* ! 125: * Flag that we know who message is from to avoid trying to ! 126: * decipher the From line. ! 127: */ ! 128: if (argc > 2 && (argv[2][0] != '\0')) ! 129: fromset++; ! 130: ! 131: #ifdef debug ! 132: printf("argv[0] is <%s>, argv[1] is <%s>, argv[2] is <%s>\n", ! 133: argv[0], argv[1], argv[2]); ! 134: #endif ! 135: state = SKIPPING; ! 136: while (fgets(buf, BFSZ, stdin) != NULL) { ! 137: if (state == READING) { ! 138: fputs(buf,pipe); ! 139: continue; ! 140: } ! 141: switch (type(buf)) { ! 142: ! 143: case FROM: ! 144: frombreak(buf, from); ! 145: break; ! 146: ! 147: case SUBJ: ! 148: p = any(buf, " \t"); ! 149: if (p == NULL) ! 150: p = buf + 8; ! 151: q = subject; ! 152: while (*++p) { ! 153: if (*p == '"') ! 154: *q++ = '\\'; ! 155: *q++ = *p; ! 156: } ! 157: q[-1] = '\0'; ! 158: break; ! 159: ! 160: case TO: ! 161: if (to[0]) ! 162: break; /* already have one */ ! 163: p = any(buf, " \t"); ! 164: if (p == NULL) ! 165: p = buf + 3; ! 166: q = to; ! 167: while (*++p) { ! 168: if (*p == '"') ! 169: *q++ = '\\'; ! 170: *q++ = *p; ! 171: } ! 172: q[-1] = '\0'; ! 173: break; ! 174: ! 175: case INCLUSIVE: ! 176: sprintf(cmdbuf,"exec %s -p", inews); ! 177: pipe = popen(cmdbuf,"w"); ! 178: if (pipe == NULL){ ! 179: perror("recnews: open failed"); ! 180: exit(1); ! 181: } ! 182: state = READING; ! 183: fputs(buf,pipe); ! 184: break; ! 185: ! 186: /* ! 187: * Kludge to compensate for messages without real headers ! 188: */ ! 189: case HEADER: ! 190: break; ! 191: ! 192: case BLANK: ! 193: state = READING; ! 194: strcpy(newsgroup, to); ! 195: sprintf(cmdbuf, ! 196: "exec %s -t \"%s\" -n \"%s\" -f \"%s\" %s", ! 197: inews, *subject ? subject : "(none)", ! 198: newsgroup, from, *approved ? approved : 0); ! 199: #ifdef debug ! 200: pipe = stdout; ! 201: printf("BLANK: %s\n", cmdbuf); ! 202: #else ! 203: pipe = popen(cmdbuf, "w"); ! 204: if (pipe == NULL) { ! 205: perror("recnews: popen failed"); ! 206: exit(1); ! 207: } ! 208: #endif ! 209: if (sender[0]) { ! 210: fputs(sender, pipe); ! 211: putc('\n', pipe); ! 212: } ! 213: break; ! 214: ! 215: case TEXT: ! 216: strcpy(newsgroup, to); ! 217: state = READING; ! 218: if (subject[0] == 0) { ! 219: strcpy(subject, buf); ! 220: if (subject[strlen(subject)-1] == '\n') ! 221: subject[strlen(subject)-1] = '\0'; ! 222: } ! 223: sprintf(cmdbuf, ! 224: "exec \"%s\" -t \"%s\" -n \"%s\" -f \"%s\" %s", ! 225: inews, subject, newsgroup, from, ! 226: *approved ? approved : 0); ! 227: #ifdef debug ! 228: pipe = stdout; ! 229: printf("TEXT: %s\n", cmdbuf); ! 230: #else ! 231: pipe = popen(cmdbuf, "w"); ! 232: if (pipe == NULL) { ! 233: perror("pipe failed"); ! 234: exit(1); ! 235: } ! 236: #endif ! 237: if (sender[0]){ ! 238: fputs(sender, pipe); ! 239: putc('\n',pipe); ! 240: } ! 241: break; ! 242: } ! 243: } ! 244: exit(0); ! 245: } ! 246: ! 247: type(p) ! 248: register char *p; ! 249: { ! 250: char *firstbl; ! 251: static char lasthdr = 1; /* prev line was a header */ ! 252: ! 253: if ((*p == ' ' || *p == '\t') && lasthdr) ! 254: return HEADER; /* continuation line */ ! 255: firstbl = any(p, " \t"); ! 256: while (*p == ' ' || *p == '?' || *p == '\t') ! 257: ++p; ! 258: ! 259: if (*p == '\n' || *p == 0) ! 260: return BLANK; ! 261: if (STRNCMP(p, ">From", 5) == 0 || STRNCMP(p, "From", 4) == 0) ! 262: return FROM; ! 263: if (STRNCMP(p, "Subj", 4)==0 || STRNCMP(p, "Re:", 3)==0 || ! 264: STRNCMP(p, "re:", 3)==0) ! 265: return SUBJ; ! 266: if (STRNCMP(p, "To", 2)==0) ! 267: return TO; ! 268: if (STRNCMP(p, "\1\1\1\1", 4)==0) ! 269: return EOM; ! 270: if (firstbl && firstbl[-1] == ':' && isalpha(*p)) ! 271: return HEADER; ! 272: lasthdr = 0; ! 273: return TEXT; ! 274: } ! 275: ! 276: /* ! 277: * Figure out who a message is from. ! 278: */ ! 279: frombreak(buf, fbuf) ! 280: register char *buf, *fbuf; ! 281: { ! 282: register char *p, *q; ! 283: if (fbuf[0] && fromset) { /* we already know who it's from */ ! 284: if (sender[0] == 0 || buf[4] == ':') { ! 285: #ifdef debug ! 286: printf("sender set to: %s", buf); ! 287: #endif ! 288: strcpy(sender, buf); ! 289: } ! 290: return; ! 291: } ! 292: /* ! 293: * Leave fancy Froms alone - this parsing is done by mail ! 294: * Just quote the double quotes to prevent interpetation ! 295: * by the shell. ! 296: * rad@tek ! 297: */ ! 298: p = any(buf, " \t"); ! 299: if (p==NULL) ! 300: p = buf + 4; ! 301: q = fbuf; ! 302: while (*++p) { ! 303: if (*p == '"') ! 304: *q++ = '\\'; ! 305: *q++ = *p; ! 306: } ! 307: q[-1] = '\0'; ! 308: if ((p=index(fbuf,'\n')) != NULL) ! 309: *p = '\0'; ! 310: if (buf[4] == ':') ! 311: fromset++; ! 312: } ! 313: ! 314: /* ! 315: * Return the ptr in sp at which a character in sq appears; ! 316: * NULL if not found ! 317: * ! 318: */ ! 319: char * ! 320: any(sp, sq) ! 321: char *sp, *sq; ! 322: { ! 323: register c1, c2; ! 324: register char *q; ! 325: ! 326: while (c1 = *sp++) { ! 327: q = sq; ! 328: while (c2 = *q++) ! 329: if (c1 == c2) ! 330: return(--sp); ! 331: } ! 332: return(NULL); ! 333: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.