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: }
Defined functions
Defined variables
Fromp
defined in line
16; used 18 times
Ifrom
defined in line
17; used 13 times
Nfrom
defined in line
19; used 5 times
Defined macros