aboutsummaryrefslogtreecommitdiff
path: root/src/main/extractor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/extractor.c')
-rw-r--r--src/main/extractor.c419
1 files changed, 10 insertions, 409 deletions
diff --git a/src/main/extractor.c b/src/main/extractor.c
index a529545..3faa897 100644
--- a/src/main/extractor.c
+++ b/src/main/extractor.c
@@ -39,398 +39,6 @@
39 39
40#if 0 40#if 0
41/** 41/**
42 * Open a file
43 */
44static int
45file_open (const char *filename, int oflag, ...)
46{
47 int mode;
48 const char *fn;
49#ifdef MINGW
50 char szFile[_MAX_PATH + 1];
51 long lRet;
52
53 if ((lRet = plibc_conv_to_win_path(filename, szFile)) != ERROR_SUCCESS)
54 {
55 errno = ENOENT;
56 SetLastError(lRet);
57 return -1;
58 }
59 fn = szFile;
60#else
61 fn = filename;
62#endif
63 mode = 0;
64#ifdef MINGW
65 /* Set binary mode */
66 mode |= O_BINARY;
67#endif
68 return OPEN(fn, oflag, mode);
69}
70
71
72/**
73 * Initializes plugin state. Calls init_state_method()
74 * directly or indirectly.
75 *
76 * @param plugin plugin to initialize
77 * @param operation_mode operation mode
78 * @param shm_name name of the shm/file
79 * @param fsize file size (may be -1)
80 */
81static void
82init_plugin_state (struct EXTRACTOR_PluginList *plugin,
83 uint8_t operation_mode,
84 const char *shm_name, int64_t fsize)
85{
86 int write_result;
87 int init_state_size;
88 unsigned char *init_state;
89 int t;
90 size_t shm_name_len = strlen (shm_name) + 1;
91
92 init_state_size = 1 + sizeof (size_t) + shm_name_len + sizeof (uint8_t) + sizeof (int64_t);
93 plugin->operation_mode = operation_mode;
94 switch (plugin->flags)
95 {
96 case EXTRACTOR_OPTION_DEFAULT_POLICY:
97 case EXTRACTOR_OPTION_OUT_OF_PROCESS_NO_RESTART:
98 init_state = malloc (init_state_size);
99 if (init_state == NULL)
100 {
101 stop_process (plugin);
102 return;
103 }
104 t = 0;
105 init_state[t] = MESSAGE_INIT_STATE;
106 t += 1;
107 memcpy (&init_state[t], &operation_mode, sizeof (uint8_t));
108 t += sizeof (uint8_t);
109 memcpy (&init_state[t], &fsize, sizeof (int64_t));
110 t += sizeof (int64_t);
111 memcpy (&init_state[t], &shm_name_len, sizeof (size_t));
112 t += sizeof (size_t);
113 memcpy (&init_state[t], shm_name, shm_name_len);
114 t += shm_name_len;
115 write_result = plugin_write (plugin, init_state, init_state_size);
116 free (init_state);
117 if (write_result < init_state_size)
118 {
119 stop_process (plugin);
120 return;
121 }
122 plugin->seek_request = 0;
123 break;
124 case EXTRACTOR_OPTION_IN_PROCESS:
125 init_state_method (plugin, operation_mode, fsize, shm_name);
126 return;
127 break;
128 case EXTRACTOR_OPTION_DISABLED:
129 return;
130 break;
131 }
132}
133
134
135/**
136 * Discards plugin state. Calls discard_state_method()
137 * directly or indirectly.
138 *
139 * @param plugin plugin to initialize
140 */
141static void
142discard_plugin_state (struct EXTRACTOR_PluginList *plugin)
143{
144 int write_result;
145 unsigned char discard_state = MESSAGE_DISCARD_STATE;
146
147 switch (plugin->flags)
148 {
149 case EXTRACTOR_OPTION_DEFAULT_POLICY:
150 case EXTRACTOR_OPTION_OUT_OF_PROCESS_NO_RESTART:
151 /* This is somewhat clumsy, but it's the only stop-indicating
152 * non-W32/POSIX-specific field i could think of...
153 */
154 if (plugin->cpipe_out != -1)
155 {
156 write_result = plugin_write (plugin, &discard_state, 1);
157 if (write_result < 1)
158 {
159 stop_process (plugin);
160 return;
161 }
162 }
163 break;
164 case EXTRACTOR_OPTION_IN_PROCESS:
165 discard_state_method (plugin);
166 return;
167 break;
168 case EXTRACTOR_OPTION_DISABLED:
169 return;
170 break;
171 }
172}
173
174
175/**
176 * Forces plugin to move the buffer window to 'pos'.
177 *
178 * @param plugin plugin context
179 * @param pos position to move to
180 * @param want_start 1 if the caller is interested in the beginning of the
181 * window, 0 if the caller is interested in its end. Window position
182 * must be aligned to page size, and this parameter controls the
183 * direction of window shift. 0 is used mostly by SEEK_END.
184 * @return 0 on success, -1 on error
185 */
186static int
187pl_pick_next_buffer_at (struct EXTRACTOR_PluginList *plugin,
188 int64_t pos,
189 uint8_t want_start)
190{
191 if (plugin->operation_mode == OPMODE_MEMORY)
192 {
193 int64_t old_pos;
194 int64_t gran_fix;
195#if !WINDOWS
196 if (plugin->shm_ptr != NULL)
197 munmap (plugin->shm_ptr, plugin->map_size);
198#else
199 if (plugin->shm_ptr != NULL)
200 UnmapViewOfFile (plugin->shm_ptr);
201#endif
202 plugin->shm_ptr = NULL;
203 old_pos = plugin->fpos + plugin->shm_pos;
204 if (pos < 0)
205 pos = 0;
206 if (pos > plugin->fsize)
207 pos = plugin->fsize - 1;
208 plugin->fpos = pos;
209 plugin->map_size = MAX_READ;
210 plugin->shm_pos = old_pos - plugin->fpos;
211 if (want_start)
212 gran_fix = -1 * (plugin->fpos % plugin->allocation_granularity);
213 else
214 {
215 gran_fix = plugin->fpos % plugin->allocation_granularity;
216 if (gran_fix > 0)
217 gran_fix = plugin->allocation_granularity - gran_fix;
218 }
219 if (plugin->fpos + gran_fix + plugin->map_size > plugin->fsize)
220 plugin->map_size = plugin->fsize - plugin->fpos - gran_fix;
221 plugin->fpos += gran_fix;
222#if !WINDOWS
223 if ((-1 == plugin->shm_id) ||
224 (NULL == (plugin->shm_ptr = mmap (NULL, plugin->map_size, PROT_READ, MAP_SHARED, plugin->shm_id, plugin->fpos))) ||
225 (plugin->shm_ptr == (void *) -1))
226 {
227 return -1;
228 }
229#else
230 LARGE_INTEGER off;
231 off.QuadPart = plugin->fpos;
232 if ((plugin->map_handle == 0) ||
233 (NULL == (plugin->shm_ptr = MapViewOfFile (plugin->map_handle, FILE_MAP_READ, off.HighPart, off.LowPart, plugin->map_size))))
234 {
235 DWORD err = GetLastError ();
236 return -1;
237 }
238#endif
239 plugin->shm_pos -= gran_fix;
240 return 0;
241 }
242 if (plugin->operation_mode == OPMODE_FILE)
243 {
244 int64_t old_pos;
245 int64_t gran_fix;
246#if !WINDOWS
247 if (plugin->shm_ptr != NULL)
248 munmap (plugin->shm_ptr, plugin->map_size);
249#else
250 if (plugin->shm_ptr != NULL)
251 UnmapViewOfFile (plugin->shm_ptr);
252#endif
253 plugin->shm_ptr = NULL;
254 old_pos = plugin->fpos + plugin->shm_pos;
255 if (pos < 0)
256 pos = 0;
257 if (pos > plugin->fsize)
258 pos = plugin->fsize - 1;
259 plugin->fpos = pos;
260 plugin->map_size = MAX_READ;
261 plugin->shm_pos = old_pos - plugin->fpos;
262 if (want_start)
263 gran_fix = -1 * (plugin->fpos % plugin->allocation_granularity);
264 else
265 {
266 gran_fix = plugin->fpos % plugin->allocation_granularity;
267 if (gran_fix > 0)
268 gran_fix = plugin->allocation_granularity - gran_fix;
269 }
270 if (plugin->fpos + gran_fix + plugin->map_size > plugin->fsize)
271 plugin->map_size = plugin->fsize - plugin->fpos - gran_fix;
272 plugin->fpos += gran_fix;
273#if !WINDOWS
274 if ((-1 == plugin->shm_id) ||
275 (NULL == (plugin->shm_ptr = mmap (NULL, plugin->map_size, PROT_READ, MAP_SHARED, plugin->shm_id, plugin->fpos))) ||
276 (plugin->shm_ptr == (void *) -1))
277 {
278 return -1;
279 }
280#else
281 LARGE_INTEGER off;
282 off.QuadPart = plugin->fpos;
283 if ((plugin->map_handle == 0) ||
284 (NULL == (plugin->shm_ptr = MapViewOfFile (plugin->map_handle, FILE_MAP_READ, off.HighPart, off.LowPart, plugin->map_size))))
285 {
286 DWORD err = GetLastError ();
287 return -1;
288 }
289#endif
290 plugin->shm_pos -= gran_fix;
291 return 0;
292 }
293 if (plugin->operation_mode == OPMODE_DECOMPRESS)
294 {
295 if (plugin->pipe_in != 0)
296 {
297 int64_t old_pos;
298 old_pos = plugin->fpos + plugin->shm_pos;
299 plugin->seek_request = pos;
300 /* Recourse into request loop to wait for shm update */
301 while (plugin->fpos != pos)
302 {
303 plugin->waiting_for_update = 1;
304 if (process_requests (plugin) < 0)
305 return -1;
306 plugin->waiting_for_update = 0;
307 }
308 plugin->shm_pos = old_pos - plugin->fpos;
309 }
310 else
311 {
312 if (pos < plugin->fpos)
313 {
314 if (1 != cfs_reset_stream (plugin->pass_cfs))
315 return -1;
316 }
317 while (plugin->fpos < pos && plugin->fpos >= 0)
318 plugin->fpos = cfs_seek (plugin->pass_cfs, pos);
319 plugin->fsize = ((struct CompressedFileSource *)plugin->pass_cfs)->uncompressed_size;
320 plugin->shm_pos = pos - plugin->fpos;
321 }
322 return 0;
323 }
324 return -1;
325}
326
327
328
329
330/**
331 * Transmits information about updated shm to plugin.
332 * For OPMODE_DECOMPRESS only.
333 *
334 * @param plugin plugin context
335 * @param position current absolute position in uncompressed stream
336 * @param map_size number of bytes that are available in shm
337 * @param fsize total size of the uncompressed stream (might be -1)
338 * @param operation_mode mode of operation
339 * @return 0 on success, 1 on error
340 */
341static int
342give_shm_to_plugin (struct EXTRACTOR_PluginList *plugin,
343 int64_t position,
344 size_t map_size, int64_t fsize,
345 uint8_t operation_mode)
346{
347 int write_result;
348 int updated_shm_size = 1 + sizeof (int64_t) + sizeof (size_t) + sizeof (int64_t);
349 unsigned char updated_shm[updated_shm_size];
350 int t = 0;
351
352 updated_shm[t] = MESSAGE_UPDATED_SHM;
353 t++;
354 memcpy (&updated_shm[t], &position, sizeof (int64_t));
355 t += sizeof (int64_t);
356 memcpy (&updated_shm[t], &map_size, sizeof (size_t));
357 t += sizeof (size_t);
358 memcpy (&updated_shm[t], &fsize, sizeof (int64_t));
359 t += sizeof (int64_t);
360 switch (plugin->flags)
361 {
362 case EXTRACTOR_OPTION_DEFAULT_POLICY:
363 case EXTRACTOR_OPTION_OUT_OF_PROCESS_NO_RESTART:
364 if (operation_mode == OPMODE_DECOMPRESS)
365 {
366 if (plugin->seek_request < 0)
367 return 0;
368 write_result = plugin_write (plugin, updated_shm, updated_shm_size);
369 if (write_result < updated_shm_size)
370 {
371 stop_process (plugin);
372 return 0;
373 }
374 }
375 return 1;
376 case EXTRACTOR_OPTION_IN_PROCESS:
377 if (operation_mode == OPMODE_DECOMPRESS)
378 {
379 plugin->fpos = position;
380 plugin->map_size = map_size;
381 plugin->fsize = fsize;
382 }
383 return 0;
384 case EXTRACTOR_OPTION_DISABLED:
385 return 0;
386 default:
387 return 1;
388 }
389}
390
391
392/**
393 * Calls _extract_method of in-process plugin.
394 *
395 * @param plugin plugin context
396 * @param shm_ptr pointer to the data buffer
397 * @param proc metadata callback
398 * @param proc_cls callback cls
399 */
400static void
401ask_in_process_plugin (struct EXTRACTOR_PluginList *plugin,
402 void *shm_ptr,
403 EXTRACTOR_MetaDataProcessor proc, void *proc_cls)
404{
405 int extract_reply;
406
407 switch (plugin->flags)
408 {
409 case EXTRACTOR_OPTION_DEFAULT_POLICY:
410 case EXTRACTOR_OPTION_OUT_OF_PROCESS_NO_RESTART:
411 return;
412 case EXTRACTOR_OPTION_IN_PROCESS:
413 if (plugin->seek_request >= 0)
414 {
415 plugin->shm_ptr = shm_ptr;
416 extract_reply = plugin->extract_method (plugin, proc, proc_cls);
417 /* Don't leak errno from the extract method */
418 errno = 0;
419 if (1 == extract_reply)
420 plugin->seek_request = -1;
421 }
422 break;
423 case EXTRACTOR_OPTION_DISABLED:
424 return;
425 break;
426 }
427}
428
429
430
431
432
433/**
434 * Checks the seek requests that plugins made, finds the one with 42 * Checks the seek requests that plugins made, finds the one with
435 * smallest offset from the beginning of the stream, and satisfies it. 43 * smallest offset from the beginning of the stream, and satisfies it.
436 * 44 *
@@ -476,22 +84,6 @@ seek_to_new_position (struct EXTRACTOR_PluginList *plugins,
476 } 84 }
477 return cfs_seek (cfs, min_pos); 85 return cfs_seek (cfs, min_pos);
478} 86}
479
480
481static void
482load_in_process_plugin (struct EXTRACTOR_PluginList *plugin)
483{
484 switch (plugin->flags)
485 {
486 case EXTRACTOR_OPTION_DEFAULT_POLICY:
487 case EXTRACTOR_OPTION_OUT_OF_PROCESS_NO_RESTART:
488 case EXTRACTOR_OPTION_DISABLED:
489 break;
490 case EXTRACTOR_OPTION_IN_PROCESS:
491 EXTRACTOR_plugin_load_ (plugin);
492 break;
493 }
494}
495#endif 87#endif
496 88
497 89
@@ -621,6 +213,15 @@ do_extract (struct EXTRACTOR_PluginList *plugins,
621 done = 0; 213 done = 0;
622 } 214 }
623 } 215 }
216
217 /* run in-process plugins */
218 for (pos = plugins; NULL != pos; pos = pos->next)
219 {
220 if (EXTRACTOR_OPTION_IN_PROCESS != pos->flags)
221 continue;
222 // FIXME: initialize read/seek context...
223 // pos->extract_method (FIXME);
224 }
624} 225}
625 226
626 227
@@ -668,7 +269,7 @@ EXTRACTOR_extract (struct EXTRACTOR_PluginList *plugins,
668 shm = EXTRACTOR_IPC_shared_memory_create_ (DEFAULT_SHM_SIZE); 269 shm = EXTRACTOR_IPC_shared_memory_create_ (DEFAULT_SHM_SIZE);
669 for (pos = plugins; NULL != pos; pos = pos->next) 270 for (pos = plugins; NULL != pos; pos = pos->next)
670 if ( (NULL == pos->shm) && 271 if ( (NULL == pos->shm) &&
671 (0 == (pos->flags & EXTRACTOR_OPTION_IN_PROCESS)) ) 272 (EXTRACTOR_OPTION_IN_PROCESS == pos->flags) )
672 { 273 {
673 pos->shm = shm; 274 pos->shm = shm;
674 pos->channel = EXTRACTOR_IPC_channel_create_ (pos, 275 pos->channel = EXTRACTOR_IPC_channel_create_ (pos,