1 | /* |
---|
2 | * |
---|
3 | * Copyright (C) 1991 by the Massachusetts Institute of Technology |
---|
4 | * Developed by the MIT Student Information Processing Board (SIPB). |
---|
5 | * For copying information, see the file mit-copyright.h in this release. |
---|
6 | * |
---|
7 | */ |
---|
8 | |
---|
9 | #ifndef lint |
---|
10 | #ifndef SABER |
---|
11 | static char *RCSid = "$Id: dsgrep.c,v 1.19 2002-11-11 18:25:04 ghudson Exp $"; |
---|
12 | #endif |
---|
13 | #endif |
---|
14 | |
---|
15 | |
---|
16 | #define MAX_MEETINGS 128 |
---|
17 | |
---|
18 | #include <stdio.h> |
---|
19 | #include <stdlib.h> |
---|
20 | #include <string.h> |
---|
21 | #include <ctype.h> |
---|
22 | #include <sys/file.h> |
---|
23 | #include <sys/types.h> |
---|
24 | #include <sys/param.h> |
---|
25 | #include <sys/stat.h> |
---|
26 | #include <discuss/discuss.h> |
---|
27 | #include <regex.h> |
---|
28 | |
---|
29 | #ifndef MAX |
---|
30 | #define MAX(a, b) ((a) < (b) ? (b) : (a)) |
---|
31 | #endif |
---|
32 | |
---|
33 | extern tfile unix_tfile(); |
---|
34 | extern tfile mem_tfile(); |
---|
35 | |
---|
36 | int verbose_errors; |
---|
37 | int bsize; |
---|
38 | char *buffer; |
---|
39 | |
---|
40 | main(argc,argv) |
---|
41 | int argc; |
---|
42 | char *argv[]; |
---|
43 | { |
---|
44 | extern int optind; |
---|
45 | extern char *optarg; |
---|
46 | |
---|
47 | char *meetings_file,*homedir,*regexp_str,*var; |
---|
48 | name_blk *meetings,*tmp_mtg; |
---|
49 | mtg_info meeting_info; |
---|
50 | char tmp_meeting_file[MAXPATHLEN]; |
---|
51 | int n_meetings,result,i,cur_meeting,n_to_look,j,c; |
---|
52 | int print_trans,flags,search_trans,search_deleted,s_trans(); |
---|
53 | int case_insens,trans_num; |
---|
54 | int high,low; |
---|
55 | regex_t search_re; |
---|
56 | tfile tf; |
---|
57 | trn_info2 ti; |
---|
58 | void s_to_lower(); |
---|
59 | int tmp_fd1,tmp_fd2; |
---|
60 | int using_dflt_mtgs = 0; |
---|
61 | struct stat statb; |
---|
62 | |
---|
63 | #if defined(__APPLE__) && defined(__MACH__) |
---|
64 | add_error_table(&et_dsc_error_table); |
---|
65 | #else |
---|
66 | initialize_dsc_error_table(); |
---|
67 | #endif |
---|
68 | |
---|
69 | n_to_look = 50; |
---|
70 | print_trans = 0; |
---|
71 | search_trans = 0; |
---|
72 | verbose_errors = 0; |
---|
73 | case_insens = 0; |
---|
74 | search_deleted = 0; |
---|
75 | trans_num = 0; |
---|
76 | meetings_file = NULL; |
---|
77 | regexp_str = NULL; |
---|
78 | |
---|
79 | while ((c = getopt(argc,argv, "n:e:f:t:apvdhi")) != EOF) |
---|
80 | switch(c) { |
---|
81 | case 'n': |
---|
82 | n_to_look = atoi(optarg); |
---|
83 | break; |
---|
84 | case 't': |
---|
85 | trans_num = atoi(optarg); |
---|
86 | break; |
---|
87 | case 'p': |
---|
88 | print_trans=1; |
---|
89 | break; |
---|
90 | case 'd': |
---|
91 | search_deleted = 1; |
---|
92 | break; |
---|
93 | case 'a': |
---|
94 | search_trans=1; |
---|
95 | bsize = 4096; |
---|
96 | if ((buffer = malloc((unsigned) bsize)) == NULL) { |
---|
97 | fprintf(stderr,"dsgrep: malloc failed\n"); |
---|
98 | exit(1); |
---|
99 | } |
---|
100 | break; |
---|
101 | case 'e': |
---|
102 | regexp_str = optarg; |
---|
103 | break; |
---|
104 | case 'f': |
---|
105 | meetings_file = optarg; |
---|
106 | break; |
---|
107 | case 'v': |
---|
108 | verbose_errors=1; |
---|
109 | break; |
---|
110 | case 'i': |
---|
111 | case_insens=1; |
---|
112 | break; |
---|
113 | case '?': |
---|
114 | case 'h': |
---|
115 | fprintf(stderr,"usage: dsgrep [-n n_trans]\n"); |
---|
116 | fprintf(stderr," [-e title_regexp]\n"); |
---|
117 | fprintf(stderr," [-t trans_num] print out a specific trans\n"); |
---|
118 | fprintf(stderr," [-a] (search text as well as title)\n"); |
---|
119 | fprintf(stderr," [-p] (print matching transactions)\n"); |
---|
120 | fprintf(stderr," [-v] (print out verbose error messages)\n"); |
---|
121 | fprintf(stderr," [-d] (search deleted transactions as well)\n"); |
---|
122 | fprintf(stderr," [-i] (convert text to lower case before searching)\n"); |
---|
123 | fprintf(stderr," [-f alt_meeting_file]\n"); |
---|
124 | fprintf(stderr," [meetings] (this must be last)\n"); |
---|
125 | exit(1); |
---|
126 | break; |
---|
127 | } |
---|
128 | |
---|
129 | if (regexp_str) { |
---|
130 | flags = REG_NOSUB | REG_EXTENDED | (case_insens ? REG_ICASE : 0); |
---|
131 | if (regcomp(&search_re, regexp_str, flags) != 0) { |
---|
132 | fprintf(stderr,"dsgrep: Invalid regular expression %s\n",regexp_str); |
---|
133 | exit(1); |
---|
134 | } |
---|
135 | } |
---|
136 | |
---|
137 | if (meetings_file) { |
---|
138 | var = malloc(strlen(meetings_file) + strlen("MEETINGS=") + 1); |
---|
139 | if (var == NULL) { |
---|
140 | fprintf(stderr,"dsgrep: could not allocate memory\n"); |
---|
141 | exit(1); |
---|
142 | } |
---|
143 | sprintf(var, "MEETINGS=%s", meetings_file); |
---|
144 | if (putenv(var) == -1) { |
---|
145 | fprintf(stderr,"dsgrep: could not add environment variable\n"); |
---|
146 | exit(1); |
---|
147 | } |
---|
148 | } |
---|
149 | |
---|
150 | switch (optind - argc) { |
---|
151 | case 0: |
---|
152 | dsc_expand_mtg_set(NULL,"*",&meetings,&cur_meeting,&result); |
---|
153 | break; |
---|
154 | case 1: |
---|
155 | dsc_expand_mtg_set(NULL,argv[optind],&meetings,&cur_meeting,&result); |
---|
156 | break; |
---|
157 | default: |
---|
158 | meetings = (name_blk *)calloc((unsigned)MAX_MEETINGS,sizeof(name_blk)); |
---|
159 | cur_meeting = 0; |
---|
160 | for(i=optind;i<argc;i++) { |
---|
161 | dsc_expand_mtg_set(NULL,argv[i],&tmp_mtg,&n_meetings,&result); |
---|
162 | if ((n_meetings == 0) && (result == 0)) { |
---|
163 | fprintf(stderr,"dsgrep: no such meeting %s\n",argv[i]); |
---|
164 | continue; |
---|
165 | } |
---|
166 | if (result != 0) { |
---|
167 | fprintf(stderr,"dsgrep: error expanding meeting %s: %s\n", |
---|
168 | argv[i],error_message(result)); |
---|
169 | exit(1); |
---|
170 | } |
---|
171 | memcpy(&meetings[cur_meeting],tmp_mtg,sizeof(name_blk)); |
---|
172 | cur_meeting++; |
---|
173 | } |
---|
174 | } |
---|
175 | |
---|
176 | if (cur_meeting == 0) { |
---|
177 | fprintf(stderr,"No meetings selected.\n"); |
---|
178 | exit(1); |
---|
179 | } |
---|
180 | |
---|
181 | tf = unix_tfile(1); /*stdout */ |
---|
182 | |
---|
183 | for(i=0;i<cur_meeting;i++) { |
---|
184 | dsc_get_mtg_info(&meetings[i],&meeting_info,&result); |
---|
185 | if (result != 0) { |
---|
186 | fprintf(stderr,"dsgrep: error getting meeting info for meeting '%s:%s': %s\n", |
---|
187 | meetings[i].hostname, meetings[i].pathname, |
---|
188 | error_message(result)); |
---|
189 | continue; |
---|
190 | } |
---|
191 | if (trans_num != 0) { |
---|
192 | low = trans_num; |
---|
193 | high = trans_num; |
---|
194 | } else { |
---|
195 | low = meeting_info.highest-n_to_look+1; |
---|
196 | low = MAX(low,1); |
---|
197 | high = meeting_info.highest; |
---|
198 | } |
---|
199 | for(j=low;j<=high;j++) |
---|
200 | { |
---|
201 | dsc_get_trn_info2(&meetings[i],j,&ti,&result); |
---|
202 | if (result != 0) { |
---|
203 | if (verbose_errors) |
---|
204 | fprintf(stderr,"dsgrep: error getting transaction info for %s[%d]: %s\n", |
---|
205 | strrchr(meetings[i].pathname,'/')+1, j, |
---|
206 | error_message(result)); |
---|
207 | continue; |
---|
208 | } |
---|
209 | if (!search_deleted && (ti.flags & TRN_FDELETED)) |
---|
210 | continue; |
---|
211 | if (!regexp_str || !regexec(&search_re,ti.subject,0,NULL,0) || |
---|
212 | (search_trans && |
---|
213 | s_trans(meetings[i],j,ti.num_chars,&search_re,case_insens))) { |
---|
214 | printf("%s [%d]: %s\n", |
---|
215 | strrchr(meetings[i].pathname,'/')+1, j, ti.subject); |
---|
216 | if (print_trans) { |
---|
217 | fflush(stdout); |
---|
218 | dsc_get_trn(&meetings[i],j,tf,&result); |
---|
219 | if ((result != 0) && verbose_errors) |
---|
220 | fprintf(stderr,"dsgrep: error getting transaction %s[%d]: %s\n", |
---|
221 | strrchr(meetings[i].pathname,'/')+1, j, |
---|
222 | error_message(result)); |
---|
223 | printf("*** End of Transaction ***\n"); |
---|
224 | } |
---|
225 | } |
---|
226 | } |
---|
227 | } |
---|
228 | if (using_dflt_mtgs) |
---|
229 | unlink(tmp_meeting_file); |
---|
230 | exit(0); |
---|
231 | } |
---|
232 | |
---|
233 | int |
---|
234 | s_trans(nbp,trans_no,n_chars,search_re,case_insens) |
---|
235 | name_blk nbp; |
---|
236 | int trans_no,n_chars; |
---|
237 | regex_t *search_re; |
---|
238 | int case_insens; |
---|
239 | { |
---|
240 | tfile tf; |
---|
241 | int result; |
---|
242 | void s_to_lower(); |
---|
243 | |
---|
244 | if (++n_chars > bsize) { |
---|
245 | free(buffer); |
---|
246 | if ((buffer = malloc((unsigned)n_chars)) == NULL) { |
---|
247 | fprintf(stderr,"dsgrep: malloc failed\n"); |
---|
248 | exit(1); |
---|
249 | } |
---|
250 | bsize = n_chars; |
---|
251 | } |
---|
252 | tf = mem_tfile(buffer,bsize); |
---|
253 | dsc_get_trn(&nbp,trans_no,tf,&result); |
---|
254 | if ((result != 0) && verbose_errors){ |
---|
255 | fprintf(stderr,"dsgrep: error getting transation %s[%d]: %s\n", |
---|
256 | strrchr(nbp.pathname,'/')+1,trans_no, |
---|
257 | error_message(result)); |
---|
258 | } |
---|
259 | tdestroy(tf); |
---|
260 | buffer[n_chars-1] = '\0'; |
---|
261 | if (case_insens) s_to_lower(buffer); |
---|
262 | return(!regexec(search_re,buffer,0,NULL,0)); |
---|
263 | } |
---|
264 | |
---|
265 | void |
---|
266 | s_to_lower(bufp) |
---|
267 | char *bufp; |
---|
268 | { |
---|
269 | while (*bufp != '\0') { |
---|
270 | if (isupper(*bufp)) *bufp = tolower(*bufp); |
---|
271 | bufp++; |
---|
272 | } |
---|
273 | } |
---|