/[MITgcm]/mitgcm.org/devel/buildweb/pkg/swish-e/src/extprog.c
ViewVC logotype

Contents of /mitgcm.org/devel/buildweb/pkg/swish-e/src/extprog.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1.1.1 - (show annotations) (download) (vendor branch)
Fri Sep 20 19:47:29 2002 UTC (22 years, 10 months ago) by adcroft
Branch: Import, MAIN
CVS Tags: baseline, HEAD
Changes since 1.1: +0 -0 lines
File MIME type: text/plain
Importing web-site building process.

1 /*
2 ** Copyright (C) 1995, 1996, 1997, 1998 Hewlett-Packard Company
3 ** Originally by Kevin Hughes, kev@kevcom.com, 3/11/94
4 **
5 ** This program and library is free software; you can redistribute it and/or
6 ** modify it under the terms of the GNU (Library) General Public License
7 ** as published by the Free Software Foundation; either version 2
8 ** of the License, or any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU (Library) General Public License for more details.
14 **
15 ** You should have received a copy of the GNU (Library) General Public License
16 ** long with this program; if not, write to the Free Software
17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 **--------------------------------------------------------------------
19 **
20 ** Mar 27, 2001 - created moseley
21 **
22 */
23
24 #ifndef _WIN32
25 #include <unistd.h>
26 #endif
27
28 #include "swish.h"
29 #include "mem.h"
30 #include "string.h"
31 #include "index.h"
32 #include "file.h"
33 #include "error.h"
34 #include "parse_conffile.h"
35
36 struct MOD_Prog
37 {
38 /* prog system specific configuration parameters */
39 struct swline *progparameterslist;
40 };
41
42
43 /*
44 -- init structures for this module
45 */
46
47 void initModule_Prog (SWISH *sw)
48 {
49 struct MOD_Prog *self;
50
51 self = (struct MOD_Prog *) emalloc(sizeof(struct MOD_Prog));
52 sw->Prog = self;
53
54 /* initialize buffers used by indexstring */
55 self->progparameterslist = (struct swline *) NULL;
56
57 return;
58 }
59
60 void freeModule_Prog (SWISH *sw)
61 {
62 struct MOD_Prog *self = sw->Prog;
63
64
65 if ( self->progparameterslist )
66 efree( self->progparameterslist );
67
68 efree ( self );
69 sw->Prog = NULL;
70
71 return;
72 }
73
74 int configModule_Prog (SWISH *sw, StringList *sl)
75
76 {
77 struct MOD_Prog *self = sw->Prog;
78 char *w0 = sl->word[0];
79
80 if (strcasecmp(w0, "SwishProgParameters") == 0)
81 {
82 if (sl->n > 1)
83 {
84 grabCmdOptions(sl, 1, &self->progparameterslist);
85 }
86 else
87 progerr("%s: requires at least one value", w0);
88 }
89
90 else
91 {
92 return 0; /* not a module directive */
93 }
94
95 return 1;
96 }
97
98
99
100 static FILE *open_external_program(SWISH * sw, char *prog)
101 {
102 char *cmd;
103 FILE *fp;
104 size_t total_len;
105 struct stat stbuf;
106 struct swline *progparameterslist = sw->Prog->progparameterslist;
107
108 if ( ! strcmp( prog, "stdin") )
109 return stdin;
110
111
112 /* get total length of configuration parameters */
113
114 total_len = strlen(prog);
115
116 while (progparameterslist)
117 {
118 total_len += strlen(progparameterslist->line) + 1; /* separate by spaces */
119 progparameterslist = progparameterslist->next;
120 }
121
122 cmd = emalloc(total_len + 20);
123 strcpy(cmd, prog);
124
125 normalize_path( cmd ); /* for stat calls */
126
127
128 /* this should probably be in file.c so filters.c can check, too */
129 /* note this won't catch errors in a shebang line, of course */
130
131 if (stat(cmd, &stbuf))
132 progerrno("External program '%s': ", cmd);
133
134 if ( stbuf.st_mode & S_IFDIR)
135 progerr("External program '%s' is a directory.", cmd);
136
137 #ifndef _WIN32
138
139 if ( access( cmd, R_OK|X_OK ) )
140 progerrno("Cannot execute '%s': ", cmd);
141
142 #endif
143
144 #ifdef _WIN32
145
146 make_windows_path( cmd );
147
148 #endif
149
150
151
152
153 progparameterslist = sw->Prog->progparameterslist;
154 while (progparameterslist)
155 {
156 strcat(cmd, " ");
157 strcat(cmd, progparameterslist->line);
158 progparameterslist = progparameterslist->next;
159 }
160
161
162 fp = popen(cmd, F_READ_TEXT);
163
164 if (!fp)
165 progerrno("Failed to spawn external program '%s': ", cmd);
166
167 efree(cmd);
168 return fp;
169 }
170
171 /* To make filters work with prog, need to write the file out to a temp file */
172 /* It will be faster to do the filtering from within the "prog" program */
173 /* This may not be safe if running as a threaded app, and I'm not clear on how portable this is */
174 /* This also uses read_stream to read in the file -- so the entire file is read into memory instead of chunked to the temp file */
175
176 static void save_to_temp_file(SWISH *sw, FileProp *fprop)
177 {
178 FILE *out;
179 char *rd_buffer = NULL; /* complete file read into buffer */
180 size_t bytes;
181
182
183 /* slirp entire file into memory -- yuck */
184 rd_buffer = read_stream(sw, fprop->real_path, fprop->fp, fprop->fsize, 0);
185
186
187 /* Save content to a temporary file */
188 efree( fprop->work_path );
189 out = create_tempfile(sw, F_WRITE_TEXT, "fltr", &fprop->work_path, 0 );
190
191 bytes = fwrite( rd_buffer, 1, fprop->fsize, out );
192
193 if ( bytes != (size_t)fprop->fsize )
194 progerrno("Failed to write temporary filter file '%s': ", fprop->work_path);
195
196
197 /* hide the fact that it's an external program */
198 fprop->fp = (FILE *) NULL;
199
200
201 //***JMRUIZ efree(rd_buffer);
202 fclose( out );
203
204 }
205
206
207
208 static void extprog_indexpath(SWISH * sw, char *prog)
209 {
210 FileProp *fprop;
211 FILE *fp;
212 char *ln;
213 char *real_path;
214 long fsize;
215 time_t mtime;
216 int index_no_content;
217 long truncate_doc_size;
218 int docType = 0;
219
220 mtime = 0;
221 fsize = 0;
222 index_no_content = 0;
223 real_path = NULL;
224
225 fp = open_external_program(sw, prog);
226
227 ln = emalloc(MAXSTRLEN + 1);
228
229 truncate_doc_size = sw->truncateDocSize;
230 sw->truncateDocSize = 0; /* can't truncate -- prog should make sure doc is not too large */
231 // $$$ This is no longer true with libxml push parser
232
233 // $$$ next time, break out the header parsing in its own function, please
234
235 /* loop on headers */
236 while (fgets(ln, MAXSTRLEN, fp) != NULL)
237 {
238 char *end;
239 char *line;
240 int has_filter = 0;
241
242 line = str_skip_ws(ln); /* skip leading white space */
243 end = strrchr(line, '\n'); /* replace \n with null -- better to remove trailing white space */
244
245 /* trim white space */
246 if (end)
247 {
248 while ( end > line && isspace( (int)*(end-1) ) )
249 end--;
250
251 *end = '\0';
252 }
253
254 if (strlen(line) == 0) /* blank line indicates body */
255 {
256 if (!fsize || !real_path)
257 progerr("External program failed to return required headers Path-Name: & Content-Length:");
258
259
260 /* Create the FileProp entry to describe this "file" */
261
262 /* This is not great -- really should make creating a fprop more generic */
263 /* this was done because file.c assumed that the "file" was on disk */
264 /* which has changed over time due to filters, http, and prog */
265
266 fprop = init_file_properties(sw);
267 fprop->real_path = real_path;
268 fprop->work_path = estrdup( real_path );
269 fprop->orig_path = estrdup( real_path );
270
271 /* Set the doc type from the header */
272 if ( docType )
273 fprop->doctype = docType;
274
275
276 /* set real_path, doctype, index_no_content, filter, stordesc */
277 init_file_prop_settings(sw, fprop);
278
279 fprop->fp = fp; /* stream to read from */
280 fprop->fsize = fsize; /* how much to read */
281 fprop->mtime = mtime;
282
283 /* header can force index_no_content */
284 if (index_no_content)
285 fprop->index_no_content++;
286
287
288 /* the quick hack to make filters work is for FilterOpen
289 * to see that fprop->fp is set, read it into a buffer
290 * write it to a temporary file, then call the filter
291 * program as noramlly is done. But much smarter to
292 * simply filter in the prog, after all. Faster, too.
293 */
294
295 if (fprop->hasfilter)
296 {
297 save_to_temp_file( sw , fprop );
298 has_filter++; /* save locally, in case it gets reset somewhere else */
299 }
300
301 if (sw->verbose >= 3)
302 printf("%s", real_path);
303 else if (sw->verbose >= 2)
304 printf("Processing %s...\n", real_path);
305
306
307 do_index_file(sw, fprop);
308
309 if ( has_filter && remove( fprop->work_path ) )
310 progwarnno("Error removing temporary file '%s': ", fprop->work_path);
311
312 free_file_properties(fprop);
313 // efree(real_path); free_file_properties will free the paths
314 real_path = NULL;
315 mtime = 0;
316 fsize = 0;
317 index_no_content = 0;
318
319 }
320
321
322 else /* we are reading headers */
323 {
324 if (strncasecmp(line, "Content-Length", 14) == 0)
325 {
326 char *x = strchr(line, ':');
327 if (!x)
328 progerr("Failed to parse Content-Length header '%s'", line);
329 fsize = strtol(++x, NULL, 10);
330 continue;
331 }
332
333 if (strncasecmp(line, "Last-Mtime", 10) == 0)
334 {
335 char *x = strchr(line, ':');
336 if (!x)
337 progerr("Failed to parse Last-Mtime header '%s'", line);
338 mtime = strtol(++x, NULL, 10);
339 continue;
340 }
341
342 if (strncasecmp(line, "No-Contents:", 12) == 0)
343 {
344 index_no_content++;
345 continue;
346 }
347
348
349 if (strncasecmp(line, "Path-Name", 9) == 0)
350 {
351 char *x = strchr(line, ':');
352 if (!x)
353 progerr("Failed to parse Path-Name header '%s'", line);
354
355 x = str_skip_ws(++x);
356 if (!*x)
357 progerr("Failed to find path name in Path-Name header '%s'", line);
358
359 real_path = emalloc(strlen(x) + 1);
360 strcpy(real_path, x);
361 continue;
362 }
363
364 if (strncasecmp(line, "Document-Type", 13) == 0)
365 {
366 char *x = strchr(line, ':');
367 if (!x)
368 progerr("Failed to parse Document-Type '%s'", line);
369
370 x = str_skip_ws(++x);
371 if (!*x)
372 progerr("Failed to documnet type in Document-Type header '%s'", line);
373
374 if ( !(docType = strtoDocType( x )) )
375 progerr("documnet type '%s' not a valid Swish-e document type in Document-Type header '%s'", x, line);
376
377 continue;
378 }
379
380 progwarn("Unknown header line: '%s' from program %s", line, prog);
381
382 }
383 }
384
385 efree(ln);
386
387 /* restore the setting */
388 sw->truncateDocSize = truncate_doc_size;
389
390 if ( pclose(fp) == -1 ) /* progerr("Failed to properly close external program"); */
391 progwarnno("Failed to properly close external program: ");
392
393 }
394
395
396
397
398
399 /* Don't use old method of config checking */
400 static int extprog_parseconfline(SWISH * sw, StringList *l)
401 {
402 return 0;
403 }
404
405
406
407 struct _indexing_data_source_def ExternalProgramDataSource = {
408 "External-Program",
409 "prog",
410 extprog_indexpath,
411 extprog_parseconfline
412 };

  ViewVC Help
Powered by ViewVC 1.1.22