1: /*
   2:  * header.c - header functions plus some other goodies
   3:  *
   4:  *	TAKEN FROM BNEWS 2.10 6/24/83
   5:  *
   6:  */
   7: 
   8: #ifdef  RCSIDENT
   9: static char *SccsId = "@(#)header.c	2.20	6/24/83";
  10: static char *RCSid = "$Header: bnewshead.c,v 1.7.0.1 85/03/06 20:03:00 notes Rel $";
  11: #endif	RCSIDENT
  12: 
  13: #include <stdio.h>
  14: #include <sys/types.h>
  15: #include    "parms.h"               /* from notes */
  16: #include    "structs.h"             /* ditto */
  17:                             /* above maybe unused */
  18: #include    "newsgate.h"
  19: 
  20: 
  21: char   *hfgets ();
  22: 
  23: static int  seenrelay;
  24: static char bfr[PATHLEN];               /* header buffer */
  25: 
  26: /*
  27:  * Read header from file fp into *hp.  If wholething is FALSE,
  28:  * it's an incremental read, otherwise start from scratch.
  29:  * Return (FILE *) if header okay, else NULL.
  30:  */
  31: 
  32: newsheader (hp, fp, wholething)
  33: register struct hbuf   *hp;
  34: FILE * fp;
  35: int     wholething;
  36: {
  37:     register int    len;
  38: 
  39:     if (wholething)                 /* from scratch */
  40:     bclear ((char *) hp, sizeof (*hp));
  41: 
  42:     seenrelay = 0;
  43: 
  44: /*
  45:  *	Check that it's a B news style header.
  46:  */
  47:     if (((hfgets (bfr, PATHLEN, fp) != NULL &&
  48:             *bfr >= 'A' && *bfr <= 'Z') && index (bfr, ':')))
  49:     if (frmread (fp, hp))
  50:         goto strip;
  51: 
  52: /*
  53:  * It's not.  Try A news (begins with PROTO).
  54:  */
  55:     if (*bfr != PROTO)
  56:     return (0);
  57: 
  58: /*
  59:  *	Read in an A news format article.
  60:  */
  61:     strncpy (hp -> oident, &(bfr[1]), NAMELEN);     /* file name */
  62:     if (!nstrip (hp -> oident))
  63:     return (0);
  64:     hfgets (hp -> nbuf, BUFLEN, fp);            /* newsgroup list */
  65:     if (!nstrip (hp -> nbuf))
  66:     return (0);
  67:     ngcat (hp -> nbuf);                 /* trailing delim */
  68:     hfgets (hp -> path, PATHLEN, fp);           /* source path */
  69:     if (!nstrip (hp -> path))
  70:     return (0);
  71:     hfgets (hp -> subdate, DATELEN, fp);        /* date */
  72:     if (!nstrip (hp -> subdate))
  73:     return (0);
  74:     hfgets (hp -> title, BUFLEN, fp);           /* title */
  75:     if (!nstrip (hp -> title))
  76:     return (0);
  77: 
  78: /*
  79:  * strip off sys! from front of path.
  80:  */
  81: strip:
  82:     strcpy (bfr, System);
  83:     if (strncmp (bfr, hp -> path, (len = strlen (bfr))) == 0
  84:         && index (NETCHRS, hp -> path[len]))
  85:     strcpy (hp -> path, &(hp -> path[len + 1]));
  86: 
  87:     if (wholething && hp -> from[0] == '\0')        /* intuit the from: */
  88:     intuitfrom (hp);                /* if wasn't there */
  89: 
  90:     if (wholething)                 /* Get message ID's. */
  91:     fixid (hp);
  92:     return (1);
  93: }
  94: 
  95: 
  96: /*
  97:  * Get header info from mail-format file.
  98:  * Return non-zero on success.
  99:  */
 100: 
 101: #include <ctype.h>
 102: #define FROM        1
 103: #define NEWSGROUP   2
 104: #define TITLE       3
 105: #define SUBMIT      4
 106: #define RECEIVE     5
 107: #define EXPIRE      6
 108: #define ARTICLEID   7
 109: #define MESSAGEID   8
 110: #define REPLYTO     9
 111: #define FOLLOWID    10
 112: #define CONTROL     11
 113: #define SENDER      12
 114: #define FOLLOWTO    13
 115: #define PATH        14
 116: #define POSTVERSION 15
 117: #define RELAYVERSION    16
 118: #define DISTRIBUTION    17
 119: #define ORGANIZATION    18
 120: #define NUMLINES    19
 121: #define KEYWORDS    20
 122: #define APPROVED    21
 123: 
 124: #define NLINE1      22
 125: #define NLINE2      23
 126: 
 127: #define OTHER       99
 128: 
 129: 
 130: char   *malloc ();
 131: 
 132: frmread (fp, hp)
 133: register    FILE * fp;
 134: register struct hbuf   *hp;
 135: {
 136:     int     unreccnt = 0;
 137:     register int    i;
 138:     long    curpos;
 139:     int     hdrlineno = 0;
 140:     int     iu;
 141: 
 142:     for (iu = 0; iu < NUNREC; iu++)
 143:     hp -> unrec[iu] = NULL;
 144: 
 145:     i = type (bfr);
 146:     do
 147:     {
 148:     curpos = ftell (fp);
 149:     hdrlineno++;
 150:     switch (i)
 151:     {
 152:         case PATH:
 153:         getfield (hp -> path);
 154:         break;
 155:         case FROM:
 156:         getfield (hp -> from);
 157:         break;
 158:         case NEWSGROUP:
 159:         getfield (hp -> nbuf);
 160:         break;
 161:         case TITLE:
 162:         getfield (hp -> title);
 163:         break;
 164:         case SUBMIT:
 165:         getfield (hp -> subdate);
 166:         break;
 167:         case RECEIVE:
 168:         getfield (hp -> recdate);
 169:         break;
 170:         case EXPIRE:
 171:         getfield (hp -> expdate);
 172:         break;
 173:         case ARTICLEID:
 174:         getfield (hp -> oident);
 175:         break;
 176:         case MESSAGEID:
 177:         getfield (hp -> ident);
 178:         break;
 179:         case REPLYTO:
 180:         getfield (hp -> replyto);
 181:         break;
 182:         case FOLLOWID:
 183:         getfield (hp -> followid);
 184:         break;
 185:         case SENDER:
 186:         getfield (hp -> sender);
 187:         break;
 188:         case FOLLOWTO:
 189:         getfield (hp -> followto);
 190:         break;
 191:         case CONTROL:
 192:         getfield (hp -> ctlmsg);
 193:         break;
 194:         case POSTVERSION:
 195:         getfield (hp -> postversion);
 196:         break;
 197:         case DISTRIBUTION:
 198:         getfield (hp -> distribution);
 199:         break;
 200:         case ORGANIZATION:
 201:         getfield (hp -> organization);
 202:         break;
 203:         case NUMLINES:
 204:         getfield (hp -> numlines);
 205:         hp -> intnumlines = atoi (hp -> numlines);
 206:         break;
 207:         case KEYWORDS:
 208:         getfield (hp -> keywords);
 209:         break;
 210:         case APPROVED:
 211:         getfield (hp -> approved);
 212:         break;
 213:         case NLINE1:                /* notes-specific */
 214:         getfield (hp -> nline1);
 215:         break;
 216:         case NLINE2:                /* notes-specific */
 217:         getfield (hp -> nline2);
 218:         break;
 219:         case RELAYVERSION:
 220:         /*
 221: 		 * Only believe a relay version if it's the first
 222: 		 * line, otherwise it probably got passed through
 223: 		 * by some old neighbor.
 224: 		 */
 225:         if (hdrlineno == 1)
 226:         {
 227:             getfield (hp -> relayversion);
 228:             seenrelay = 1;
 229:         }
 230:         break;
 231:         case OTHER:
 232:         if (unreccnt < NUNREC)
 233:         {
 234:             hp -> unrec[unreccnt] = malloc (strlen (bfr) + 1);
 235:             strcpy (hp -> unrec[unreccnt], bfr);
 236:             unreccnt++;
 237:         }
 238:         break;
 239:     }
 240:     } while ((i = type (hfgets (bfr, LBUFLEN, fp))) > 0);
 241: 
 242:     if (*bfr != '\n')
 243:     {
 244:     printf ("Bizzaro header line: %s\n", bfr);
 245:     return (0);
 246:     }
 247: 
 248: /*
 249:  *	Check to see if the REQUIRED headers are present.  If so, return
 250:  *	that we found a message. Otherwise barf.
 251:  */
 252:     if ((hp -> from[0] || hp -> path[0]) &&
 253:         hp -> subdate[0] &&
 254:         (hp -> ident[0] || hp -> oident[0]))
 255:     {
 256:     return TRUE;
 257:     }
 258:     return FALSE;
 259: }
 260: 
 261: /*
 262:  * There was no From: line in the message (because it was generated by
 263:  * an old news program).  Guess what it should have been and create it.
 264:  */
 265: 
 266: intuitfrom (hp)
 267: register struct hbuf   *hp;
 268: {
 269:     char   *tp;
 270:     char   *user,
 271:            *host,
 272:            *fullname;
 273:     char   *tailpath ();
 274:     char   *at,
 275:            *dot;
 276: 
 277:     tp = tailpath (hp);
 278:     user = rindex (tp, '!');
 279:     if (user == NULL)
 280:     user = tp;
 281:     else
 282:     *user++ = '\0';
 283: 
 284:     /* Check for an existing Internet address on the end. */
 285:     at = index (user, '@');
 286:     if (at)
 287:     {
 288:     dot = index (at, '.');
 289:     if (dot)
 290:     {
 291:         strcpy (hp -> from, user);
 292:         return;
 293:     }
 294: /* @ signs are illegal except for the biggie, so */
 295:     *at = '%';
 296:     }
 297: 
 298:     if (tp[0] == '.')
 299:     host = index (tp, '!') + 1;
 300:     else
 301:     if (user == tp)
 302:         host = System;
 303:     else
 304:         host = tp;
 305: 
 306:     tp = index (host, '@');
 307:     if (tp != NULL)
 308:     *tp = 0;
 309:     sprintf (hp -> from, "%s@%s.%s", user, host, DFLTDOMAIN);
 310: 
 311:     fullname = index (hp -> path, '(');
 312:     if (fullname != NULL)
 313:     {
 314:     fullname--;
 315:     strcat (hp -> from, fullname);
 316:     *fullname = 0;
 317:     }
 318: }
 319: 
 320: /*
 321:  * If the message has only one of ident/oident, guess what
 322:  * the other one should be and fill them both in.
 323:  */
 324: 
 325: fixid (hp)
 326: register struct hbuf   *hp;
 327: {
 328:     char    lbuf[100];
 329:     char   *p;
 330: #ifdef  OLD
 331:     char   *q;
 332: #endif	OLD
 333: 
 334:     if (hp -> ident[0] == '\0' && hp -> oident[0] != '\0')
 335:     {
 336:     strcpy (lbuf, hp -> oident);
 337:     p = index (lbuf, '.');
 338:     if (p == 0)
 339:     {
 340:         strcpy (hp -> ident, hp -> oident);
 341:         return;
 342:     }
 343:     *p++ = '\0';
 344:     /*
 345: 	 * It may seem strange that we hardwire ".UUCP" in
 346: 	 * here instead of DFLTDOMAIN.  However, we are trying
 347: 	 * to guess what the domain was on the posting system,
 348: 	 * not the local system.  Since we don't really know
 349: 	 * what the posting system does, we just go with the
 350: 	 * majority - almost everyone will be a .UUCP if they
 351: 	 * didn't fill in their Message-ID.
 352: 	 */
 353:     sprintf (hp -> ident, "<%s@%s%s>", p, lbuf, ".UUCP");
 354:     }
 355: 
 356: #ifdef OLD
 357:     if (hp -> oident[0] == '\0' && hp -> ident[0] != '\0')
 358:     {
 359:     strcpy (lbuf, hp -> ident);
 360:     p = index (lbuf, '@');
 361:     if (p == 0)
 362:     {
 363:         strcpy (hp -> oident, hp -> ident);
 364:         return;
 365:     }
 366:     *p++ = '\0';
 367:     q = index (p, '.');
 368:     if (!q)
 369:         q = index (p, '>');
 370:     if (q)
 371:         *q++ = '\0';
 372:     p[SNLN] = '\0';
 373:     sprintf (hp -> oident, "%s.%s", p, lbuf + 1);
 374:     }
 375: #endif
 376: }
 377: 
 378: /*
 379:  * Get the given field of a header (char * parm) from bfr, but only
 380:  * if there's something actually there (after the colon).  Don't
 381:  * bother if we already have an entry for this field.
 382:  */
 383: 
 384: getfield (hpfield)
 385: char   *hpfield;
 386: {
 387:     char   *ptr;
 388: 
 389:     if (hpfield[0])
 390:     return;
 391:     for (ptr = index (bfr, ':'); isspace (*++ptr);)
 392:     ;
 393:     if (*ptr != '\0')
 394:     {
 395:     strcpy (hpfield, ptr);
 396:     nstrip (hpfield);
 397:     }
 398:     return;
 399: }
 400: 
 401: 
 402: /*
 403:  *	Determine the type of the header
 404:  */
 405: 
 406: #define its(type) (!strncmp(ptr,type,strlen(type)))
 407: 
 408: type (ptr)
 409: char   *ptr;
 410: {
 411:     char   *colon,
 412:            *space;
 413: 
 414:     if (!isalpha (*ptr) && strncmp (ptr, "From ", 5))
 415:     return FALSE;
 416:     colon = index (ptr, ':');
 417:     space = index (ptr, ' ');
 418:     if (!colon || colon + 1 != space)
 419:     return FALSE;
 420:     if (its ("From: "))
 421:     if (index (ptr, '@') && !index (ptr, '!') && seenrelay)
 422:         return FROM;
 423:     else
 424:         return PATH;
 425:     if (its ("Path: "))
 426:     return PATH;
 427:     if (its ("Newsgroups: "))
 428:     return NEWSGROUP;
 429:     if (its ("Subject: ") || its ("Title: "))
 430:     return TITLE;
 431:     if (its ("Posted: ") || its ("Date: "))
 432:     return SUBMIT;
 433:     if (its ("Date-Received: ") || its ("Received: "))
 434:     return RECEIVE;
 435:     if (its ("Expires: "))
 436:     return EXPIRE;
 437:     if (its ("Article-I.D.: "))
 438:     return ARTICLEID;
 439:     if (its ("Message-ID: "))
 440:     return MESSAGEID;
 441:     if (its ("Reply-To: "))
 442:     return REPLYTO;
 443:     if (its ("References: "))
 444:     return FOLLOWID;
 445:     if (its ("Control: "))
 446:     return CONTROL;
 447:     if (its ("Sender: "))
 448:     return SENDER;
 449:     if (its ("Followup-To: "))
 450:     return FOLLOWTO;
 451:     if (its ("Posting-Version: "))
 452:     return POSTVERSION;
 453:     if (its ("Relay-Version: "))
 454:     return RELAYVERSION;
 455:     if (its ("Distribution: "))
 456:     return DISTRIBUTION;
 457:     if (its ("Organization: "))
 458:     return ORGANIZATION;
 459:     if (its ("Lines: "))
 460:     return NUMLINES;
 461:     if (its ("Keywords: "))
 462:     return KEYWORDS;
 463:     if (its ("Approved: "))
 464:     return APPROVED;
 465:     if (its ("Nf-ID: "))
 466:     return NLINE1;
 467:     if (its ("Nf-From: "))
 468:     return NLINE2;
 469:     return OTHER;
 470: }
 471: 
 472: /*
 473:  * Set nc bytes, starting at cp, to zero.
 474:  */
 475: 
 476: bclear (cp, nc)
 477: register char  *cp;
 478: register int    nc;
 479: {
 480:     while (nc--)
 481:     *cp++ = 0;
 482: }
 483: 
 484: /*
 485:  * Strip trailing newlines, blanks, and tabs from 's'.
 486:  * Return TRUE if newline was found, else FALSE.
 487:  */
 488: 
 489: nstrip (s)
 490: register char  *s;
 491: {
 492:     register char  *p;
 493:     register int    rc;
 494: 
 495:     rc = FALSE;
 496:     p = s;
 497:     while (*p)
 498:     if (*p++ == '\n')
 499:         rc = TRUE;
 500:     while (--p >= s && (*p == '\n' || *p == ' ' || *p == '\t'));
 501:     *++p = '\0';
 502:     return (rc);
 503: }
 504: 
 505: /*
 506:  * Append NGDELIM to string.
 507:  */
 508: 
 509: ngcat (s)
 510: register char  *s;
 511: {
 512:     if (*s)
 513:     {
 514:     while (*s++);
 515:     s -= 2;
 516:     if (*s++ == NGDELIM)
 517:         return;
 518:     }
 519:     *s++ = NGDELIM;
 520:     *s = '\0';
 521: }
 522: 
 523: /*
 524:  * Return a compact representation of the person who posted the given
 525:  * message.  A sender or internet name will be used, otherwise
 526:  * the last part of the path is used preceeded by an optional ".."
 527:  */
 528: char   *
 529:         tailpath (hp)
 530: struct hbuf *hp;
 531: {
 532:     char   *p,
 533:            *r;
 534:     static char resultbuf[BUFLEN];
 535:     char    pathbuf[PATHLEN];
 536:     char   *malloc ();
 537: 
 538:     /*
 539:      * This only happens for articles posted by old news software
 540:      * in non-internet format.
 541:      */
 542:     resultbuf[0] = '\0';
 543:     strcpy (pathbuf, hp -> path);
 544:     p = index (pathbuf, ' ');
 545:     if (p)
 546:     *p = '\0';                  /* Chop off trailing " (name)" */
 547:     r = rindex (pathbuf, '!');
 548:     if (r == 0)
 549:     {
 550:     r = pathbuf;
 551:     }
 552:     else
 553:     {
 554:     while (r > pathbuf && *--r != '!')
 555:         ;
 556:     if (r > pathbuf)
 557:     {
 558:         r++;
 559:         strcpy (resultbuf, "..!");
 560:     }
 561:     }
 562:     strcat (resultbuf, r);
 563:     return resultbuf;
 564: }
 565: 
 566: 
 567: 
 568: /*
 569:  * hfgets is like fgets, but deals with continuation lines.
 570:  * It also ensures that even if a line that is too long is
 571:  * received, the remainder of the line is thrown away
 572:  * instead of treated like a second line.
 573:  */
 574: 
 575: char   *hfgets (buf, len, fp)
 576: char   *buf;
 577: int     len;
 578: FILE * fp;
 579: {
 580:     register int    c;
 581:     register char  *cp,
 582:                    *tp;
 583: 
 584:     cp = fgets (buf, len, fp);
 585:     if (cp == NULL)
 586:     return NULL;
 587: 
 588:     tp = cp + strlen (cp);
 589:     if (tp[-1] != '\n')
 590:     {
 591:     /*
 592: 	 * Line too long - part read didn't fit into a newline
 593: 	 */
 594:     while ((c = getc (fp)) != '\n' && c != EOF)
 595:         ;
 596:     }
 597:     else
 598:     *--tp = '\0';                   /* clobber newline */
 599: 
 600:     while ((c = getc (fp)) == ' ' || c == '\t')     /* continuation */
 601:     {
 602:     /*
 603: 	 * Continuation line.
 604: 	 */
 605:     while ((c = getc (fp)) == ' ' || c == '\t') /* skip white space */
 606:         ;
 607:     if (tp - cp < len)
 608:     {
 609:         *tp++ = ' ';
 610:         *tp++ = c;
 611:     }
 612:     while ((c = getc (fp)) != '\n' && c != EOF)
 613:         if (tp - cp < len)
 614:         *tp++ = c;
 615:     }
 616:     *tp++ = '\n';
 617:     *tp++ = '\0';
 618:     if (c != EOF)
 619:     ungetc (c, fp);                 /* push back char */
 620:     return cp;
 621: }

Defined functions

bclear defined in line 476; used 1 times
  • in line 40
fixid defined in line 325; used 1 times
  • in line 91
frmread defined in line 132; used 1 times
  • in line 49
getfield defined in line 384; used 23 times
hfgets defined in line 575; used 7 times
intuitfrom defined in line 266; used 1 times
  • in line 88
newsheader defined in line 32; used 1 times
ngcat defined in line 509; used 1 times
  • in line 67
nstrip defined in line 489; used 6 times
tailpath defined in line 528; used 2 times
type defined in line 408; used 5 times

Defined variables

RCSid defined in line 10; never used
SccsId defined in line 9; never used
bfr defined in line 24; used 16 times
seenrelay defined in line 23; used 3 times

Defined macros

APPROVED defined in line 122; used 1 times
ARTICLEID defined in line 108; used 1 times
CONTROL defined in line 112; used 1 times
DISTRIBUTION defined in line 118; used 1 times
EXPIRE defined in line 107; used 1 times
FOLLOWID defined in line 111; used 1 times
FOLLOWTO defined in line 114; used 1 times
FROM defined in line 102; used 1 times
KEYWORDS defined in line 121; used 1 times
MESSAGEID defined in line 109; used 1 times
NEWSGROUP defined in line 103; used 1 times
NLINE1 defined in line 124; used 1 times
NLINE2 defined in line 125; used 1 times
NUMLINES defined in line 120; used 1 times
ORGANIZATION defined in line 119; used 1 times
OTHER defined in line 127; used 1 times
PATH defined in line 115; used 2 times
POSTVERSION defined in line 116; used 1 times
RECEIVE defined in line 106; used 1 times
RELAYVERSION defined in line 117; used 1 times
REPLYTO defined in line 110; used 1 times
SENDER defined in line 113; used 1 times
SUBMIT defined in line 105; used 1 times
TITLE defined in line 104; used 1 times
its defined in line 406; used 26 times
Last modified: 1985-10-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2022
Valid CSS Valid XHTML 1.0 Strict