|
|
1.1 ! root 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.22 10/15/87"; ! 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: STRCMP(username, "Unknown") == 0) ! 46: username = AllocCpy(p->pw_name); ! 47: userhome = AllocCpy(p->pw_dir); ! 48: flag = FALSE; ! 49: } ! 50: (void) strcpy(header.path, username); ! 51: } ! 52: ! 53: /* no sys file on clients via nntp */ ! 54: #ifndef SERVER ! 55: static FILE *sysfile; ! 56: ! 57: char *fldget(); ! 58: ! 59: static int sfline; ! 60: ! 61: /* ! 62: * Open SUBFILE. ! 63: */ ! 64: s_openr() ! 65: { ! 66: sysfile = xfopen(SUBFILE, "r"); ! 67: sfline = 0; ! 68: } ! 69: ! 70: /* ! 71: * Read SUBFILE. ! 72: */ ! 73: s_read(sp) ! 74: register struct srec *sp; ! 75: { ! 76: register char *p; ! 77: register int c; ! 78: char *e; ! 79: int chop_spaces = 0; ! 80: again: ! 81: p = bfr; ! 82: /* ! 83: * Read the SUBFILE (/usr/lib/news/sys) from the current ! 84: * position to the first unescaped newline. If a newline is ! 85: * escaped with a backslash (\) continue reading but throw away ! 86: * the backslash and newline; read the next line skipping spaces ! 87: * and tabs until the first non-space/tab character, then start ! 88: * looking for a newline again. Skipping the leading ! 89: * spaces/tabs after a escaped newline keeps the news groups ! 90: * together. If a line begins with a newline, just skip it. ! 91: */ ! 92: for (e=p+LBUFLEN; p < e && (c=getc(sysfile)) != EOF; p++) { ! 93: *p = c; ! 94: if (c == '\n') { ! 95: sfline++; ! 96: if (p == bfr || p[-1] != '\\') { ! 97: p[1] = '\0'; ! 98: break; ! 99: } else { ! 100: chop_spaces++; ! 101: p -= 2; ! 102: } ! 103: } else if (chop_spaces) { ! 104: if (c == '\t' || c == ' ') ! 105: p--; ! 106: else ! 107: chop_spaces = 0; ! 108: } ! 109: } ! 110: if (c == EOF) { ! 111: return FALSE; ! 112: } ! 113: p = bfr; ! 114: while (*p == ' ' || *p == '\t') /* skip leading white space */ ! 115: p++; ! 116: if (*p == '\n') ! 117: goto again; /* skip newlines */ ! 118: if (!nstrip(p)) ! 119: xerror("SUBFILE (%s) line %d too long.", SUBFILE, sfline); ! 120: if (*p == '#') ! 121: goto again; ! 122: sp->s_xmit[0] = '\0'; ! 123: sp->s_flags[0] = '\0'; ! 124: sp->s_nosend = (char *)0; ! 125: ! 126: p = fldget(sp->s_name, p); ! 127: if (*p++ == '\0') ! 128: xerror("Bad SUBFILE (%s) line %d.", SUBFILE, sfline); ! 129: /* ! 130: * A sys file line reading "ME" means the name of the local system. ! 131: */ ! 132: if (STRCMP(sp->s_name, "ME") == 0) ! 133: (void) strcpy(sp->s_name, LOCALPATHSYSNAME); ! 134: e = index(sp->s_name, '/'); ! 135: if (e) { ! 136: *e++ = '\0'; ! 137: sp->s_nosend = e; ! 138: } ! 139: p = fldget(sp->s_nbuf, p); ! 140: lcase(sp->s_nbuf); ! 141: if (*p++ == '\0') ! 142: return TRUE; ! 143: ! 144: p = fldget(sp->s_flags, p); ! 145: if (*p++ == '\0') ! 146: return TRUE; ! 147: ! 148: (void) fldget(sp->s_xmit, p); ! 149: return TRUE; ! 150: } ! 151: ! 152: char * ! 153: fldget(q, p) ! 154: register char *q, *p; ! 155: { ! 156: while (*p && *p != ':') { ! 157: if (*p == '\\' && p[1]==':') ! 158: p++; ! 159: *q++ = *p++; ! 160: } ! 161: *q = '\0'; ! 162: return p; ! 163: } ! 164: ! 165: /* ! 166: * Find the SUBFILE record for a system. ! 167: */ ! 168: s_find(sp, system) ! 169: register struct srec *sp; ! 170: char *system; ! 171: { ! 172: s_openr(); ! 173: while (s_read(sp)) ! 174: if (STRNCMP(system, sp->s_name, SNLN) == 0) { ! 175: s_close(); ! 176: return TRUE; ! 177: } ! 178: s_close(); ! 179: return FALSE; ! 180: } ! 181: ! 182: /* ! 183: * Close sysfile. ! 184: */ ! 185: s_close() ! 186: { ! 187: (void) fclose(sysfile); ! 188: } ! 189: #endif /* SERVER */ ! 190: ! 191: extern struct timeb Now; ! 192: ! 193: time_t ! 194: cgtdate(datestr) ! 195: char *datestr; ! 196: { ! 197: char junk[40],month[40],day[30],tod[60],year[50]; ! 198: static time_t lasttime; ! 199: static char lastdatestr[BUFLEN] = ""; ! 200: ! 201: if ( lastdatestr[0] && STRCMP(datestr, lastdatestr) == 0) ! 202: return lasttime; ! 203: lasttime = getdate(datestr, &Now); ! 204: if (lasttime < 0 && ! 205: sscanf(datestr, "%s %s %s %s %s", junk, month, day, tod, year) == 5) { ! 206: (void) sprintf(bfr, "%s %s, %s %s", month, day, year, tod); ! 207: lasttime = getdate(bfr, &Now); ! 208: if (lasttime < 0) { ! 209: logerr("Unparsable date \"%s\"", datestr); ! 210: datestr = "now"; /* better than nothing */ ! 211: lasttime = Now.time; ! 212: } ! 213: } ! 214: strncpy(lastdatestr, datestr, BUFLEN); ! 215: return lasttime; ! 216: } ! 217: ! 218: lcase(s) ! 219: register char *s; ! 220: { ! 221: register char *ptr; ! 222: ! 223: for (ptr = s; *ptr; ptr++) ! 224: if (isupper(*ptr)) ! 225: *ptr = tolower(*ptr); ! 226: } ! 227: ! 228: /* ! 229: * Return a compact representation of the person who posted the given ! 230: * message. A sender or internet name will be used, otherwise ! 231: * the last part of the path is used preceded by an optional ".." ! 232: */ ! 233: char * ! 234: tailpath(hp) ! 235: struct hbuf *hp; ! 236: { ! 237: char *p, *r; ! 238: static char resultbuf[BUFLEN]; ! 239: char pathbuf[PATHLEN]; ! 240: char *malloc(); ! 241: ! 242: /* ! 243: * This only happens for articles posted by old news software ! 244: * in non-internet format. ! 245: */ ! 246: resultbuf[0] = '\0'; ! 247: (void) strncpy(pathbuf, hp->path, PATHLEN); ! 248: p = index(pathbuf, ' '); ! 249: if (p) ! 250: *p = '\0'; /* Chop off trailing " (name)" */ ! 251: r = rindex(pathbuf, '!'); ! 252: if (r == 0) { ! 253: r = pathbuf; ! 254: } else { ! 255: while (r > pathbuf && *--r != '!') ! 256: ; ! 257: if (r > pathbuf) { ! 258: r++; ! 259: (void) strcpy(resultbuf, "..!"); ! 260: } ! 261: } ! 262: (void) strcat(resultbuf, r); ! 263: return resultbuf; ! 264: } ! 265: ! 266: /* ! 267: * arpadate is like ctime(3) except that the time is returned in ! 268: * an acceptable ARPANET time format instead of ctime format. ! 269: */ ! 270: char * ! 271: arpadate(longtime) ! 272: time_t *longtime; ! 273: { ! 274: register char *p, *q, *ud; ! 275: register int i; ! 276: static char b[40]; ! 277: extern struct tm *gmtime(); ! 278: extern char *asctime(); ! 279: ! 280: /* Get current time. This will be used resolve the timezone. */ ! 281: ud = asctime(gmtime(longtime)); ! 282: ! 283: /* Crack the UNIX date line in a singularly unoriginal way. */ ! 284: q = b; ! 285: ! 286: #ifdef notdef ! 287: /* until every site installs the fix to getdate.y, the day ! 288: of the week can cause time warps */ ! 289: p = &ud[0]; /* Mon */ ! 290: *q++ = *p++; ! 291: *q++ = *p++; ! 292: *q++ = *p++; ! 293: *q++ = ','; *q++ = ' '; ! 294: #endif ! 295: ! 296: p = &ud[8]; /* 16 */ ! 297: if (*p == ' ') ! 298: p++; ! 299: else ! 300: *q++ = *p++; ! 301: *q++ = *p++; *q++ = ' '; ! 302: ! 303: p = &ud[4]; /* Sep */ ! 304: *q++ = *p++; *q++ = *p++; *q++ = *p++; *q++ = ' '; ! 305: ! 306: p = &ud[22]; /* 1979 */ ! 307: *q++ = *p++; *q++ = *p++; *q++ = ' '; ! 308: ! 309: p = &ud[11]; /* 01:03:52 */ ! 310: for (i = 8; i > 0; i--) ! 311: *q++ = *p++; ! 312: ! 313: *q++ = ' '; ! 314: *q++ = 'G'; /* GMT */ ! 315: *q++ = 'M'; ! 316: *q++ = 'T'; ! 317: *q = '\0'; ! 318: ! 319: return b; ! 320: } ! 321: ! 322: char * ! 323: replyname(hptr) ! 324: struct hbuf *hptr; ! 325: { ! 326: register char *ptr; ! 327: static char tbuf[PATHLEN]; ! 328: ! 329: ptr = hptr->path; ! 330: if (PREFIX(ptr, PATHSYSNAME) && ! 331: index(NETCHRS, ptr[strlen(PATHSYSNAME)])) ! 332: ptr = index(ptr, '!') + 1; ! 333: #ifdef INTERNET ! 334: if (hptr->from[0]) ! 335: ptr = hptr->from; ! 336: if (hptr->replyto[0]) ! 337: ptr = hptr->replyto; ! 338: #else /* !INTERNET */ ! 339: if (hptr->replyto[0] && !index(hptr->replyto, '@')) ! 340: ptr = hptr->replyto; ! 341: #endif ! 342: (void) strcpy(tbuf, ptr); ! 343: ptr = index(tbuf, '('); ! 344: if (ptr) { ! 345: while (ptr[-1] == ' ') ! 346: ptr--; ! 347: *ptr = 0; ! 348: } ! 349: #ifdef SunIII ! 350: if (ptr = rindex(tbuf, '.')) { ! 351: if (PREFIX(++ptr, "OZ")) { ! 352: /* some people only allow it in lower case ... */ ! 353: strcpy(ptr, "oz"); ! 354: return tbuf; ! 355: } ! 356: if (PREFIX(ptr, "UUCP") || PREFIX(ptr, "ARPA") || ! 357: PREFIX(ptr, "DEC") || PREFIX(ptr, "CSNET")) { ! 358: strcat(tbuf, "@munnari.oz"); /* via sun to munnari */ ! 359: return tbuf; ! 360: } ! 361: } ! 362: /* ! 363: * must(?) have come from a uucp site, lets look see if path passes ! 364: * through munnari, and if so delete the fake uucp path after that. ! 365: */ ! 366: for (ptr = tbuf ;; ptr++) { ! 367: if (PREFIX(ptr, "munnari!")) { ! 368: strcpy(tbuf, ptr+8); ! 369: break; ! 370: } ! 371: ptr = index(ptr, '!'); ! 372: if (ptr == (char *)0) ! 373: break; ! 374: } ! 375: /* ! 376: * now, just send the address we have left to munnari, and ! 377: * hope that something sensible will be done with it there. ! 378: * (This works in more cases than you'd think ...) ! 379: */ ! 380: strcat(tbuf, "@munnari.oz"); ! 381: #else /* !SunIII */ ! 382: #ifndef INTERNET ! 383: /* ! 384: * Play games stripping off multiple berknet ! 385: * addresses (a!b!c:d:e => a!b!d:e) here. ! 386: */ ! 387: for (ptr=tbuf; *ptr; ptr++) { ! 388: register char *ptr2; ! 389: ! 390: if (index(NETCHRS, *ptr) && *ptr == ':' && ! 391: (ptr2=index(ptr+1, ':'))) ! 392: (void) strcpy(ptr, ptr2); ! 393: } ! 394: #else /* INTERNET */ ! 395: { ! 396: char mbuf[BUFLEN], modadd[BUFLEN]; ! 397: FILE *mfd; ! 398: /* Let's find a path to the backbone */ ! 399: sprintf(mbuf, "%s/mailpaths", LIB); ! 400: mfd = xfopen(mbuf, "r"); ! 401: do { ! 402: if (fgets(mbuf, sizeof mbuf, mfd) == NULL) ! 403: xerror("Can't find internet in %s/mailpaths", ! 404: LIB); ! 405: } while (!PREFIX(mbuf, "internet")); ! 406: if (sscanf(mbuf, "%*s %s", modadd) != 1) ! 407: xerror("backbone address corrupted"); ! 408: (void) fclose(mfd); ! 409: (void)strcpy(mbuf, tbuf); ! 410: /* If we are lucky, there is no ! or @ in the forward address */ ! 411: if (strpbrk(modadd, "!@") == NULL) { ! 412: sprintf(tbuf, modadd, mbuf); ! 413: } else { ! 414: char *cp = index(mbuf, '@'); ! 415: if (index(modadd, '@') == NULL && cp) { ! 416: /* we have to rearrange the address so no @ are in it */ ! 417: char atbuf[BUFLEN]; ! 418: *cp++ = '\0'; ! 419: sprintf(atbuf, "%s!%s", cp, mbuf); ! 420: sprintf(tbuf, modadd, atbuf); ! 421: } else if (cp) { ! 422: /* some days you don't get lucky. presume the % hack */ ! 423: *cp = '%'; ! 424: sprintf(tbuf, modadd, mbuf); ! 425: } ! 426: } ! 427: } ! 428: #endif /* INTERNET */ ! 429: #endif /* !SunIII */ ! 430: return tbuf; ! 431: } ! 432: ! 433: ! 434: /* ! 435: * Given an article ID, find the line in the history file that mentions it. ! 436: * Return the text of the line, or NULL if not found. A pointer to a ! 437: * static area is returned. ! 438: */ ! 439: char * ! 440: findhist(artid) ! 441: char *artid; ! 442: { ! 443: static char lbuf[256]; ! 444: char oidbuf[BUFSIZ]; ! 445: FILE *hfp; ! 446: register char *p; ! 447: #ifdef SERVER ! 448: char workspace[256]; ! 449: struct tm *tm; ! 450: long clock; ! 451: #else /* !SERVER */ ! 452: #ifdef DBM ! 453: datum lhs, rhs; ! 454: datum fetch(); ! 455: long fpos; /* We have to use an explicit variable to insure alignment */ ! 456: #else /* !DBM */ ! 457: char *histfile(); ! 458: #endif /* !DBM */ ! 459: #endif /* !SERVER */ ! 460: /* Try to understand old artid's as well. Assume .UUCP domain. */ ! 461: if (artid[0] != '<') { ! 462: p = index(artid, '.'); ! 463: if (p) ! 464: *p++ = '\0'; ! 465: (void) sprintf(oidbuf, "<%s@%s.UUCP>", p, artid); ! 466: if (p) ! 467: *--p = '.'; ! 468: } else ! 469: (void) strcpy(oidbuf, artid); ! 470: #ifdef SERVER ! 471: (void) sprintf(lbuf,"STAT %s",oidbuf); ! 472: put_server(lbuf); ! 473: (void) get_server(workspace,sizeof(workspace)); ! 474: if (*workspace != CHAR_OK) ! 475: return NULL; ! 476: (void) sprintf(lbuf,"XHDR xref %s",oidbuf); ! 477: put_server(lbuf); ! 478: (void) get_server(workspace,sizeof(workspace)); /* get response */ ! 479: if (*workspace != CHAR_OK) ! 480: return NULL; /* old style nntp */ ! 481: (void) get_server(workspace,sizeof(workspace)); /* get header line */ ! 482: sync_server(); /* get rid of the rest of it */ ! 483: p = index(workspace,' '); ! 484: p++; ! 485: ! 486: if (*p == '(') { /* there is no xref line */ ! 487: long s,sm; ! 488: FILE * af; ! 489: char n[100], buf[100], *name; ! 490: (void) sprintf(lbuf,"XHDR newsgroups %s",oidbuf); ! 491: put_server(lbuf); ! 492: (void) get_server(workspace,sizeof(workspace)); ! 493: if (*workspace != CHAR_OK) ! 494: return NULL; ! 495: (void) get_server(workspace,sizeof(workspace)); ! 496: sync_server(); ! 497: if ((name = index(workspace,' ')) == NULL) ! 498: return NULL; ! 499: name++; ! 500: /* now we fetch the line from the active file */ ! 501: af = xfopen(ACTIVE, "r"); ! 502: while (fgets(buf, sizeof(buf), af) != NULL) { ! 503: if (sscanf(buf, "%s %ld %ld", n, &s, &sm) == 3 && ! 504: STRCMP(n, name) == 0) { ! 505: break; ! 506: } ! 507: } ! 508: (void) fclose(af); ! 509: /* now we ask for a message ids in that newsgroup */ ! 510: if (set_group(name) == NULL) ! 511: return NULL; ! 512: (void) sprintf(lbuf, "XHDR message-id %d-%d", sm, s); ! 513: put_server(lbuf); ! 514: (void) get_server(workspace,sizeof(workspace)); ! 515: if (*workspace != CHAR_OK) ! 516: return NULL; ! 517: while ( get_server(workspace,sizeof(workspace)) >= 0) { ! 518: if (*workspace == '.' && strlen(workspace) == 1) ! 519: return NULL; ! 520: if (strindex(workspace,oidbuf) > -1) ! 521: break; ! 522: } ! 523: sync_server(); ! 524: *(index(workspace,' ')) = '\0'; ! 525: (void) sprintf(lbuf, "%s/%s", n, workspace); ! 526: bzero(workspace,sizeof(workspace)); ! 527: strcpy(workspace, lbuf); ! 528: } else { ! 529: bzero(lbuf, sizeof(lbuf)); ! 530: strcpy(lbuf, p); ! 531: while (*p != '\0' && (p = index(lbuf,':')) != NULL) { ! 532: *p = '/'; ! 533: p++; ! 534: } ! 535: strcpy(workspace, lbuf); ! 536: } ! 537: p = &workspace[0]; ! 538: time(&clock); ! 539: tm = localtime(&clock); ! 540: #ifdef USG ! 541: sprintf(lbuf, "%s\t%2.2d/%2.2d/%d %2.2d:%2.2d\t%s", ! 542: #else /* !USG */ ! 543: sprintf(lbuf, "%s\t%02d/%02d/%d %02d:%02d\t%s", ! 544: #endif /* !USG */ ! 545: oidbuf,tm->tm_mon,tm->tm_mday,tm->tm_year,tm->tm_hour,tm->tm_min,p); ! 546: return lbuf; /* not really the same, but close */ ! 547: #else /* !SERVER */ ! 548: lcase(oidbuf); ! 549: #ifdef DBM ! 550: initdbm(ARTFILE); ! 551: lhs.dptr = oidbuf; ! 552: lhs.dsize = strlen(lhs.dptr) + 1; ! 553: rhs = fetch(lhs); ! 554: if (rhs.dptr == NULL) ! 555: return NULL; ! 556: hfp = xfopen(ARTFILE, "r"); ! 557: /* The bcopy is NECESSARY to insure alignment on some machines */ ! 558: bcopy(rhs.dptr, (char *)&fpos, sizeof (long)); ! 559: fseek(hfp, fpos, 0); ! 560: #else /* !DBM */ ! 561: hfp = xfopen(histfile(oidbuf), "r"); ! 562: #endif /* !DBM */ ! 563: while (fgets(lbuf, BUFLEN, hfp) != NULL) { ! 564: p = index(lbuf, '\t'); ! 565: if (p == NULL) ! 566: p = index(lbuf, '\n'); ! 567: *p = 0; ! 568: if (STRCMP(lbuf, artid) == 0 || STRCMP(lbuf, oidbuf) == 0) { ! 569: (void) fclose(hfp); ! 570: *p = '\t'; ! 571: *(lbuf + strlen(lbuf) - 1) = 0; /* zap the \n */ ! 572: return lbuf; ! 573: } ! 574: #ifdef DBM ! 575: break; ! 576: #endif /* DBM */ ! 577: } ! 578: (void) fclose(hfp); ! 579: return NULL; ! 580: #endif /* !SERVER */ ! 581: } ! 582: ! 583: /* ! 584: * Hunt up the article "artid", and return the newsgroup/artnum ! 585: * where it can be found. ! 586: */ ! 587: char * ! 588: findfname(artid) ! 589: char *artid; ! 590: { ! 591: char *line, *p, *q; ! 592: char *findhist(); ! 593: static char fname[BUFLEN]; ! 594: ! 595: line = findhist(artid); ! 596: if (line) { ! 597: /* Look for it stored as an article, where it should be */ ! 598: p = index(line, '\t'); ! 599: p = index(p+1, '\t'); ! 600: p++; ! 601: if (*p) { ! 602: q = index(p, ' '); ! 603: if (q) ! 604: *q = 0; ! 605: (void) strcpy(fname, p); ! 606: return fname; ! 607: } ! 608: } ! 609: return NULL; ! 610: } ! 611: ! 612: /* ! 613: * Hunt up the article "artid", fopen it for read, and return a ! 614: * file descriptor to it. We look everywhere we can think of. ! 615: */ ! 616: FILE * ! 617: hfopen(artid) ! 618: char *artid; ! 619: { ! 620: char *p; ! 621: char *findhist(); ! 622: FILE *rv = NULL; ! 623: char fname[BUFLEN]; ! 624: ! 625: p = findfname(artid); ! 626: if (p) { ! 627: #ifdef SERVER ! 628: if ((rv = getartbyid(p)) != NULL) { ! 629: strcpy(fname, article_name()); ! 630: (void) fclose(rv); ! 631: rv = NULL; ! 632: } ! 633: else ! 634: xerror("Cannot hfopen article %s", artid); ! 635: #else /* !SERVER */ ! 636: (void) strcpy(fname, dirname(p)); ! 637: #endif /* !SERVER */ ! 638: rv = fopen(fname, "r"); /* NOT xfopen! */ ! 639: if (rv == NULL) ! 640: xerror("Cannot hfopen article %s", artid); ! 641: } ! 642: #ifdef SERVER ! 643: (void) unlink(fname); ! 644: #endif /* !SERVER */ ! 645: return rv; ! 646: } ! 647: #ifndef SERVER ! 648: # ifdef DBM ! 649: /* ! 650: ** Avoid problems of multiple dbminit calls. ! 651: */ ! 652: initdbm(name) ! 653: char *name; ! 654: { ! 655: static int called = 0; ! 656: ! 657: if (called != 0) ! 658: return; ! 659: called = 1; ! 660: (void) dbminit(name); ! 661: } ! 662: # endif /* DBM */ ! 663: #endif /* !SERVER */ ! 664: ! 665: #ifndef BSD4_2 ! 666: /* ! 667: * move n bytes from a to b ! 668: */ ! 669: bcopy(a, b, n) ! 670: register char *a, *b; ! 671: register n; ! 672: { ! 673: while (--n >= 0) ! 674: *b++ = *a++; ! 675: } ! 676: #endif ! 677: ! 678: #if !defined(BSD4_2) ! 679: rename(from,to) ! 680: register char *from, *to; ! 681: { ! 682: (void) unlink(to); ! 683: if (link(from, to) < 0) ! 684: return -1; ! 685: ! 686: (void) unlink(from); ! 687: return 0; ! 688: } ! 689: #endif /* !BSD4_2 */ ! 690: ! 691: #ifndef DBM ! 692: /* ! 693: ** Generate the appropriate history subfile name ! 694: */ ! 695: char * ! 696: histfile(hline) ! 697: char *hline; ! 698: { ! 699: char chr; /* least significant digit of article number */ ! 700: static char subfile[BUFLEN]; ! 701: ! 702: chr = findhfdigit(hline); ! 703: sprintf(subfile, "%s.d/%c", ARTFILE, chr); ! 704: return subfile; ! 705: } ! 706: ! 707: findhfdigit(fn) ! 708: char *fn; ! 709: { ! 710: register char *p; ! 711: register int chr; ! 712: ! 713: p = index(fn, '@'); ! 714: if (p != NULL && p > fn) ! 715: chr = *(p - 1); ! 716: else ! 717: chr = '0'; ! 718: if (!isdigit(chr)) ! 719: chr = '0'; ! 720: return chr; ! 721: } ! 722: #endif /* !DBM */ ! 723: ! 724: #ifdef VMS ! 725: /* ! 726: * These functions open an article with one level of indirection, ! 727: * to support symbolic links. xart_open exits if the open fails. ! 728: */ ! 729: FILE * ! 730: xart_open (filename,mode) ! 731: char *filename,*mode; ! 732: { ! 733: FILE *fp = art_open (filename, mode); ! 734: extern int errno; ! 735: if (fp == NULL) ! 736: xerror("Cannot open article %s (%s): %s\n", ! 737: filename, mode, errmsg(errno)); ! 738: return fp; ! 739: } ! 740: ! 741: FILE * ! 742: art_open (filename,mode) ! 743: char *filename,*mode; ! 744: { ! 745: char linkfile[BUFSIZ]; ! 746: FILE *fp; ! 747: ! 748: if ((fp = fopen (filename, mode)) == NULL) ! 749: return NULL; ! 750: if (fgets (linkfile, BUFSIZ, fp) == NULL || linkfile[0] != '/') { ! 751: rewind (fp); ! 752: return fp; ! 753: } ! 754: /* Chase the symbolic link. */ ! 755: (void) fclose (fp); ! 756: if ((fp = fopen (linkfile, mode)) == NULL) ! 757: /* Clean up dangling link, if we have the power. Ignore error if we don't. */ ! 758: (void) unlink (filename); ! 759: return fp; ! 760: } ! 761: #endif /* VMS */ ! 762: ! 763: /* ! 764: * Generate the name of the person responsible for posting this article, ! 765: * in order to check that two articles were posted by the same person. ! 766: */ ! 767: char * ! 768: senderof(hp) ! 769: struct hbuf *hp; ! 770: { ! 771: register char *q, *tp; ! 772: char *tailpath(); ! 773: static char senderbuf[BUFLEN]; ! 774: ! 775: if (hp->sender[0]) ! 776: tp = hp->sender; ! 777: else if (hp->from[0]) ! 778: tp = hp->from; ! 779: else ! 780: tp = tailpath(hp); ! 781: ! 782: (void) strncpy(senderbuf, tp, BUFLEN); ! 783: /* Remove full name */ ! 784: q = index(senderbuf, ' '); ! 785: if (q) ! 786: *q = '\0'; ! 787: ! 788: return senderbuf; ! 789: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.