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