libgnomevfs2-mythtv/modules/mythtv-method.c
author leo_sobral
Fri Mar 23 14:34:50 2007 +0000 (2007-03-23)
branchtrunk
changeset 441 f310d1d086b5
parent 408 7d529c58a88f
child 447 c632a2009bee
permissions -rwxr-xr-x
[svn r446] Object ref fixed
     1 /*
     2  * @author Hallyson Melo <hallyson.melo@indt.org.br>
     3  *
     4  * This program is free software; you can redistribute it and/or modify
     5  * it under the terms of the GNU Lesser General Public License as published by
     6  * the Free Software Foundation; either version 2 of the License, or
     7  * (at your option) any later version.
     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 Lesser 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 #ifdef HAVE_CONFIG_H
    20 #include <config.h>
    21 #endif
    22 
    23 #include <string.h>
    24 #include <glib.h>
    25 #include <glib/gprintf.h>
    26 #include <glib/gstdio.h>
    27 #include <math.h>
    28 
    29 #include <libgnomevfs/gnome-vfs-module.h>
    30 #include <libgnomevfs/gnome-vfs-utils.h>
    31 
    32 #include <gmyth/gmyth_file_transfer.h>
    33 #include <gmyth/gmyth_livetv.h>
    34 #include <gmyth/gmyth_uri.h>
    35 #include <gmyth/gmyth_recorder.h>
    36 #include <gmyth/gmyth_backendinfo.h>
    37 #include <gmyth/gmyth_util.h>
    38 #include <gmyth/gmyth_remote_util.h>
    39 #include <gmyth/gmyth_tvchain.h>
    40 #include <gmyth/gmyth_programinfo.h>
    41 
    42 #define GST_MYTHTV_ID_NUM               1
    43 #define MYTHTV_VERSION_DEFAULT          30
    44 #define MYTHTV_TRANSFER_MAX_WAITS       100
    45 
    46 /* internal GnomeVFS plug-in buffer size ( 120 Kbytes ) */
    47 #define MYTHTV_BUFFER_SIZE                          80*1024
    48 /* internally sized GnomeVFS plug-in buffer ( 4 Kbytes ) */
    49 #define MYTHTV_MAX_VFS_BUFFER_SIZE                  4096
    50 /* maximum number of bytes to be requested to the MythTV backend ( 64 Kbytes ) */
    51 #define MYTHTV_MAX_REQUEST_SIZE                     64*1024
    52 
    53 static GnomeVFSResult do_read (GnomeVFSMethod * method,
    54 			       GnomeVFSMethodHandle * method_handle,
    55 			       gpointer buffer,
    56 			       GnomeVFSFileSize num_bytes,
    57 			       GnomeVFSFileSize * bytes_read,
    58 			       GnomeVFSContext * context);
    59 
    60 typedef struct {
    61 	GMythFileTransfer *file_transfer;
    62 	GMythLiveTV *livetv;
    63 	gchar *channel_name;
    64 
    65 	gint mythtv_version;
    66 	gint64 content_size;
    67 	guint64 bytes_read;
    68 
    69 	GByteArray *buffer;
    70 	gsize buffer_remain;
    71 	gboolean is_livetv;
    72 
    73 	gboolean configured;
    74 
    75 } MythtvHandle;
    76 
    77 //static MythtvHandle *myth_handle = NULL;
    78 #ifdef DEBUG
    79 static FILE *fpout = NULL;
    80 static gboolean first = TRUE;
    81 #endif
    82 
    83 static GnomeVFSResult
    84 do_open (GnomeVFSMethod * method,
    85 	 GnomeVFSMethodHandle ** method_handle,
    86 	 GnomeVFSURI * uri,
    87 	 GnomeVFSOpenMode mode, GnomeVFSContext * context)
    88 {
    89 	MythtvHandle *myth_handle = NULL;
    90 	GMythBackendInfo *backend_info = NULL;
    91 	GMythURI *gmyth_uri = NULL;
    92 	gboolean ret = TRUE;
    93 
    94 	_GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL);
    95 	_GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL);
    96 
    97 	if (mode & GNOME_VFS_OPEN_WRITE) {
    98 		return GNOME_VFS_ERROR_NOT_PERMITTED;
    99 	}
   100 
   101 	if (gnome_vfs_uri_get_host_name (uri) == NULL) {
   102 		return GNOME_VFS_ERROR_INVALID_HOST_NAME;
   103 	}
   104 
   105     // FIXME: myth_handle is always NULL here
   106 	if ((NULL == myth_handle) || !myth_handle->configured) {
   107 		myth_handle = g_new0 (MythtvHandle, 1);
   108 
   109 		myth_handle->configured = FALSE;
   110 
   111 		myth_handle->is_livetv = FALSE;
   112 
   113 		/* Initialize mythtv handler */
   114 		myth_handle->file_transfer = NULL;
   115 		myth_handle->livetv = NULL;
   116 		myth_handle->mythtv_version = MYTHTV_VERSION_DEFAULT;
   117 		myth_handle->bytes_read = 0;
   118 		myth_handle->content_size = (GnomeVFSFileSize) - 1;
   119 
   120 		/* Creates and fills out the backend info structure */
   121 		backend_info =
   122 		    gmyth_backend_info_new_with_uri
   123 		    (gnome_vfs_unescape_string
   124 		     (gnome_vfs_uri_to_string
   125 		      (uri, GNOME_VFS_URI_HIDE_NONE), ""));
   126 
   127 		/* creates an instance of  */
   128 		gmyth_uri =
   129 		    gmyth_uri_new_with_value (gnome_vfs_unescape_string
   130 					      (gnome_vfs_uri_to_string
   131 					       (uri,
   132 						GNOME_VFS_URI_HIDE_NONE),
   133 					       ""));
   134 
   135 		myth_handle->is_livetv = gmyth_uri_is_livetv (gmyth_uri);
   136 
   137 		/* Connect to the backend */
   138 		if (gmyth_uri != NULL && myth_handle->is_livetv == TRUE) {
   139 
   140 			if (NULL == myth_handle->livetv) {
   141 				myth_handle->livetv = gmyth_livetv_new (backend_info);
   142 
   143 				myth_handle->channel_name =
   144 				    gmyth_uri_get_channel_name (gmyth_uri);
   145 
   146 				g_debug ("[%s] Channel name = %s\n",
   147 					 __FUNCTION__,
   148 					 myth_handle->channel_name);
   149 
   150 				if (myth_handle->channel_name != NULL) {
   151 					if (gmyth_livetv_channel_name_setup (myth_handle->livetv,
   152     					     myth_handle->channel_name) == FALSE) {
   153 						g_object_unref (gmyth_uri);
   154 						ret = FALSE;
   155 					}
   156 				} else {
   157 					if (gmyth_livetv_setup (myth_handle->livetv) == FALSE) {
   158 						g_object_unref (gmyth_uri);
   159 						ret = FALSE;
   160 					}
   161 				}
   162 			}
   163 
   164 			if (NULL == myth_handle->file_transfer) {
   165 				myth_handle->file_transfer =
   166 				    gmyth_livetv_create_file_transfer (myth_handle->livetv);
   167 
   168 				if (NULL == myth_handle->file_transfer) {
   169 					ret = FALSE;
   170 					g_debug
   171 					    ("MythTV FileTransfer is NULL!\n");
   172 					return GNOME_VFS_ERROR_NOT_OPEN;
   173 				}
   174 
   175 				if (!gmyth_file_transfer_open
   176 				    (myth_handle->file_transfer,
   177 				     myth_handle->livetv->uri !=
   178 				     NULL ?
   179 				     gmyth_uri_get_path (myth_handle->
   180 							 livetv->
   181 							 uri) :
   182 				     myth_handle->livetv->proginfo->
   183 				     pathname->str)) {
   184 					g_debug
   185 					    ("Couldn't open MythTV FileTransfer is NULL!\n");
   186 					g_object_unref (myth_handle->
   187 							file_transfer);
   188 					myth_handle->file_transfer = NULL;
   189 					ret = FALSE;
   190 				}
   191 			} /* if - FileTransfer is NULL, or not */
   192 		} else {
   193 			if (NULL == myth_handle->file_transfer) {
   194 
   195 				myth_handle->file_transfer =
   196 				    gmyth_file_transfer_new (backend_info);
   197 
   198 				/* Verifies if the file exists */
   199 				if (!gmyth_util_file_exists
   200 				    (backend_info,
   201 				     gmyth_uri_get_path (gmyth_uri))) {
   202 					g_object_unref (backend_info);
   203 					ret = FALSE;
   204 				}
   205 
   206 				/* sets the Playback monitor connection */
   207 				ret =
   208 				    gmyth_file_transfer_open (myth_handle->
   209 							      file_transfer,
   210 							      gmyth_uri_get_path
   211 							      (gmyth_uri));
   212 
   213 			}
   214 		} /* if - LiveTV or not? */
   215 
   216 		if (ret == FALSE) {
   217 			g_debug ("MythTV FileTransfer open error.\n");
   218 			return GNOME_VFS_ERROR_NOT_OPEN;
   219 		}
   220 
   221 		myth_handle->configured = TRUE;
   222 
   223 		g_object_unref (backend_info);
   224 
   225 		if (gmyth_uri != NULL)
   226 			g_object_unref (gmyth_uri);
   227 
   228 		myth_handle->buffer =
   229 		    g_byte_array_sized_new (MYTHTV_BUFFER_SIZE);
   230 		myth_handle->buffer_remain = 0;
   231 
   232 		g_return_val_if_fail (myth_handle->file_transfer != NULL,
   233 				      GNOME_VFS_ERROR_NOT_OPEN);
   234 
   235 		if ( /*myth_handle->file_transfer->filesize <= 0 && */
   236 		    myth_handle->is_livetv) {
   237 			myth_handle->content_size =
   238 			    gmyth_recorder_get_file_position (myth_handle->livetv->recorder);
   239 		} else {
   240 			myth_handle->content_size =
   241 			    myth_handle->file_transfer->filesize;
   242 		}
   243 
   244 	}
   245 	/* if - configured or not? */
   246 	*method_handle = (GnomeVFSMethodHandle *) myth_handle;
   247 
   248 	return GNOME_VFS_OK;
   249 }
   250 
   251 static GnomeVFSResult
   252 do_read (GnomeVFSMethod * method,
   253 	 GnomeVFSMethodHandle * method_handle,
   254 	 gpointer buffer,
   255 	 GnomeVFSFileSize num_bytes,
   256 	 GnomeVFSFileSize * bytes_read, 
   257      GnomeVFSContext * context)
   258 {
   259 	MythtvHandle *myth_handle = (MythtvHandle *) method_handle;
   260 	GnomeVFSFileSize bytes_to_read = num_bytes;
   261 
   262 	if (!myth_handle->is_livetv
   263 	    && (myth_handle->bytes_read >= myth_handle->content_size))
   264 		return GNOME_VFS_ERROR_EOF;
   265 
   266 	/* fixme: change this to min math function */
   267 	if ((myth_handle->content_size > 0)) {
   268 		if (!myth_handle->is_livetv &&
   269 		    (num_bytes >
   270 		     (myth_handle->content_size -
   271 		      myth_handle->bytes_read))) {
   272 			bytes_to_read =
   273 			    myth_handle->content_size -
   274 			    myth_handle->bytes_read;
   275 		}
   276 	}
   277 
   278 	/* Loop sending the Myth File Transfer request:
   279 	 * Retry whilst authentication fails and we supply it. */
   280 	if ((myth_handle->buffer_remain =
   281 	     myth_handle->buffer->len) < bytes_to_read) {
   282 		gint buffer_size;
   283 
   284 		while (MYTHTV_BUFFER_SIZE != myth_handle->buffer_remain) {
   285 			/* resize buffer length request to no more than MYTHTV_MAX_REQUEST_SIZE */
   286 			if ((MYTHTV_BUFFER_SIZE -
   287 			     myth_handle->buffer_remain) <=
   288 			    MYTHTV_MAX_REQUEST_SIZE)
   289 				buffer_size =
   290 				    MYTHTV_BUFFER_SIZE -
   291 				    myth_handle->buffer_remain;
   292 			else
   293 				buffer_size = MYTHTV_MAX_REQUEST_SIZE;
   294 
   295 			GByteArray *tmp_buffer = g_byte_array_new ();
   296 
   297 			g_debug ("Asking %d bytes (there is %d bytes in the buffer)\n",
   298 			     buffer_size, myth_handle->buffer_remain);
   299 
   300 			gint len =
   301 			    gmyth_file_transfer_read (myth_handle->
   302 						      file_transfer,
   303 						      tmp_buffer,
   304 						      buffer_size, TRUE);
   305 
   306 			if ( !myth_handle->is_livetv ) {
   307 				if ( len < 0 ) {
   308 					g_byte_array_free (tmp_buffer, TRUE);
   309 					g_debug ("Fail to read bytes");
   310 					return GNOME_VFS_ERROR_IO;
   311 				} else if ( len == 0 ) {
   312 				   g_byte_array_free (tmp_buffer, TRUE);
   313 				   g_warning ("End of file probably achieved");
   314 				   return GNOME_VFS_ERROR_EOF;
   315 			   }
   316 			} /* if */
   317 			
   318 			myth_handle->buffer =
   319 			    g_byte_array_append (myth_handle->buffer,
   320 						 tmp_buffer->data, len);
   321 
   322 			myth_handle->buffer_remain += len;
   323 
   324 			if (tmp_buffer != NULL) {
   325 				g_byte_array_free (tmp_buffer, TRUE);
   326 				tmp_buffer = NULL;
   327 			}
   328 		}		/* while - iterates until fills the internal buffer */
   329 
   330 	}
   331         
   332 	/* if - got from the network, or not */
   333 	bytes_to_read =
   334 	    (bytes_to_read >
   335 	     myth_handle->buffer_remain) ? myth_handle->
   336 	    buffer_remain : bytes_to_read;
   337 	/* gets the first buffer_size bytes from the byte array buffer variable */
   338 
   339 	g_memmove (buffer, myth_handle->buffer->data, bytes_to_read);
   340 
   341 	myth_handle->bytes_read += bytes_to_read;
   342 	myth_handle->buffer_remain -= bytes_to_read;
   343 
   344 	/* flushs the newly buffer got from byte array */
   345 	myth_handle->buffer =
   346 	    g_byte_array_remove_range (myth_handle->buffer, 0,
   347 				       bytes_to_read);
   348 	g_debug
   349 	    ("Got from %llu bytes from internal buffer. (there are %d bytes in the buffer, from a total of %llu dispatched.)\n",
   350 	     bytes_to_read, myth_handle->buffer_remain,
   351 	     myth_handle->bytes_read);
   352 
   353 	*bytes_read = bytes_to_read;
   354 
   355 	return GNOME_VFS_OK;
   356 }
   357 
   358 static GnomeVFSResult
   359 do_close (GnomeVFSMethod * method,
   360 	  GnomeVFSMethodHandle * method_handle, GnomeVFSContext * context)
   361 {
   362 
   363 	MythtvHandle *myth_handle = (MythtvHandle *) method_handle;
   364 
   365 	//if ( NULL == myth_handle || myth_handle->configured ) {
   366 
   367 	if (myth_handle->is_livetv && myth_handle->livetv != NULL) {
   368 		g_object_unref (myth_handle->livetv);
   369 		myth_handle->livetv = NULL;
   370 	}
   371    
   372 	if (myth_handle->file_transfer != NULL) {
   373 		g_object_unref (myth_handle->file_transfer);
   374 		myth_handle->file_transfer = NULL;
   375 	}
   376 
   377 	if (myth_handle->buffer) {
   378 		g_byte_array_free (myth_handle->buffer, TRUE);
   379 		myth_handle->buffer = NULL;
   380 	}
   381 
   382 	myth_handle->configured = FALSE;
   383 
   384 	g_free (myth_handle->channel_name);
   385     
   386 	g_free (myth_handle);
   387 
   388 	myth_handle = NULL;
   389 
   390 	// }
   391 
   392 	return GNOME_VFS_OK;
   393 }
   394 
   395 static GnomeVFSResult
   396 do_get_file_info (GnomeVFSMethod * method,
   397 		  GnomeVFSURI * uri,
   398 		  GnomeVFSFileInfo * file_info,
   399 		  GnomeVFSFileInfoOptions options,
   400 		  GnomeVFSContext * context)
   401 {
   402 	GMythFileTransfer *file_transfer = NULL;
   403 	GMythRecorder *recorder = NULL;
   404 	GMythTVChain *tvchain = NULL;
   405 	GMythBackendInfo *backend_info = NULL;
   406 	GMythURI *gmyth_uri = NULL;
   407 	GMythSocket *socket = NULL;
   408 	gboolean is_livetv = FALSE;
   409 	gboolean ret = TRUE;
   410 	gboolean res = TRUE;
   411 
   412 	/* Creates and fills out the backend info structure */
   413 	backend_info =
   414 	    gmyth_backend_info_new_with_uri (gnome_vfs_unescape_string
   415 					     (gnome_vfs_uri_to_string
   416 					      (uri,
   417 					       GNOME_VFS_URI_HIDE_NONE),
   418 					      ""));
   419 
   420 	/* creates an instance of */
   421 	gmyth_uri =
   422 	    gmyth_uri_new_with_value (gnome_vfs_unescape_string
   423 				      (gnome_vfs_uri_to_string
   424 				       (uri, GNOME_VFS_URI_HIDE_NONE),
   425 				       ""));
   426 
   427 	is_livetv = gmyth_uri_is_livetv (gmyth_uri);
   428 
   429     file_info->valid_fields = 0;
   430 	file_info->valid_fields = file_info->valid_fields
   431 	    | GNOME_VFS_FILE_INFO_FIELDS_TYPE
   432 	    | GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE
   433 	    | GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
   434 	file_info->type = GNOME_VFS_FILE_TYPE_REGULAR;
   435 	/* fixme: get from file extension? */
   436 	file_info->mime_type = g_strdup ("video/x-nuv");
   437 	file_info->permissions =
   438 	    GNOME_VFS_PERM_USER_READ |
   439 	    GNOME_VFS_PERM_OTHER_READ | GNOME_VFS_PERM_GROUP_READ;
   440 
   441 	g_debug ("gnome_vfs_uri == %s | gmyth_uri == %s.\n",
   442 		 gnome_vfs_uri_get_path (uri),
   443 		 gmyth_uri_get_path (gmyth_uri));
   444 
   445 	/* Connect to the backend */
   446 	if (gmyth_uri != NULL && is_livetv == TRUE) {
   447 
   448 		/* start to get file info from LiveTV remote encoder */
   449 		socket = gmyth_socket_new ();
   450 
   451 		/* FIME: Implement this at gmyth_socket */
   452 		res =
   453 		    gmyth_socket_connect_to_backend (socket,
   454 						     backend_info->hostname,
   455 						     backend_info->port,
   456 						     TRUE);
   457 		if (!res) {
   458 			g_debug ("[%s] LiveTV can not connect to backend",  __FUNCTION__);
   459 			res = FALSE;
   460 			goto error;
   461 		}
   462 
   463 		if (gmyth_remote_util_get_free_recorder_count (socket) <= 0) {
   464 			g_debug ("No free remote encoder available.");
   465 			res = FALSE;
   466 			goto error;
   467 		}
   468 
   469 		/* Gets the recorder num */
   470 		recorder = remote_request_next_free_recorder (socket, -1);
   471 
   472 		if (socket != NULL)
   473 			g_object_unref (socket);
   474 
   475 		if (recorder == NULL) {
   476 			g_debug ("[%s] None remote encoder available", __FUNCTION__);
   477 			res = FALSE;
   478 			goto error;
   479 		}
   480 
   481 		/* Init remote encoder. Opens its control socket. */
   482 		res = gmyth_recorder_setup (recorder);
   483 		if (!res) {
   484 			g_debug ("[%s] Fail while setting remote encoder\n", __FUNCTION__);
   485 			res = FALSE;
   486 			goto error;
   487 		}
   488 
   489 		/* Creates livetv chain handler */
   490 		tvchain = gmyth_tvchain_new ();
   491 		gmyth_tvchain_initialize (tvchain, backend_info);
   492 
   493 		if (tvchain == NULL || tvchain->tvchain_id == NULL) {
   494 			res = FALSE;
   495 			goto error;
   496 		}
   497 		/* Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly) */
   498 		res = gmyth_recorder_spawntv (recorder, gmyth_tvchain_get_id(tvchain));
   499 		if (!res) {
   500 			g_warning ("[%s] Fail while spawn tv\n",
   501 				   __FUNCTION__);
   502 			res = FALSE;
   503 			goto error;
   504 		}
   505 		
   506 		sleep(1);
   507 
   508 		/* DEBUG message */
   509 		GMythProgramInfo *prog_info =
   510 		    gmyth_recorder_get_current_program_info (recorder);
   511 
   512 		if (prog_info != NULL) {
   513 
   514 			g_debug ("path = %s", prog_info->pathname->str);
   515 
   516 			file_info->name =
   517 			    g_strdup (g_strrstr
   518 				      (prog_info->pathname->str, "/"));
   519 
   520 		} else {
   521 			file_info->name = g_strdup ("LiveTV.nuv");
   522             /* Size being overrided below ... */
   523 			//file_info->size = gmyth_recorder_get_file_position (recorder);
   524 		}
   525 
   526 		if (recorder != NULL)
   527 			g_object_unref (recorder);
   528 
   529 		if (prog_info != NULL)
   530 			g_object_unref (prog_info);
   531 
   532 		if (tvchain != NULL)
   533 			g_object_unref (tvchain);
   534 
   535 		//file_info->size = (GnomeVFSFileSize) - 1;
   536 
   537 	} else {
   538 
   539         /* start to get file info from remote file encoder */
   540         file_transfer = gmyth_file_transfer_new (backend_info);
   541 
   542 		/* Verifies if the file exists */
   543     	if (!gmyth_util_file_exists (backend_info, gmyth_uri_get_path (gmyth_uri))) {
   544             g_object_unref (backend_info);
   545             return GNOME_VFS_ERROR_NOT_FOUND;
   546 		}
   547 
   548 		/* sets the Playback monitor connection */
   549 		ret = gmyth_file_transfer_open (file_transfer,
   550 					      gmyth_uri_get_path (gmyth_uri));
   551 
   552 		file_info->name = g_strdup (gnome_vfs_uri_get_path (uri));
   553 
   554 	} /* if - LiveTV or not? */
   555 
   556 	if (ret == FALSE) {
   557 		g_debug ("MythTV FileTransfer open error\n");
   558 		return GNOME_VFS_ERROR_NOT_OPEN;
   559 	}
   560 
   561     /* Just for recorded content */
   562 	if (ret == TRUE && file_transfer != NULL) {
   563 		file_info->size =
   564 		    gmyth_file_transfer_get_filesize (file_transfer);
   565 
   566         file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_SIZE;
   567         
   568 		if (file_transfer)
   569 			g_object_unref (file_transfer);
   570 	}
   571 
   572 error:
   573 	if (backend_info)
   574 		g_object_unref (backend_info);
   575 
   576 	if (!res)
   577 		return GNOME_VFS_ERROR_IO;
   578 
   579 	return GNOME_VFS_OK;
   580 }
   581 
   582 static gboolean
   583 do_is_local (GnomeVFSMethod * method, const GnomeVFSURI * uri)
   584 {
   585 	return FALSE;
   586 }
   587 
   588 static GnomeVFSMethod method = {
   589 	sizeof (GnomeVFSMethod),
   590 	do_open,
   591 	NULL,
   592 	do_close,
   593 	do_read,
   594 	NULL,
   595 	NULL,
   596 	NULL,
   597 	NULL,
   598 	NULL,
   599 	NULL,
   600 	NULL,
   601 	do_get_file_info,
   602 	NULL,
   603 	do_is_local,
   604 	NULL,
   605 	NULL,
   606 	NULL,
   607 	NULL,
   608 	NULL,
   609 	NULL,
   610 	NULL,
   611 	NULL,
   612 	NULL,
   613 	NULL,
   614 	NULL,
   615 	NULL,
   616 };
   617 
   618 
   619 GnomeVFSMethod *
   620 vfs_module_init (const char *method_name, const char *args)
   621 {
   622 	return &method;
   623 }
   624 
   625 void
   626 vfs_module_shutdown (GnomeVFSMethod * method)
   627 {
   628 }