source: trunk/third/gnome-vfs2/test/test-shell.c @ 20794

Revision 20794, 25.4 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20793, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2/* test-shell.c - A small program to allow testing of a wide variety of
3   gnome-vfs functionality
4
5   Copyright (C) 2000 Free Software Foundation
6
7   The Gnome Library is free software; you can redistribute it and/or
8   modify it under the terms of the GNU Library General Public License as
9   published by the Free Software Foundation; either version 2 of the
10   License, or (at your option) any later version.
11
12   The Gnome Library is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   Library General Public License for more details.
16
17   You should have received a copy of the GNU Library General Public
18   License along with the Gnome Library; see the file COPYING.LIB.  If not,
19   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20   Boston, MA 02111-1307, USA.
21
22   Author: Michael Meeks <mmeeks@gnu.org>
23   
24   NB. This code leaks everywhere, don't loose hair.
25*/
26
27#include <config.h>
28
29#include <errno.h>
30#include <glib/ghash.h>
31#include <glib/gstrfuncs.h>
32#include <glib/gstring.h>
33#include <glib/gmessages.h>
34#include <glib/gutils.h>
35#include <libgnomevfs/gnome-vfs-init.h>
36#include <libgnomevfs/gnome-vfs-directory.h>
37#include <libgnomevfs/gnome-vfs-find-directory.h>
38#include <libgnomevfs/gnome-vfs-ops.h>
39#include <libgnomevfs/gnome-vfs-ssl.h>
40#include <libgnomevfs/gnome-vfs-module-callback.h>
41#include <libgnomevfs/gnome-vfs-standard-callbacks.h>
42#include <popt.h>
43#include <stdio.h>
44#include <stdlib.h>
45#include <string.h>
46#include <time.h>
47#include <unistd.h>
48
49#define TEST_DEBUG 0
50
51static char delim[]=" ";
52static char **arg_data = NULL;
53static int    arg_cur  = 0;
54
55static char *cur_dir = NULL;
56
57static GHashTable *files = NULL;
58
59FILE *vfserr = NULL;
60
61
62static gboolean
63show_if_error (GnomeVFSResult result, const char *what, const char *what2)
64{
65        if (result != GNOME_VFS_OK) {
66                fprintf (vfserr, "%s%s `%s'\n",
67                         what, what2, gnome_vfs_result_to_string (result));
68                return TRUE;
69        } else
70                return FALSE;
71}
72
73static void
74register_file (const char *str, GnomeVFSHandle *handle)
75{
76        if (!str)
77                fprintf (vfserr, "Need a valid name");
78        else
79                g_hash_table_insert (files, g_strdup (str), handle);
80}
81
82static GnomeVFSHandle *
83lookup_file (const char *str)
84{
85        GnomeVFSHandle *handle;
86
87        if (!str) {
88                fprintf (vfserr, "Invalid handle '%s'\n", str);
89                return NULL;
90        }
91
92        handle = g_hash_table_lookup (files, str);
93        if (!handle)
94                fprintf (vfserr, "Can't find handle '%s'\n", str);
95
96        return handle;
97}
98
99static void
100close_file (const char *str)
101{
102        GnomeVFSResult result;
103        gpointer hash_key, value;
104
105        if (!str)
106                fprintf (vfserr, "Can't close NULL handles\n");
107
108        else if (g_hash_table_lookup_extended (files, str, &hash_key, &value)) {
109                g_hash_table_remove (files, str);
110
111                result = gnome_vfs_close ((GnomeVFSHandle *)value);
112                show_if_error (result, "closing ", (char *)hash_key);
113
114                g_free (hash_key);
115        } else
116
117                fprintf (vfserr, "Unknown file handle '%s'\n", str);
118}
119
120static gboolean
121kill_file_cb (gpointer  key,
122              gpointer  value,
123              gpointer  user_data)
124{
125        GnomeVFSResult result;
126
127        result = gnome_vfs_close (value);
128        show_if_error (result, "closing ", key);
129        g_free (key);
130
131        return TRUE;
132}
133
134static void
135close_files (void)
136{
137        g_hash_table_foreach_remove (files, kill_file_cb, NULL);
138        g_hash_table_destroy (files);
139}
140
141static void
142do_ls (void)
143{
144        GnomeVFSResult result;
145        GList *list, *node;
146        GnomeVFSFileInfo *info;
147        const char *path;
148
149        if (!arg_data [arg_cur])
150                path = cur_dir;
151        else
152                path = arg_data [arg_cur++];
153
154        result = gnome_vfs_directory_list_load
155                (&list, path,
156                 GNOME_VFS_FILE_INFO_DEFAULT |
157                 GNOME_VFS_FILE_INFO_GET_MIME_TYPE);
158        if (show_if_error (result, "open directory ", cur_dir))
159                return;
160
161        for (node = list; node != NULL; node = node->next) {
162                char prechar = '\0', postchar = '\0';
163                info = node->data;
164
165                if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE) {
166                        switch (info->type) {
167                        case GNOME_VFS_FILE_TYPE_DIRECTORY:
168                                prechar = '[';
169                                postchar = ']';
170                                break;
171                        case GNOME_VFS_FILE_TYPE_UNKNOWN:
172                                prechar = '?';
173                                break;
174                        case GNOME_VFS_FILE_TYPE_FIFO:
175                                prechar = '|';
176                                break;
177                        case GNOME_VFS_FILE_TYPE_SOCKET:
178                                prechar = '-';
179                                break;
180                        case GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE:
181                        case GNOME_VFS_FILE_TYPE_BLOCK_DEVICE:
182                                prechar = '@';
183                                break;
184                        case GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK:
185                                prechar = '#';
186                                break;
187                        default:
188                                prechar = '\0';
189                                break;
190                        }
191                        if (!postchar)
192                                postchar = prechar;
193                }
194                printf ("%c%s%c", prechar, info->name, postchar);
195
196                if (strlen (info->name) < 40) {
197                        int i, pad;
198
199                        pad = 40 - strlen (info->name) -
200                                (prechar?1:0) - (postchar?1:0);
201
202                        for (i = 0; i < pad; i++)
203                                printf (" ");
204                }
205                if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
206                        long i = info->size;
207                        printf (" : %ld bytes", i);
208                }
209
210                if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE) {
211                        printf (", type '%s'", info->mime_type);
212                }
213
214                printf ("\n");
215        }
216       
217        gnome_vfs_file_info_list_free (list);
218}
219
220static void
221list_commands (void)
222{
223        printf ("command can be one or all of:\n");
224        printf ("Main operations:\n");
225        printf (" * ls [opt_dir]            list files\n");
226        printf (" * cd [dir]                enter storage\n");
227        printf (" * mv <a> <b>              move object\n");
228        printf (" * rm <file>               remove stream\n");
229        printf (" * mkdir <dir>             make storage\n");
230        printf (" * rmdir <dir>             remove storage\n");
231        printf (" * info,stat <a>           get information on object\n");
232        printf (" * cat,type <a>            dump text file to console\n");
233        printf (" * dump <a>                dump binary file to console\n");
234        printf (" * sync:                   for sinkers\n");
235        printf (" * ssl:                    displays ssl enabled state\n");
236        printf (" * findtrash:              locates a trash directory for a URI\n");
237        printf (" * quit,exit,bye:          exit\n");
238        printf ("File operations:\n");
239        printf (" * open <handle> <name>:   open a file\n");
240        printf (" * create <handle> <name>: create a file\n");
241        printf (" * handleinfo <handle>:    information from handle\n");
242        printf (" * close <handle>:         close a file\n");
243        printf (" * read <handle> <bytes>:  read bytes from stream\n");
244        printf (" * seek <handle> <pos>:    seek set position\n");
245}
246
247static gboolean
248simple_regexp (const char *regexp, const char *fname)
249{
250        int      i, j;
251        gboolean ret = TRUE;
252
253        g_return_val_if_fail (fname != NULL, FALSE);
254        g_return_val_if_fail (regexp != NULL, FALSE);
255
256        for (i = j = 0; regexp [i] && fname [j]; j++, i++) {
257                if (regexp [i] == '\\' &&
258                    !(i > 0 && regexp [i - 1] == '\\')) {
259                        j--;
260                        continue;
261                }
262
263                if (regexp [i] == '.' &&
264                    !(i > 0 && regexp [i - 1] == '\\'))
265                        continue;
266
267                if (g_ascii_tolower (regexp [i]) != g_ascii_tolower (fname [j])) {
268                        ret = FALSE;
269                        break;
270                }
271        }
272
273        if (regexp [i] && regexp [i] == '*')
274                ret = TRUE;
275
276        else if (!regexp [i] && fname [j])
277                ret = FALSE;
278       
279        else if (!fname [j] && regexp [i])
280                ret = FALSE;
281
282/*      if (ret)
283        printf ("'%s' matched '%s'\n", regexp, fname);*/
284
285        return ret;
286}
287
288static gboolean
289validate_path (const char *path)
290{
291        GnomeVFSResult result;
292        GList *list;
293
294        result = gnome_vfs_directory_list_load (
295                &list, path, GNOME_VFS_FILE_INFO_DEFAULT);
296
297        if (show_if_error (result, "open directory ", path)) {
298                return FALSE;
299        }
300
301        gnome_vfs_file_info_list_free (list);
302
303        return TRUE;
304}
305
306static char *
307get_regexp_name (const char *regexp, const char *path, gboolean dir)
308{
309        GnomeVFSResult result;
310        GList *list, *node;
311        GnomeVFSFileInfo *info;
312        char *res = NULL;
313
314        result = gnome_vfs_directory_list_load (
315                &list, path, GNOME_VFS_FILE_INFO_DEFAULT);
316
317        if (show_if_error (result, "open directory ", path))
318                return NULL;
319
320        for (node = list; node != NULL; node = node->next) {
321                info = node->data;
322
323                if (simple_regexp (regexp, info->name)) {
324                        if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE) {
325                                if ((dir  && info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) ||
326                                    (!dir && info->type != GNOME_VFS_FILE_TYPE_DIRECTORY)) {
327                                        res = g_strdup (info->name);
328                                        break;
329                                }
330                        } else {
331                                fprintf (vfserr, "Can't cope with no type data");
332                                res = g_strdup (info->name);
333                                break;
334                        }
335                }
336        }
337        gnome_vfs_file_info_list_free (list);
338
339        return res;
340}
341
342static void
343do_cd (void)
344{
345        char *p;
346
347        p = arg_data [arg_cur++];
348
349        if (!p) {
350                fprintf (vfserr, "Takes a directory argument\n");
351                return;
352        }
353
354        if (!g_ascii_strcasecmp (p, "..")) {
355                guint lp;
356                char **tmp;
357                GString *newp = g_string_new ("");
358
359                tmp = g_strsplit (cur_dir, "/", -1);
360                lp  = 0;
361                if (!tmp [lp])
362                        return;
363
364                while (tmp [lp + 1]) {
365                        g_string_append_printf (newp, "%s/", tmp [lp]);
366                        lp++;
367                }
368                g_free (cur_dir);
369                cur_dir = newp->str;
370                g_string_free (newp, FALSE);
371        } else if (!g_ascii_strcasecmp (p, ".")) {
372        } else {
373                char *newpath;
374
375                if (strchr (p, ':') ||
376                    p [0] == '/') {
377                        if (p [strlen (p) - 1] != '/')
378                                newpath = g_strconcat (p, "/", NULL);
379                        else
380                                newpath = g_strdup (p);
381                } else {
382                        char *ptr;
383                       
384                        ptr = get_regexp_name (p, cur_dir, TRUE);
385                        if (!ptr) {
386                                fprintf (vfserr, "Can't find '%s'\n", p);
387                                return;
388                        }
389
390                        newpath = g_strconcat (cur_dir, ptr, "/", NULL);
391                }
392
393                if (validate_path (newpath)) {
394                        g_free (cur_dir);
395                        cur_dir = newpath;
396                } else
397                        fprintf (vfserr, "Invalid path %s\n", newpath);
398        }
399}
400
401static char *
402get_fname (void)
403{
404        char *fname, *reg_name, *f;
405
406        if (!arg_data [arg_cur])
407                return NULL;
408       
409        reg_name = arg_data [arg_cur++];
410        fname = get_regexp_name (reg_name, cur_dir, FALSE);
411
412        if (!fname)
413                fname = reg_name;
414       
415        if (strchr (fname, ':') ||
416            fname [0] == '/')
417                f = g_strdup (fname);
418        else if (cur_dir)
419                f = g_strconcat (cur_dir, fname, NULL);
420        else
421                f = g_strdup (fname);
422
423        return f;
424}
425
426static void
427do_cat (void)
428{
429        char *from;
430        GnomeVFSHandle *from_handle;
431        GnomeVFSResult  result;
432
433        from = get_fname ();
434
435        result = gnome_vfs_open (&from_handle, from, GNOME_VFS_OPEN_READ);
436        if (show_if_error (result, "open ", from))
437                return;
438
439        while (1) {
440                GnomeVFSFileSize bytes_read;
441                guint8           data [1025];
442               
443                result = gnome_vfs_read (from_handle, data, 1024, &bytes_read);
444                if (show_if_error (result, "read ", from))
445                        return;
446
447                if (bytes_read == 0)
448                        break;
449               
450                if (bytes_read >  0 &&
451                    bytes_read <= 1024)
452                        data [bytes_read] = '\0';
453                else {
454                        data [1024] = '\0';
455                        g_warning ("Wierd error from vfs_read");
456                }
457                fprintf (stdout, "%s", data);
458        }
459
460        result = gnome_vfs_close (from_handle);
461        if (show_if_error (result, "close ", from))
462                return;
463        fprintf (stdout, "\n");
464}
465
466static void
467do_rm (void)
468{
469        char          *fname;
470        GnomeVFSResult result;
471
472        fname = get_fname ();
473
474        result = gnome_vfs_unlink (fname);
475        if (show_if_error (result, "unlink ", fname))
476                return;
477}
478
479static void
480do_mkdir (void)
481{
482        char          *fname;
483        GnomeVFSResult result;
484
485        fname = get_fname ();
486
487        result = gnome_vfs_make_directory (fname, GNOME_VFS_PERM_USER_ALL);
488        if (show_if_error (result, "mkdir ", fname))
489                return;
490}
491
492static void
493do_rmdir (void)
494{
495        char          *fname;
496        GnomeVFSResult result;
497
498        fname = get_fname ();
499
500        result = gnome_vfs_remove_directory (fname);
501        if (show_if_error (result, "rmdir ", fname))
502                return;
503}
504
505static void
506do_mv (void)
507{
508        char          *from, *to;
509        char          *msg;
510        GnomeVFSResult result;
511
512        from = get_fname ();
513        to = get_fname ();
514        if (!from || !to) {
515                fprintf (vfserr, "mv <from> <to>\n");
516                return;
517        }
518
519        result = gnome_vfs_move (from, to, FALSE);
520
521        msg = g_strdup_printf ("%s to %s", from, to);
522        show_if_error (result, "move ", msg);
523        g_free (msg);
524}
525
526static void
527do_findtrash (void)
528{
529        char *from;
530        char *uri_as_string;
531        GnomeVFSResult    result;
532        GnomeVFSURI *from_uri;
533        GnomeVFSURI *result_vfs_uri;
534
535        from = get_fname ();
536
537        from_uri = gnome_vfs_uri_new (from);
538        result = gnome_vfs_find_directory (from_uri,
539                                           GNOME_VFS_DIRECTORY_KIND_TRASH,
540                                           &result_vfs_uri,
541                                           TRUE, TRUE, 0777);
542
543        if (result != GNOME_VFS_OK) {
544                fprintf (stdout, "couldn't find or create trash there, error code %d", result);
545        } else {
546                uri_as_string = gnome_vfs_uri_to_string (result_vfs_uri, GNOME_VFS_URI_HIDE_NONE);
547                fprintf (stdout, "trash found or created here: %s", uri_as_string);
548                g_free (uri_as_string);
549        }
550
551        gnome_vfs_uri_unref (from_uri);
552        gnome_vfs_uri_unref (result_vfs_uri);
553}
554
555static void
556do_ssl (void)
557{
558        if (gnome_vfs_ssl_enabled ())
559                fprintf (stdout, "SSL enabled\n");
560        else
561                fprintf (stdout, "SSL disabled\n");
562}
563
564static void
565print_info (GnomeVFSFileInfo *info)
566{
567        const char *mime_type;
568        struct tm *loctime;
569
570        fprintf (stdout, "Name: '%s'\n", info->name);
571        if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE) {
572                fprintf (stdout, "Type: ");
573                switch (info->type) {
574                case GNOME_VFS_FILE_TYPE_UNKNOWN:
575                        fprintf (stdout, "unknown");
576                        break;
577                case GNOME_VFS_FILE_TYPE_REGULAR:
578                        fprintf (stdout, "regular");
579                        break;
580                case GNOME_VFS_FILE_TYPE_DIRECTORY:
581                        fprintf (stdout, "directory");
582                        break;
583                case GNOME_VFS_FILE_TYPE_FIFO:
584                        fprintf (stdout, "fifo");
585                        break;
586                case GNOME_VFS_FILE_TYPE_SOCKET:
587                        fprintf (stdout, "socket");
588                        break;
589                case GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE:
590                        fprintf (stdout, "char");
591                        break;
592                case GNOME_VFS_FILE_TYPE_BLOCK_DEVICE:
593                        fprintf (stdout, "block");
594                        break;
595                case GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK:
596                        fprintf (stdout, "symlink\n");
597                        fprintf (stdout, "symlink points to: %s",
598                                 info->symlink_name);
599                        break;
600                default:
601                        fprintf (stdout, "Error; invalid value");
602                        break;
603                }
604        } else
605                fprintf (stdout, "Type invalid");
606        fprintf (stdout, "\n");
607
608        if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
609                long i = info->size;
610                fprintf (stdout, "Size: %ld bytes", i);
611        } else {
612                fprintf (stdout, "Size invalid");
613        }
614        fprintf (stdout, "\n");
615
616        mime_type = gnome_vfs_file_info_get_mime_type (info);
617
618        fprintf (stdout, "Mime Type: %s \n", mime_type);
619       
620        loctime = localtime(&info->atime);
621        fprintf (stdout, "Last Accessed: %s", asctime(loctime));
622        loctime = localtime(&info->mtime);
623        fprintf (stdout, "Last Modified: %s", asctime(loctime));
624        loctime = localtime(&info->ctime);
625        fprintf (stdout, "Last Changed: %s", asctime(loctime));
626       
627        fprintf (stdout, "uid: %d\n", info->uid);
628
629        fprintf (stdout, "gid: %d\n", info->gid);
630        fprintf (stdout, "\n");
631        /* FIXME bugzilla.eazel.com 2800: hack here; should dump them all */
632}
633
634static void
635do_info (void)
636{
637        char             *from;
638        GnomeVFSResult    result;
639        GnomeVFSFileInfo *info;
640
641        from = get_fname ();
642
643
644        info = gnome_vfs_file_info_new ();
645        result = gnome_vfs_get_file_info (
646                from, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE);
647
648        if (show_if_error (result, "getting info on: ", from))
649                return;
650
651        print_info (info);
652        gnome_vfs_file_info_unref (info);
653}
654
655static void
656do_cp (void)
657{
658        char *from = NULL;
659        char *to = NULL;
660        GnomeVFSHandle *from_handle = NULL;
661        GnomeVFSHandle *to_handle = NULL;
662        GnomeVFSResult  result;
663
664        from = get_fname ();
665
666        if (from)
667                to = get_fname ();
668        else {
669                fprintf (vfserr, "cp <from> <to>\n");
670                goto out;
671        }
672       
673        result = gnome_vfs_open (&from_handle, from, GNOME_VFS_OPEN_READ);
674        if (show_if_error (result, "open ", from))
675                goto out;
676
677        result = gnome_vfs_open (&to_handle, to, GNOME_VFS_OPEN_WRITE);
678        if (result == GNOME_VFS_ERROR_NOT_FOUND)
679                result = gnome_vfs_create (&to_handle, to, GNOME_VFS_OPEN_WRITE, FALSE,
680                                           GNOME_VFS_PERM_USER_ALL);
681        if (show_if_error (result, "open ", to))
682                goto out;
683
684        while (1) {
685                GnomeVFSFileSize bytes_read;
686                GnomeVFSFileSize bytes_written;
687                guint8           data [1024];
688               
689                result = gnome_vfs_read (from_handle, data, 1024, &bytes_read);
690                if (show_if_error (result, "read ", from))
691                        goto out;
692
693                if (bytes_read == 0)
694                        break;
695               
696                result = gnome_vfs_write (to_handle, data, bytes_read, &bytes_written);
697                if (show_if_error (result, "write ", to))
698                        goto out;
699
700                if (bytes_read != bytes_written)
701                        fprintf (vfserr, "Didn't write it all");
702        }
703
704 out:
705        g_free (from);
706        g_free (to);
707
708        if (to_handle) {
709                result = gnome_vfs_close (to_handle);
710                if (show_if_error (result, "close ", to))
711                        /* Nothing */;
712        }
713
714        if (from_handle) {
715                result = gnome_vfs_close (from_handle);
716                if (show_if_error (result, "close ", from))
717                        /* Nothing */;
718        }
719}
720
721static void
722ms_ole_dump (guint8 const *ptr, guint32 len, guint32 offset)
723{
724        guint32 lp,lp2;
725        guint32 off;
726
727        for (lp = 0;lp<(len+15)/16;lp++) {
728                printf ("%8x | ", lp*16 + offset);
729                for (lp2=0;lp2<16;lp2++) {
730                        off = lp2 + (lp<<4);
731                        off<len?printf("%2x ", ptr[off]):printf("XX ");
732                }
733                printf ("| ");
734                for (lp2=0;lp2<16;lp2++) {
735                        off = lp2 + (lp<<4);
736                        printf ("%c", off<len?(ptr[off]>'!'&&ptr[off]<127?ptr[off]:'.'):'*');
737                }
738                printf ("\n");
739        }
740}
741
742static void
743do_dump (void)
744{
745        char *from;
746        GnomeVFSHandle *from_handle;
747        GnomeVFSResult  result;
748        guint32         offset;
749
750        from = get_fname ();
751
752        result = gnome_vfs_open (&from_handle, from, GNOME_VFS_OPEN_READ);
753        if (show_if_error (result, "open ", from))
754                return;
755
756        for (offset = 0; 1; ) {
757                GnomeVFSFileSize bytes_read;
758                guint8           data [1024];
759               
760                result = gnome_vfs_read (from_handle, data, 1024, &bytes_read);
761                if (show_if_error (result, "read ", from))
762                        return;
763
764                if (bytes_read == 0)
765                        break;
766
767                ms_ole_dump (data, bytes_read, offset);
768               
769                offset += bytes_read;
770        }
771
772        result = gnome_vfs_close (from_handle);
773        if (show_if_error (result, "close ", from))
774                return;
775}
776
777
778/*
779 * ---------------------------------------------------------------------
780 */
781
782static char *
783get_handle (void)
784{
785        if (!arg_data [arg_cur])
786                return NULL;
787
788        return arg_data [arg_cur++];
789}
790
791static int
792get_int (void)
793{
794        if (!arg_data [arg_cur])
795                return 0;
796
797        return atoi (arg_data [arg_cur++]);
798}
799
800static void
801do_open (void)
802{
803        char *from, *handle;
804        GnomeVFSHandle *from_handle;
805        GnomeVFSResult  result;
806
807        handle = get_handle ();
808        from = get_fname ();
809
810        if (!handle || !from) {
811                fprintf (vfserr, "open <handle> <filename>\n");
812                return;
813        }
814
815        result = gnome_vfs_open (&from_handle, from, GNOME_VFS_OPEN_READ);
816        if (show_if_error (result, "open ", from))
817                return;
818
819        register_file (handle, from_handle);
820}
821
822static void
823do_create (void)
824{
825        char *from, *handle;
826        GnomeVFSHandle *from_handle;
827        GnomeVFSResult  result;
828
829        handle = get_handle ();
830        from = get_fname ();
831
832        if (!handle || !from) {
833                fprintf (vfserr, "create <handle> <filename>\n");
834                return;
835        }
836
837        result = gnome_vfs_create (&from_handle, from, GNOME_VFS_OPEN_READ,
838                                   FALSE, GNOME_VFS_PERM_USER_READ |
839                                   GNOME_VFS_PERM_USER_WRITE);
840        if (show_if_error (result, "create ", from))
841                return;
842
843        register_file (handle, from_handle);
844}
845
846static void
847do_read (void)
848{
849        char            *handle;
850        int              length;
851        GnomeVFSHandle  *from_handle;
852        GnomeVFSResult   result;
853        GnomeVFSFileSize bytes_read;
854        guint8          *data;
855
856        handle = get_handle ();
857        length = get_int ();
858
859        if (length < 0) {
860                fprintf (vfserr, "Can't read %d bytes\n", length);
861                return;
862        }
863
864        from_handle = lookup_file (handle);
865        if (!from_handle)
866                return;
867
868        data = g_malloc (length);
869        result = gnome_vfs_read (from_handle, data, length, &bytes_read);
870        if (show_if_error (result, "read ", handle))
871                return;
872
873        ms_ole_dump (data, bytes_read, 0);
874}
875
876static void
877do_seek (void)
878{
879        char            *handle;
880        int              offset;
881        GnomeVFSHandle  *from_handle;
882        GnomeVFSResult   result;
883
884        handle = get_handle ();
885        offset = get_int ();
886
887        if (offset < 0) {
888                fprintf (vfserr, "Can't seek to %d bytes offset\n", offset);
889                return;
890        }
891
892        from_handle = lookup_file (handle);
893        if (!from_handle)
894                return;
895
896        result = gnome_vfs_seek (from_handle, GNOME_VFS_SEEK_START, offset);
897        if (show_if_error (result, "seek ", handle))
898                return;
899}
900
901static void
902do_close (void)
903{
904        close_file (get_handle ());
905}
906
907static void
908do_handleinfo (void)
909{
910        const char *handlename = get_handle ();
911        GnomeVFSResult    result;
912        GnomeVFSHandle *handle = lookup_file (handlename);
913        GnomeVFSFileInfo *info;
914
915        if (!handle)
916                return;
917
918        info = gnome_vfs_file_info_new ();
919        result = gnome_vfs_get_file_info_from_handle (handle, info,
920                                                      GNOME_VFS_FILE_INFO_GET_MIME_TYPE);
921
922        if (show_if_error (result, "getting info from handle: ", handlename))
923                return;
924
925        print_info (info);
926        gnome_vfs_file_info_unref (info);
927}
928
929/*
930 * ---------------------------------------------------------------------
931 */
932
933GMainLoop *main_loop = NULL;
934
935int interactive = 0;
936const struct poptOption options [] = {
937        { "interactive", 'i', POPT_ARG_NONE, &interactive, 0,
938          "Allow interactive input", NULL  },
939        { NULL, '\0', 0, NULL, 0 }
940};
941
942static gboolean
943callback (GIOChannel *source,
944          GIOCondition condition,
945          gpointer data)
946{
947        char *buffer = data;
948        char buf[1024];
949        int len;
950
951        len = read (0, buf, sizeof (buf) - 1);
952
953        if (len + strlen (buffer) + 1 > 1024)
954                len = 1024 - strlen (buffer) - 1;
955
956        buf[len] = '\0';
957        strcat (buffer, buf);
958
959        if (strchr (buf, '\n') != NULL &&
960            main_loop != NULL) {
961                g_main_loop_quit (main_loop);
962        }
963
964        return TRUE;
965}
966
967static char *
968get_input_string (const char *prompt)
969{
970        char buffer[512];
971
972        printf (prompt);
973        fgets (buffer, 511, stdin);
974        if (strchr (buffer, '\n'))
975                *strchr (buffer, '\n') = '\0';
976       
977        return g_strndup (buffer, 512);
978}
979
980static void
981authentication_callback (gconstpointer in, gsize in_size,
982                         gpointer out, gsize out_size,
983                         gpointer user_data)
984{
985        GnomeVFSModuleCallbackAuthenticationIn *in_real;
986        GnomeVFSModuleCallbackAuthenticationOut *out_real;
987
988        g_return_if_fail (sizeof (GnomeVFSModuleCallbackAuthenticationIn) == in_size
989                && sizeof (GnomeVFSModuleCallbackAuthenticationOut) == out_size);
990
991        g_return_if_fail (in != NULL);
992        g_return_if_fail (out != NULL);
993
994        in_real = (GnomeVFSModuleCallbackAuthenticationIn *)in;
995        out_real = (GnomeVFSModuleCallbackAuthenticationOut *)out;
996       
997        printf ("Authenticate for uri: %s realm: %s\n", in_real->uri, in_real->realm);
998
999        out_real->username = get_input_string ("Username:\n");
1000        out_real->password = get_input_string ("Password:\n");
1001}
1002
1003int
1004main (int argc, const char **argv)
1005{
1006        poptContext popt_context;
1007        int exit = 0;
1008        char *buffer = g_new (char, 1024) ;
1009        const char **args;
1010        FILE *instream;
1011
1012        /* default to interactive on a terminal */
1013        interactive = isatty (0);
1014
1015        files = g_hash_table_new (g_str_hash, g_str_equal);
1016
1017        popt_context = poptGetContext ("test-vfs", argc, argv,
1018                                       options, 0);
1019
1020        while (poptGetNextOpt (popt_context) != -1)
1021                ;
1022
1023        if (interactive)
1024                vfserr = stderr;
1025        else
1026                vfserr = stdout;
1027
1028        if (!gnome_vfs_init ()) {
1029                fprintf (vfserr, "Cannot initialize gnome-vfs.\n");
1030                return 1;
1031        }
1032        gnome_vfs_module_callback_push
1033                (GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION,
1034                 authentication_callback, NULL, NULL);
1035
1036        instream = stdin;
1037        args = poptGetArgs (popt_context);
1038        if (!args)
1039                cur_dir = g_get_current_dir ();
1040        else
1041                cur_dir = g_strdup (args [0]);
1042
1043        if (cur_dir && cur_dir [strlen (cur_dir)] != '/') {
1044                char *new_dir = g_strconcat (cur_dir, "/", NULL);
1045                g_free (cur_dir);
1046                cur_dir = new_dir;
1047        }
1048               
1049        poptFreeContext (popt_context);
1050
1051        while (!exit) {
1052                char *ptr;
1053
1054                if (interactive) {
1055                        GIOChannel *ioc;
1056                        guint watch_id;
1057                        strcpy (buffer, "");
1058
1059                        main_loop = g_main_loop_new (NULL, TRUE);
1060
1061                        ioc = g_io_channel_unix_new (0 /* stdin */);
1062                        watch_id = g_io_add_watch (ioc,
1063                                                   G_IO_IN | G_IO_HUP | G_IO_ERR,
1064                                                   callback, buffer);
1065                        g_io_channel_unref (ioc);
1066
1067                        if (interactive) {
1068                                fprintf (stdout,"\n%s > ", cur_dir);
1069                                fflush (stdout);
1070                        }
1071
1072                        g_main_loop_run (main_loop);
1073
1074                        g_source_remove (watch_id);
1075
1076                        g_main_loop_unref (main_loop);
1077                        main_loop = NULL;
1078                } else {
1079                        /* In non-interactive mode we just do this evil
1080                         * thingie */
1081                        buffer[0] = '\0';
1082                        fgets (buffer, 1023, instream);
1083                        if (!buffer [0]) {
1084                                exit = 1;
1085                                continue;
1086                        }
1087                }
1088
1089                if (!buffer || buffer [0] == '#')
1090                        continue;
1091
1092                arg_data = g_strsplit (g_strchomp (buffer), delim, -1);
1093                arg_cur  = 0;
1094                if ((!arg_data || !arg_data[0]) && interactive) continue;
1095                if (!interactive)
1096                        printf ("Command : '%s'\n", arg_data [0]);
1097                ptr = arg_data[arg_cur++];
1098                if (!ptr)
1099                        continue;
1100
1101                if (g_ascii_strcasecmp (ptr, "ls") == 0)
1102                        do_ls ();
1103                else if (g_ascii_strcasecmp (ptr, "cd") == 0)
1104                        do_cd ();
1105                else if (g_ascii_strcasecmp (ptr, "dump") == 0)
1106                        do_dump ();
1107                else if (g_ascii_strcasecmp (ptr, "type") == 0 ||
1108                         g_ascii_strcasecmp (ptr, "cat") == 0)
1109                        do_cat ();
1110                else if (g_ascii_strcasecmp (ptr, "cp") == 0)
1111                        do_cp ();
1112                else if (g_ascii_strcasecmp (ptr, "rm") == 0)
1113                        do_rm ();
1114                else if (g_ascii_strcasecmp (ptr, "mkdir") == 0)
1115                        do_mkdir ();
1116                else if (g_ascii_strcasecmp (ptr, "rmdir") == 0)
1117                        do_rmdir ();
1118                else if (g_ascii_strcasecmp (ptr, "mv") == 0)
1119                        do_mv ();
1120                else if (g_ascii_strcasecmp (ptr, "info") == 0 ||
1121                         g_ascii_strcasecmp (ptr, "stat") == 0)
1122                        do_info ();
1123                else if (g_ascii_strcasecmp (ptr, "findtrash") == 0)
1124                        do_findtrash ();
1125                else if (g_ascii_strcasecmp (ptr, "ssl") == 0)
1126                        do_ssl ();
1127                else if (g_ascii_strcasecmp (ptr, "sync") == 0)
1128                        fprintf (vfserr, "a shell is like a boat, it lists or syncs (RMS)\n");
1129                else if (g_ascii_strcasecmp (ptr,"help") == 0 ||
1130                         g_ascii_strcasecmp (ptr,"?")    == 0 ||
1131                         g_ascii_strcasecmp (ptr,"info") == 0 ||
1132                         g_ascii_strcasecmp (ptr,"man")  == 0)
1133                        list_commands ();
1134                else if (g_ascii_strcasecmp (ptr,"exit") == 0 ||
1135                         g_ascii_strcasecmp (ptr,"quit") == 0 ||
1136                         g_ascii_strcasecmp (ptr,"q")    == 0 ||
1137                         g_ascii_strcasecmp (ptr,"bye") == 0)
1138                        exit = 1;
1139
1140                /* File ops */
1141                else if (g_ascii_strcasecmp (ptr, "open") == 0)
1142                        do_open ();
1143                else if (g_ascii_strcasecmp (ptr, "create") == 0)
1144                        do_create ();
1145                else if (g_ascii_strcasecmp (ptr, "close") == 0)
1146                        do_close ();
1147                else if (g_ascii_strcasecmp (ptr, "handleinfo") == 0)
1148                        do_handleinfo ();
1149                else if (g_ascii_strcasecmp (ptr, "read") == 0)
1150                        do_read ();
1151                else if (g_ascii_strcasecmp (ptr, "seek") == 0)
1152                        do_seek ();
1153               
1154                else
1155                        fprintf (vfserr, "Unknown command '%s'", ptr);
1156
1157                g_strfreev (arg_data);
1158                arg_data = NULL;
1159        }
1160
1161        g_free (buffer);
1162        g_free (cur_dir);
1163
1164        close_files ();
1165
1166        return 0;
1167}
1168
Note: See TracBrowser for help on using the repository browser.