+captive-bug-replay client to read --bug-pathname bugreports.
[captive.git] / src / client / bug-replay / main.c
1 /* $Id$
2  * developer replaying of bugreport snapshots
3  * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; exactly version 2 of June 1991 is required
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19
20 #include "config.h"
21
22 #include <glib/gmessages.h>
23 #include <stdlib.h>
24 #include <glib/giochannel.h>
25 #include <popt.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include <libxml/xmlreader.h>
29 #include <glib-object.h>        /* for g_type_init() */
30 #include <glib/ghash.h>
31
32 #include <captive/libxml.h>
33 #include <captive/options.h>
34 #include <captive/macros.h>
35 #include "../../libcaptive/client/giochannel-blind.h"   /* FIXME: pathname */
36 #include <captive/client-vfs.h>
37 #include <captive/client-directory.h>
38 #include <captive/client-file.h>
39
40
41 static gchar *optarg_module_path;
42
43 static const struct poptOption popt_table[]={
44 #define BUG_REPLAY_POPT(longname,argInfoP,argP,descripP,argDescripP) \
45                 { \
46                         longName: (longname), \
47                         shortName: 0, \
48                         argInfo: (argInfoP), \
49                         arg: (void *)argP, \
50                         val: 0, \
51                         descrip: (descripP), \
52                         argDescrip: (argDescripP), \
53                 }
54
55                 BUG_REPLAY_POPT("module-path",POPT_ARG_STRING,&optarg_module_path,N_("Disk path for W32 modules and filesystem"),N_("path")),
56
57 #undef BUG_REPLAY_POPT
58                 POPT_AUTOHELP
59                 POPT_TABLEEND
60                 };
61
62
63 static void object_hash_key_destroy_func(const xmlChar *xml_object)
64 {
65         g_return_if_fail(xml_object!=NULL);
66
67         xmlFree((xmlChar *)xml_object);
68 }
69
70 static void object_hash_value_destroy_func(GObject *captive_any_object)
71 {
72         g_return_if_fail(G_IS_OBJECT(captive_any_object));
73
74         g_object_unref(captive_any_object);
75 }
76
77
78 int main(int argc,char **argv)
79 {
80 poptContext context;
81 int errint;
82 const char **cmd_argv;
83 struct captive_options options;
84 xmlTextReader *xml_reader;
85 GList *action_list;     /* of 'xmlNode *' */
86 gboolean preread;
87 gboolean module_is_filesystem=FALSE;
88 CaptiveVfsObject *captive_vfs_object;
89 gboolean action_is_first;
90 xmlNode *xml_node;
91 GHashTable *object_hash;
92 GObject *object;
93 gboolean errbool;
94 CaptiveDirectoryObject *captive_directory_object;
95 CaptiveFileObject *captive_file_object;
96 GnomeVFSResult errgnomevfsresult;
97 struct captive_libxml_string_drop_stack *drop_stack=NULL;
98 const xmlChar *xml_object;
99
100         /* Prevent output block buffering if redirecting stdout to file. */
101         setvbuf(stdout,(char *)NULL,_IONBF,0);
102         setvbuf(stderr,(char *)NULL,_IONBF,0);
103
104         /* Initialize GObject subsystem of GLib. */
105         g_type_init();
106
107         captive_options_init(&options);
108
109         context=poptGetContext(
110                         PACKAGE,        /* name */
111                         argc,(/*en-const*/const char **)argv,   /* argc,argv */
112                         popt_table,     /* options */
113                         POPT_CONTEXT_POSIXMEHARDER);    /* flags; && !POPT_CONTEXT_KEEP_FIRST */
114         if (context==NULL) {
115                 g_assert_not_reached(); /* argument recognization args_error */
116                 return EXIT_FAILURE;
117                 }
118         errint=poptReadDefaultConfig(context,
119                         TRUE);  /* useEnv */
120         if (errint!=0) {
121                 g_assert_not_reached(); /* argument recognization args_error */
122                 return EXIT_FAILURE;
123                 }
124         errint=poptGetNextOpt(context);
125         if (errint!=-1) {
126                 g_assert_not_reached(); /* some non-callbacked argument reached */
127                 return EXIT_FAILURE;
128                 }
129         cmd_argv=poptGetArgs(context);
130
131         if (!cmd_argv || !cmd_argv[0] || cmd_argv[1]) {
132                 g_error("Exactly one argument required - pathname to .captivebug.xml.gz bugreport to replay");
133                 return EXIT_FAILURE;
134                 }
135
136   options.rwmode=CAPTIVE_OPTION_RWMODE_BLIND;
137   options.debug_messages=TRUE;
138
139         options.image_iochannel=NULL;
140         action_list=NULL;
141         options.media=CAPTIVE_OPTION_MEDIA_UNKNOWN;
142
143         xml_reader=xmlNewTextReaderFilename(cmd_argv[0]);
144         g_assert(xml_reader!=NULL);
145         preread=FALSE;
146         while (preread || 1==xmlTextReaderRead(xml_reader)) {
147                 preread=FALSE;
148                 switch (xmlTextReaderNodeType(xml_reader)) {
149
150                         case CAPTIVE_XML_TEXT_READER_NODE_TYPE_COMMENT:
151                                 break;
152
153                         case CAPTIVE_XML_TEXT_READER_NODE_TYPE_TEXT:    /* Even empty nodes have some '#text'. */
154                                 break;
155
156                         case CAPTIVE_XML_TEXT_READER_NODE_TYPE_END:     /* We do not track tag ends. */
157                                 break;
158
159                         case CAPTIVE_XML_TEXT_READER_NODE_TYPE_START: {
160 const xmlChar *xml_name;
161
162                                 xml_name=xmlTextReaderName(xml_reader);
163                                 /**/ if (!xmlStrcmp(xml_name,"bug")) {  /* root tag */
164                                         }
165                                 else if (!xmlStrcmp(xml_name,"captive")) {
166 const xmlChar *xml_captive_version;
167
168                                         xml_captive_version=captive_libxml_string_drop(&drop_stack,xmlTextReaderGetAttribute(xml_reader,"version"));
169                                         g_assert(xml_captive_version!=NULL);
170                                         g_assert(!xmlStrcmp(xml_captive_version,VERSION));
171                                         }
172                                 else if (!xmlStrcmp(xml_name,"filesystem")) {   /* contains <module/> */
173                                         module_is_filesystem=TRUE;
174                                         }
175                                 else if (!xmlStrcmp(xml_name,"load_module")) {  /* contains <module/> */
176                                         module_is_filesystem=FALSE;
177                                         }
178                                 else if (!xmlStrcmp(xml_name,"module")) {
179 const xmlChar *xml_module_basename;
180 struct captive_options_module *options_module;
181 gboolean errbool;
182
183                                         if (module_is_filesystem)
184                                                 options_module=&options.filesystem;
185                                         else {
186                                                 captive_new(options_module);
187                                                 options.load_module=g_list_append(options.load_module,options_module);
188                                                 }
189                                         xml_module_basename=captive_libxml_string_drop(&drop_stack,xmlTextReaderGetAttribute(xml_reader,"basename"));
190                                         g_assert(xml_module_basename!=NULL);
191                                         g_assert(strchr(xml_module_basename,'/')==NULL);        /* a bit of security */
192                                         errbool=captive_options_module_load(options_module,
193                                                         captive_printf_alloca("%s/%s",
194                                                                         (optarg_module_path ? optarg_module_path : "."),xml_module_basename));
195                                         g_assert(errbool==TRUE);
196                                         switch (options_module->type) {
197                                                 case CAPTIVE_OPTIONS_MODULE_TYPE_PE32: {
198 const xmlChar *xml_module_md5,*xml_module_length;
199
200                                                         if (options_module->u.pe32.md5
201                                                                         && (xml_module_md5=captive_libxml_string_drop(&drop_stack,xmlTextReaderGetAttribute(xml_reader,"version"))))
202                                                                 g_assert(!xmlStrcmp(xml_module_md5,options_module->u.pe32.md5));
203                                                         if ((xml_module_length=captive_libxml_string_drop(&drop_stack,xmlTextReaderGetAttribute(xml_reader,"length"))))
204                                                                 g_assert(!xmlStrcmp(xml_module_length,
205                                                                                 captive_printf_alloca("%lu",(unsigned long)options_module->u.pe32.length)));
206                                                         } break;
207                                                 case CAPTIVE_OPTIONS_MODULE_TYPE_GMODULE:
208                                                         /* No possibility to check anything. */
209                                                         break;
210                                                 default: g_assert_not_reached();
211                                                 }
212                                         }
213                                 else if (!xmlStrcmp(xml_name,"action")) {
214 int xml_action_depth;
215 gboolean action_done,action_preread;
216
217                                         g_assert(action_list==NULL);
218                                         xml_action_depth=xmlTextReaderDepth(xml_reader);
219                                         action_preread=FALSE;
220                                         action_done=FALSE;
221                                         while (!action_done) {
222                                                 if (!action_preread) {
223                                                         errint=xmlTextReaderRead(xml_reader);
224                                                         g_assert(errint==1);
225                                                         }
226                                                 action_preread=FALSE;
227                                                 g_assert(xml_action_depth<=xmlTextReaderDepth(xml_reader));
228                                                 switch (xmlTextReaderNodeType(xml_reader)) {
229                                                         case CAPTIVE_XML_TEXT_READER_NODE_TYPE_COMMENT:
230                                                                 break;
231                                                         case CAPTIVE_XML_TEXT_READER_NODE_TYPE_TEXT:    /* Even empty nodes have some '#text'. */
232                                                                 break;
233                                                         case CAPTIVE_XML_TEXT_READER_NODE_TYPE_END: {   /* We do not track tag ends. */
234                                                                 if ((action_done=(xml_action_depth==xmlTextReaderDepth(xml_reader)))) {
235 const xmlChar *xml_name_end;
236
237                                                                         xml_name_end=captive_libxml_string_drop(&drop_stack,xmlTextReaderName(xml_reader));
238                                                                         g_assert(!xmlStrcmp(xml_name_end,"action"));
239                                                                         }
240                                                                 } break;
241                                                         case CAPTIVE_XML_TEXT_READER_NODE_TYPE_START: {
242 xmlNode *xml_node;
243                                                                 
244                                                                 xml_node=xmlTextReaderExpand(xml_reader);
245                                                                 g_assert(xml_node!=NULL);
246                                                                 xml_node=xmlCopyNode(xml_node,
247                                                                                 1);     /* recursive */
248                                                                 errint=xmlTextReaderNext(xml_reader);
249                                                                 g_assert(errint==1);
250                                                                 action_preread=TRUE;
251                                                                 action_list=g_list_prepend(action_list,xml_node);       /* we are prepending to be effective */
252                                                                 } break;
253                                                         default: g_assert_not_reached();
254                                                         }
255                                                 }
256                                         }
257                                 else if (!xmlStrcmp(xml_name,"media")) {
258 const xmlChar *xml_media_end_name,*xml_media_type;
259
260                                         g_assert(options.image_iochannel==NULL);
261                                         options.image_iochannel=(GIOChannel *)captive_giochannel_blind_new_from_xml(xml_reader);
262                                         g_assert(CAPTIVE_XML_TEXT_READER_NODE_TYPE_END==xmlTextReaderNodeType(xml_reader));
263                                         xml_media_end_name=xmlTextReaderName(xml_reader);
264                                         g_assert(xml_media_end_name!=NULL);
265                                         g_assert(!xmlStrcmp(xml_media_end_name,"media"));
266                                         xmlFree((xmlChar *)xml_media_end_name);
267                                         xml_media_type=xmlTextReaderGetAttribute(xml_reader,"type");
268                                         g_assert(xml_media_type!=NULL);
269                                         /**/ if (!xmlStrcmp(xml_media_type,"cdrom"))
270                                                 options.media=CAPTIVE_OPTION_MEDIA_CDROM;
271                                         else if (!xmlStrcmp(xml_media_type,"disk"))
272                                                 options.media=CAPTIVE_OPTION_MEDIA_DISK;
273                                         else g_assert_not_reached();
274                                         xmlFree((xmlChar *)xml_media_type);
275                                         }
276                                 else if (!xmlStrcmp(xml_name,"log")) {
277                                         errint=xmlTextReaderNext(xml_reader);
278                                         g_assert(errint==1);
279                                         preread=TRUE;
280                                         }
281                                 else g_error("Unknown START node: %s",xml_name);
282                                 xmlFree((xmlChar *)xml_name);
283                                 } break;
284
285                         default: g_assert_not_reached();
286                         }
287                 captive_libxml_string_drop_flush(&drop_stack);
288                 }
289         xmlFreeTextReader(xml_reader);
290
291         g_assert(options.image_iochannel!=NULL);
292         action_list=g_list_reverse(action_list);        /* we were g_list_prepend()ing for effectivity */
293         g_assert(options.media!=CAPTIVE_OPTION_MEDIA_UNKNOWN);
294
295         if (GNOME_VFS_OK!=captive_vfs_new(&captive_vfs_object,&options)) {
296                 g_error(_("captive_vfs_new() failed"));
297                 return EXIT_FAILURE;
298                 }
299         captive_options_free(&options);
300
301         /* 'cmd_argv' gets cleared by 'poptFreeContext(context);' below */
302         poptFreeContext(context);
303
304   object_hash=g_hash_table_new_full(
305                         g_str_hash,     /* hash_func */
306                         g_str_equal,    /* key_equal_func */
307                         (GDestroyNotify)object_hash_key_destroy_func,   /* key_destroy_func */
308                         (GDestroyNotify)object_hash_value_destroy_func);        /* value_destroy_func */
309
310         for (
311                         action_is_first=TRUE;
312                         action_list;
313                         xmlFreeNode(xml_node),action_is_first=FALSE) {
314
315                 captive_libxml_string_drop_flush(&drop_stack);
316
317 #define GET_PROP_STRING(prop_name) ({ \
318                 const xmlChar *_get_prop_string_r=captive_libxml_string_drop(&drop_stack,xmlGetProp(xml_node,(prop_name))); \
319                 g_assert(_get_prop_string_r!=NULL); \
320                 _get_prop_string_r; \
321                 })
322 #define GET_PROP_GINT64(prop_name) (captive_libxml_sscanf_gint64(GET_PROP_STRING((prop_name))))
323
324                 xml_node=action_list->data;
325                 g_assert(xml_node!=NULL);
326                 action_list=g_list_delete_link(action_list,action_list);
327                 g_message("replay action: %s()",xml_node->name);
328                 xml_object=GET_PROP_STRING("object");
329                 object=g_hash_table_lookup(object_hash,xml_object);
330                 g_assert(object==NULL || G_IS_OBJECT(object));
331
332                 if (!xmlStrcmp(xml_node->name,"vfs_new")) {
333                         g_assert(action_is_first==TRUE);
334                         g_assert(captive_vfs_object!=NULL);
335                         g_assert(object==NULL);
336                         g_hash_table_insert(object_hash,g_strdup(xml_object),captive_vfs_object);
337                         continue;
338                         }
339                 if (!xmlStrcmp(xml_node->name,"vfs_commit")) {
340                         g_assert(action_is_first==TRUE);
341                         g_assert(captive_vfs_object!=NULL);
342                         g_assert(object==NULL);
343                         g_hash_table_insert(object_hash,g_strdup(xml_object),captive_vfs_object);
344                         continue;
345                         }
346                 g_assert(action_is_first==FALSE);
347                 if (!xmlStrcmp(xml_node->name,"vfs_close")) {
348                         g_assert(captive_vfs_object!=NULL);
349                         g_assert(CAPTIVE_VFS_OBJECT(object)==captive_vfs_object);
350                         errbool=g_hash_table_remove(object_hash,xml_object);    /* g_object_unref() by object_hash_value_destroy_func() */
351                         g_assert(errbool==TRUE);
352                         continue;
353                         }
354                 g_assert(captive_vfs_object!=NULL);
355
356                 /* DIRECTORY */
357                 if (!xmlStrcmp(xml_node->name,"directory_new_open")) {
358                         g_assert(object==NULL);
359                         errgnomevfsresult=captive_directory_new_open(&captive_directory_object,captive_vfs_object,
360                                         GET_PROP_STRING("pathname"));
361                         g_assert((errgnomevfsresult==GNOME_VFS_OK)==GET_PROP_GINT64("result"));
362                         if (errgnomevfsresult==GNOME_VFS_OK)
363                                 g_hash_table_insert(object_hash,g_strdup(xml_object),captive_directory_object);
364                         continue;
365                         }
366                 if (!xmlStrcmp(xml_node->name,"directory_new_make")) {
367                         g_assert(object==NULL);
368                         errgnomevfsresult=captive_directory_new_make(&captive_directory_object,captive_vfs_object,
369                                         GET_PROP_STRING("pathname"),
370                                         GET_PROP_GINT64("perm"));
371                         g_assert((errgnomevfsresult==GNOME_VFS_OK)==GET_PROP_GINT64("result"));
372                         if (errgnomevfsresult==GNOME_VFS_OK)
373                                 g_hash_table_insert(object_hash,g_strdup(xml_object),captive_directory_object);
374                         continue;
375                         }
376                 if (!xmlStrcmp(xml_node->name,"directory_close")) {
377                         captive_directory_object=CAPTIVE_DIRECTORY_OBJECT(object);
378                         errbool=g_hash_table_remove(object_hash,xml_object);    /* g_object_unref() by object_hash_value_destroy_func() */
379                         g_assert(errbool==TRUE);
380                         continue;
381                         }
382                 if (!xmlStrcmp(xml_node->name,"directory_read")) {
383 GnomeVFSFileInfo file_info;
384
385                         captive_directory_object=CAPTIVE_DIRECTORY_OBJECT(object);
386                         errgnomevfsresult=captive_directory_read(captive_directory_object,&file_info);
387                         g_assert(!strcmp(gnome_vfs_result_to_string(errgnomevfsresult),GET_PROP_STRING("result")));
388                         continue;
389                         }
390                 if (!xmlStrcmp(xml_node->name,"directory_remove")) {
391                         captive_directory_object=CAPTIVE_DIRECTORY_OBJECT(object);
392                         errgnomevfsresult=captive_directory_remove(captive_directory_object);
393                         g_assert(!strcmp(gnome_vfs_result_to_string(errgnomevfsresult),GET_PROP_STRING("result")));
394                         continue;
395                         }
396
397                 /* FILE */
398                 if (!xmlStrcmp(xml_node->name,"file_new_open")) {
399                         g_assert(object==NULL);
400                         errgnomevfsresult=captive_file_new_open(&captive_file_object,captive_vfs_object,
401                                         GET_PROP_STRING("pathname"),
402                                         GET_PROP_GINT64("mode"));
403                         g_assert((errgnomevfsresult==GNOME_VFS_OK)==GET_PROP_GINT64("result"));
404                         if (errgnomevfsresult==GNOME_VFS_OK)
405                                 g_hash_table_insert(object_hash,g_strdup(xml_object),captive_file_object);
406                         continue;
407                         }
408                 if (!xmlStrcmp(xml_node->name,"file_new_create")) {
409                         g_assert(object==NULL);
410                         errgnomevfsresult=captive_file_new_create(&captive_file_object,captive_vfs_object,
411                                         GET_PROP_STRING("pathname"),
412                                         GET_PROP_GINT64("mode"),
413                                         GET_PROP_GINT64("exclusive"),
414                                         GET_PROP_GINT64("perm"));
415                         g_assert((errgnomevfsresult==GNOME_VFS_OK)==GET_PROP_GINT64("result"));
416                         if (errgnomevfsresult==GNOME_VFS_OK)
417                                 g_hash_table_insert(object_hash,g_strdup(xml_object),captive_file_object);
418                         continue;
419                         }
420                 if (!xmlStrcmp(xml_node->name,"file_close")) {
421                         captive_file_object=CAPTIVE_FILE_OBJECT(object);
422                         errbool=g_hash_table_remove(object_hash,xml_object);    /* g_object_unref() by object_hash_value_destroy_func() */
423                         g_assert(errbool==TRUE);
424                         continue;
425                         }
426                 if (!xmlStrcmp(xml_node->name,"file_read")) {
427 gpointer buffer;
428 GnomeVFSFileSize num_bytes,bytes_read;
429
430                         captive_file_object=CAPTIVE_FILE_OBJECT(object);
431                         num_bytes=GET_PROP_GINT64("num_bytes");
432                         buffer=g_malloc(num_bytes);
433                         errgnomevfsresult=captive_file_read(captive_file_object,buffer,num_bytes,&bytes_read);
434                         g_assert(!strcmp(gnome_vfs_result_to_string(errgnomevfsresult),GET_PROP_STRING("result")));
435                         if (errgnomevfsresult==GNOME_VFS_OK)
436                                 g_assert((gint64)bytes_read==GET_PROP_GINT64("bytes_read_return"));
437                         g_free(buffer);
438                         continue;
439                         }
440                 if (!xmlStrcmp(xml_node->name,"file_write")) {
441 gpointer buffer;
442 GnomeVFSFileSize num_bytes,bytes_written;
443
444                         captive_file_object=CAPTIVE_FILE_OBJECT(object);
445                         num_bytes=GET_PROP_GINT64("num_bytes");
446                         buffer=g_malloc(num_bytes);
447                         memset(buffer,'X',num_bytes);   /* FIXME: better pattern */
448                         errgnomevfsresult=captive_file_write(captive_file_object,buffer,num_bytes,&bytes_written);
449                         g_assert(!strcmp(gnome_vfs_result_to_string(errgnomevfsresult),GET_PROP_STRING("result")));
450                         if (errgnomevfsresult==GNOME_VFS_OK)
451                                 g_assert((gint64)bytes_written==GET_PROP_GINT64("bytes_written_return"));
452                         g_free(buffer);
453                         continue;
454                         }
455                 if (!xmlStrcmp(xml_node->name,"file_seek")) {
456 GnomeVFSSeekPosition whence;
457 const xmlChar *whence_string;
458
459                         captive_file_object=CAPTIVE_FILE_OBJECT(object);
460                         whence_string=GET_PROP_STRING("whence");
461                         /**/ if (!xmlStrcmp(whence_string,"start"  )) whence=GNOME_VFS_SEEK_START;
462                         else if (!xmlStrcmp(whence_string,"current")) whence=GNOME_VFS_SEEK_CURRENT;
463                         else if (!xmlStrcmp(whence_string,"end"    )) whence=GNOME_VFS_SEEK_END;
464                         else g_assert_not_reached();
465                         errgnomevfsresult=captive_file_seek(captive_file_object,whence,
466                                         GET_PROP_GINT64("offset"));
467                         g_assert(!strcmp(gnome_vfs_result_to_string(errgnomevfsresult),GET_PROP_STRING("result")));
468                         continue;
469                         }
470                 if (!xmlStrcmp(xml_node->name,"file_tell")) {
471 GnomeVFSFileOffset offset;
472
473                         captive_file_object=CAPTIVE_FILE_OBJECT(object);
474                         errgnomevfsresult=captive_file_tell(captive_file_object,&offset);
475                         g_assert(!strcmp(gnome_vfs_result_to_string(errgnomevfsresult),GET_PROP_STRING("result")));
476                         if (errgnomevfsresult==GNOME_VFS_OK)
477                                 g_assert((gint64)offset==GET_PROP_GINT64("offset"));
478                         continue;
479                         }
480                 if (!xmlStrcmp(xml_node->name,"file_remove")) {
481                         captive_file_object=CAPTIVE_FILE_OBJECT(object);
482                         errgnomevfsresult=captive_file_remove(captive_file_object);
483                         g_assert(!strcmp(gnome_vfs_result_to_string(errgnomevfsresult),GET_PROP_STRING("result")));
484                         continue;
485                         }
486                 if (!xmlStrcmp(xml_node->name,"file_file_info_get")) {
487 GnomeVFSFileInfo file_info;
488
489                         captive_file_object=CAPTIVE_FILE_OBJECT(object);
490                         errgnomevfsresult=captive_file_file_info_get(captive_file_object,&file_info);
491                         g_assert(!strcmp(gnome_vfs_result_to_string(errgnomevfsresult),GET_PROP_STRING("result")));
492                         continue;
493                         }
494                 if (!xmlStrcmp(xml_node->name,"file_file_info_set")) {
495 GnomeVFSFileInfo file_info;
496
497                         captive_file_object=CAPTIVE_FILE_OBJECT(object);
498                         /* FIXME: We do not have 'file_info' content in the bug file! */
499                         errgnomevfsresult=captive_file_file_info_get(captive_file_object,&file_info);
500                         g_assert(errgnomevfsresult==GNOME_VFS_OK);
501                         errgnomevfsresult=captive_file_file_info_set(captive_file_object,&file_info,
502                                         GET_PROP_GINT64("mask"));
503                         g_assert(!strcmp(gnome_vfs_result_to_string(errgnomevfsresult),GET_PROP_STRING("result")));
504                         continue;
505                         }
506                 if (!xmlStrcmp(xml_node->name,"file_truncate")) {
507                         captive_file_object=CAPTIVE_FILE_OBJECT(object);
508                         errgnomevfsresult=captive_file_truncate(captive_file_object,
509                                         GET_PROP_GINT64("file_size"));
510                         g_assert(!strcmp(gnome_vfs_result_to_string(errgnomevfsresult),GET_PROP_STRING("result")));
511                         continue;
512                         }
513                 if (!xmlStrcmp(xml_node->name,"file_move")) {
514                         captive_file_object=CAPTIVE_FILE_OBJECT(object);
515                         errgnomevfsresult=captive_file_move(captive_file_object,
516                                         GET_PROP_STRING("pathname_new"),
517                                         GET_PROP_GINT64("force_replace"));
518                         g_assert(!strcmp(gnome_vfs_result_to_string(errgnomevfsresult),GET_PROP_STRING("result")));
519                         continue;
520                         }
521
522                 g_error("Unknown action: %s()",xml_node->name);
523
524 #undef GET_PROP_GINT64
525 #undef GET_PROP_STRING
526                 }
527
528         g_error("All actions were processed, no vfs_close() found");
529         return EXIT_FAILURE;
530 }