|
|
1.1 ! root 1: /* ! 2: * rfuncs2 - more routines needed by readr. ! 3: */ ! 4: static char *sccsid = "@(#)rfuncs2.c 1.9 4/25/83"; ! 5: ! 6: #include "rparams.h" ! 7: ! 8: static char lbuf[BUFLEN*2]; ! 9: ! 10: FILE *popen(); ! 11: ! 12: /* ! 13: * nglist is the list of newsgroups in an article we want to follow up. ! 14: * Do any special fascist processing to prevent certain kinds of followups. ! 15: * In this case, there are two things we want to do: ! 16: * All followups to "net.general" are fed to "net.followup". ! 17: * However, if "net.general" is mentioned along with "net.news.group", ! 18: * just remove the net.general. ! 19: */ ! 20: launder(nglist) ! 21: char *nglist; ! 22: { ! 23: char *cp, *op; ! 24: char outbuf[128]; ! 25: int seen_group = 0; ! 26: ! 27: for (cp = index(nglist, 'n'); cp; cp = index(cp + 1, 'n')) ! 28: if (strncmp("news.group", cp, 10) == 0) ! 29: seen_group++; ! 30: for (cp = index(nglist, 'n'); cp; cp = index(cp + 1, 'n')) ! 31: if (strncmp("net.general", cp, 11) == 0) { ! 32: /* 11 = strlen("net.general") */ ! 33: strcpy(outbuf, cp + 11); ! 34: if (!seen_group) { ! 35: strcpy(cp, "net.followup"); ! 36: cp += 12; /* 12 = strlen("net.followup") */ ! 37: } ! 38: if (cp[-1] == ',' && outbuf[0] == ',') ! 39: cp--; ! 40: strcpy(cp, outbuf); ! 41: } ! 42: } ! 43: ! 44: ! 45: /* ! 46: * Match title. ! 47: */ ! 48: titmat(h, titlist) ! 49: register struct hbuf *h; ! 50: register char *titlist; ! 51: { ! 52: register char *p; ! 53: register int titlen; ! 54: ! 55: while (*titlist != '\0') { ! 56: titlen = strlen(titlist); ! 57: for (p = h->title; *p != '\0'; p++) ! 58: if (strncmp(p, titlist, titlen) == 0) { ! 59: return(TRUE); ! 60: } ! 61: titlist += titlen + 1; ! 62: } ! 63: return(FALSE); ! 64: } ! 65: ! 66: ! 67: /* ! 68: * Save the news item in the user's file. ! 69: * Fri Mar 12 20:04:43 EST 1982: (ittvax!swatt) ! 70: * Allow files with first character as '|' to write article ! 71: * to program across a pipe. ! 72: */ ! 73: ! 74: #define PIPECHAR '|' ! 75: ! 76: save(file, to) ! 77: register char *file, *to; ! 78: { ! 79: register FILE *ufp, *hfp; ! 80: struct hbuf hh; ! 81: int isprogram = 0; ! 82: int isnew = 1; ! 83: ! 84: if ((hfp = fopen(file, "r")) == NULL) { ! 85: printf("Can't get article.\n"); ! 86: return; ! 87: } ! 88: if (hread(&hh, hfp, TRUE) == NULL) { ! 89: printf("Article is garbled.\n"); ! 90: return; ! 91: } ! 92: ufp = fopen(to, "r"); ! 93: if (ufp != NULL) { ! 94: fclose(ufp); ! 95: isnew = 0; ! 96: } ! 97: setgid(gid); ! 98: setuid(uid); ! 99: umask(savmask); ! 100: ! 101: if (*to == PIPECHAR) { ! 102: if ((ufp = popen (&to[1], "w")) == NULL) { ! 103: printf ("Cannot execute %s\n", &to[1]); ! 104: return; ! 105: } ! 106: isprogram++; ! 107: } else if ((ufp = fopen(to, "a")) == NULL) { ! 108: printf("Cannot append to %s.\n", to); ! 109: return; ! 110: } ! 111: /* ! 112: * V7MAIL code is here to conform to V7 mail format. ! 113: * If you need a different format to be able to ! 114: * use your local mail command (such as four ^A's ! 115: * on the end of articles) substitute it here. ! 116: */ ! 117: #ifdef V7MAIL ! 118: fprintf(ufp, "From %s %s", ! 119: #ifdef INTERNET ! 120: hh.from, ! 121: #else ! 122: hh.path, ! 123: #endif ! 124: ctime(&hh.subtime)); ! 125: #endif ! 126: hprint(&hh, ufp, 2); ! 127: #ifdef V7MAIL ! 128: tprint(hfp, ufp, TRUE); ! 129: putc('\n', ufp); /* force blank line at end (ugh) */ ! 130: #else ! 131: tprint(hfp, ufp, FALSE); ! 132: #endif ! 133: fclose(hfp); ! 134: if (isprogram) ! 135: pclose (ufp); ! 136: else ! 137: fclose(ufp); ! 138: if (!isprogram) ! 139: printf("%s: %s\n", to, isnew ? "New file" : "Appended"); ! 140: } ! 141: ! 142: ! 143: /* ! 144: * Print out the rest of the article. ! 145: */ ! 146: tprint(ifp, ofp, checkfrom) ! 147: register FILE *ifp, *ofp; ! 148: int checkfrom; ! 149: { ! 150: register int c; ! 151: ! 152: while ((fgets(bfr, sizeof bfr, ifp)) != NULL && !sigtrap) { ! 153: if (checkfrom && strncmp(bfr, "From ", 5) == 0) ! 154: putc('>', ofp); ! 155: fputs(bfr, ofp); ! 156: } ! 157: if (sigtrap) ! 158: qfflush(ofp); ! 159: fflush(ofp); ! 160: fprintf(ofp, (sigtrap ? "\n\n" : "\n")); ! 161: sigtrap = FALSE; ! 162: } ! 163: ! 164: ! 165: /* ! 166: * Print the file header. ! 167: */ ! 168: hprint(hp, ofp, verbose) ! 169: register struct hbuf *hp; ! 170: int verbose; ! 171: register FILE *ofp; ! 172: { ! 173: register char *p1, *p2; ! 174: char fname[BUFLEN]; ! 175: char *tailpath(); ! 176: ! 177: fname[0] = '\0'; /* init name holder */ ! 178: ! 179: if (verbose == 2) { ! 180: lhwrite(hp, ofp); ! 181: return; ! 182: } ! 183: ! 184: if (lflag || eflag) { ! 185: char buf1[80], buf2[200]; ! 186: char *cp; ! 187: ! 188: strcpy(bfr, groupdir); ! 189: for (cp=bfr; *cp; cp++) ! 190: if (*cp == '/') ! 191: *cp = '.'; ! 192: sprintf(buf1, "%s/%d", bfr, bit); ! 193: sprintf(buf2, "%-20s %s", buf1, hp->title); ! 194: fprintf(ofp, "%.76s\n", buf2); ! 195: return; ! 196: } ! 197: ! 198: p1 = index(hp->from, '('); /* Find the sender's full name. */ ! 199: if (p1 == NULL && hp->path[0]) ! 200: p1 = index(hp->path, '('); ! 201: if (p1 != NULL) { ! 202: strcpy(fname, p1+1); ! 203: p2 = index(fname, ')'); ! 204: if (p2 != NULL) ! 205: *p2 = '\0'; ! 206: } ! 207: ! 208: fprintf(ofp, "Subject: %s\n", hp->title); ! 209: if (!hflag && hp->keywords[0]) ! 210: fprintf(ofp, "Keywords: %s\n", hp->keywords); ! 211: if (verbose) { ! 212: fprintf(ofp, "From: %s\n", hp->from); ! 213: fprintf(ofp, "Path: %s\n", hp->path); ! 214: if (hp->organization[0]) ! 215: fprintf(ofp, "Organization: %s\n", hp->organization); ! 216: } ! 217: else { ! 218: if (p1 != NULL) ! 219: *--p1 = '\0'; /* bump over the '(' */ ! 220: #ifdef INTERNET ! 221: /* ! 222: * Prefer Path line if it's in internet format, or if we don't ! 223: * understand internet format here, or if there is no reply-to. ! 224: */ ! 225: fprintf(ofp, "From: %s", hp->from); ! 226: #else ! 227: fprintf(ofp, "Path: %s", tailpath(hp)); ! 228: #endif ! 229: if (fname[0] != '\0') { ! 230: fprintf(ofp, " (%s", fname); ! 231: if (hp->organization[0] && !hflag) ! 232: fprintf(ofp, " @ %s", hp->organization); ! 233: fprintf(ofp, ")"); ! 234: } ! 235: fprintf(ofp, "\n"); ! 236: if (p1 != NULL) ! 237: *p1 = ' '; ! 238: } ! 239: ! 240: ngdel(strcpy(bfr, hp->nbuf)); ! 241: if (verbose) { ! 242: fprintf(ofp, "Newsgroups: %s\n", bfr); ! 243: fprintf(ofp, "Date: %s\n", hp->subdate); ! 244: if (hp->sender[0]) ! 245: fprintf(ofp, "Sender: %s\n", hp->sender); ! 246: if (hp->replyto[0]) ! 247: fprintf(ofp, "Reply-To: %s\n", hp->replyto); ! 248: if (hp->followto[0]) ! 249: fprintf(ofp, "Followup-To: %s\n", hp->followto); ! 250: } ! 251: else if (index(bfr, ',') || strcmp(groupdir, "junk") == 0) ! 252: fprintf(ofp, "Newsgroups: %s\n", bfr); ! 253: ! 254: if (pflag || ofp != stdout) ! 255: putc('\n', ofp); ! 256: } ! 257: ! 258: ! 259: /* ! 260: * If ofp != stdout, close it and run the script in coptbuf. ! 261: */ ! 262: cout(ofp) ! 263: FILE *ofp; ! 264: { ! 265: register char *p, *q, *r; ! 266: ! 267: if (ofp == stdout) ! 268: return; ! 269: fclose(ofp); ! 270: p = coptbuf; ! 271: q = lbuf; ! 272: while ((*q = *p++) != '\0') ! 273: if (*q++ == FMETA) { ! 274: q--; ! 275: r = outfile; ! 276: while ((*q++ = *r++) != '\0') ! 277: ; ! 278: q--; ! 279: } ! 280: fwait(fsubr(ushell, lbuf, (char *)NULL)); ! 281: unlink(outfile); ! 282: } ! 283: ! 284: ! 285: cdump(ofp) ! 286: register FILE *ofp; ! 287: { ! 288: if (ofp == stdout) ! 289: return; ! 290: fclose(ofp); ! 291: unlink(outfile); ! 292: } ! 293: ! 294: ! 295: /* ! 296: * Quiet 'flush'. ! 297: * Empty (without fflush()) the buffer for stream fp. ! 298: */ ! 299: /* ARGSUSED */ ! 300: qfflush(fp) ! 301: FILE *fp; ! 302: { ! 303: /* Alas, stdio does not permit this */ ! 304: } ! 305: ! 306: ! 307: /* ! 308: * Count the number of remaining lines in file fp. ! 309: * Do not move the file pointer. ! 310: */ ! 311: linecnt(fp) ! 312: FILE *fp; ! 313: { ! 314: long curpos; ! 315: register int nlines = 0; ! 316: register int c; ! 317: ! 318: if (fp == NULL) ! 319: return 0; ! 320: curpos = ftell(fp); ! 321: while ((c = getc(fp)) != EOF) ! 322: if (c == '\n') ! 323: nlines++; ! 324: fseek(fp, curpos, 0); ! 325: return nlines; ! 326: } ! 327: ! 328: ! 329: /* ! 330: * Transmit file to system. ! 331: */ ! 332: transmit(sp, file) ! 333: register struct srec *sp; ! 334: char *file; ! 335: { ! 336: register FILE *ifp, *ofp; ! 337: register int c; ! 338: struct hbuf hh; ! 339: char TRANS[BUFLEN]; ! 340: ! 341: #ifdef DEBUG ! 342: fprintf(stderr, "xmit %s to %s using %s\n", file, sp->s_name, sp->s_xmit); ! 343: #endif ! 344: ifp = xfopen(file, "r"); ! 345: if (hread(&hh, ifp, TRUE) == NULL) ! 346: return; ! 347: strcpy(TRANS, "/tmp/trXXXXXX"); ! 348: ofp = xfopen(mktemp(TRANS), "w"); ! 349: if (index(sp->s_flags, 'A') == NULL) ! 350: hwrite(&hh, ofp); ! 351: else ! 352: ohwrite(&hh, ofp); ! 353: while ((c = getc(ifp)) != EOF) ! 354: putc(c, ofp); ! 355: fclose(ifp); ! 356: fclose(ofp); ! 357: if (*sp->s_xmit == '\0' || index(sp->s_flags, 'F') || index(sp->s_flags, 'U')) ! 358: sprintf(bfr, DFTXMIT, sp->s_name, TRANS); ! 359: else ! 360: sprintf(bfr, "(%s) < %s", sp->s_xmit, TRANS); ! 361: #ifdef DEBUG ! 362: fprintf(stderr, "%s\n", bfr); ! 363: #endif ! 364: fwait(fsubr(pshell, bfr, (char *)NULL)); ! 365: unlink(TRANS); ! 366: } ! 367: ! 368: ! 369: /* ! 370: * Cancel the article whose header is in hp, by posting a control message ! 371: * to cancel it. The scope of the control message depends on who would ! 372: * really be willing to cancel it. It is sent as far as it will do any good. ! 373: * notauthor is true iff the person posting this article is not the ! 374: * real author of the article being cancelled. ! 375: */ ! 376: cancel(ofp, hp, notauthor) ! 377: FILE *ofp; ! 378: struct hbuf *hp; ! 379: int notauthor; ! 380: { ! 381: FILE *inews; ! 382: struct utsname me; ! 383: char *p; ! 384: char distgroup[64]; ! 385: int pid; ! 386: ! 387: fflush(stdout); ! 388: pid = fork(); ! 389: if (pid > 0) ! 390: return 0; ! 391: uname(&me); ! 392: strcpy(distgroup, hp->nbuf); ! 393: p = index(distgroup, '.'); ! 394: if (notauthor) ! 395: sprintf(distgroup, "to.%s", me.nodename); ! 396: else ! 397: sprintf(distgroup, "%s", hp->nbuf); ! 398: sprintf(bfr, "%s -t 'cmsg cancel %s' -n %s < /dev/null", ! 399: INEWS, hp->ident, distgroup); ! 400: if ((inews = popen(bfr, "w")) == NULL) ! 401: fprintf(ofp, "Can't fork %s\n", INEWS); ! 402: else ! 403: pclose(inews); ! 404: if (pid == 0) ! 405: exit(0); ! 406: return 0; ! 407: } ! 408: ! 409: ! 410: dash(num, ofp) ! 411: register int num; ! 412: register FILE *ofp; ! 413: { ! 414: register int i; ! 415: ! 416: for (i = 0; i < num; i++) ! 417: putc('-', ofp); ! 418: putc('\n', ofp); ! 419: } ! 420: ! 421: ! 422: help(ofp) ! 423: register FILE *ofp; ! 424: { ! 425: register FILE *fp; ! 426: register int c; ! 427: ! 428: if (cflag) { ! 429: oneline: ! 430: fprintf(ofp, "(n)ext re(p)rint (w)rite (q)uit (r)eply\ ! 431: (c)ancel -[n] +[n] (f)ollowup (N)ext (U)nsubscribe (v)ersion\n"); ! 432: return; ! 433: } ! 434: if ((fp = fopen(HELPFILE, "r")) == NULL) { ! 435: fprintf(ofp, "No help file.\n"); ! 436: goto oneline; ! 437: } ! 438: while ((c = getc(fp)) != EOF && !sigtrap) ! 439: putc(c, ofp); ! 440: fclose(fp); ! 441: } ! 442: ! 443: ! 444: pout(ofp) ! 445: FILE *ofp; ! 446: { ! 447: register char *p, *q, *r; ! 448: ! 449: p = PAGER; ! 450: q = lbuf; ! 451: while ((*q = *p++) != '\0') ! 452: if (*q++ == FMETA) { ! 453: q--; ! 454: r = filename; ! 455: while ((*q++ = *r++) != '\0') ! 456: ; ! 457: q--; ! 458: } ! 459: fwait(fsubr(ushell, lbuf, (char *)NULL)); ! 460: fprintf(ofp, "\n"); ! 461: } ! 462: ! 463: ! 464: /* ! 465: * like strcat but be careful with quotes. since there appears to be no way ! 466: * to quote an apostrophe in sh, we change them to double quotes. ! 467: */ ! 468: strqcat(dest, src) ! 469: register char *dest, *src; ! 470: { ! 471: while (*dest++) ! 472: ; ! 473: dest--; ! 474: while (*src) { ! 475: if (*src == '\'') ! 476: *dest++ = '"', src++; ! 477: else ! 478: *dest++ = *src++; ! 479: } ! 480: *dest++ = 0; ! 481: } ! 482: ! 483: /* ! 484: * Print a very brief version of the date in question. ! 485: */ ! 486: char * ! 487: briefdate(datestr) ! 488: char *datestr; ! 489: { ! 490: long dt, now; ! 491: char *tmstr; ! 492: char *wkday, *monthdate, *timeofday; ! 493: static char rbuf[20]; ! 494: ! 495: dt = cgtdate(datestr); ! 496: tmstr = ctime(&dt); ! 497: ! 498: wkday = tmstr; tmstr[3] = '\0'; ! 499: monthdate = tmstr+4; tmstr[10] = '\0'; ! 500: timeofday = tmstr+11; tmstr[16] = '\0'; ! 501: ! 502: time(&now); ! 503: if (now - dt < 7 * DAYS) ! 504: strcpy(rbuf, wkday); ! 505: else ! 506: strcpy(rbuf, monthdate); ! 507: strcat(rbuf, " "); ! 508: strcat(rbuf, timeofday); ! 509: return rbuf; ! 510: } ! 511: ! 512: /* ! 513: * Return TRUE iff stdout is /dev/null. ! 514: */ ! 515: ignoring() ! 516: { ! 517: struct stat ss, ns; ! 518: ! 519: fstat(1, &ss); ! 520: stat("/dev/null", &ns); ! 521: if (ss.st_dev == ns.st_dev && ss.st_rdev == ns.st_rdev) ! 522: return TRUE; ! 523: return FALSE; ! 524: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.