~ubuntu-branches/ubuntu/warty/gnome-vfs2/warty

« back to all changes in this revision

Viewing changes to modules/computer-method.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2004-10-11 16:04:46 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20041011160446-lc0ervct24rylahc
Tags: 2.8.2-0ubuntu1
* New upstream release:
  - performance increase in gnome-vfs-volume-monitor.
  - make folders open with components, to make run-dialog work for folders.
  - add support for additional headers to http backend (Warty: #2163).
  - default to the workgroup specified in smb.conf for network://.
* debian/patches/13_ssl_crash.patch:
  - removed, these changes are in the new version.
* debian/patches/14_default-workgroup.patch:
  - removed, these changes are in the new version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 
2
/* computer-method.c - The 
 
3
 
 
4
   Copyright (C) 2003 Red Hat, Inc
 
5
 
 
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.
 
10
 
 
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.
 
15
 
 
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.
 
20
 
 
21
   Authors:
 
22
         Alexander Larsson <alexl@redhat.com>
 
23
 */
 
24
 
 
25
#include <config.h>
 
26
 
 
27
#include <stdlib.h>
 
28
#include <string.h>
 
29
 
 
30
#include <libgnomevfs/gnome-vfs-i18n.h>
 
31
#include <libgnomevfs/gnome-vfs-module-shared.h>
 
32
#include <libgnomevfs/gnome-vfs-module.h>
 
33
#include <libgnomevfs/gnome-vfs-volume-monitor.h>
 
34
#include <libgnomevfs/gnome-vfs-utils.h>
 
35
#include <libgnomevfs/gnome-vfs-monitor-private.h>
 
36
 
 
37
typedef enum {
 
38
        COMPUTER_HOME_LINK,
 
39
        COMPUTER_ROOT_LINK,
 
40
        COMPUTER_DRIVE,
 
41
        COMPUTER_VOLUME,
 
42
        COMPUTER_NETWORK_LINK
 
43
} ComputerFileType;
 
44
 
 
45
typedef struct {
 
46
        char *file_name; /* Not encoded */
 
47
        ComputerFileType type;
 
48
 
 
49
        GnomeVFSVolume *volume;
 
50
        GnomeVFSDrive *drive;
 
51
        
 
52
        GList *file_monitors;
 
53
} ComputerFile;
 
54
 
 
55
typedef struct {
 
56
        GList *files;
 
57
        GList *dir_monitors;
 
58
} ComputerDir;
 
59
 
 
60
typedef struct {
 
61
        GnomeVFSMonitorType type;
 
62
        ComputerFile *file;
 
63
} ComputerMonitor;
 
64
 
 
65
static ComputerDir *root_dir = NULL;
 
66
 
 
67
G_LOCK_DEFINE_STATIC (root_dir);
 
68
 
 
69
static ComputerFile *
 
70
computer_file_new (ComputerFileType type)
 
71
{
 
72
        ComputerFile *file;
 
73
 
 
74
        file = g_new0 (ComputerFile, 1);
 
75
        file->type = type;
 
76
        
 
77
        return file;
 
78
}
 
79
 
 
80
static void
 
81
computer_file_free (ComputerFile *file)
 
82
{
 
83
        GList *l;
 
84
        ComputerMonitor *monitor;
 
85
        
 
86
        if (file->type == COMPUTER_VOLUME) {
 
87
                gnome_vfs_volume_unref (file->volume);
 
88
        }
 
89
        if (file->type == COMPUTER_DRIVE) {
 
90
                gnome_vfs_drive_unref (file->drive);
 
91
        }
 
92
        
 
93
        for (l = file->file_monitors; l != NULL; l = l->next) {
 
94
                monitor = l->data;
 
95
                monitor->file = NULL;
 
96
        }
 
97
        g_list_free (file->file_monitors);
 
98
        
 
99
        g_free (file);
 
100
}
 
101
 
 
102
static GnomeVFSURI *
 
103
computer_file_get_uri (ComputerFile *file) {
 
104
        GnomeVFSURI *uri;
 
105
        GnomeVFSURI *tmp;
 
106
 
 
107
        uri = gnome_vfs_uri_new ("computer:///");
 
108
        if (file != NULL) {
 
109
                tmp = uri;
 
110
                uri = gnome_vfs_uri_append_file_name (uri, file->file_name);
 
111
                gnome_vfs_uri_unref (tmp);
 
112
        }
 
113
        return uri;
 
114
}
 
115
 
 
116
 
 
117
static void
 
118
computer_file_add (ComputerDir *dir, ComputerFile *file)
 
119
{
 
120
        ComputerMonitor *monitor;
 
121
        GList *l;
 
122
        GnomeVFSURI *uri;
 
123
 
 
124
        dir->files = g_list_prepend (dir->files, file);
 
125
 
 
126
        uri = computer_file_get_uri (file);
 
127
        for (l = dir->dir_monitors; l != NULL; l = l->next) {
 
128
                monitor = l->data;
 
129
                gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)monitor,
 
130
                                            uri,
 
131
                                            GNOME_VFS_MONITOR_EVENT_CREATED);
 
132
        }
 
133
        gnome_vfs_uri_unref (uri);
 
134
}
 
135
 
 
136
static void
 
137
computer_file_remove (ComputerDir *dir, ComputerFile *file)
 
138
{
 
139
        ComputerMonitor *monitor;
 
140
        GList *l;
 
141
        GnomeVFSURI *uri;
 
142
        
 
143
        dir->files = g_list_remove (dir->files, file);
 
144
 
 
145
        uri = computer_file_get_uri (file);
 
146
        for (l = dir->dir_monitors; l != NULL; l = l->next) {
 
147
                monitor = l->data;
 
148
                gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)monitor,
 
149
                                            uri,
 
150
                                            GNOME_VFS_MONITOR_EVENT_DELETED);
 
151
        }
 
152
        for (l = file->file_monitors; l != NULL; l = l->next) {
 
153
                monitor = l->data;
 
154
                gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)monitor,
 
155
                                            uri,
 
156
                                            GNOME_VFS_MONITOR_EVENT_DELETED);
 
157
        }
 
158
        gnome_vfs_uri_unref (uri);
 
159
        
 
160
        computer_file_free (file);
 
161
}
 
162
 
 
163
static void
 
164
computer_file_changed (ComputerDir *dir, ComputerFile *file)
 
165
{
 
166
        ComputerMonitor *monitor;
 
167
        GList *l;
 
168
        GnomeVFSURI *uri;
 
169
 
 
170
        uri = computer_file_get_uri (file);
 
171
        for (l = dir->dir_monitors; l != NULL; l = l->next) {
 
172
                monitor = l->data;
 
173
                gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)monitor,
 
174
                                            uri,
 
175
                                            GNOME_VFS_MONITOR_EVENT_CHANGED);
 
176
        }
 
177
        for (l = file->file_monitors; l != NULL; l = l->next) {
 
178
                monitor = l->data;
 
179
                gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)monitor,
 
180
                                            uri,
 
181
                                            GNOME_VFS_MONITOR_EVENT_CHANGED);
 
182
        }
 
183
        gnome_vfs_uri_unref (uri);
 
184
}
 
185
 
 
186
static ComputerFile *
 
187
get_volume_file (ComputerDir *dir, GnomeVFSVolume *volume)
 
188
{
 
189
        GList *l;
 
190
        ComputerFile *file;
 
191
 
 
192
        for (l = dir->files; l != NULL; l = l->next) {
 
193
                file = l->data;
 
194
                if (file->type == COMPUTER_VOLUME &&
 
195
                    file->volume == volume) {
 
196
                        return file;
 
197
                }
 
198
        }
 
199
        return NULL;
 
200
}
 
201
 
 
202
static ComputerFile *
 
203
get_drive_file (ComputerDir *dir, GnomeVFSDrive *drive)
 
204
{
 
205
        GList *l;
 
206
        ComputerFile *file;
 
207
 
 
208
        for (l = dir->files; l != NULL; l = l->next) {
 
209
                file = l->data;
 
210
                if (file->type == COMPUTER_DRIVE &&
 
211
                    file->drive == drive) {
 
212
                        return file;
 
213
                }
 
214
        }
 
215
        return NULL;
 
216
}
 
217
 
 
218
static ComputerFile *
 
219
get_file (ComputerDir *dir, char *name)
 
220
{
 
221
        GList *l;
 
222
        ComputerFile *file;
 
223
 
 
224
        if (!name) {
 
225
                return NULL;
 
226
        }
 
227
 
 
228
        for (l = dir->files; l != NULL; l = l->next) {
 
229
                file = l->data;
 
230
                if (strcmp (file->file_name, name) == 0) {
 
231
                        return file;
 
232
                }
 
233
        }
 
234
        return NULL;
 
235
}
 
236
 
 
237
static char *
 
238
build_file_name (char *name, char *extension)
 
239
{
 
240
        char *escaped;
 
241
        char *ret;
 
242
        
 
243
        escaped = gnome_vfs_escape_string (name);
 
244
        ret = g_strconcat (escaped, extension, NULL);
 
245
        g_free (escaped);
 
246
        
 
247
        return ret;
 
248
}
 
249
 
 
250
static void
 
251
volume_mounted (GnomeVFSVolumeMonitor *volume_monitor,
 
252
                GnomeVFSVolume         *volume,
 
253
                ComputerDir            *dir)
 
254
{
 
255
        ComputerFile *file;
 
256
        GnomeVFSDrive *drive;
 
257
        char *name;
 
258
        
 
259
        G_LOCK (root_dir);
 
260
        if (gnome_vfs_volume_is_user_visible (volume)) {
 
261
                drive = gnome_vfs_volume_get_drive (volume);
 
262
                if (drive == NULL) {
 
263
                        file = computer_file_new (COMPUTER_VOLUME);
 
264
                        name = gnome_vfs_volume_get_display_name (volume);
 
265
                        file->file_name = build_file_name (name, ".volume");
 
266
                        g_free (name);
 
267
                        file->volume = gnome_vfs_volume_ref (volume);
 
268
                        computer_file_add (dir, file);
 
269
                } else {
 
270
                        file = get_drive_file (dir, drive);
 
271
                        if (file != NULL) {
 
272
                                computer_file_changed (dir, file);
 
273
                        }
 
274
                }
 
275
                gnome_vfs_drive_unref (drive);
 
276
        }
 
277
        G_UNLOCK (root_dir);
 
278
}
 
279
 
 
280
static void
 
281
volume_unmounted (GnomeVFSVolumeMonitor *volume_monitor,
 
282
                  GnomeVFSVolume        *volume,
 
283
                  ComputerDir           *dir)
 
284
{
 
285
        ComputerFile *file;
 
286
        GnomeVFSDrive *drive;
 
287
        
 
288
        G_LOCK (root_dir);
 
289
        drive = gnome_vfs_volume_get_drive (volume);
 
290
        if (drive != NULL) {
 
291
                file = get_drive_file (dir, drive);
 
292
                if (file != NULL) {
 
293
                        computer_file_changed (dir, file);
 
294
                }
 
295
                gnome_vfs_drive_unref (drive);
 
296
        }
 
297
        
 
298
        file = get_volume_file (dir, volume);
 
299
        if (file != NULL) {
 
300
                computer_file_remove (dir, file);
 
301
        }
 
302
        G_UNLOCK (root_dir);
 
303
}
 
304
 
 
305
static void
 
306
drive_connected (GnomeVFSVolumeMonitor *volume_monitor,
 
307
                 GnomeVFSDrive         *drive,
 
308
                 ComputerDir           *dir)
 
309
{
 
310
        ComputerFile *file;
 
311
        char *name;
 
312
        
 
313
        G_LOCK (root_dir);
 
314
        if (gnome_vfs_drive_is_user_visible (drive)) {
 
315
                file = computer_file_new (COMPUTER_DRIVE);
 
316
                name = gnome_vfs_drive_get_display_name (drive);
 
317
                file->file_name = build_file_name (name, ".drive");
 
318
                g_free (name);
 
319
                file->drive = gnome_vfs_drive_ref (drive);
 
320
                computer_file_add (dir, file);
 
321
        }
 
322
        G_UNLOCK (root_dir);
 
323
}
 
324
 
 
325
static void
 
326
drive_disconnected (GnomeVFSVolumeMonitor *volume_monitor,
 
327
                    GnomeVFSDrive         *drive,
 
328
                    ComputerDir           *dir)
 
329
{
 
330
        ComputerFile *file;
 
331
        
 
332
        G_LOCK (root_dir);
 
333
        file = get_drive_file (dir, drive);
 
334
        if (file != NULL) {
 
335
                computer_file_remove (dir, file);
 
336
        }
 
337
        G_UNLOCK (root_dir);
 
338
}
 
339
 
 
340
static void
 
341
fill_root (ComputerDir *dir)
 
342
{
 
343
        GnomeVFSVolumeMonitor *monitor;
 
344
        GnomeVFSVolume *volume;
 
345
        GnomeVFSDrive *drive;
 
346
        GList *volumes, *drives, *l;
 
347
        ComputerFile *file;
 
348
        char *name;
 
349
        
 
350
        monitor = gnome_vfs_get_volume_monitor ();
 
351
 
 
352
#if 0
 
353
        /* Don't want home in computer:// */
 
354
        file = computer_file_new (COMPUTER_HOME_LINK);
 
355
        file->file_name = g_strdup ("Home.desktop");
 
356
        computer_file_add (dir, file);
 
357
#endif
 
358
        
 
359
        file = computer_file_new (COMPUTER_ROOT_LINK);
 
360
        file->file_name = g_strdup ("Filesystem.desktop");
 
361
        computer_file_add (dir, file);
 
362
        
 
363
        file = computer_file_new (COMPUTER_NETWORK_LINK);
 
364
        file->file_name = g_strdup ("Network.desktop");
 
365
        computer_file_add (dir, file);
 
366
        
 
367
        volumes = gnome_vfs_volume_monitor_get_mounted_volumes (monitor);
 
368
        drives = gnome_vfs_volume_monitor_get_connected_drives (monitor);
 
369
        
 
370
        for (l = drives; l != NULL; l = l->next) {
 
371
                drive = l->data;
 
372
                if (gnome_vfs_drive_is_user_visible (drive)) {
 
373
                        file = computer_file_new (COMPUTER_DRIVE);
 
374
                        name = gnome_vfs_drive_get_display_name (drive);
 
375
                        file->file_name = build_file_name (name, ".drive");
 
376
                        g_free (name);
 
377
                        file->drive = gnome_vfs_drive_ref (drive);
 
378
                        computer_file_add (dir, file);
 
379
                }
 
380
        }
 
381
        
 
382
        for (l = volumes; l != NULL; l = l->next) {
 
383
                volume = l->data;
 
384
                if (gnome_vfs_volume_is_user_visible (volume)) {
 
385
                        drive = gnome_vfs_volume_get_drive (volume);
 
386
                        if (drive == NULL) {
 
387
                                file = computer_file_new (COMPUTER_VOLUME);
 
388
                                name = gnome_vfs_volume_get_display_name (volume);
 
389
                                file->file_name = build_file_name (name, ".volume");
 
390
                                g_free (name);
 
391
                                file->volume = gnome_vfs_volume_ref (volume);
 
392
                                computer_file_add (dir, file);
 
393
                        }
 
394
                        gnome_vfs_drive_unref (drive);
 
395
                }
 
396
        }
 
397
 
 
398
        g_list_foreach (drives, (GFunc) gnome_vfs_drive_unref, NULL);
 
399
        g_list_foreach (volumes, (GFunc) gnome_vfs_volume_unref, NULL);
 
400
        g_list_free (drives);
 
401
        g_list_free (volumes);
 
402
 
 
403
        g_signal_connect (monitor, "volume_mounted",
 
404
                          G_CALLBACK (volume_mounted), dir);
 
405
        g_signal_connect (monitor, "volume_unmounted",
 
406
                          G_CALLBACK (volume_unmounted), dir);
 
407
        g_signal_connect (monitor, "drive_connected",
 
408
                          G_CALLBACK (drive_connected), dir);
 
409
        g_signal_connect (monitor, "drive_disconnected",
 
410
                          G_CALLBACK (drive_disconnected), dir);
 
411
        
 
412
}
 
413
 
 
414
static ComputerDir *
 
415
get_root (void)
 
416
{
 
417
        G_LOCK (root_dir);
 
418
        if (root_dir == NULL) {
 
419
                root_dir = g_new0 (ComputerDir, 1);
 
420
                fill_root (root_dir);
 
421
        }
 
422
        
 
423
        G_UNLOCK (root_dir);
 
424
 
 
425
        return root_dir;
 
426
}
 
427
 
 
428
typedef struct {
 
429
        char *data;
 
430
        int len;
 
431
        int pos;
 
432
} FileHandle;
 
433
 
 
434
static FileHandle *
 
435
file_handle_new (char *data)
 
436
{
 
437
        FileHandle *result;
 
438
        result = g_new (FileHandle, 1);
 
439
 
 
440
        result->data = data;
 
441
        result->len = strlen (data);
 
442
        result->pos = 0;
 
443
 
 
444
        return result;
 
445
}
 
446
 
 
447
static void
 
448
file_handle_destroy (FileHandle *handle)
 
449
{
 
450
        g_free (handle->data);
 
451
        g_free (handle);
 
452
}
 
453
 
 
454
static char *
 
455
get_data_for_volume (GnomeVFSVolume *volume)
 
456
{
 
457
        char *uri;
 
458
        char *name;
 
459
        char *icon;
 
460
        char *data;
 
461
 
 
462
        uri = gnome_vfs_volume_get_activation_uri (volume);
 
463
        name = gnome_vfs_volume_get_display_name (volume);
 
464
        icon = gnome_vfs_volume_get_icon (volume);
 
465
        data = g_strdup_printf ("[Desktop Entry]\n"
 
466
                                "Encoding=UTF-8\n"
 
467
                                "Name=%s\n"
 
468
                                "Type=FSDevice\n"
 
469
                                "Icon=%s\n"
 
470
                                "URL=%s\n"
 
471
                                "X-Gnome-Volume=%ld",
 
472
                                name,
 
473
                                icon,
 
474
                                uri,
 
475
                                gnome_vfs_volume_get_id (volume));
 
476
 
 
477
        g_free (uri);
 
478
        g_free (name);
 
479
        g_free (icon);
 
480
        
 
481
        return data;
 
482
}
 
483
 
 
484
static char *
 
485
get_data_for_drive (GnomeVFSDrive *drive)
 
486
{
 
487
        char *uri;
 
488
        char *name;
 
489
        char *icon;
 
490
        char *data;
 
491
        char *tmp1, *tmp2;
 
492
        GList *volume_list;
 
493
 
 
494
        volume_list = gnome_vfs_drive_get_mounted_volumes (drive);
 
495
        if (volume_list != NULL) {
 
496
                GnomeVFSVolume *volume;
 
497
                volume = GNOME_VFS_VOLUME (volume_list->data);
 
498
 
 
499
                uri = gnome_vfs_volume_get_activation_uri (volume);
 
500
                tmp1 = gnome_vfs_drive_get_display_name (drive);
 
501
                tmp2 = gnome_vfs_volume_get_display_name (volume);
 
502
                if (strcmp (tmp1, tmp2) != 0) {
 
503
                        name = g_strconcat (tmp1, ": ", tmp2, NULL);
 
504
                } else {
 
505
                        name = g_strdup (tmp1);
 
506
                }
 
507
                g_free (tmp1);
 
508
                g_free (tmp2);
 
509
                icon = gnome_vfs_volume_get_icon (volume);
 
510
                gnome_vfs_volume_unref (volume);
 
511
        } else {
 
512
                uri = gnome_vfs_drive_get_activation_uri (drive);
 
513
                name = gnome_vfs_drive_get_display_name (drive);
 
514
                icon = gnome_vfs_drive_get_icon (drive);
 
515
        }
 
516
        data = g_strdup_printf ("[Desktop Entry]\n"
 
517
                                "Encoding=UTF-8\n"
 
518
                                "Name=%s\n"
 
519
                                "Type=FSDevice\n"
 
520
                                "Icon=%s\n"
 
521
                                "URL=%s\n"
 
522
                                "X-Gnome-Drive=%ld",
 
523
                                name,
 
524
                                icon,
 
525
                                uri,
 
526
                                gnome_vfs_drive_get_id (drive));
 
527
        g_free (uri);
 
528
        g_free (name);
 
529
        g_free (icon);
 
530
        
 
531
        return data;
 
532
}
 
533
 
 
534
static char *
 
535
get_data_for_network (void)
 
536
{
 
537
        char *data;
 
538
 
 
539
        data = g_strdup_printf ("[Desktop Entry]\n"
 
540
                                "Encoding=UTF-8\n"
 
541
                                "Name=%s\n"
 
542
                                "Type=Link\n"
 
543
                                "Icon=gnome-fs-network\n"
 
544
                                "URL=network://\n",
 
545
                                _("Network"));
 
546
 
 
547
        return data;
 
548
}
 
549
 
 
550
static char *
 
551
get_data_for_home (void)
 
552
{
 
553
        char *data;
 
554
        char *uri;
 
555
 
 
556
        uri = gnome_vfs_get_uri_from_local_path (g_get_home_dir ());
 
557
        data = g_strdup_printf ("[Desktop Entry]\n"
 
558
                                "Encoding=UTF-8\n"
 
559
                                "Name=%s\n"
 
560
                                "Type=Link\n"
 
561
                                "Icon=gnome-fs-home\n"
 
562
                                "URL=%s\n",
 
563
                                _("Home"),
 
564
                                uri);
 
565
        g_free (uri);
 
566
 
 
567
        return data;
 
568
}
 
569
 
 
570
static char *
 
571
get_data_for_root (void)
 
572
{
 
573
        char *data;
 
574
 
 
575
        data = g_strdup_printf ("[Desktop Entry]\n"
 
576
                                "Encoding=UTF-8\n"
 
577
                                "Name=%s\n"
 
578
                                "Type=Link\n"
 
579
                                "Icon=gnome-dev-harddisk\n"
 
580
                                "URL=file:///\n",
 
581
                                _("Filesystem"));
 
582
 
 
583
        return data;
 
584
}
 
585
 
 
586
static GnomeVFSResult
 
587
do_open (GnomeVFSMethod *method,
 
588
         GnomeVFSMethodHandle **method_handle,
 
589
         GnomeVFSURI *uri,
 
590
         GnomeVFSOpenMode mode,
 
591
         GnomeVFSContext *context)
 
592
{
 
593
        FileHandle *file_handle;
 
594
        ComputerFile *file;
 
595
        ComputerDir *dir;
 
596
        char *data;
 
597
        char *name;
 
598
        
 
599
        _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL);
 
600
        _GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL);
 
601
 
 
602
        if (mode & GNOME_VFS_OPEN_WRITE) {
 
603
                return GNOME_VFS_ERROR_NOT_PERMITTED;
 
604
        }
 
605
 
 
606
        if (strcmp (uri->text, "/") == 0) {
 
607
                return GNOME_VFS_ERROR_NOT_PERMITTED;
 
608
        }
 
609
 
 
610
        dir = get_root ();
 
611
 
 
612
        G_LOCK (root_dir);
 
613
        
 
614
        name = gnome_vfs_uri_extract_short_name (uri);
 
615
        file = get_file (dir, name);
 
616
        g_free (name);
 
617
        
 
618
        if (file == NULL) {
 
619
                G_UNLOCK (root_dir);
 
620
                return GNOME_VFS_ERROR_NOT_FOUND;
 
621
        }
 
622
 
 
623
        data = NULL;
 
624
        switch (file->type) {
 
625
        case COMPUTER_HOME_LINK:
 
626
                data = get_data_for_home ();
 
627
                break;
 
628
        case COMPUTER_ROOT_LINK:
 
629
                data = get_data_for_root ();
 
630
                break;
 
631
        case COMPUTER_NETWORK_LINK:
 
632
                data = get_data_for_network ();
 
633
                break;
 
634
        case COMPUTER_DRIVE:
 
635
                data = get_data_for_drive (file->drive);
 
636
                break;
 
637
        case COMPUTER_VOLUME:
 
638
                data = get_data_for_volume (file->volume);
 
639
                break;
 
640
        }
 
641
 
 
642
        G_UNLOCK (root_dir);
 
643
                
 
644
        file_handle = file_handle_new (data);
 
645
 
 
646
        *method_handle = (GnomeVFSMethodHandle *) file_handle;
 
647
 
 
648
        return GNOME_VFS_OK;
 
649
}
 
650
 
 
651
static GnomeVFSResult
 
652
do_create (GnomeVFSMethod *method,
 
653
           GnomeVFSMethodHandle **method_handle,
 
654
           GnomeVFSURI *uri,
 
655
           GnomeVFSOpenMode mode,
 
656
           gboolean exclusive,
 
657
           guint perm,
 
658
           GnomeVFSContext *context)
 
659
{
 
660
        return GNOME_VFS_ERROR_NOT_PERMITTED;
 
661
}
 
662
 
 
663
static GnomeVFSResult
 
664
do_close (GnomeVFSMethod *method,
 
665
          GnomeVFSMethodHandle *method_handle,
 
666
          GnomeVFSContext *context)
 
667
{
 
668
        FileHandle *file_handle;
 
669
 
 
670
        g_return_val_if_fail (method_handle != NULL, GNOME_VFS_ERROR_INTERNAL);
 
671
 
 
672
        file_handle = (FileHandle *) method_handle;
 
673
 
 
674
        file_handle_destroy (file_handle);
 
675
 
 
676
        return GNOME_VFS_OK;
 
677
}
 
678
 
 
679
static GnomeVFSResult
 
680
do_read (GnomeVFSMethod *method,
 
681
         GnomeVFSMethodHandle *method_handle,
 
682
         gpointer buffer,
 
683
         GnomeVFSFileSize num_bytes,
 
684
         GnomeVFSFileSize *bytes_read,
 
685
         GnomeVFSContext *context)
 
686
{
 
687
        FileHandle *file_handle;
 
688
        int read_len;
 
689
 
 
690
        g_return_val_if_fail (method_handle != NULL, GNOME_VFS_ERROR_INTERNAL);
 
691
 
 
692
        file_handle = (FileHandle *) method_handle;
 
693
        *bytes_read = 0;
 
694
        
 
695
        if (file_handle->pos >= file_handle->len) {
 
696
                return GNOME_VFS_ERROR_EOF;
 
697
        }
 
698
 
 
699
        read_len = MIN (num_bytes, file_handle->len - file_handle->pos);
 
700
 
 
701
        memcpy (buffer, file_handle->data + file_handle->pos, read_len);
 
702
        *bytes_read = read_len;
 
703
        file_handle->pos += read_len;
 
704
 
 
705
        
 
706
        return GNOME_VFS_OK;
 
707
}
 
708
 
 
709
static GnomeVFSResult
 
710
do_write (GnomeVFSMethod *method,
 
711
          GnomeVFSMethodHandle *method_handle,
 
712
          gconstpointer buffer,
 
713
          GnomeVFSFileSize num_bytes,
 
714
          GnomeVFSFileSize *bytes_written,
 
715
          GnomeVFSContext *context)
 
716
{
 
717
        return GNOME_VFS_ERROR_NOT_PERMITTED;
 
718
}
 
719
 
 
720
 
 
721
static GnomeVFSResult
 
722
do_seek (GnomeVFSMethod *method,
 
723
         GnomeVFSMethodHandle *method_handle,
 
724
         GnomeVFSSeekPosition whence,
 
725
         GnomeVFSFileOffset offset,
 
726
         GnomeVFSContext *context)
 
727
{
 
728
        FileHandle *file_handle;
 
729
 
 
730
        file_handle = (FileHandle *) method_handle;
 
731
 
 
732
        switch (whence) {
 
733
        case GNOME_VFS_SEEK_START:
 
734
                file_handle->pos = offset;
 
735
                break;
 
736
        case GNOME_VFS_SEEK_CURRENT:
 
737
                file_handle->pos += offset;
 
738
                break;
 
739
        case GNOME_VFS_SEEK_END:
 
740
                file_handle->pos = file_handle->len + offset;
 
741
                break;
 
742
        }
 
743
 
 
744
        if (file_handle->pos < 0) {
 
745
                file_handle->pos = 0;
 
746
        }
 
747
        
 
748
        if (file_handle->pos > file_handle->len) {
 
749
                file_handle->pos = file_handle->len;
 
750
        }
 
751
        
 
752
        return GNOME_VFS_OK;
 
753
}
 
754
 
 
755
static GnomeVFSResult
 
756
do_tell (GnomeVFSMethod *method,
 
757
         GnomeVFSMethodHandle *method_handle,
 
758
         GnomeVFSFileOffset *offset_return)
 
759
{
 
760
        FileHandle *file_handle;
 
761
 
 
762
        file_handle = (FileHandle *) method_handle;
 
763
 
 
764
        *offset_return = file_handle->pos;
 
765
        return GNOME_VFS_OK;
 
766
}
 
767
 
 
768
 
 
769
static GnomeVFSResult
 
770
do_truncate_handle (GnomeVFSMethod *method,
 
771
                    GnomeVFSMethodHandle *method_handle,
 
772
                    GnomeVFSFileSize where,
 
773
                    GnomeVFSContext *context)
 
774
{
 
775
        return GNOME_VFS_ERROR_NOT_PERMITTED;
 
776
}
 
777
 
 
778
static GnomeVFSResult
 
779
do_truncate (GnomeVFSMethod *method,
 
780
             GnomeVFSURI *uri,
 
781
             GnomeVFSFileSize where,
 
782
             GnomeVFSContext *context)
 
783
{
 
784
        return GNOME_VFS_ERROR_NOT_PERMITTED;
 
785
}
 
786
 
 
787
typedef struct {
 
788
        GnomeVFSFileInfoOptions options;
 
789
        GList *entries;
 
790
} DirectoryHandle;
 
791
 
 
792
static DirectoryHandle *
 
793
directory_handle_new (GnomeVFSFileInfoOptions options)
 
794
{
 
795
        DirectoryHandle *result;
 
796
 
 
797
        result = g_new (DirectoryHandle, 1);
 
798
        result->options = options;
 
799
        result->entries = NULL;
 
800
 
 
801
        return result;
 
802
}
 
803
 
 
804
static void
 
805
directory_handle_destroy (DirectoryHandle *dir_handle)
 
806
{
 
807
        g_list_foreach (dir_handle->entries, (GFunc)g_free, NULL);
 
808
        g_list_free (dir_handle->entries);
 
809
        g_free (dir_handle);
 
810
}
 
811
 
 
812
static GnomeVFSResult
 
813
do_open_directory (GnomeVFSMethod *method,
 
814
                   GnomeVFSMethodHandle **method_handle,
 
815
                   GnomeVFSURI *uri,
 
816
                   GnomeVFSFileInfoOptions options,
 
817
                   GnomeVFSContext *context)
 
818
{
 
819
        DirectoryHandle *dir_handle;
 
820
        GList *l;
 
821
        ComputerFile *file;
 
822
        ComputerDir *dir;
 
823
 
 
824
        dir_handle = directory_handle_new (options);
 
825
 
 
826
        dir = get_root ();
 
827
 
 
828
        G_LOCK (root_dir);
 
829
        for (l = dir->files; l != NULL; l = l->next) {
 
830
                file = l->data;
 
831
                dir_handle->entries = g_list_prepend (dir_handle->entries,
 
832
                                                      g_strdup (file->file_name));
 
833
        }
 
834
        G_UNLOCK (root_dir);
 
835
 
 
836
        *method_handle = (GnomeVFSMethodHandle *) dir_handle;
 
837
        
 
838
        return GNOME_VFS_OK;
 
839
}
 
840
 
 
841
static GnomeVFSResult
 
842
do_close_directory (GnomeVFSMethod *method,
 
843
                    GnomeVFSMethodHandle *method_handle,
 
844
                    GnomeVFSContext *context)
 
845
{
 
846
        DirectoryHandle *dir_handle;
 
847
 
 
848
        dir_handle = (DirectoryHandle *) method_handle;
 
849
 
 
850
        directory_handle_destroy (dir_handle);
 
851
 
 
852
        return GNOME_VFS_OK;
 
853
}
 
854
 
 
855
static GnomeVFSResult
 
856
do_read_directory (GnomeVFSMethod *method,
 
857
                   GnomeVFSMethodHandle *method_handle,
 
858
                   GnomeVFSFileInfo *file_info,
 
859
                   GnomeVFSContext *context)
 
860
{
 
861
        DirectoryHandle *handle;
 
862
        GList *entry;
 
863
 
 
864
        handle = (DirectoryHandle *) method_handle;
 
865
 
 
866
        if (handle->entries == NULL) {
 
867
                return GNOME_VFS_ERROR_EOF;
 
868
        }
 
869
 
 
870
        entry = handle->entries;
 
871
        handle->entries = g_list_remove_link (handle->entries, entry);
 
872
        
 
873
        file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE;
 
874
        file_info->name = g_strdup (entry->data);
 
875
        g_free (entry->data);
 
876
        g_list_free_1 (entry);
 
877
 
 
878
        file_info->mime_type = g_strdup ("application/x-desktop");
 
879
        file_info->type = GNOME_VFS_FILE_TYPE_REGULAR;
 
880
        file_info->valid_fields |=
 
881
                GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE |
 
882
                GNOME_VFS_FILE_INFO_FIELDS_TYPE;
 
883
 
 
884
        file_info->permissions =
 
885
                GNOME_VFS_PERM_USER_READ |
 
886
                GNOME_VFS_PERM_OTHER_READ |
 
887
                GNOME_VFS_PERM_GROUP_READ;
 
888
        file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
 
889
        
 
890
        return GNOME_VFS_OK;
 
891
}
 
892
 
 
893
static GnomeVFSResult
 
894
do_get_file_info (GnomeVFSMethod *method,
 
895
                  GnomeVFSURI *uri,
 
896
                  GnomeVFSFileInfo *file_info,
 
897
                  GnomeVFSFileInfoOptions options,
 
898
                  GnomeVFSContext *context)
 
899
{
 
900
        file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE;
 
901
 
 
902
        if (strcmp (uri->text, "/") == 0) {
 
903
                file_info->name = g_strdup ("/");
 
904
                
 
905
                file_info->mime_type = g_strdup ("x-directory/normal");
 
906
                file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY;
 
907
                file_info->valid_fields |=
 
908
                        GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE |
 
909
                        GNOME_VFS_FILE_INFO_FIELDS_TYPE;
 
910
        } else {
 
911
                file_info->name = gnome_vfs_uri_extract_short_name (uri);
 
912
                
 
913
                file_info->mime_type = g_strdup ("application/x-desktop");
 
914
                file_info->type = GNOME_VFS_FILE_TYPE_REGULAR;
 
915
                file_info->valid_fields |=
 
916
                        GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE |
 
917
                        GNOME_VFS_FILE_INFO_FIELDS_TYPE;
 
918
        }
 
919
        file_info->permissions =
 
920
                GNOME_VFS_PERM_USER_READ |
 
921
                GNOME_VFS_PERM_OTHER_READ |
 
922
                GNOME_VFS_PERM_GROUP_READ;
 
923
        file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
 
924
        
 
925
        return GNOME_VFS_OK;
 
926
}
 
927
 
 
928
static GnomeVFSResult
 
929
do_get_file_info_from_handle (GnomeVFSMethod *method,
 
930
                              GnomeVFSMethodHandle *method_handle,
 
931
                              GnomeVFSFileInfo *file_info,
 
932
                              GnomeVFSFileInfoOptions options,
 
933
                              GnomeVFSContext *context)
 
934
{
 
935
        FileHandle *file_handle;
 
936
 
 
937
        file_handle = (FileHandle *) method_handle;
 
938
 
 
939
        file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE;
 
940
        
 
941
        file_info->mime_type = g_strdup ("application/x-desktop");
 
942
        file_info->size = file_handle->len;
 
943
        file_info->type = GNOME_VFS_FILE_TYPE_REGULAR;
 
944
        file_info->valid_fields |=
 
945
                GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE |
 
946
                GNOME_VFS_FILE_INFO_FIELDS_SIZE |
 
947
                GNOME_VFS_FILE_INFO_FIELDS_TYPE;
 
948
 
 
949
        return GNOME_VFS_OK;
 
950
}
 
951
 
 
952
static gboolean
 
953
do_is_local (GnomeVFSMethod *method,
 
954
             const GnomeVFSURI *uri)
 
955
{
 
956
        return TRUE;
 
957
}
 
958
 
 
959
 
 
960
static GnomeVFSResult
 
961
do_make_directory (GnomeVFSMethod *method,
 
962
                   GnomeVFSURI *uri,
 
963
                   guint perm,
 
964
                   GnomeVFSContext *context)
 
965
{
 
966
        return GNOME_VFS_ERROR_NOT_PERMITTED;
 
967
}
 
968
 
 
969
static GnomeVFSResult
 
970
do_remove_directory (GnomeVFSMethod *method,
 
971
                     GnomeVFSURI *uri,
 
972
                     GnomeVFSContext *context)
 
973
{
 
974
        return GNOME_VFS_ERROR_NOT_PERMITTED;
 
975
}
 
976
 
 
977
 
 
978
static GnomeVFSResult
 
979
do_find_directory (GnomeVFSMethod *method,
 
980
                   GnomeVFSURI *near_uri,
 
981
                   GnomeVFSFindDirectoryKind kind,
 
982
                   GnomeVFSURI **result_uri,
 
983
                   gboolean create_if_needed,
 
984
                   gboolean find_if_needed,
 
985
                   guint permissions,
 
986
                   GnomeVFSContext *context)
 
987
{
 
988
        return GNOME_VFS_ERROR_NOT_SUPPORTED;
 
989
}
 
990
 
 
991
static GnomeVFSResult
 
992
do_move (GnomeVFSMethod *method,
 
993
         GnomeVFSURI *old_uri,
 
994
         GnomeVFSURI *new_uri,
 
995
         gboolean force_replace,
 
996
         GnomeVFSContext *context)
 
997
{
 
998
        return GNOME_VFS_ERROR_NOT_PERMITTED;
 
999
}
 
1000
 
 
1001
static GnomeVFSResult
 
1002
do_unlink (GnomeVFSMethod *method,
 
1003
           GnomeVFSURI *uri,
 
1004
           GnomeVFSContext *context)
 
1005
{
 
1006
        return GNOME_VFS_ERROR_NOT_PERMITTED;
 
1007
}
 
1008
 
 
1009
static GnomeVFSResult
 
1010
do_create_symbolic_link (GnomeVFSMethod *method,
 
1011
                         GnomeVFSURI *uri,
 
1012
                         const char *target_reference,
 
1013
                         GnomeVFSContext *context)
 
1014
{
 
1015
        return GNOME_VFS_ERROR_NOT_PERMITTED;
 
1016
}
 
1017
 
 
1018
/* When checking whether two locations are on the same file system, we are
 
1019
   doing this to determine whether we can recursively move or do other
 
1020
   sorts of transfers.  When a symbolic link is the "source", its
 
1021
   location is the location of the link file, because we want to
 
1022
   know about transferring the link, whereas for symbolic links that
 
1023
   are "targets", we use the location of the object being pointed to,
 
1024
   because that is where we will be moving/copying to. */
 
1025
static GnomeVFSResult
 
1026
do_check_same_fs (GnomeVFSMethod *method,
 
1027
                  GnomeVFSURI *source_uri,
 
1028
                  GnomeVFSURI *target_uri,
 
1029
                  gboolean *same_fs_return,
 
1030
                  GnomeVFSContext *context)
 
1031
{
 
1032
        return TRUE;
 
1033
}
 
1034
 
 
1035
static GnomeVFSResult
 
1036
do_set_file_info (GnomeVFSMethod *method,
 
1037
                  GnomeVFSURI *uri,
 
1038
                  const GnomeVFSFileInfo *info,
 
1039
                  GnomeVFSSetFileInfoMask mask,
 
1040
                  GnomeVFSContext *context)
 
1041
{
 
1042
        return GNOME_VFS_ERROR_NOT_PERMITTED;
 
1043
}
 
1044
 
 
1045
static GnomeVFSResult
 
1046
do_monitor_add (GnomeVFSMethod *method,
 
1047
                GnomeVFSMethodHandle **method_handle_return,
 
1048
                GnomeVFSURI *uri,
 
1049
                GnomeVFSMonitorType monitor_type)
 
1050
{
 
1051
        ComputerDir *dir;
 
1052
        ComputerMonitor *monitor;
 
1053
        char *name;
 
1054
 
 
1055
        if (strcmp (uri->text, "/") == 0) {
 
1056
                dir = get_root ();
 
1057
 
 
1058
                monitor = g_new0 (ComputerMonitor, 1);
 
1059
                monitor->type = GNOME_VFS_MONITOR_DIRECTORY;
 
1060
                
 
1061
                G_LOCK (root_dir);
 
1062
                dir->dir_monitors = g_list_prepend (dir->dir_monitors, monitor);
 
1063
                G_UNLOCK (root_dir);
 
1064
        } else {
 
1065
                if (monitor_type != GNOME_VFS_MONITOR_FILE) {
 
1066
                        return GNOME_VFS_ERROR_NOT_SUPPORTED;
 
1067
                }
 
1068
                
 
1069
                dir = get_root ();
 
1070
 
 
1071
                monitor = g_new0 (ComputerMonitor, 1);
 
1072
                monitor->type = GNOME_VFS_MONITOR_FILE;
 
1073
                
 
1074
                G_LOCK (root_dir);
 
1075
                name = gnome_vfs_uri_extract_short_name (uri);
 
1076
                monitor->file = get_file (dir, name);
 
1077
                g_free (name);
 
1078
 
 
1079
                if (monitor->file != NULL) {
 
1080
                        monitor->file->file_monitors = g_list_prepend (monitor->file->file_monitors,
 
1081
                                                                       monitor);
 
1082
                }
 
1083
                G_UNLOCK (root_dir);
 
1084
                
 
1085
        }
 
1086
        
 
1087
        *method_handle_return = (GnomeVFSMethodHandle *)monitor;
 
1088
        
 
1089
        return GNOME_VFS_OK;
 
1090
}
 
1091
 
 
1092
static GnomeVFSResult
 
1093
do_monitor_cancel (GnomeVFSMethod *method,
 
1094
                   GnomeVFSMethodHandle *method_handle)
 
1095
{
 
1096
        ComputerDir *dir;
 
1097
        ComputerMonitor *monitor;
 
1098
        ComputerFile *file;
 
1099
 
 
1100
        dir = get_root ();
 
1101
 
 
1102
        G_LOCK (root_dir);
 
1103
        monitor = (ComputerMonitor *) method_handle;
 
1104
        if (monitor->type == GNOME_VFS_MONITOR_DIRECTORY) {
 
1105
                dir->dir_monitors = g_list_remove (dir->dir_monitors, monitor);
 
1106
        } else {
 
1107
                file = monitor->file;
 
1108
                if (file != NULL) {
 
1109
                        file->file_monitors = g_list_remove (file->file_monitors,
 
1110
                                                             monitor);
 
1111
                }
 
1112
        }
 
1113
        G_UNLOCK (root_dir);
 
1114
 
 
1115
        g_free (monitor);
 
1116
        
 
1117
        return GNOME_VFS_OK;
 
1118
}
 
1119
 
 
1120
static GnomeVFSResult
 
1121
do_file_control (GnomeVFSMethod *method,
 
1122
                 GnomeVFSMethodHandle *method_handle,
 
1123
                 const char *operation,
 
1124
                 gpointer operation_data,
 
1125
                 GnomeVFSContext *context)
 
1126
{
 
1127
        return GNOME_VFS_ERROR_NOT_SUPPORTED;
 
1128
}
 
1129
 
 
1130
static GnomeVFSMethod method = {
 
1131
        sizeof (GnomeVFSMethod),
 
1132
        do_open,
 
1133
        do_create,
 
1134
        do_close,
 
1135
        do_read,
 
1136
        do_write,
 
1137
        do_seek,
 
1138
        do_tell,
 
1139
        do_truncate_handle,
 
1140
        do_open_directory,
 
1141
        do_close_directory,
 
1142
        do_read_directory,
 
1143
        do_get_file_info,
 
1144
        do_get_file_info_from_handle,
 
1145
        do_is_local,
 
1146
        do_make_directory,
 
1147
        do_remove_directory,
 
1148
        do_move,
 
1149
        do_unlink,
 
1150
        do_check_same_fs,
 
1151
        do_set_file_info,
 
1152
        do_truncate,
 
1153
        do_find_directory,
 
1154
        do_create_symbolic_link,
 
1155
        do_monitor_add,
 
1156
        do_monitor_cancel,
 
1157
        do_file_control
 
1158
};
 
1159
 
 
1160
GnomeVFSMethod *
 
1161
vfs_module_init (const char *method_name, const char *args)
 
1162
{
 
1163
        return &method;
 
1164
}
 
1165
 
 
1166
void
 
1167
vfs_module_shutdown (GnomeVFSMethod *method)
 
1168
{
 
1169
}