|
|
1.1 ! root 1: /* ! 2: * This software is Copyright (c) 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: * header.c - header functions plus some other goodies ! 16: */ ! 17: /*LINTLIBRARY*/ ! 18: ! 19: #ifdef SCCSID ! 20: static char *SccsId = "@(#)header.c 2.49 10/7/87"; ! 21: #endif /* SCCSID */ ! 22: ! 23: #include <stdio.h> ! 24: #include "params.h" ! 25: #include "patchlevel.h" ! 26: ! 27: char *hfgets(); ! 28: ! 29: char *news_version = NEWS_VERSION; ! 30: ! 31: /* ! 32: * Read header from file fp into *hp. If wholething is FALSE, ! 33: * it's an incremental read, otherwise start from scratch. ! 34: * Return (FILE *) if header okay, else NULL. ! 35: */ ! 36: FILE * ! 37: hread(hp, fp, wholething) ! 38: register struct hbuf *hp; ! 39: FILE *fp; ! 40: int wholething; ! 41: { ! 42: #ifndef GENERICPATH ! 43: register int len; ! 44: #endif /* GENERICPATH */ ! 45: register int i; ! 46: #ifdef OLD ! 47: char *p; ! 48: #endif /* OLD */ ! 49: ! 50: if (wholething) { ! 51: for(i=0;i<NUNREC;i++) ! 52: if (hp->unrec[i] != NULL) ! 53: free(hp->unrec[i]); ! 54: else ! 55: break; ! 56: bzero((char *)hp, sizeof (*hp)); ! 57: for (i=0;i<NUNREC;i++) ! 58: hp->unrec[i] = NULL; ! 59: } ! 60: ! 61: /* Check that it's a B news style header. */ ! 62: if (hfgets(bfr, PATHLEN, fp) != NULL && isalpha(bfr[0]) ! 63: && index(bfr, ':')) ! 64: if (frmread(fp, hp)) ! 65: goto strip; ! 66: ! 67: if (!nstrip(bfr+1)) ! 68: return NULL; ! 69: ! 70: /* It's not. Try A news (begins with PROTO). */ ! 71: if (bfr[0] != PROTO) ! 72: return NULL; ! 73: #ifndef OLD ! 74: logerr("Can not process A news format article without OLD defined"); ! 75: #else /* OLD */ ! 76: /* Read in an A news format article. */ ! 77: p = index(bfr+1, '.'); ! 78: if (p == NULL) { ! 79: (void) strcpy(hp->ident, bfr+1); ! 80: return NULL; ! 81: } ! 82: *p++ = '\0'; ! 83: (void) sprintf(hp->ident, "<%s@%s%s>", p, bfr+1, ".UUCP"); ! 84: ! 85: /* Newsgroup List */ ! 86: if (hfgets(hp->nbuf, BUFLEN, fp) == NULL || !nstrip(hp->nbuf)) ! 87: return NULL; ! 88: /* source path */ ! 89: if (hfgets(hp->path, PATHLEN, fp) == NULL || !nstrip(hp->path)) ! 90: return NULL; ! 91: /* date */ ! 92: if (hfgets(hp->subdate, DATELEN, fp) == NULL || !nstrip(hp->subdate)) ! 93: return NULL; ! 94: /* title */ ! 95: if (hfgets(hp->title, BUFLEN, fp) == NULL || !nstrip(hp->title)) ! 96: return NULL; ! 97: #endif /* OLD */ ! 98: ! 99: strip: /* strip off sys! from front of path. */ ! 100: #ifndef GENERICPATH ! 101: if (strncmp(PATHSYSNAME, hp->path, (len = strlen(PATHSYSNAME))) == 0 ! 102: && index(NETCHRS, hp->path[len])) ! 103: (void) strcpy(hp->path, &(hp->path[len+1])); ! 104: #endif /* GENERICPATH */ ! 105: lcase(hp->nbuf); ! 106: ! 107: /* Intuit the From: line if only a path was given. */ ! 108: if (wholething) { ! 109: #ifdef OLD ! 110: if (hp->from[0] == '\0') ! 111: intuitfrom(hp); ! 112: else ! 113: #endif /* OLD */ ! 114: fixfrom(hp); ! 115: } ! 116: ! 117: return fp; ! 118: } ! 119: ! 120: ! 121: /* ! 122: * Get header info from mail-format file. ! 123: * Return non-zero on success. ! 124: */ ! 125: #define FROM 1 ! 126: #define NEWSGROUP 2 ! 127: #define TITLE 3 ! 128: #define SUBMIT 4 ! 129: #define RECEIVE 5 ! 130: #define EXPIRE 6 ! 131: #define ARTICLEID 7 ! 132: #define MESSAGEID 8 ! 133: #define REPLYTO 9 ! 134: #define FOLLOWID 10 ! 135: #define CONTROL 11 ! 136: #define SENDER 12 ! 137: #define FOLLOWTO 13 ! 138: #define PATH 14 ! 139: #define POSTVERSION 15 ! 140: #define RELAYVERSION 16 ! 141: #define DISTRIBUTION 17 ! 142: #define ORGANIZATION 18 ! 143: #define NUMLINES 19 ! 144: #define KEYWORDS 20 ! 145: #define APPROVED 21 ! 146: #define NFID 22 ! 147: #define NFFROM 23 ! 148: #define XREF 24 ! 149: #define SUMMARY 25 ! 150: #define XPATH 26 ! 151: #define SUPERSEDES 27 ! 152: #define OTHER 99 ! 153: ! 154: char *malloc(); ! 155: ! 156: frmread(fp, hp) ! 157: register FILE *fp; ! 158: register struct hbuf *hp; ! 159: { ! 160: int unreccnt = 0; ! 161: register int i; ! 162: ! 163: i = type(bfr); ! 164: do { ! 165: switch (i) { ! 166: case PATH: ! 167: getfield(hp->path, sizeof(hp->path)); ! 168: break; ! 169: case FROM: ! 170: getfield(hp->from, sizeof(hp->from)); ! 171: break; ! 172: case NEWSGROUP: ! 173: getfield(hp->nbuf, sizeof(hp->nbuf)); ! 174: break; ! 175: case TITLE: ! 176: getfield(hp->title, sizeof(hp->title)); ! 177: break; ! 178: case SUBMIT: ! 179: getfield(hp->subdate, sizeof(hp->subdate)); ! 180: break; ! 181: case EXPIRE: ! 182: getfield(hp->expdate, sizeof(hp->expdate)); ! 183: break; ! 184: #ifdef OLD ! 185: case ARTICLEID: ! 186: /* Believe Message-ID in preference to Article-ID */ ! 187: if (hp->ident[0] == '\0') { ! 188: register char *p; ! 189: char msgb[NAMELEN]; ! 190: getfield(msgb, sizeof msgb); ! 191: p = index(msgb, '.'); ! 192: if (p == NULL) { ! 193: (void) strcpy(hp->ident, msgb); ! 194: } else { ! 195: *p++ = '\0'; ! 196: (void) sprintf(hp->ident, "<%s@%s%s>", p, msgb, ".UUCP"); ! 197: } ! 198: } ! 199: break; ! 200: #endif /* OLD */ ! 201: case MESSAGEID: ! 202: getfield(hp->ident, sizeof(hp->ident)); ! 203: break; ! 204: case REPLYTO: ! 205: getfield(hp->replyto, sizeof(hp->replyto)); ! 206: break; ! 207: case FOLLOWID: ! 208: getfield(hp->followid, sizeof(hp->followid)); ! 209: break; ! 210: case SENDER: ! 211: getfield(hp->sender, sizeof(hp->sender)); ! 212: break; ! 213: case FOLLOWTO: ! 214: getfield(hp->followto, sizeof(hp->followto)); ! 215: break; ! 216: case CONTROL: ! 217: getfield(hp->ctlmsg, sizeof(hp->ctlmsg)); ! 218: break; ! 219: case DISTRIBUTION: ! 220: getfield(hp->distribution, sizeof(hp->distribution)); ! 221: if (strcmp(hp->distribution, "net") == 0 ! 222: || strcmp(hp->distribution, "world") == 0) ! 223: hp->distribution[0] = '\0'; ! 224: break; ! 225: case ORGANIZATION: ! 226: getfield(hp->organization, sizeof(hp->organization)); ! 227: break; ! 228: case NUMLINES: ! 229: getfield(hp->numlines, sizeof(hp->numlines)); ! 230: hp->intnumlines = atoi(hp->numlines); ! 231: break; ! 232: case KEYWORDS: ! 233: getfield(hp->keywords, sizeof(hp->keywords)); ! 234: break; ! 235: case APPROVED: ! 236: getfield(hp->approved, sizeof(hp->approved)); ! 237: break; ! 238: case NFID: ! 239: getfield(hp->nf_id, sizeof(hp->nf_id)); ! 240: break; ! 241: case NFFROM: ! 242: getfield(hp->nf_from, sizeof(hp->nf_from)); ! 243: break; ! 244: case SUPERSEDES: ! 245: getfield(hp->supersedes, sizeof(hp->supersedes)); ! 246: break; ! 247: /* discard these lines */ ! 248: case XREF: ! 249: case XPATH: ! 250: case RELAYVERSION: ! 251: case POSTVERSION: ! 252: case RECEIVE: ! 253: break; ! 254: case SUMMARY: ! 255: getfield(hp->summary, sizeof(hp->summary)); ! 256: break; ! 257: case OTHER: ! 258: if (unreccnt < NUNREC) { ! 259: if ((hp->unrec[unreccnt] = malloc((unsigned)(strlen(bfr) + 1))) != NULL ) { ! 260: (void) strcpy(hp->unrec[unreccnt], bfr); ! 261: (void) nstrip(hp->unrec[unreccnt]); ! 262: unreccnt++; ! 263: } else ! 264: xerror("frmread: out of memory"); ! 265: } ! 266: break; ! 267: } ! 268: } while ((i = type(hfgets(bfr, LBUFLEN, fp))) > 0); ! 269: ! 270: if ((hp->from[0] || hp->path[0]) && hp->subdate[0] && hp->ident[0]) ! 271: return TRUE; ! 272: return FALSE; ! 273: } ! 274: ! 275: #ifdef OLD ! 276: /* ! 277: * There was no From: line in the message (because it was generated by ! 278: * an old news program). Guess what it should have been and create it. ! 279: */ ! 280: intuitfrom(hp) ! 281: register struct hbuf *hp; ! 282: { ! 283: char *tp; ! 284: char *user, *host; ! 285: char *tailpath(), *rindex(); ! 286: char *at, *dot; ! 287: char pathbuf[PATHLEN]; ! 288: char fullname[BUFLEN]; ! 289: extern char *mydomain(); ! 290: ! 291: tp = tailpath(hp); ! 292: user = rindex(tp, '!'); ! 293: if (user == NULL) ! 294: user = tp; ! 295: else ! 296: *user++ = '\0'; ! 297: ! 298: /* Check for an existing Internet address on the end. */ ! 299: at = index(user, '@'); ! 300: if (at) { ! 301: dot = index(at, '.'); ! 302: if (dot) { ! 303: (void) strcpy(hp->from, user); ! 304: return; ! 305: } ! 306: /* @ signs are illegal except for the biggie, so */ ! 307: *at = '%'; ! 308: } ! 309: ! 310: if (tp[0] == '.') ! 311: host = index(tp, '!') + 1; ! 312: else if (user == tp) ! 313: host = FROMSYSNAME; ! 314: else ! 315: host = tp; ! 316: ! 317: tp = index(host, '@'); ! 318: if (tp != NULL) ! 319: *tp = 0; ! 320: if (index(host, '.') != NULL) ! 321: (void) sprintf(hp->from, "%s@%s%s", user, host, mydomain()); ! 322: else ! 323: (void) sprintf(hp->from, "%s@%s", user, host); ! 324: ! 325: skin(pathbuf, fullname, hp->path); /* remove RFC822-style comments */ ! 326: if (fullname[0] != '\0') { ! 327: strcat(hp->from, " ("); ! 328: (void) strcat(hp->from, fullname); ! 329: strcat(hp->from, ")"); ! 330: } ! 331: strcpy(hp->path, pathbuf); /* and stick it back in */ ! 332: } ! 333: #endif /* OLD */ ! 334: ! 335: /* ! 336: * Canonicalize the "From:" line into the form ! 337: * ! 338: * From: <mail-address> (full-name) ! 339: * ! 340: * RFC822 doesn't require the comment to be at the end of the string ! 341: * like that. ! 342: */ ! 343: fixfrom(hp) ! 344: register struct hbuf *hp; ! 345: { ! 346: char frombuf[PATHLEN]; ! 347: char fullname[BUFLEN]; ! 348: ! 349: skin(frombuf, fullname, hp->from); /* remove RFC822-style comments */ ! 350: if (fullname[0] != '\0') { ! 351: strcat(frombuf, " ("); ! 352: strcat(frombuf, fullname); ! 353: strcat(frombuf, ")"); ! 354: } ! 355: strcpy(hp->from, frombuf); /* stick the canonicalized "from" back in */ ! 356: } ! 357: ! 358: skin(name, fullname, hfield) ! 359: char *name; ! 360: char *fullname; ! 361: char *hfield; ! 362: { ! 363: register int c; ! 364: register char *cp, *cp2; ! 365: char *bufend; ! 366: int gotlt, parenlev, lastsp; ! 367: int seenfullname = FALSE; ! 368: ! 369: *fullname = '\0'; /* no full name yet */ ! 370: if (strpbrk(hfield, "(< ") == NULL) { /* include ',' ?? */ ! 371: strcpy(name, hfield); ! 372: return; ! 373: } ! 374: gotlt = 0; ! 375: parenlev = 0; ! 376: lastsp = 0; ! 377: bufend = name; ! 378: for (cp = hfield, cp2 = bufend; c = *cp++; ) { ! 379: switch (c) { ! 380: case '(': ! 381: /* ! 382: * Start of a "comment". ! 383: * Ignore it, or save it in "fullname" if we haven't ! 384: * seen a comment yet. ! 385: */ ! 386: parenlev++; ! 387: while ((c = *cp) != 0) { ! 388: cp++; ! 389: switch (c) { ! 390: case '\\': ! 391: if ((c = *cp) == 0) ! 392: goto outcm; ! 393: cp++; ! 394: break; ! 395: case '(': ! 396: parenlev++; ! 397: break; ! 398: case ')': ! 399: parenlev--; ! 400: if (parenlev == 0) ! 401: goto outcm; ! 402: break; ! 403: } ! 404: if (!seenfullname) ! 405: *fullname++ = c; ! 406: } ! 407: outcm: ! 408: parenlev = 0; ! 409: lastsp = 0; ! 410: if (!seenfullname) { ! 411: *fullname = '\0'; ! 412: seenfullname = TRUE; /* only extract first comment */ ! 413: } ! 414: break; ! 415: ! 416: case '"': ! 417: /* ! 418: * Start of a "quoted-string". ! 419: * Copy it in its entirety. ! 420: */ ! 421: while ((c = *cp) != 0) { ! 422: cp++; ! 423: switch (c) { ! 424: case '\\': ! 425: if ((c = *cp) == 0) ! 426: goto outqs; ! 427: cp++; ! 428: break; ! 429: case '"': ! 430: goto outqs; ! 431: } ! 432: *cp2++ = c; ! 433: } ! 434: outqs: ! 435: lastsp = 0; ! 436: break; ! 437: ! 438: case ' ': ! 439: if (cp[0] == 'a' && cp[1] == 't' && cp[2] == ' ') ! 440: cp += 3, *cp2++ = '@'; ! 441: else ! 442: if (cp[0] == '@' && cp[1] == ' ') ! 443: cp += 2, *cp2++ = '@'; ! 444: else ! 445: lastsp = 1; ! 446: break; ! 447: ! 448: case '<': ! 449: if (!seenfullname) { ! 450: *cp2 = '\0'; ! 451: strcpy(fullname, name); ! 452: seenfullname = TRUE; ! 453: } ! 454: cp2 = bufend; ! 455: gotlt++; ! 456: lastsp = 0; ! 457: break; ! 458: ! 459: case '>': ! 460: if (gotlt) { ! 461: gotlt = 0; ! 462: /* ! 463: * this doesn't seem reasonable, what about (,) ! 464: * or "," ?? ! 465: */ ! 466: while (*cp != ',' && *cp != 0) ! 467: cp++; ! 468: if (*cp == 0 ) ! 469: goto done; ! 470: *cp2++ = ','; ! 471: *cp2++ = ' '; ! 472: bufend = cp2; ! 473: break; ! 474: } ! 475: ! 476: /* Fall into . . . */ ! 477: ! 478: default: ! 479: if (lastsp) { ! 480: lastsp = 0; ! 481: *cp2++ = ' '; ! 482: } ! 483: *cp2++ = c; ! 484: break; ! 485: } ! 486: } ! 487: done: ! 488: *cp2 = 0; ! 489: } ! 490: ! 491: ! 492: #ifdef OLD ! 493: char * ! 494: oident(ident) ! 495: char *ident; ! 496: { ! 497: char lbuf[BUFLEN]; ! 498: static char oidbuf[BUFLEN]; ! 499: register char *p, *q; ! 500: ! 501: (void) strcpy(lbuf, ident); ! 502: p = index(lbuf, '@'); ! 503: if (p == NULL) ! 504: return ident; ! 505: *p++ = '\0'; ! 506: q = index(p, '.'); ! 507: if (q == NULL) ! 508: q = index(p, '>'); ! 509: if (q) ! 510: *q++ = '\0'; ! 511: p[SNLN] = '\0'; ! 512: (void) sprintf(oidbuf, "%s.%s", p, lbuf+1); ! 513: return oidbuf; ! 514: } ! 515: #endif /* OLD */ ! 516: ! 517: /* ! 518: * Get the given field of a header (char * parm) from bfr, but only ! 519: * if there's something actually there (after the colon). Don't ! 520: * bother if we already have an entry for this field. ! 521: */ ! 522: getfield(hpfield, size) ! 523: char *hpfield; ! 524: int size; ! 525: { ! 526: register char *ptr; ! 527: ! 528: if (hpfield[0]) ! 529: return; ! 530: for (ptr = index(bfr, ':'); isspace(*++ptr); ) ! 531: ; ! 532: if (*ptr != '\0') { ! 533: (void) strncpy(hpfield, ptr, size - 1); ! 534: (void) nstrip(hpfield); ! 535: } ! 536: } ! 537: ! 538: ! 539: #define its(type) (PREFIX(ptr, type)) ! 540: type(ptr) ! 541: register char *ptr; ! 542: { ! 543: register char *colon, *space; ! 544: ! 545: if (ptr == NULL) ! 546: return FALSE; ! 547: if (its("From: ")) ! 548: if (index(ptr, '@') || !index(ptr, '!')) ! 549: return FROM; ! 550: else ! 551: return PATH; ! 552: if (its("Path: ")) ! 553: return PATH; ! 554: if (its("Newsgroups: ")) ! 555: return NEWSGROUP; ! 556: if (its("Subject: ")) ! 557: return TITLE; ! 558: if (its("Date: ")) ! 559: return SUBMIT; ! 560: if (its("Date-Received: ")) ! 561: return RECEIVE; ! 562: #ifdef OLD ! 563: if (its("Title: ")) ! 564: return TITLE; ! 565: if (its("Posted: ")) ! 566: return SUBMIT; ! 567: #endif /* OLD */ ! 568: if (its("Received: ")) ! 569: return RECEIVE; ! 570: if (its("Expires: ")) ! 571: return EXPIRE; ! 572: if (its("Article-I.D.: ")) ! 573: return ARTICLEID; ! 574: if (its("Message-ID: ")) ! 575: return MESSAGEID; ! 576: if (its("Reply-To: ")) ! 577: return REPLYTO; ! 578: if (its("References: ")) ! 579: return FOLLOWID; ! 580: if (its("Control: ")) ! 581: return CONTROL; ! 582: if (its("Sender: ")) ! 583: return SENDER; ! 584: if (its("Followup-To: ")) ! 585: return FOLLOWTO; ! 586: if (its("Distribution: ")) ! 587: return DISTRIBUTION; ! 588: if (its("Organization: ")) ! 589: return ORGANIZATION; ! 590: if (its("Lines: ")) ! 591: return NUMLINES; ! 592: if (its("Summary: ")) ! 593: return SUMMARY; ! 594: if (its("Keywords: ")) ! 595: return KEYWORDS; ! 596: if (its("Approved: ")) ! 597: return APPROVED; ! 598: if (its("Nf-ID: ")) ! 599: return NFID; ! 600: if (its("Nf-From: ")) ! 601: return NFFROM; ! 602: if (its("Supersedes: ")) ! 603: return SUPERSEDES; ! 604: if (its("Xref: ")) ! 605: return XREF; ! 606: if (its("Xpath: ")) ! 607: return XPATH; ! 608: if (its("Posting-Version: ")) ! 609: return POSTVERSION; ! 610: if (its("Relay-Version: ")) ! 611: return RELAYVERSION; ! 612: if (!isalpha(*ptr)) ! 613: return FALSE; ! 614: colon = index(ptr, ':'); ! 615: space = index(ptr, ' '); ! 616: if (!colon || space && space < colon) ! 617: return FALSE; ! 618: return OTHER; ! 619: } ! 620: ! 621: /* ! 622: * Write header at 'hp' on stream 'fp' in B+ format. Include received date ! 623: * if wr is 1. Leave off sysname if wr is 2. ! 624: */ ! 625: #ifndef DOXREFS ! 626: /*ARGSUSED*/ ! 627: #endif /* !DOXREFS */ ! 628: ihwrite(hp, fp, wr) ! 629: register struct hbuf *hp; ! 630: register FILE *fp; ! 631: int wr; ! 632: { ! 633: int iu; ! 634: time_t t; ! 635: time_t cgtdate(); ! 636: ! 637: /* ! 638: * We're being tricky with Path/From because of upward compatibility ! 639: * issues. The new version considers From and Path to be separate. ! 640: * The old one thinks they both mean "Path" but only believes the ! 641: * first one it sees, so will ignore the second. ! 642: */ ! 643: if (PREFIX(hp->path, PATHSYSNAME) && ! 644: index(NETCHRS, hp->path[strlen(PATHSYSNAME)])) ! 645: fprintf(fp, "Path: %s\n", hp->path); ! 646: else ! 647: fprintf(fp, "Path: %s!%s\n", PATHSYSNAME, hp->path); ! 648: if (hp->from[0]) ! 649: fprintf(fp, "From: %s\n", hp->from); ! 650: ! 651: fprintf(fp, "Newsgroups: %s\n", hp->nbuf); ! 652: fprintf(fp, "Subject: %s\n", hp->title); ! 653: if (*hp->summary) ! 654: fprintf(fp, "Summary: %s\n", hp->summary); ! 655: if (*hp->keywords) ! 656: fprintf(fp, "Keywords: %s\n", hp->keywords); ! 657: fprintf(fp, "Message-ID: %s\n", hp->ident); ! 658: t = cgtdate(hp->subdate); ! 659: fprintf(fp, "Date: %s\n", arpadate(&t)); ! 660: #ifdef OLD ! 661: fprintf(fp, "Article-I.D.: %s\n", oident(hp->ident)); ! 662: fprintf(fp, "Posted: %s", ctime(&t)); ! 663: #endif /* OLD */ ! 664: if (*hp->expdate) ! 665: fprintf(fp, "Expires: %s\n", hp->expdate); ! 666: if (*hp->followid) { ! 667: register char *dp, *cp; ! 668: ! 669: dp = cp = hp->followid; ! 670: while (*cp != '\0') ! 671: if (*cp == '<' && *(cp + 1) == '>') ! 672: cp += 2; ! 673: else ! 674: *dp++ = *cp++; ! 675: *dp = '\0'; ! 676: if (*hp->followid) ! 677: fprintf(fp, "References: %s\n", hp->followid); ! 678: } ! 679: if (*hp->ctlmsg) ! 680: fprintf(fp, "Control: %s\n", hp->ctlmsg); ! 681: if (*hp->sender) ! 682: fprintf(fp, "Sender: %s\n", hp->sender); ! 683: if (*hp->replyto) ! 684: fprintf(fp, "Reply-To: %s\n", hp->replyto); ! 685: if (*hp->followto) ! 686: fprintf(fp, "Followup-To: %s\n", hp->followto); ! 687: if (*hp->distribution) ! 688: fprintf(fp, "Distribution: %s\n", hp->distribution); ! 689: if (*hp->organization) ! 690: fprintf(fp, "Organization: %s\n", hp->organization); ! 691: if (*hp->numlines) ! 692: fprintf(fp, "Lines: %s\n", hp->numlines); ! 693: if (*hp->approved) ! 694: fprintf(fp, "Approved: %s\n", hp->approved); ! 695: if (*hp->nf_id) ! 696: fprintf(fp, "Nf-ID: %s\n", hp->nf_id); ! 697: if (*hp->nf_from) ! 698: fprintf(fp, "Nf-From: %s\n", hp->nf_from); ! 699: if (*hp->supersedes) ! 700: fprintf(fp, "Supersedes: %s\n", hp->supersedes); ! 701: #ifdef DOXREFS ! 702: if ( wr ==1 && *hp->xref) ! 703: fprintf(fp, "Xref: %s\n", hp->xref); ! 704: #endif /* DOXREFS */ ! 705: for (iu = 0; iu < NUNREC; iu++) { ! 706: if (hp->unrec[iu]) ! 707: fprintf(fp, "%s\n", &hp->unrec[iu][0]); ! 708: } ! 709: putc('\n', fp); ! 710: } ! 711: ! 712: ! 713: #ifndef BSD4_2 ! 714: /* ! 715: * Set nc bytes, starting at cp, to zero. ! 716: */ ! 717: bzero(cp, nc) ! 718: register char *cp; ! 719: register int nc; ! 720: { ! 721: if (nc > 0) ! 722: do { ! 723: *cp++ = 0; ! 724: } while (--nc); ! 725: } ! 726: #endif /* !BSD4_2 */ ! 727: ! 728: /* ! 729: * hfgets is like fgets, but deals with continuation lines. ! 730: * It also ensures that even if a line that is too long is ! 731: * received, the remainder of the line is thrown away ! 732: * instead of treated like a second line. ! 733: */ ! 734: char * ! 735: hfgets(buf, len, fp) ! 736: char *buf; ! 737: int len; ! 738: FILE *fp; ! 739: { ! 740: register int c; ! 741: register int n = 0; ! 742: register char *cp; ! 743: ! 744: cp = buf; ! 745: while (n < len && (c = getc(fp)) != EOF) { ! 746: if (c == '\n') ! 747: break; ! 748: if (isprint(c) || c == '\b' || c == ' ' || c == '\t') { ! 749: *cp++ = c; ! 750: n++; ! 751: } ! 752: } ! 753: if (c == EOF && cp == buf) ! 754: return NULL; ! 755: *cp = '\0'; ! 756: ! 757: if (c != '\n') { ! 758: /* Line too long - part read didn't fit into a newline */ ! 759: while ((c = getc(fp)) != '\n' && c != EOF) ! 760: ; ! 761: } else if (cp == buf) { ! 762: /* Don't look for continuation of blank lines */ ! 763: *cp++ = '\n'; ! 764: *cp = '\0'; ! 765: return buf; ! 766: } ! 767: ! 768: while ((c = getc(fp)) == ' ' || c == '\t') { /* for each cont line */ ! 769: /* Continuation line. */ ! 770: if ((n += 2) < len) { ! 771: *cp++ = '\n'; ! 772: *cp++ = c; ! 773: } ! 774: while ((c = getc(fp)) != '\n' && c != EOF) ! 775: if ((isprint(c) || c == '\b' || c == ' ' || c == '\t') ! 776: && n++ < len) ! 777: *cp++ = c; ! 778: } ! 779: if (n >= len - 1) ! 780: cp = buf + len - 2; ! 781: *cp++ = '\n'; ! 782: *cp = '\0'; ! 783: if (c != EOF) ! 784: (void) ungetc(c, fp); /* push back first char of next header */ ! 785: return buf; ! 786: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.