1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* Test-method.c: Gnome-VFS testing method
4 Copyright (C) 2000 Eazel
6 The Gnome Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
11 The Gnome Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with the Gnome Library; see the file COPYING.LIB. If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
21 Authors: Seth Nickell (seth@eazel.com) */
23 /* Create a settings file and put it at PREFIX/etc/vfs/Test-conf.xml,
24 * then point gnome-vfs clients to test:<uri_minus_scheme> which will
25 * translate into the "real" method (e.g. test:///home/seth).
27 * The delay is in milliseconds.
29 * Here's a sample config file (pointing to the file method):
31 * <?xml version="1.0"?>
32 * <TestModule method="file">
33 * <function name="open_directory" delay="2000"/>
39 #include <glib/gstrfuncs.h>
40 #include <libgnomevfs/gnome-vfs-cancellable-ops.h>
41 #include <libgnomevfs/gnome-vfs-ops.h>
42 #include <libgnomevfs/gnome-vfs-i18n.h>
43 #include <libgnomevfs/gnome-vfs-module.h>
44 #include <libxml/parser.h>
45 #include <libxml/tree.h>
46 #include <libxml/xmlmemory.h>
51 #include <sys/types.h>
54 #define TEST_CONF_ENV_VARIABLE "GNOME_VFS_TEST_CONFIG_FILE"
60 gboolean override_result;
61 GnomeVFSResult overridden_result_value;
64 #define NUM_RESULT_STRINGS 41
66 static gboolean properly_initialized;
68 static char *test_method_name;
69 static GList *settings_list;
71 static const char * const
72 result_strings[NUM_RESULT_STRINGS] = {
74 "GNOME_VFS_ERROR_NOT_FOUND",
75 "GNOME_VFS_ERROR_GENERIC",
76 "GNOME_VFS_ERROR_INTERNAL",
77 "GNOME_VFS_ERROR_BAD_PARAMETERS",
78 "GNOME_VFS_ERROR_NOT_SUPPORTED",
80 "GNOME_VFS_ERROR_CORRUPTED_DATA",
81 "GNOME_VFS_ERROR_WRONG_FORMAT",
82 "GNOME_VFS_ERROR_BAD_FILE",
83 "GNOME_VFS_ERROR_TOO_BIG",
84 "GNOME_VFS_ERROR_NO_SPACE",
85 "GNOME_VFS_ERROR_READ_ONLY",
86 "GNOME_VFS_ERROR_INVALID_URI",
87 "GNOME_VFS_ERROR_NOT_OPEN",
88 "GNOME_VFS_ERROR_INVALID_OPEN_MODE",
89 "GNOME_VFS_ERROR_ACCESS_DENIED",
90 "GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES",
91 "GNOME_VFS_ERROR_EOF",
92 "GNOME_VFS_ERROR_NOT_A_DIRECTORY",
93 "GNOME_VFS_ERROR_IN_PROGRESS",
94 "GNOME_VFS_ERROR_INTERRUPTED",
95 "GNOME_VFS_ERROR_FILE_EXISTS",
96 "GNOME_VFS_ERROR_LOOP",
97 "GNOME_VFS_ERROR_NOT_PERMITTED",
98 "GNOME_VFS_ERROR_IS_DIRECTORY",
99 "GNOME_VFS_ERROR_NO_MEMORY",
100 "GNOME_VFS_ERROR_HOST_NOT_FOUND",
101 "GNOME_VFS_ERROR_INVALID_HOST_NAME",
102 "GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS",
103 "GNOME_VFS_ERROR_LOGIN_FAILED",
104 "GNOME_VFS_ERROR_CANCELLED",
105 "GNOME_VFS_ERROR_DIRECTORY_BUSY",
106 "GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY",
107 "GNOME_VFS_ERROR_TOO_MANY_LINKS",
108 "GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM",
109 "GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM",
110 "GNOME_VFS_ERROR_NAME_TOO_LONG",
111 "GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE",
112 "GNOME_VFS_NUM_ERRORS"
115 /* Module entry points. */
116 GnomeVFSMethod *vfs_module_init (const char *method_name,
118 void vfs_module_shutdown (GnomeVFSMethod *method);
121 translate_uri (GnomeVFSURI *uri)
123 GnomeVFSURI *translated_uri;
125 char *translated_uri_text;
128 uri_text = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE);
129 no_method = strchr (uri_text, ':');
131 if (test_method_name != NULL) {
132 translated_uri_text = g_strconcat (test_method_name,
135 translated_uri_text = NULL;
138 if (translated_uri_text != NULL) {
139 translated_uri = gnome_vfs_uri_new (translated_uri_text);
141 translated_uri = NULL;
144 g_free (translated_uri_text);
147 return translated_uri;
150 /* reads the configuration file and returns TRUE if there are special options for
151 this execution of the operation.
153 if TRUE is returned then result will contain the result the operation should return
154 and perform_operation will be TRUE if the operation should execute the underlying
157 static const OperationSettings *
158 get_operation_settings (const char *function_identifier)
160 static OperationSettings empty_settings;
162 OperationSettings *settings;
164 for (node = settings_list; node != NULL; node = node->next) {
165 settings = node->data;
166 if (g_ascii_strcasecmp (settings->operation_name, function_identifier) == 0) {
171 return &empty_settings;
174 static const OperationSettings *
175 start_operation (const char *name,
177 GnomeVFSURI **saved_uri)
179 const OperationSettings *settings;
182 settings = get_operation_settings (name);
184 tv.tv_sec = settings->delay / 1000;
185 tv.tv_usec = 1000 * (settings->delay % 1000);
186 select (0, NULL, NULL, NULL, &tv);
190 *uri = translate_uri (*uri);
195 static GnomeVFSResult
196 finish_operation (const OperationSettings *settings,
197 GnomeVFSResult result,
199 GnomeVFSURI **saved_uri)
202 gnome_vfs_uri_unref (*uri);
206 if (settings->override_result) {
207 return settings->overridden_result_value;
212 #define PERFORM_OPERATION(name, operation) \
214 const OperationSettings *settings; \
215 GnomeVFSURI *saved_uri; \
216 GnomeVFSResult result; \
218 if (!properly_initialized) { \
219 return GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE; \
222 settings = start_operation (#name, &uri, &saved_uri); \
223 if (settings->skip) { \
224 result = GNOME_VFS_OK; \
226 result = operation; \
228 return finish_operation (settings, result, \
233 #define PERFORM_OPERATION_NO_URI(name, operation) \
235 const OperationSettings *settings; \
236 GnomeVFSResult result; \
238 if (!properly_initialized) { \
239 return GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE; \
242 settings = start_operation (#name, NULL, NULL); \
243 if (settings->skip) { \
244 result = GNOME_VFS_OK; \
246 result = operation; \
248 return finish_operation (settings, result, \
253 parse_result_text (const char *result_text,
254 GnomeVFSResult *result_code)
258 for (i = 0; i < NUM_RESULT_STRINGS; i++) {
259 if (g_ascii_strcasecmp (result_text, result_strings[i]) == 0) {
269 load_settings (const char *filename)
274 OperationSettings *operation;
277 doc = xmlParseFile (filename);
280 || doc->xmlRootNode == NULL
281 || doc->xmlRootNode->name == NULL
282 || g_ascii_strcasecmp (doc->xmlRootNode->name, "testmodule") != 0) {
287 test_method_name = xmlGetProp (doc->xmlRootNode, "method");
289 for (node = doc->xmlRootNode->xmlChildrenNode; node != NULL; node = node->next) {
290 name = xmlGetProp (node, "name");
295 operation = g_new0 (OperationSettings, 1);
296 operation->operation_name = name;
298 str = xmlGetProp (node, "delay");
300 sscanf (str, "%d", &operation->delay);
304 str = xmlGetProp(node, "execute_operation");
305 if (str != NULL && g_ascii_strcasecmp (str, "FALSE") == 0) {
306 operation->skip = TRUE;
310 str = xmlGetProp (node, "result");
312 operation->override_result = parse_result_text
313 (str, &operation->overridden_result_value);
317 settings_list = g_list_prepend (settings_list, operation);
322 static GnomeVFSResult
323 do_open (GnomeVFSMethod *method,
324 GnomeVFSMethodHandle **method_handle,
326 GnomeVFSOpenMode mode,
327 GnomeVFSContext *context)
329 PERFORM_OPERATION (open, gnome_vfs_open_uri_cancellable ((GnomeVFSHandle **) method_handle, uri, mode, context));
332 static GnomeVFSResult
333 do_create (GnomeVFSMethod *method,
334 GnomeVFSMethodHandle **method_handle,
336 GnomeVFSOpenMode mode,
339 GnomeVFSContext *context)
341 /* FIXME bugzilla.eazel.com 3837: Not implemented. */
342 return GNOME_VFS_ERROR_INTERNAL;
345 static GnomeVFSResult
346 do_close (GnomeVFSMethod *method,
347 GnomeVFSMethodHandle *method_handle,
348 GnomeVFSContext *context)
350 PERFORM_OPERATION_NO_URI (close, gnome_vfs_close_cancellable ((GnomeVFSHandle *) method_handle, context));
353 static GnomeVFSResult
354 do_read (GnomeVFSMethod *method,
355 GnomeVFSMethodHandle *method_handle,
357 GnomeVFSFileSize num_bytes,
358 GnomeVFSFileSize *bytes_read,
359 GnomeVFSContext *context)
361 PERFORM_OPERATION_NO_URI (read, gnome_vfs_read_cancellable ((GnomeVFSHandle *) method_handle, buffer, num_bytes, bytes_read, context));
364 static GnomeVFSResult
365 do_write (GnomeVFSMethod *method,
366 GnomeVFSMethodHandle *method_handle,
367 gconstpointer buffer,
368 GnomeVFSFileSize num_bytes,
369 GnomeVFSFileSize *bytes_written,
370 GnomeVFSContext *context)
372 PERFORM_OPERATION_NO_URI (write, gnome_vfs_write_cancellable((GnomeVFSHandle *) method_handle, buffer, num_bytes, bytes_written, context));
375 static GnomeVFSResult
376 do_seek (GnomeVFSMethod *method,
377 GnomeVFSMethodHandle *method_handle,
378 GnomeVFSSeekPosition whence,
379 GnomeVFSFileOffset offset,
380 GnomeVFSContext *context)
382 PERFORM_OPERATION_NO_URI (seek, gnome_vfs_seek_cancellable ((GnomeVFSHandle *) method_handle, whence, offset, context));
385 static GnomeVFSResult
386 do_tell (GnomeVFSMethod *method,
387 GnomeVFSMethodHandle *method_handle,
388 GnomeVFSFileOffset *offset_return)
390 PERFORM_OPERATION_NO_URI (tell, gnome_vfs_tell ((GnomeVFSHandle *) method_handle, offset_return));
394 static GnomeVFSResult
395 do_open_directory (GnomeVFSMethod *method,
396 GnomeVFSMethodHandle **method_handle,
398 GnomeVFSFileInfoOptions options,
399 GnomeVFSContext *context)
401 PERFORM_OPERATION (open_directory, gnome_vfs_directory_open_from_uri ((GnomeVFSDirectoryHandle **) method_handle, uri, options));
404 static GnomeVFSResult
405 do_close_directory (GnomeVFSMethod *method,
406 GnomeVFSMethodHandle *method_handle,
407 GnomeVFSContext *context)
409 PERFORM_OPERATION_NO_URI (close_directory, gnome_vfs_directory_close ((GnomeVFSDirectoryHandle *) method_handle));
412 static GnomeVFSResult
413 do_read_directory (GnomeVFSMethod *method,
414 GnomeVFSMethodHandle *method_handle,
415 GnomeVFSFileInfo *file_info,
416 GnomeVFSContext *context)
418 PERFORM_OPERATION_NO_URI (read_directory, gnome_vfs_directory_read_next ((GnomeVFSDirectoryHandle *) method_handle, file_info));
421 static GnomeVFSResult
422 do_get_file_info (GnomeVFSMethod *method,
424 GnomeVFSFileInfo *file_info,
425 GnomeVFSFileInfoOptions options,
426 GnomeVFSContext *context)
428 PERFORM_OPERATION (get_file_info, gnome_vfs_get_file_info_uri_cancellable (uri, file_info, options, context));
431 static GnomeVFSResult
432 do_get_file_info_from_handle (GnomeVFSMethod *method,
433 GnomeVFSMethodHandle *method_handle,
434 GnomeVFSFileInfo *file_info,
435 GnomeVFSFileInfoOptions options,
436 GnomeVFSContext *context)
438 PERFORM_OPERATION_NO_URI (get_file_info_from_handle, gnome_vfs_get_file_info_from_handle_cancellable ((GnomeVFSHandle *) method_handle, file_info, options, context));
442 do_is_local (GnomeVFSMethod *method,
443 const GnomeVFSURI *uri)
445 /* FIXME bugzilla.eazel.com 3837: Not implemented. */
449 static GnomeVFSResult
450 do_make_directory (GnomeVFSMethod *method,
453 GnomeVFSContext *context)
455 PERFORM_OPERATION (make_directory, gnome_vfs_make_directory_for_uri_cancellable (uri, perm, context));
458 static GnomeVFSResult
459 do_remove_directory (GnomeVFSMethod *method,
461 GnomeVFSContext *context)
463 PERFORM_OPERATION (remove_directory, gnome_vfs_remove_directory_from_uri_cancellable (uri, context));
466 static GnomeVFSResult
467 do_move (GnomeVFSMethod *method,
468 GnomeVFSURI *old_uri,
469 GnomeVFSURI *new_uri,
470 gboolean force_replace,
471 GnomeVFSContext *context)
473 /* FIXME bugzilla.eazel.com 3837: Not implemented. */
474 return gnome_vfs_move_uri_cancellable (old_uri, new_uri, force_replace, context);
477 static GnomeVFSResult
478 do_unlink (GnomeVFSMethod *method,
480 GnomeVFSContext *context)
482 PERFORM_OPERATION (unlink, gnome_vfs_unlink_from_uri_cancellable (uri, context));
485 static GnomeVFSResult
486 do_check_same_fs (GnomeVFSMethod *method,
489 gboolean *same_fs_return,
490 GnomeVFSContext *context)
492 /* FIXME bugzilla.eazel.com 3837: Not implemented. */
493 return gnome_vfs_check_same_fs_uris_cancellable (a, b, same_fs_return, context);
496 static GnomeVFSResult
497 do_set_file_info (GnomeVFSMethod *method,
499 const GnomeVFSFileInfo *info,
500 GnomeVFSSetFileInfoMask mask,
501 GnomeVFSContext *context)
503 PERFORM_OPERATION (set_file_info, gnome_vfs_set_file_info_cancellable (uri, info, mask, context));
506 static GnomeVFSResult
507 do_truncate (GnomeVFSMethod *method,
509 GnomeVFSFileSize where,
510 GnomeVFSContext *context)
512 PERFORM_OPERATION (truncate, gnome_vfs_truncate_uri_cancellable (uri, where, context));
515 static GnomeVFSResult
516 do_truncate_handle (GnomeVFSMethod *method,
517 GnomeVFSMethodHandle *method_handle,
518 GnomeVFSFileSize where,
519 GnomeVFSContext *context)
521 PERFORM_OPERATION_NO_URI (truncate_handle, gnome_vfs_truncate_handle_cancellable ((GnomeVFSHandle *) method_handle, where, context));
524 static GnomeVFSResult
525 do_find_directory (GnomeVFSMethod *method,
527 GnomeVFSFindDirectoryKind kind,
528 GnomeVFSURI **result_uri,
529 gboolean create_if_needed,
530 gboolean find_if_needed,
532 GnomeVFSContext *context)
534 PERFORM_OPERATION (find_directory, gnome_vfs_find_directory_cancellable (uri, kind, result_uri, create_if_needed, find_if_needed, permissions, context));
537 static GnomeVFSResult
538 do_create_symbolic_link (GnomeVFSMethod *method,
540 const char *target_reference,
541 GnomeVFSContext *context)
543 PERFORM_OPERATION (create_symbolic_link, gnome_vfs_create_symbolic_link_cancellable (uri, target_reference, context));
546 static GnomeVFSMethod method = {
547 sizeof (GnomeVFSMethod),
560 do_get_file_info_from_handle,
570 do_create_symbolic_link
575 vfs_module_init (const char *method_name, const char *args)
581 conf_file = getenv (TEST_CONF_ENV_VARIABLE);
583 if (conf_file == NULL) {
584 conf_file = PREFIX "/etc/vfs/Test-conf.xml";
587 if (load_settings (conf_file) == FALSE) {
589 // FIXME: we probably shouldn't use printf to output the message
590 printf (_("Didn't find a valid settings file at %s\n"),
592 printf (_("Use the %s environment variable to specify a different location.\n"),
593 TEST_CONF_ENV_VARIABLE);
594 properly_initialized = FALSE;
596 properly_initialized = TRUE;
603 vfs_module_shutdown (GnomeVFSMethod *method)
606 OperationSettings *settings;
608 for (node = settings_list; node != NULL; node = node->next) {
609 settings = node->data;
610 xmlFree (settings->operation_name);
613 g_list_free (settings_list);
614 xmlFree (test_method_name);