1: /*
   2:  * This software is Copyright (c) 1985 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:  *
  16:  * funcs2 - functions used by both inews and readnews.
  17:  */
  18: 
  19: #ifdef SCCSID
  20: static char *SccsId = "@(#)funcs2.c	1.13	1/17/86";
  21: #endif /* SCCSID */
  22: 
  23: #include "params.h"
  24: 
  25: #ifdef SunIII
  26: #ifndef INTERNET
  27: #define INTERNET
  28: #endif /* !INTERNET */
  29: #endif /* SunIII */
  30: 
  31: /*LINTLIBRARY*/
  32: 
  33: /*
  34:  * Get user name and home directory.
  35:  */
  36: getuser()
  37: {
  38:     static int flag = TRUE;
  39:     register struct passwd *p;
  40: 
  41:     if (flag) {
  42:         if ((p = getpwuid(uid)) == NULL)
  43:             xerror("Cannot get user's name");
  44:         if ( username == NULL || username[0] == 0)
  45:             username = AllocCpy(p->pw_name);
  46:         userhome = AllocCpy(p->pw_dir);
  47:         flag = FALSE;
  48:     }
  49:     (void) strcpy(header.path, username);
  50: }
  51: 
  52: static  FILE    *sysfile;
  53: 
  54: char *fldget();
  55: 
  56: static int sfline;
  57: 
  58: /*
  59:  * Open SUBFILE.
  60:  */
  61: s_openr()
  62: {
  63:     sysfile = xfopen(SUBFILE, "r");
  64:     sfline = 0;
  65: }
  66: 
  67: /*
  68:  * Read SUBFILE.
  69:  */
  70: s_read(sp)
  71: register struct srec *sp;
  72: {
  73:     register char *p;
  74:     register int  c;
  75:     char *e;
  76:     int chop_spaces = 0;
  77: again:
  78:     p = bfr;
  79:         /*
  80:          * Read  the  SUBFILE  (/usr/lib/news/sys)  from   the   current
  81: 	 * position  to  the  first  unescaped newline.  If a newline is
  82: 	 * escaped with a backslash (\) continue reading but throw  away
  83: 	 * the backslash and newline; read the next line skipping spaces
  84: 	 * and tabs until the first non-space/tab character, then  start
  85: 	 * looking   for   a   newline   again.   Skipping  the  leading
  86: 	 * spaces/tabs after a escaped newline  keeps  the  news  groups
  87: 	 * together.  If  a  line  begins  with a newline, just skip it.
  88: 	 */
  89:     for (e=p+LBUFLEN; p < e && (c=getc(sysfile)) != EOF; p++) {
  90:         *p = c;
  91:         if (c == '\n') {
  92:             sfline++;
  93:             if (p == bfr || p[-1] != '\\') {
  94:                 p[1] = '\0';
  95:                 break;
  96:             } else {
  97:                 chop_spaces++;
  98:                 p -= 2;
  99:             }
 100:         } else if (chop_spaces) {
 101:             if (c == '\t' || c == ' ')
 102:                 p--;
 103:             else
 104:                 chop_spaces = 0;
 105:         }
 106:     }
 107:     if (c == EOF) {
 108:         return FALSE;
 109:     }
 110:     p = bfr;
 111:     if (*p == '\n')
 112:         goto again;      /* skip newlines */
 113:     if (!nstrip(p))
 114:         xerror("SUBFILE (%s) line %d too long.", SUBFILE, sfline);
 115:     if (*p == '#')
 116:         goto again;
 117:     sp->s_xmit[0] = '\0';
 118:     sp->s_flags[0] = '\0';
 119:     sp->s_nosend = (char *)0;
 120: 
 121:     p = fldget(sp->s_name, p);
 122:     if (*p++ == '\0')
 123:         xerror("Bad SUBFILE (%s) line %d.", SUBFILE, sfline);
 124: /*
 125:  * A sys file line reading "ME" means the name of the local system.
 126:  */
 127:     if (strcmp(sp->s_name, "ME") == 0)
 128:         (void) strcpy(sp->s_name, FULLSYSNAME);
 129:     e = index(sp->s_name, '/');
 130:     if (e) {
 131:         *e++ = '\0';
 132:         sp->s_nosend = e;
 133:     }
 134:     p = fldget(sp->s_nbuf, p);
 135:     lcase(sp->s_nbuf);
 136:     if (*p++ == '\0')
 137:         return TRUE;
 138: 
 139:     p = fldget(sp->s_flags, p);
 140:     if (*p++ == '\0')
 141:         return TRUE;
 142: 
 143:     (void) fldget(sp->s_xmit, p);
 144:     return TRUE;
 145: }
 146: 
 147: char *
 148: fldget(q, p)
 149: register char *q, *p;
 150: {
 151:     while (*p && *p != ':') {
 152:         if (*p == '\\' && p[1]==':')
 153:             p++;
 154:         *q++ = *p++;
 155:     }
 156:     *q = '\0';
 157:     return p;
 158: }
 159: 
 160: /*
 161:  * Find the SUBFILE record for a system.
 162:  */
 163: s_find(sp, system)
 164: register struct srec *sp;
 165: char *system;
 166: {
 167:     s_openr();
 168:     while (s_read(sp))
 169:         if (strncmp(system, sp->s_name, SNLN) == 0) {
 170:             s_close();
 171:             return TRUE;
 172:         }
 173:     s_close();
 174:     return FALSE;
 175: }
 176: 
 177: /*
 178:  * Close sysfile.
 179:  */
 180: s_close()
 181: {
 182:     (void) fclose(sysfile);
 183: }
 184: 
 185: time_t
 186: cgtdate(datestr)
 187: char *datestr;
 188: {
 189:     char    junk[40],month[40],day[30],tod[60],year[50];
 190:     static time_t lasttime;
 191:     static char lastdatestr[BUFLEN] = "";
 192: 
 193:     if ( lastdatestr[0] && strcmp(datestr, lastdatestr) == 0)
 194:         return lasttime;
 195:     lasttime = getdate(datestr, (struct timeb *)NULL);
 196:     if (lasttime < 0 &&
 197:       sscanf(datestr, "%s %s %s %s %s", junk, month, day, tod, year) == 5) {
 198:         (void) sprintf(bfr, "%s %s, %s %s", month, day, year, tod);
 199:         lasttime = getdate(bfr, (struct timeb *)NULL);
 200:     }
 201:     strncpy(lastdatestr, datestr, BUFLEN);
 202:     return lasttime;
 203: }
 204: 
 205: lcase(s)
 206: register char *s;
 207: {
 208:     register char *ptr;
 209: 
 210:     for (ptr = s; *ptr; ptr++)
 211:         if (isupper(*ptr))
 212:             *ptr = tolower(*ptr);
 213: }
 214: 
 215: /*
 216:  * Return a compact representation of the person who posted the given
 217:  * message.  A sender or internet name will be used, otherwise
 218:  * the last part of the path is used preceded by an optional ".."
 219:  */
 220: char *
 221: tailpath(hp)
 222: struct hbuf *hp;
 223: {
 224:     char *p, *r;
 225:     static char resultbuf[BUFLEN];
 226:     char pathbuf[PATHLEN];
 227:     char *malloc();
 228: 
 229:     /*
 230: 	 * This only happens for articles posted by old news software
 231: 	 * in non-internet format.
 232: 	 */
 233:     resultbuf[0] = '\0';
 234:     (void) strncpy(pathbuf, hp->path, PATHLEN);
 235:     p = index(pathbuf, ' ');
 236:     if (p)
 237:         *p = '\0';  /* Chop off trailing " (name)" */
 238:     r = rindex(pathbuf, '!');
 239:     if (r == 0) {
 240:         r = pathbuf;
 241:     } else {
 242:         while (r > pathbuf && *--r != '!')
 243:             ;
 244:         if (r > pathbuf) {
 245:             r++;
 246:             (void) strcpy(resultbuf, "..!");
 247:         }
 248:     }
 249:     (void) strcat(resultbuf, r);
 250:     return resultbuf;
 251: }
 252: 
 253: /*
 254:  * arpadate is like ctime(3) except that the time is returned in
 255:  * an acceptable ARPANET time format instead of ctime format.
 256:  */
 257: char *
 258: arpadate(longtime)
 259: time_t *longtime;
 260: {
 261:     register char *p, *q, *ud;
 262:     register int i;
 263:     static char b[40];
 264:     extern struct tm *gmtime();
 265:     extern char *asctime();
 266: 
 267:     /*  Get current time. This will be used resolve the timezone. */
 268:     ud = asctime(gmtime(longtime));
 269: 
 270:     /*  Crack the UNIX date line in a singularly unoriginal way. */
 271:     q = b;
 272: 
 273: #ifdef notdef
 274: /* until every site installs the fix to getdate.y, the day
 275:    of the week can cause time warps */
 276:     p = &ud[0];     /* Mon */
 277:     *q++ = *p++;
 278:     *q++ = *p++;
 279:     *q++ = *p++;
 280:     *q++ = ','; *q++ = ' ';
 281: #endif
 282: 
 283:     p = &ud[8];     /* 16 */
 284:     if (*p == ' ')
 285:         p++;
 286:     else
 287:         *q++ = *p++;
 288:     *q++ = *p++; *q++ = ' ';
 289: 
 290:     p = &ud[4];     /* Sep */
 291:     *q++ = *p++; *q++ = *p++; *q++ = *p++; *q++ = ' ';
 292: 
 293:     p = &ud[22];        /* 1979 */
 294:     *q++ = *p++; *q++ = *p++; *q++ = ' ';
 295: 
 296:     p = &ud[11];        /* 01:03:52 */
 297:     for (i = 8; i > 0; i--)
 298:         *q++ = *p++;
 299: 
 300:     *q++ = ' ';
 301:     *q++ = 'G';     /* GMT */
 302:     *q++ = 'M';
 303:     *q++ = 'T';
 304:     *q = '\0';
 305: 
 306:     return b;
 307: }
 308: 
 309: char *
 310: replyname(hptr)
 311: struct hbuf *hptr;
 312: {
 313:     register char *ptr;
 314:     static char tbuf[PATHLEN];
 315: 
 316:     ptr = hptr->path;
 317:     if (prefix(ptr, FULLSYSNAME) &&
 318:         index(NETCHRS, ptr[strlen(FULLSYSNAME)]))
 319:         ptr = index(ptr, '!') + 1;
 320: #ifdef INTERNET
 321:     if (hptr->from[0])
 322:         ptr = hptr->from;
 323:     if (hptr->replyto[0])
 324:         ptr = hptr->replyto;
 325: #endif
 326:     (void) strcpy(tbuf, ptr);
 327:     ptr = index(tbuf, '(');
 328:     if (ptr) {
 329:         while (ptr[-1] == ' ')
 330:             ptr--;
 331:         *ptr = 0;
 332:     }
 333: #ifdef  SunIII
 334:     if (ptr = rindex(tbuf, '.')) {
 335:         if (prefix(++ptr, "OZ")) {
 336:             /* some people only allow it in lower case ... */
 337:             strcpy(ptr, "oz");
 338:             return tbuf;
 339:         }
 340:         if (prefix(ptr, "UUCP") || prefix(ptr, "ARPA") ||
 341:             prefix(ptr, "DEC") || prefix(ptr, "CSNET")) {
 342:             strcat(tbuf, "@munnari.oz");    /* via sun to munnari */
 343:             return tbuf;
 344:         }
 345:     }
 346:     /*
 347: 	 * must(?) have come from a uucp site, lets look see if path passes
 348: 	 * through munnari, and if so delete the fake uucp path after that.
 349: 	 */
 350:     for (ptr = tbuf ;; ptr++) {
 351:         if (prefix(ptr, "munnari!")) {
 352:             strcpy(tbuf, ptr+8);
 353:             break;
 354:         }
 355:         ptr = index(ptr, '!');
 356:         if (ptr == (char *)0)
 357:             break;
 358:     }
 359:     /*
 360: 	 * now, just send the address we have left to munnari, and
 361: 	 * hope that something sensible will be done with it there.
 362: 	 * (This works in more cases than you'd think ...)
 363: 	 */
 364:     strcat(tbuf, "@munnari.oz");
 365: #else /* !SunIII */
 366: #ifndef INTERNET
 367:     /*
 368: 	 * Play games stripping off multiple berknet
 369: 	 * addresses (a!b!c:d:e => a!b!d:e) here.
 370: 	 */
 371:     for (ptr=tbuf; *ptr; ptr++) {
 372:         register char *ptr2;
 373: 
 374:         if (index(NETCHRS, *ptr) && *ptr == ':' &&
 375:             (ptr2=index(ptr+1, ':')))
 376:             (void) strcpy(ptr, ptr2);
 377:     }
 378: #endif /* !INTERNET */
 379: #endif /* SunIII */
 380:     return tbuf;
 381: }
 382: 
 383: #ifdef DBM
 384: typedef struct {
 385:     char *dptr;
 386:     int dsize;
 387: } datum;
 388: #endif /* DBM */
 389: 
 390: /*
 391:  * Given an article ID, find the line in the history file that mentions it.
 392:  * Return the text of the line, or NULL if not found.  A pointer to a
 393:  * static area is returned.
 394:  */
 395: char *
 396: findhist(artid)
 397: char *artid;
 398: {
 399:     static char lbuf[256];
 400:     char oidbuf[BUFSIZ];
 401:     FILE *hfp;
 402:     register char *p;
 403: #ifdef DBM
 404:     datum lhs, rhs;
 405:     datum fetch();
 406:     long fpos; /* We have to use an explicit variable to insure alignment */
 407: #else /* !DBM */
 408:     char *histfile();
 409: #endif /* !DBM */
 410: 
 411:     /* Try to understand old artid's as well.  Assume .UUCP domain. */
 412:     if (artid[0] != '<') {
 413:         p = index(artid, '.');
 414:         if (p)
 415:             *p++ = '\0';
 416:         (void) sprintf(oidbuf, "<%s@%s.UUCP>", p, artid);
 417:         if (p)
 418:             *--p = '.';
 419:     } else
 420:         (void) strcpy(oidbuf, artid);
 421:     lcase(oidbuf);
 422: #ifdef DBM
 423:     initdbm(ARTFILE);
 424:     lhs.dptr = oidbuf;
 425:     lhs.dsize = strlen(lhs.dptr) + 1;
 426:     rhs = fetch(lhs);
 427:     if (rhs.dptr == NULL)
 428:         return NULL;
 429:     hfp = xfopen(ARTFILE, "r");
 430:     /* The bcopy is NECESSARY to insure alignment on some machines */
 431:     bcopy(rhs.dptr, (char *)&fpos, sizeof (long));
 432:     fseek(hfp, fpos, 0);
 433: #else /* !DBM */
 434:     hfp = xfopen(histfile(oidbuf), "r");
 435: #endif /* !DBM */
 436:     while (fgets(lbuf, BUFLEN, hfp) != NULL) {
 437:         p = index(lbuf, '\t');
 438:         if (p == NULL)
 439:             p = index(lbuf, '\n');
 440:         *p = 0;
 441:         if (strcmp(lbuf, artid) == 0 || strcmp(lbuf, oidbuf) == 0) {
 442:             (void) fclose(hfp);
 443:             *p = '\t';
 444:             *(lbuf + strlen(lbuf) - 1) = 0; /* zap the \n */
 445:             return lbuf;
 446:         }
 447: #ifdef DBM
 448:         break;
 449: #endif /* DBM */
 450:     }
 451:     (void) fclose(hfp);
 452:     return NULL;
 453: }
 454: 
 455: /*
 456:  * Hunt up the article "artid", and return the newsgroup/artnum
 457:  * where it can be found.
 458:  */
 459: char *
 460: findfname(artid)
 461: char *artid;
 462: {
 463:     char *line, *p, *q;
 464:     char *findhist();
 465:     static char fname[BUFLEN];
 466: 
 467:     line = findhist(artid);
 468:     if (line) {
 469:         /* Look for it stored as an article, where it should be */
 470:         p = index(line, '\t');
 471:         p = index(p+1, '\t');
 472:         p++;
 473:         if (*p) {
 474:             q = index(p, ' ');
 475:             if (q)
 476:                 *q = 0;
 477:             (void) strcpy(fname, p);
 478:             return fname;
 479:         }
 480:     }
 481:     return NULL;
 482: }
 483: 
 484: /*
 485:  * Hunt up the article "artid", fopen it for read, and return a
 486:  * file descriptor to it.  We look everywhere we can think of.
 487:  */
 488: FILE *
 489: hfopen(artid)
 490: char *artid;
 491: {
 492:     char *p;
 493:     char *findhist();
 494:     FILE *rv = NULL;
 495:     char fname[BUFLEN];
 496: 
 497:     p = findfname(artid);
 498:     if (p) {
 499:         (void) strcpy(fname, dirname(p));
 500:         rv = fopen(fname, "r"); /* NOT xfopen! */
 501:         if (rv == NULL)
 502:             xerror("Cannot hfopen article %s", artid);
 503:     }
 504:     return rv;
 505: }
 506: 
 507: #ifdef DBM
 508: /*
 509: ** Avoid problems of multiple dbminit calls.
 510: */
 511: initdbm(name)
 512: char *name;
 513: {
 514:     static int called = 0;
 515: 
 516:     if (called != 0)
 517:         return;
 518:     called = 1;
 519:     (void) dbminit(name);
 520: }
 521: #endif
 522: 
 523: #ifndef BSD4_2
 524: /*
 525:  * move n bytes from a to b
 526:  */
 527: bcopy(a, b, n)
 528: register char *a, *b;
 529: register n;
 530: {
 531:     while (--n >= 0)
 532:         *b++ = *a++;
 533: }
 534: #endif
 535: 
 536: #if !defined(BSD4_2) && !defined(BSD4_1C)
 537: rename(from,to)
 538: register char *from, *to;
 539: {
 540:     (void) unlink(to);
 541:     if (link(from, to) < 0)
 542:         return -1;
 543: 
 544:     (void) unlink(from);
 545:     return 0;
 546: }
 547: #endif /* !BSD4_2 && ! BSD4_1C */
 548: 
 549: #ifndef DBM
 550: /*
 551: ** Generate the appropriate history subfile name
 552: */
 553: char *
 554: histfile(hline)
 555: char *hline;
 556: {
 557:     char *p;
 558:     char chr;   /* least significant digit of article number */
 559:     static char subfile[BUFLEN];
 560: 
 561:     p = strchr(hline, '@');
 562:     if (p != NULL && p > hline)
 563:         chr = *(p - 1);
 564:     else
 565:         chr = '0';
 566:     if (!isdigit(chr))
 567:         chr = '0';
 568:     sprintf(subfile, "%s.d/%c", ARTFILE, chr);
 569:     if (access(subfile, 04) < 0)
 570:         return(ARTFILE);
 571:     return(subfile);
 572: }
 573: #endif /* !DBM */

Defined functions

bcopy defined in line 527; used 1 times
findfname defined in line 459; used 1 times
fldget defined in line 147; used 5 times
getuser defined in line 36; never used
hfopen defined in line 488; used 2 times
histfile defined in line 553; used 7 times
initdbm defined in line 511; used 4 times
lcase defined in line 205; used 2 times
rename defined in line 537; never used
s_close defined in line 180; used 3 times
s_find defined in line 163; used 2 times
s_openr defined in line 61; used 4 times
s_read defined in line 70; used 4 times

Defined variables

SccsId defined in line 20; never used
sfline defined in line 56; used 4 times

Defined macros

INTERNET defined in line 27; used 3 times
Last modified: 1986-01-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1200
Valid CSS Valid XHTML 1.0 Strict