1: #include "parms.h"
   2: #include "structs.h"
   3: #include "newsgate.h"
   4: 
   5: #ifdef  RCSIDENT
   6: static char *RCSid = "$Header: newsdump.c,v 1.7.0.10 85/10/31 09:03:40 notes Rel $";
   7: #endif	RCSIDENT
   8: 
   9: /*
  10:  *	newsnote - take a note and dump it in a format that news will
  11:  *	understand. Submit the article to the news program as
  12:  *	defined in newsgate.h
  13:  *
  14:  *	newsresp - similar to newsnote, but it dumps a response instead.
  15:  *
  16:  *	The routines build some title lines and other headers for
  17:  *	submission to the news insertion program. The rest of the
  18:  *	article is fed to the news program through a pipe.
  19:  *	This turned out to be mucho mucho easier than building the
  20:  *	properly formatted intersystem files.
  21:  *
  22:  *	Original Coding:	Ray Essick	April 1982
  23:  *	Modified to produce cleaner looking output:
  24:  *				Ray Essick	May 1, 1982
  25:  *				(with good help from Brian Redman (harpo!ber)
  26:  *	Modified to solve meta-character ("'`) problems in popen()
  27:  *				Ray Essick	September 1982
  28:  *
  29:  *	Lots of code by Tw Cook at Hewlett-Packard to implement
  30:  *	compatibility with the USENET standards for news.
  31:  *			January 1984.
  32:  */
  33: 
  34: extern char *mnames[];                  /* month names */
  35: FILE * popen ();
  36: 
  37: char   *Version = "$Revision: 1.7.0.10 $";      /* Use RCS info */
  38: 
  39: newsnote (io, note, notenum, ngroup, backwards)
  40: struct io_f *io;
  41: struct note_f  *note;
  42: char   *ngroup;                     /* to this newsgroup */
  43: {
  44:     FILE * rnews;                   /* rnews pipe */
  45:     char    cmdline[CMDLEN];                /* command line  */
  46:     char    line[TITLEN + 50];              /* scratch line */
  47:     int     i;
  48:     char   *p,
  49:            *q;
  50:     char    ntitle[TITLEN + 10];            /* title */
  51:     char    from[SYSSZ + NAMESZ + 3];           /* formatted author */
  52:     char    path[BUFSIZ];               /* path to author */
  53:     char   *author;                 /* for Path line */
  54: 
  55: /*
  56:  *	format some of the internal data structures in a suitable
  57:  *	format to send to the news system.
  58:  */
  59: 
  60:     strcpy (ntitle, note -> ntitle);            /* make a title */
  61:     if (backwards)
  62:     {
  63:     strcat (ntitle, " ");               /* separate */
  64:     strcat (ntitle, NFSUFFIX);          /* add suffix */
  65:     }
  66: 
  67:     /*
  68:      * From:
  69:      *		author information
  70:      */
  71:     sprintf (from, "%s@%s",             /* author */
  72:         note -> n_auth.aname, note -> n_auth.asystem);
  73: #ifdef  notdef
  74:     /*
  75:      * decided it was better to NOT append a domain here...
  76:      */
  77:     if (index (note -> n_auth.asystem, '.') != (char *) NULL)/* domained */
  78:     {
  79:     sprintf (from, "%s@%s",
  80:         note -> n_auth.aname, note -> n_auth.asystem);
  81:     }
  82:     else
  83:     {
  84:     sprintf (from, "%s@%s.%s",
  85:         note -> n_auth.aname, note -> n_auth.asystem,
  86:         DFLTDOMAIN);                /* append default */
  87:     }
  88: #endif	notdef
  89:     /*
  90:      * Path:
  91:      *	where the article has been
  92:      *  Maybe we want to use some format besides a!b!c, something like
  93:      *  a,b,c
  94:      */
  95:     if (!strcmp (System, note -> n_id.sys))     /* local */
  96:     {
  97:     sprintf (path, "%s", note -> n_id.sys);
  98:     }
  99:     else
 100:     {
 101:     if (!strcmp (note -> n_id.sys, note -> n_from)) /* one hop */
 102:     {
 103:         sprintf (path, "%s!%s",
 104:             System,
 105:             note -> n_id.sys);
 106:     }
 107:     else
 108:     {
 109:         sprintf (path, "%s!%s!%s",          /* several hops */
 110:             System, note -> n_from, note -> n_id.sys);
 111:     }
 112:     }
 113: #ifdef  UGLYPATH                    /* usually so */
 114:     /*
 115:      * Fill in the "authorname" with either a placeholder
 116:      * or the real author name. Key this off whether the unique
 117:      * id matches the author's home system.
 118:      *
 119:      * This will usually use AUTHORPLACEHOLDER on new systems
 120:      * since the unique id's don't have the domains in yet.
 121:      *
 122:      * hacked at to satisfy the public at large still using the
 123:      * Path line although it's not supposed to be good any longer.
 124:      * new code checks to see if things are a common prefix. and
 125:      * that the next character in the longer string is a "."
 126:      * if so, it declares things good enough and uses the real author.
 127:      */
 128:     {
 129:     int     idlen,
 130:             authlen;
 131:     int     isok;
 132:     int     minlen;
 133: 
 134:     idlen = strlen (note -> n_id.sys);
 135:     authlen = strlen (note -> n_auth.asystem);
 136:     minlen = idlen < authlen ? idlen : authlen; /* get shortest */
 137:     isok = (strncmp (note -> n_id.sys, note -> n_auth.asystem, minlen) == 0);
 138:     if (isok && idlen < authlen)            /* id is short */
 139:     {
 140:         isok &= (note -> n_auth.asystem[idlen] == '.');
 141:     }
 142:     else
 143:     {
 144:         if (isok && authlen < idlen)
 145:         isok &= (note -> n_id.sys[authlen] == '.');
 146:     }
 147:     if (isok)
 148:         author = note -> n_auth.aname;      /* ok for him */
 149:     else
 150:         author = AUTHORPLACEHOLDER;         /* not local */
 151:     }
 152: #else   !UGLYPATH
 153:     /*
 154:      * the bnews code all assumes that the last component of
 155:      * the Path line is a user name. If we don't append something,
 156:      * that system will see the articles again, since news will
 157:      * disregard it when comparing to see where things have been.
 158:      */
 159:     author = AUTHORPLACEHOLDER;
 160: #endif	UGLYPATH
 161: /*
 162:  *	dump the article
 163:  */
 164: 
 165:     if ((rnews = popen (rnewscmd, "w")) == NULL)    /* open news pipe */
 166:     return (-1);                    /* report failure */
 167: 
 168:     fprintf (rnews, "Relay-Version: Notesfiles %s; site %s\n",
 169:         Version, System);
 170: /*
 171:  *	Here we make a slight deviation from what one would expect.
 172:  *	We use the LOCAL version of the notes/news gateway to pick
 173:  *	the Posting Version line. This is because we are the version
 174:  *	that actually makes the insertion into the news system.
 175:  *
 176:  *	To back it up, the Usenet Standards papr (rfc whatever) says
 177:  *	that the Posting-version "identifies the software responsible
 178:  *	for entering this message into the network".
 179:  *	Whether the "site" field should be the gatewaying site or where
 180:  *	the article originated is a good question.
 181:  *	I chose to make it the notes->news gateway running locally and
 182:  *	the site where the article originated.
 183:  *
 184:  *	The stuff with the #ifdef notdef is to preserve the old code
 185:  *	that just labeled article we gateway with a Posting version
 186:  *	of "Notesfiles" instead of "Notesfiles 1.x".
 187:  */
 188: #ifdef  notdef
 189:     if (!strcmp (System, note -> n_id.sys))     /* local note */
 190: #endif	notdef
 191:     {
 192:     /*
 193: 	 * always consider ourselves the posting version. We are the
 194: 	 * site that posted it to news!  There could be a question
 195: 	 * about articles gated in two places or which site should be
 196: 	 * there.
 197: 	 */
 198:     fprintf (rnews, "Posting-Version: Notesfiles %s; site %s\n",
 199:         Version, note -> n_id.sys);
 200:     }
 201: #ifdef  notdef
 202:     else                        /* remote note */
 203:     fprintf (rnews, "Posting-Version: Notesfiles; site %s.%s\n",
 204:         note -> n_id.sys, DFLTDOMAIN);      /* unknown version */
 205: #endif	notdef
 206:     fprintf (rnews, "From: %s\n", from);        /* formatted */
 207: /*
 208:  *	Sample format that is legal
 209:  *  fprintf (rnews, "Date: 13-Jan-83 12:08 PST\n");
 210:  */
 211:     fprintf (rnews, "Date: %02d-%3s-%02d %02d:%02d %3s\n",
 212:         note -> n_date.w_day,
 213:         mnames[note -> n_date.w_month],
 214:         note -> n_date.w_year - 1900,
 215:         note -> n_date.w_hours,
 216:         note -> n_date.w_mins,
 217:         tzone (&note -> n_date));
 218:     fprintf (rnews, "Newsgroups: %s\n", ngroup);
 219:     fprintf (rnews, "Subject: %s\n", ntitle);
 220:     fprintf (rnews, "Message-ID: <%ld@%s>\n", note -> n_id.uniqid,
 221:         note -> n_id.sys);
 222:     fprintf (rnews, "Path: %s!%s\n", path, author);
 223: 
 224: /*
 225:  *	send out the notesfile specfic headers
 226:  */
 227:     if (note -> n_addr.addr == 0)           /* make sure */
 228:     note -> n_addr.textlen = 0;         /* on empty text */
 229: 
 230:     fprintf (rnews, "%s: #N:%s:%ld:%03o:%ld\n",     /* nf header */
 231:         NFLINE1,                    /* "NF-line1" */
 232:         note -> n_id.sys, note -> n_id.uniqid,
 233:         note -> n_stat, ((long) note -> n_addr.textlen));
 234: 
 235:     fprintf (rnews, "%s: %s!%s    %3s %2d %02d:%02d:00 %4d\n",
 236:         NFLINE2,                    /* "Nf-line2" */
 237:         note -> n_auth.asystem, note -> n_auth.aname,/* author */
 238:         mnames[note -> n_date.w_month],     /* date written */
 239:         note -> n_date.w_day,
 240:         note -> n_date.w_hours,
 241:         note -> n_date.w_mins,
 242:         note -> n_date.w_year);
 243: /*
 244:  *	Optional headers that we don't hassle with right now:
 245:  *	   Organization:	make a table driven routine to grab
 246:  */
 247: 
 248:     putc ('\n', rnews);                 /* separator */
 249:     if (backwards)                  /* include old stuff */
 250:     {
 251:     fprintf (rnews, "#N:%s:%ld:%03o:%ld\n",     /* nf header */
 252:         note -> n_id.sys, note -> n_id.uniqid,
 253:         note -> n_stat, ((long) note -> n_addr.textlen));
 254: 
 255:     fprintf (rnews, "%s!%s    %3s %2d %02d:%02d:00 %4d\n",
 256:         note -> n_auth.asystem, note -> n_auth.aname,/* author */
 257:         mnames[note -> n_date.w_month],     /* date written */
 258:         note -> n_date.w_day,
 259:         note -> n_date.w_hours,
 260:         note -> n_date.w_mins,
 261:         note -> n_date.w_year);
 262:     }
 263:     putc ('\n', rnews);                 /* separator */
 264:     pageout (io, &note -> n_addr, rnews);       /* dump text */
 265:     fprintf (rnews, "\n");              /* ensure newline */
 266:     pclose (rnews);                 /* close it */
 267:     sleep (SLEEPTIME);                  /* wait a while */
 268:     return (0);
 269: }
 270: 
 271: /*
 272:  *	newsresp
 273:  *
 274:  *	Dump a response to the news system.
 275:  */
 276: 
 277: newsresp (io, note, notenum, rsprec, roffset, respnum, ngroup, backwards)
 278: struct io_f *io;
 279: struct note_f  *note;
 280: struct resp_f  *rsprec;
 281: char   *ngroup;
 282: {
 283:     char    cmdline[CMDLEN];                /* leggo brand */
 284:     char    line[TITLEN + 50];              /* scratch */
 285:     FILE * rnews;
 286:     int     i;
 287:     char   *p,
 288:            *q;
 289:     char    ntitle[TITLEN + 20];            /* formatted title */
 290:     char    from[SYSSZ + NAMESZ + 3];           /* formatted author */
 291:     char    path[BUFSIZ];               /* path to author */
 292:     char   *author;                 /* for Path: */
 293:     long    uniquenum;
 294: 
 295: /*
 296:  *	pre-format a few fields like titles, author information,
 297:  *	paths to authors, and that sort of gunk.
 298:  */
 299: 
 300:     ntitle[0] = '\0';                   /* empty string */
 301:     if (strncmp (note -> ntitle, "Re:", 3) &&       /* is it already */
 302:         strncmp (note -> ntitle, "RE:", 3) &&   /* a response-like */
 303:         strncmp (note -> ntitle, "re:", 3))     /* title? */
 304:     {                           /* flag it as a */
 305:     strcat (ntitle, "Re: ");            /* response */
 306:     }
 307:     strcat (ntitle, note -> ntitle);            /* include title */
 308:     if (backwards)
 309:     {
 310:     strcat (ntitle, " ");
 311:     strcat (ntitle, NFSUFFIX);          /* include old */
 312:     }
 313: 
 314:     /*
 315:      * From:
 316:      *	author information
 317:      */
 318:     sprintf (from, "%s@%s",             /* author */
 319:         rsprec -> r_auth[roffset].aname, rsprec -> r_auth[roffset].asystem);
 320: #ifdef  notdef
 321:     /*
 322:      * decided it was better to NOT append a domain at this point
 323:      */
 324:     if (index (rsprec -> r_auth[roffset].asystem, '.') != (char *) NULL)
 325:     {                           /* already domained */
 326:     sprintf (from, "%s@%s",
 327:         rsprec -> r_auth[roffset].aname, rsprec -> r_auth[roffset].asystem);
 328:     }
 329:     else
 330:     {
 331:     sprintf (from, "%s@%s.%s",
 332:         rsprec -> r_auth[roffset].aname, rsprec -> r_auth[roffset].asystem,
 333:         DFLTDOMAIN);
 334:     }
 335: #endif	notdef
 336:     /*
 337:      * Path:
 338:      *	Where the article has been
 339:      */
 340:     if (!strcmp (System, rsprec -> r_id[roffset].sys))  /* local */
 341:     {
 342:     sprintf (path, "%s", rsprec -> r_id[roffset].sys);
 343:     }
 344:     else
 345:     {
 346:     if (!strcmp (rsprec -> r_id[roffset].sys, rsprec -> r_from[roffset]))
 347:     {                       /* one hop */
 348:         sprintf (path, "%s!%s",
 349:             System,
 350:             rsprec -> r_id[roffset].sys);
 351:     }
 352:     else
 353:     {
 354:         sprintf (path, "%s!%s!%s",          /* several hops */
 355:             System,
 356:             rsprec -> r_from[roffset],
 357:             rsprec -> r_id[roffset].sys);
 358:     }
 359:     }
 360: #ifdef  UGLYPATH                    /* usually so */
 361:     /*
 362:      * See if we can use the author's name instead of
 363:      * AUTHORPLACEHOLDER.  Check this by comparin unique id's
 364:      * and the author's system.
 365:      *
 366:      * see similar code above in newsnote() for explanation of the
 367:      * gyrations here.
 368:      */
 369:     {
 370:     int     idlen,
 371:             authlen;
 372:     int     isok;
 373:     int     minlen;
 374: 
 375:     idlen = strlen (rsprec -> r_id[roffset].sys);
 376:     authlen = strlen (rsprec -> r_auth[roffset].asystem);
 377:     minlen = idlen < authlen ? idlen : authlen;
 378:     isok = (strncmp (rsprec -> r_id[roffset].sys, rsprec -> r_auth[roffset].asystem, minlen) == 0);
 379:     if (isok && idlen < authlen)            /* id is short */
 380:     {
 381:         isok &= (rsprec -> r_auth[roffset].asystem[idlen] == '.');
 382:     }
 383:     else
 384:     {
 385:         if (isok && authlen < idlen)        /* author syste is short */
 386:         isok &= (rsprec -> r_id[roffset].sys[authlen] == '.');
 387:     }
 388:     if (isok)
 389:         author = rsprec -> r_auth[roffset].aname;
 390:     else
 391:         author = AUTHORPLACEHOLDER;
 392:     }
 393: #else   !UGLYPATH
 394:     /*
 395:      * since bnews programs all assume the last component of the
 396:      * path line is a user name, we have to put something there
 397:      * to keep them from disregarding the system name when trying
 398:      * to see where the article has been.
 399:      */
 400:     author = AUTHORPLACEHOLDER;
 401: #endif	UGLYPATH
 402: 
 403: /*
 404:  *	Time to send the article to the news system
 405:  */
 406: 
 407:     if ((rnews = popen (rnewscmd, "w")) == NULL)    /* will it work */
 408:     return (-1);                    /* report failure */
 409: 
 410:     fprintf (rnews, "Relay-Version: Notesfiles %s; site %s\n",
 411:         Version, System);
 412: #ifdef  notdef
 413:     if (!strcmp (System, rsprec -> r_id[roffset].sys))  /* local note */
 414: #endif	notdef
 415:     {
 416:     /*
 417: 	 * always consider ourselves the posting version. We are the
 418: 	 * site that posted it to news!  There could be a question
 419: 	 * about articles gated in two places or which site should be
 420: 	 * there.
 421: 	 *
 422: 	 * See comments around similar lines within the newsnote()
 423: 	 * routine above
 424: 	 */
 425:     fprintf (rnews, "Posting-Version: Notesfiles %s; site %s\n",
 426:         Version, rsprec -> r_id[roffset].sys);
 427:     }
 428: #ifdef  notdef
 429:     else                        /* remote note */
 430:     fprintf (rnews, "Posting-Version: Notesfiles; site %s.%s\n",
 431:         rsprec -> r_id[roffset].sys, DFLTDOMAIN);/* unknown version */
 432: #endif	notdef
 433:     fprintf (rnews, "From: %s\n", from);        /* formatted */
 434: /*
 435:  *	Sample format that is legal
 436:  *  fprintf (rnews, "Date: 13-Jan-83 12:08 PST\n");
 437:  */
 438:     fprintf (rnews, "Date: %02d-%3s-%02d %02d:%02d %3s\n",
 439:         rsprec -> r_when[roffset].w_day,
 440:         mnames[rsprec -> r_when[roffset].w_month],
 441:         rsprec -> r_when[roffset].w_year - 1900,
 442:         rsprec -> r_when[roffset].w_hours,
 443:         rsprec -> r_when[roffset].w_mins,
 444:         tzone (&rsprec -> r_when[roffset]));
 445:     fprintf (rnews, "Newsgroups: %s\n", ngroup);
 446:     fprintf (rnews, "Subject: %s\n", ntitle);
 447:     fprintf (rnews, "Message-ID: <%ld@%s>\n",
 448:         rsprec -> r_id[roffset].uniqid, rsprec -> r_id[roffset].sys);
 449:     fprintf (rnews, "Path: %s!%s\n", path, author);
 450: 
 451: /*
 452:  *	send out the notesfile specfic headers
 453:  */
 454:     fprintf (rnews, "%s: #R:%s:%ld:%s:%ld:%03o:%ld\n",
 455:         NFLINE1,                    /* Nf-ID */
 456:         note -> n_id.sys, note -> n_id.uniqid,
 457:         rsprec -> r_id[roffset].sys,
 458:         rsprec -> r_id[roffset].uniqid,
 459:         rsprec -> r_stat[roffset],
 460:         ((long) rsprec -> r_addr[roffset].textlen));/* force it long */
 461: 
 462: 
 463:     fprintf (rnews, "%s: %s!%s    %3s %2d %02d:%02d:00 %4d\n",
 464:         NFLINE2,                    /* NF-From */
 465:         rsprec -> r_auth[roffset].asystem, rsprec -> r_auth[roffset].aname,
 466:         mnames[rsprec -> r_when[roffset].w_month],  /* date written */
 467:         rsprec -> r_when[roffset].w_day,
 468:         rsprec -> r_when[roffset].w_hours,
 469:         rsprec -> r_when[roffset].w_mins,
 470:         rsprec -> r_when[roffset].w_year);
 471:     /*
 472:      * we used to negate and multiply by 100 news ids. this was tied
 473:      * to the fact that news and notes id's conflicted.
 474:      * the new code to handle the arbitrary string message ids uses
 475:      * negative numbers to store the length of the original id.
 476:      * we change the following if from <0 to <-100 because
 477:      * we know lengths are likely < 100 and that the old flipped
 478:      * format is definitely <= -100.
 479:      */
 480:     if ((uniquenum = note -> n_id.uniqid) <= -100)  /* re-invert news */
 481:     uniquenum /= (-100);                /* back to normal */
 482:     if (uniquenum >= 0)                 /* normal form */
 483:     {
 484:     fprintf (rnews, "References: <%ld@%s>\n",
 485:         uniquenum, note -> n_id.sys);
 486:     }
 487:     else
 488:     {                           /* all in n_id.sys */
 489:     /*
 490: 	 * print it if we have the entire id.  if we only have a part,
 491: 	 * punt and that's too bad.
 492: 	 */
 493:     if (-uniquenum == strlen (note -> n_id.sys))    /* have it all */
 494:         fprintf (rnews, "References: %s\n", note -> n_id.sys);
 495:     }
 496: 
 497:     putc ('\n', rnews);                 /* separator */
 498:     if (backwards)                  /* old stuff included */
 499:     {
 500:     fprintf (rnews, "#R:%s:%ld:%s:%ld:%03o:%ld\n",
 501:         note -> n_id.sys, note -> n_id.uniqid,
 502:         rsprec -> r_id[roffset].sys,
 503:         rsprec -> r_id[roffset].uniqid,
 504:         rsprec -> r_stat[roffset],
 505:         ((long) rsprec -> r_addr[roffset].textlen));/* force it long */
 506: 
 507:     fprintf (rnews, "%s!%s    %3s %2d %02d:%02d:00 %4d\n",
 508:         rsprec -> r_auth[roffset].asystem, rsprec -> r_auth[roffset].aname,
 509:         mnames[rsprec -> r_when[roffset].w_month],/* date written */
 510:         rsprec -> r_when[roffset].w_day,
 511:         rsprec -> r_when[roffset].w_hours,
 512:         rsprec -> r_when[roffset].w_mins,
 513:         rsprec -> r_when[roffset].w_year);
 514:     }
 515:     putc ('\n', rnews);                 /* separator */
 516:     pageout (io, &rsprec -> r_addr[roffset], rnews);    /* dump text */
 517:     fprintf (rnews, "\n");              /* ensure a newline */
 518:     pclose (rnews);                 /* close it */
 519:     sleep (SLEEPTIME);                  /* and wait */
 520:     return (0);
 521: }
 522: 
 523: /*
 524:  *	A quick and cheap way to calculate a timezone.
 525:  *
 526:  *	This routine makes the assumption that a notesfile site
 527:  *	we gateway for is in the same timezone as our site.
 528:  *
 529:  */
 530: 
 531: char   *tzone (when)
 532: struct when_f   when;                   /* unused */
 533: {
 534: #ifdef  BSD42
 535: #include        <sys/time.h>            /* it moved! */
 536: #else
 537: #include        <time.h>
 538: #endif	BSD42
 539: #include    <sys/types.h>               /* for ftime */
 540: 
 541:     struct tm  *ltime;
 542:     extern struct tm   *localtime ();
 543:     long    timenow;
 544: 
 545: #ifdef  USG
 546:     struct tm  *bp;
 547:     extern char *tzname[];
 548: 
 549:     time (&timenow);
 550:     ltime = localtime (&timenow);
 551:     return (tzname[ltime -> tm_isdst]);
 552: #else
 553: /*
 554:  *	for systems that still have the "timezone" function from V7
 555:  */
 556: #include    <sys/timeb.h>               /* for ftime */
 557:     struct timeb    rawtime;
 558:     extern char *timezone ();               /* please lint */
 559: 
 560:     ftime (&rawtime);                   /* get information */
 561:     time (&timenow);                    /* get now */
 562:     ltime = localtime (&timenow);           /* see if DST */
 563:     return (timezone ((int) rawtime.timezone, ltime -> tm_isdst));
 564: #endif
 565: }

Defined functions

newsnote defined in line 39; used 1 times
newsresp defined in line 277; used 1 times
tzone defined in line 531; used 3 times

Defined variables

RCSid defined in line 6; never used
Version defined in line 37; used 4 times
Last modified: 1985-10-31
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3795
Valid CSS Valid XHTML 1.0 Strict