|
|
1.1 ! root 1: /* $Header$ */ ! 2: ! 3: /* ! 4: * Author: Peter J. Nicklin ! 5: */ ! 6: #include <ctype.h> ! 7: #include <stdio.h> ! 8: #include "date.h" ! 9: #include "from.h" ! 10: #include "null.h" ! 11: #include "yesno.h" ! 12: ! 13: #define INCRFROM 1000 /* amount to increase From ptr array */ ! 14: #define MAXFROM 1000 /* initial size of From pointer array */ ! 15: ! 16: static FROM **Fromp; /* pointer to "From " pointer array */ ! 17: static int Ifrom; /* current "From " ptr array index */ ! 18: static int Maxfrom = MAXFROM; /* maximum number of "From " lines */ ! 19: static int Nfrom; /* number of "From " lines */ ! 20: ! 21: /* ! 22: * fromcmp() compares the dates of two "From " lines and returns an integer ! 23: * less than, equal to, or greater than zero, according to the chronological ! 24: * order of the dates. ! 25: */ ! 26: static int ! 27: fromcmp(f1, f2) ! 28: register FROM **f1; /* FROM struct pointer */ ! 29: register FROM **f2; /* FROM struct pointer */ ! 30: { ! 31: register int d; /* relative time */ ! 32: ! 33: if ((d = (*f1)->bdt.t_year - (*f2)->bdt.t_year) < 0 || d > 0) ! 34: return(d); ! 35: else if ((d = (*f1)->bdt.t_mon - (*f2)->bdt.t_mon) < 0 || d > 0) ! 36: return(d); ! 37: else if ((d = (*f1)->bdt.t_day - (*f2)->bdt.t_day) < 0 || d > 0) ! 38: return(d); ! 39: else if ((d = (*f1)->bdt.t_hour - (*f2)->bdt.t_hour) < 0 || d > 0) ! 40: return(d); ! 41: else if ((d = (*f1)->bdt.t_min - (*f2)->bdt.t_min) < 0 || d > 0) ! 42: return(d); ! 43: return((*f1)->bdt.t_sec - (*f2)->bdt.t_sec); ! 44: } ! 45: ! 46: ! 47: ! 48: /* ! 49: * isfrom() returns a pointer to a "From " line struct if a "From " line, ! 50: * otherwise NULL. ! 51: */ ! 52: FROM * ! 53: isfrom(linebuf) ! 54: char *linebuf; /* line to be examined */ ! 55: { ! 56: static FROM from; /* "From " line struct */ ! 57: static char frombuf[BUFSIZ]; /* parsed "From " line buffer */ ! 58: char *strcpy(); /* string copy */ ! 59: int isdate(); /* is string a ctime(3) date? */ ! 60: int strncmp(); /* compare strings for n chars */ ! 61: void parsefrom(); /* parse "From " line */ ! 62: ! 63: if (strncmp(linebuf, "From ", 5) != 0) ! 64: return(0); ! 65: /* ! 66: * save a copy of linebuf in frombuf because parsefrom() ! 67: * breaks up the buffer into several strings and assigns ! 68: * from struct pointers to those strings ! 69: */ ! 70: strcpy(frombuf, linebuf); ! 71: parsefrom(frombuf, &from); ! 72: if (!isdate(from.date)) ! 73: return(NULL); ! 74: return(&from); ! 75: } ! 76: ! 77: ! 78: ! 79: /* ! 80: * initfrom() creates a "From " pointer array and initializes it with ! 81: * a dummy from struct to take care of spurious lines of information ! 82: * before the first "From " line in the file. Returns a pointer to the ! 83: * from struct, or NULL if out of memory. ! 84: */ ! 85: FROM * ! 86: initfrom() ! 87: { ! 88: char *calloc(); /* zeroed memory allocation */ ! 89: char *malloc(); /* memory allocator */ ! 90: ! 91: if ((Fromp=(FROM **) malloc((unsigned)Maxfrom*sizeof(FROM *))) == NULL) ! 92: return((FROM *) NULL); ! 93: Ifrom = 0; ! 94: if ((Fromp[Ifrom] = (FROM *) calloc(1, sizeof(FROM))) == NULL) ! 95: return((FROM *) NULL); ! 96: Nfrom = 1; ! 97: return(Fromp[Ifrom]); ! 98: } ! 99: ! 100: ! 101: ! 102: /* ! 103: * nextword() collects a liberal (blank, tab delimited) word and returns a ! 104: * pointer to the next word or string. ! 105: */ ! 106: char * ! 107: nextword(word, bp) ! 108: register char *bp; /* buffer pointer */ ! 109: char **word; /* word or string */ ! 110: { ! 111: for (; *bp != '\0' && isspace(*bp); bp++) ! 112: continue; ! 113: *word = bp; ! 114: for (; *bp != '\0' && !isspace(*bp); bp++) ! 115: continue; ! 116: *bp++ = '\0'; ! 117: for (; *bp != '\0' && isspace(*bp); bp++) ! 118: continue; ! 119: return(bp); ! 120: } ! 121: ! 122: ! 123: ! 124: /* ! 125: * outfrom() copies an input stream to an output stream in chronological ! 126: * order of "From " messages. Returns YES if successful, otherwise NO. ! 127: */ ! 128: outfrom(ifp, ofp) ! 129: register FILE *ifp; /* input stream */ ! 130: register FILE *ofp; /* output stream */ ! 131: { ! 132: register int c; /* current character */ ! 133: register int i; /* "From " pointer array index */ ! 134: register int n; /* character counter */ ! 135: ! 136: for (i = 0; i < Nfrom; i++) ! 137: { ! 138: fseek(ifp, Fromp[i]->m_seek, 0); ! 139: for (n = Fromp[i]->m_len; n > 0; n--) ! 140: { ! 141: c = getc(ifp); ! 142: if (putc(c, ofp) == EOF) ! 143: return(NO); ! 144: } ! 145: } ! 146: return(YES); ! 147: } ! 148: ! 149: ! 150: ! 151: /* ! 152: * parsefrom splits a "From " line into its components and sets from ! 153: * struct pointers into frombuf. ! 154: */ ! 155: void ! 156: parsefrom(frombuf, from) ! 157: char *frombuf; /* "From " line buffer */ ! 158: FROM *from; /* "From " line struct */ ! 159: { ! 160: register char *dp; /* date pointer */ ! 161: register char *fb; /* frombuf pointer */ ! 162: char *nextword(); /* get word & go to next word */ ! 163: char *skipword(); /* skip to next word */ ! 164: char *strcpy(); /* string copy */ ! 165: int strncmp(); /* compare strings for n chars */ ! 166: ! 167: fb = frombuf; ! 168: fb = nextword(&from->from, skipword(fb)); ! 169: if (strncmp("tty", fb, 3) == 0) ! 170: fb = nextword(&from->tty, skipword(fb)); ! 171: from->date = fb; ! 172: for (dp = fb; *dp != '\n' && *dp != '\0'; dp++) ! 173: continue; ! 174: *dp = '\0'; ! 175: } ! 176: ! 177: ! 178: ! 179: /* ! 180: * savefrom() saves a "From " struct somewhere and appends it to the From ! 181: * pointer array. The array is extended if necessary. Returns a pointer ! 182: * to the somewhere, or NULL if out of memory. ! 183: */ ! 184: FROM * ! 185: savefrom(f) ! 186: FROM *f; /* "From " line struct */ ! 187: { ! 188: char *malloc(); /* memory allocator */ ! 189: char *realloc(); /* reallocate memory block */ ! 190: ! 191: if (Nfrom > Maxfrom) ! 192: { ! 193: Maxfrom += INCRFROM; ! 194: if ((Fromp = (FROM **) realloc((char *)Fromp, ! 195: (unsigned)Maxfrom*sizeof(FROM *))) == NULL) ! 196: return((FROM *) NULL); ! 197: } ! 198: if ((Fromp[++Ifrom] = (FROM *) malloc(sizeof(FROM))) == NULL) ! 199: return((FROM *) NULL); ! 200: Nfrom++; ! 201: ! 202: Fromp[Ifrom]->bdt.t_sec = f->bdt.t_sec; ! 203: Fromp[Ifrom]->bdt.t_min = f->bdt.t_min; ! 204: Fromp[Ifrom]->bdt.t_hour = f->bdt.t_hour; ! 205: Fromp[Ifrom]->bdt.t_day = f->bdt.t_day; ! 206: Fromp[Ifrom]->bdt.t_mon = f->bdt.t_mon; ! 207: Fromp[Ifrom]->bdt.t_year = f->bdt.t_year; ! 208: Fromp[Ifrom]->m_seek = f->m_seek; ! 209: Fromp[Ifrom]->m_len = 0; ! 210: return(Fromp[Ifrom]); ! 211: } ! 212: ! 213: ! 214: ! 215: /* ! 216: * sortfrom() sorts "From " lines chronologically. ! 217: */ ! 218: void ! 219: sortfrom() ! 220: { ! 221: int fromcmp(); /* compare "From " lines by date */ ! 222: ! 223: qsort((char *) Fromp, Nfrom, sizeof(FROM *), fromcmp); ! 224: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.