|
|
1.1 ! root 1: /* down!honey 4/84 */ ! 2: /* article msg-id [ ... msg-id ] */ ! 3: * where message-id is usually of the form [email protected], ! 4: * and the domain in the message-id is optional. ! 5: * ! 6: * BUGS: ! 7: * Cannot handle all domains, for instance, BERKELEY.EDU. ! 8: */ ! 9: ! 10: #define HISTORY "/usr/lib/news/history" ! 11: #define NEWSDIR "/usr/spool/news" ! 12: ! 13: char *formats[] = { /* add as appropriate */ ! 14: "<%s.uucp>", ! 15: "<%s>", ! 16: "<%s.arpa>", ! 17: "<%s.oz>", ! 18: 0 ! 19: }; ! 20: ! 21: #include <stdio.h> ! 22: #include <sysexits.h> ! 23: #include <ctype.h> ! 24: ! 25: typedef struct { ! 26: char *dptr; ! 27: int dsize; ! 28: } datum; ! 29: ! 30: #if defined(USG_INDEX) ! 31: /* S3 or S5 both call strchr() what 4.X BSD calls index */ ! 32: #define index strchr ! 33: #endif ! 34: ! 35: long lseek(); ! 36: char *index(); ! 37: datum fetch(), dofetch(); ! 38: ! 39: main(argc, argv) ! 40: char **argv; ! 41: { ! 42: int fd; ! 43: char buf[BUFSIZ], *ptr1, *ptr2; ! 44: datum content; ! 45: ! 46: if ((fd = open(HISTORY, 0)) < 0) { ! 47: perror(HISTORY); ! 48: exit(EX_UNAVAILABLE); ! 49: } ! 50: if (dbminit(HISTORY) < 0) { ! 51: fprintf(stderr, "dbm error\n"); ! 52: exit(EX_UNAVAILABLE); ! 53: } ! 54: for (--argc, argv++; argc; --argc, argv++) { ! 55: long foff; /* file offset */ ! 56: content = dofetch(*argv); ! 57: if (content.dptr == 0) { ! 58: printf("%s: No such key\n", *argv); ! 59: continue; ! 60: } ! 61: ! 62: /* Correct a machine dependent bug here, caused */ ! 63: /* because the lseek offset pointed to by dptr might */ ! 64: /* not be long-aligned. */ ! 65: /* Guy Harris suggested bug fix to prevent core drop. */ ! 66: /* This bug was written up in net.bugs.4bsd and */ ! 67: /* cross-posted to net.news.b */ ! 68: bcopy(content.dptr, (char *)&foff, sizeof foff); ! 69: ! 70: if (lseek(fd, foff, 0) < 0) ! 71: continue; ! 72: if (read(fd, buf, sizeof buf) <= 0) ! 73: continue; ! 74: ! 75: /* ! 76: * To understand this piece of code, you must understand ! 77: * that the format of lines in the history file are either: ! 78: * <msg-id>TAB<date>SPACE<time>TABthenNL ! 79: * <msg-id>TAB<date>SPACE<time>TAB<spoolpathname>NL ! 80: * <msg-id>TAB<date>SPACE<time>TAB<spoolpathname>SPACE... ! 81: * The first format occurs when expired, ! 82: * the second form occurs when exactly one pathname, ! 83: * and the third occurs when cross-postings. ! 84: */ ! 85: * ! 86: ! 87: /* remove end of line */ ! 88: if ((ptr2 = index(buf, '\n')) == 0) ! 89: continue; ! 90: *ptr2 = '\0'; ! 91: ! 92: /* The 4th field contains the article file name */ ! 93: ! 94: if ((ptr1 = index(buf, '\t')) == 0) ! 95: continue; ! 96: ptr1++; ! 97: ! 98: /* ptr1 now at begin of field 2 - the date field */ ! 99: ! 100: if ((ptr1 = index(ptr1, '\t')) == 0) ! 101: continue; ! 102: ptr1++; ! 103: ! 104: /* ptr1 now at begin of field 4 - the article spool pathname */ ! 105: /* or the newline that has been converted to a NULL */ ! 106: ! 107: /* change net.unix/231 to net/unix/231 */ ! 108: for (ptr2 = ptr1; ptr2 = index(ptr2, '.'); *ptr2 = '/') ! 109: ; ! 110: ! 111: /* terminate after the first pathname, if any */ ! 112: if ((ptr2 = index(ptr1, ' ')) != NULL) ! 113: *ptr2 = '\0'; ! 114: ! 115: if (*ptr1 == '\0') ! 116: printf("expired\n"); ! 117: else ! 118: printf("%s/%s\n", NEWSDIR, ptr1); ! 119: } ! 120: exit(EX_OK); ! 121: } ! 122: ! 123: datum ! 124: dofetch(str) ! 125: char *str; ! 126: { ! 127: datum key, content; ! 128: char buf[BUFSIZ], **fmt; ! 129: register char *rcp; ! 130: ! 131: for (fmt = formats; *fmt; fmt++) { ! 132: sprintf(buf, *fmt, str); ! 133: rcp = buf - 1; ! 134: while (*++rcp) ! 135: if (isupper(*rcp)) ! 136: *rcp = tolower(*rcp); ! 137: key.dptr = buf; ! 138: key.dsize = strlen(buf) + 1; ! 139: content = fetch(key); ! 140: if (content.dptr) ! 141: break; ! 142: } ! 143: return(content); ! 144: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.