/* $Id$ Copyright (C) 2006-2007 tooar This file is part of emelFM2. emelFM2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. emelFM2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with emelFM2; see the file GPL. If not, contact the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** @file src/filesystem/e2_vfs.h @brief header for virtual filesystem functions */ #ifndef E2_VFS_H #define E2_VFS_H #include "emelfm2.h" #ifdef E2_VFS #include //enumerator and count of v-tab liststore columns enum { VFSPROTONAME, //0 protocol (string) VFSHOSTNAME, //1 hostname VFSPATH, //2 path relative to parent place (only relevant for archives ?) VFSUSER, //3 user VFSPASSWORD, //4 password (utf8 plaintext, obfuscated when cached) VFSPORT, //5 port (string) VFSALIAS, //6 short-name utf8 string //end of displayed, editable items VFSAHIST1, //7 pane1 latest dir, utf8 string VFSAHIST2, //8 pane2 latest dir, utf8 string //end of cached items VFSMOUNTED, //9 gboolean TRUE when this place is ready to use (R/only if in dialog) // VFSPROTO, //10 protonum (integer) VFSEDITED, //10 boolean VFSID, //11 CRC-32 signature, for matching store entries VFSDATA, //12 ptr to PlaceInfo data struct, or NULL VFSCOLCOUNT }; //initial columns VFSPROTONAME to VFSDISPLAY-1 are shown in v-tab dialogs #define VFSDISPLAY VFSAHIST1 //FIXME make this stuff dynamic //support 20 remote-types and 20 arhive-types and (because it's last) unlimited synth-types #define E2_VPROTO_MINARCHIVE 20 #define E2_VPROTO_MINSYNTH 40 typedef enum { E2_VPROTO_INVALID = -1, E2_VPROTO_FTP = 0, E2_VPROTO_FTPS, E2_VPROTO_HTTP, E2_VPROTO_HTTPS, //last of initially-listed values E2_VPROTO_SSH, E2_VPROTO_FISH, E2_VPROTO_FSP, E2_VPROTO_MAXREMOTE, E2_VPROTO_TBZ2 = E2_VPROTO_MINARCHIVE, E2_VPROTO_TGZ, E2_VPROTO_TAR, E2_VPROTO_ZIP, //last of initially-listed values E2_VPROTO_7Z, E2_VPROTO_ARJ, E2_VPROTO_RAR, E2_VPROTO_RPM, // E2_VPROTO_DEB, //unsupported E2_VPROTO_MAXARCHIVE, E2_VPROTO_MAXSYNTH = E2_VPROTO_MINSYNTH } E2_VFSProtocol; //number of default remote protocols #define RPROTOCOUNT E2_VPROTO_MAXREMOTE //7 #define RPROTOINIT 4 //number of default archive protocols #define APROTOCOUNT 8 //E2_VPROTO_MAXARCHIVE - E2_VPROTO_MINARCHIVE #define APROTOINIT 4 //number of default "synthetic" protocols #define SPROTOCOUNT 0 //E2_VPROTO_MAXSYNTH - E2_VPROTO_MINSYNTH #define SPROTOINIT 0 //to append rows to liststore, set this > RPROTOCOUNT + APROTOCOUNT + SPROTOCOUNT #define LASTPROTOCOUNT 100 /* use ptr to parent data struct //enumerator for type of "parent" of an opened archive, to facilitate cd .. etc typedef enum { FS_LOCALPARENT, //a mounted dir FS_REMOTEPARENT, //a remote site FS_ARCHIVEPARENT //an archive } E2_FSParentType; */ //flags for available actions for a protocol as implemented by a library typedef enum { E2_PROT_CAN_ADD = 1, E2_PROT_CAN_DELETE = 1<<1, E2_PROT_CAN_LINK = 1<<2, //within-site or within-archive linking is ok E2_PROT_CAN_EXTRACT = 1<<3, //extract item for use E2_PROT_CAN_SNIFF = 1<<4, //extract item to determine its properties //flags for available item-properties E2_PROT_HAS_TYPE = 1<<6, E2_PROT_HAS_SIZE = 1<<7, E2_PROT_HAS_UPERMS = 1<<8, //has unix-style permissions E2_PROT_HAS_OPERMS = 1<<9, //has other-style permissions E2_PROT_HAS_UID = 1<<10, E2_PROT_HAS_GID = 1<<11, E2_PROT_HAS_MTIME = 1<<12, E2_PROT_HAS_ATIME = 1<<13, E2_PROT_HAS_CTIME = 1<<14, //flags for property-change capability (subject to permission) E2_PROT_CAN_NAME = 1<<15, E2_PROT_CAN_SIZE = 1<<16, E2_PROT_CAN_UPERMS = 1<<17, //has unix-style permissions E2_PROT_CAN_OPERMS = 1<<18, //has other-style permissions E2_PROT_CAN_UID = 1<<19, E2_PROT_CAN_GID = 1<<20, E2_PROT_CAN_MTIME = 1<<21, E2_PROT_CAN_ATIME = 1<<22, E2_PROT_CAN_CTIME = 1<<23, E2_PROT_CAN_MONITOR = 1<<24 //can do FAM } E2_VFSOpFlags; //111 1101 1111 1110 1110 0111 #define E2_PROT_LOCAL 0x7DFEE7 //enumerator for type of directory string to prepend when getting-absolute or comparing //The order here matters, it's used in parsing typedef enum { E2_DIR_WORK = 0,//the displayed dir, view->dir E2_DIR_PRIVATE, //private-use temp dir + if needed, workdir E2_DIR_LOGIN, //for remote sites, escaped full URI + if needed, workdir E2_DIR_SITE, //for remote sites, unescaped site name + if needed, workdir //as above, but use active-pane data instead of specified-pane data E2_DIRCUR_WORK = 10, E2_DIRCUR_PRIVATE, E2_DIRCUR_LOGIN, E2_DIRCUR_SITE } E2_FSDirType; //enumerator and count of backends to handle "dir" operations in a pane typedef enum { FS_NONE = -1, FS_SELF = 0, //0 = default FS_FUSEAPI, //only relevant for linux and freeBSD FS_GVFS, FS_MC, //use lib from mc FS_XDG, //use lib from freedesktop.org FS_GNOMEVFS, FS_MAX //array-size counter (1 too big!) } E2_FSHandler; //enumerator and count of supported vfs libraries typedef enum _E2_HandlerLib { E2_LIBERROR = -2, E2_LIBNONE, //0-based index of handlers which need to be loaded E2_LIBGVFS, //E2_LIBMC, //lib from mc //E2_LIBXDG, //lib from freedesktop.org //E2_LIBGNOMEVFS, E2_LIBVFS_MAX } E2_HandlerLib; /* //data structure for each item->data in archives history list //CHECKME need this sort of thing for remote sites too ? typedef struct { E2_FSParentType parent_type; gchar *virt_path; //utf8 string, virtual path of archive, in accordance with //parent_type, it can be absolute local path, or remote URL, //or inside another archive gchar *tmp_path; //localised string, path of temp dir used to process items //from the archive or the whole archive if it's remotely located GNode* virt_root; //root of data tree containing virtual directory structure //for items in archive //each node's data is an index into node-data E2_VFSFlags flags; //information about items in the archive GList *node_data; //list of E2_VFSArchNode's for each node in the virtual tree } E2_VFSArchHistory; typedef struct { gchar *path; //utf8 string, absolute path of node relative to archive root gchar *line; //string extracted from archive contents listing, //encoding indeterminate, probably localised //May be NULL for an item added to the archive after opening //but then, info will hold data for display E2_VFSFlags *flagsptr; //pointer to flags in "parent" E2_VFSArchHistory FileInfo *info; //NULL until the dir containing this item is processed for //display in a filelist //Then, filename is as stored in archive, assumed localised //statbuf maybe incomplete, in accordance with flags } E2_VFSArchNode; */ typedef enum _E2_VFSMonitorType { E2VFS_TIMEOUT = 1, E2VFS_TIMER = 1 << 1, //progress monitoring via glib timer E2VFS_THREAD = 1 << 2, //progress monitoring via new self-managed thread E2VFS_CANCEL = 1 << 3, //GCancellable used, if handler is gvfs E2VFS_PROG = 1 << 4, //show progress E2VFS_NEWERR = 1 << 5, } E2_VFSMonitorType; typedef struct _E2_VFSMonitor { E2_VFSMonitorType flags; E2_HandlerLib handler; //for customised processing struct _E2_FsFuncs *iface; //FIXME may need 2 interfaces when 2 libs involved in an operation guint timer_id; GCancellable *c; // pthread_t thread_id; //if supporting timeouts via threads too guint interval; //seconds or milliseconds between popup dialogs GMutex *mutx; GError **error; GtkWidget *slow_dialog; //too-slow dialog, for destruction const gchar *progtitle; const gchar *progmsg; //main label content const gchar *progfmt; //a format sring with a "%d", for printing current percentage GtkWidget *progbar; GtkWidget *progress_dialog; //progress dialog, for destruction } E2_VFSMonitor; //for checking presence of a function in an interface, after that interfact has been loaded //#define IFACE_OFFSET(func) (off_t) ((gpointer)&((E2_FsFuncs*)&app)->func - (gpointer)&app) #define IFACE_OFFSET(func) ((gpointer)&((E2_FsFuncs*)&app)->func - (gpointer)&app) typedef struct _E2_FsFuncs { gboolean (*mount) (VPATH *, E2_VFSMonitor *); gboolean (*unmount) (VPATH *, E2_VFSMonitor *); // gboolean (*monitor) (VPATH *); CHECK is this only useful for local files ? // gboolean (*demonitor) (VPATH *); gint (*stat) (VPATH *, struct stat *, E2_VFSMonitor *); //looks through links gint (*lstat) (VPATH *, struct stat *, E2_VFSMonitor *); //?? valid for vfs ? // gpointer fstat; invalid without handles gint (*access) (VPATH *, gint, E2_VFSMonitor *); //looks through links gint (*laccess) (VPATH *, gint, E2_VFSMonitor *); //no look through links // gpointer open; useless without handles and/or streams // gpointer fopen; invalid without handles and/or streams (local = open stream) // gpointer close; useless without handles and/or streams // gpointer fclose; invalid without handles (local = close stream) gboolean (*readfile) (VPATH *, gpointer *, gulong *, gboolean, E2_VFSMonitor *); //aka get (into memory) // gpointer readblock; //get a buffer's worth (covers sniff) useless without handles and/or streams gboolean (*writefile) (VPATH *, gpointer, size_t, mode_t, E2_VFSMonitor *); //aka put (from memory) // gpointer writeblock; //write a buffer's worth useless without handles and/or streams // gpointer writestring; //write string useless without handles and/or streams // gpointer chdir; //can't set the "default" dir in some non-local-filesystem // gpointer opendir; useless when can only get whole dir at once // gpointer closedir; useless when can only get whole dir at once gpointer (*readdir) (VPATH *, gpointer, gpointer, GDestroyNotify, E2_VFSMonitor *); //enumerate dir contents into a list of names gboolean (*mkdir) (VPATH *, mode_t, E2_VFSMonitor *); gboolean (*copy) (VPATH *, VPATH *, gboolean, E2_VFSMonitor *); //can be 2 namespaces gboolean (*move) (VPATH *, VPATH *, gboolean, E2_VFSMonitor *); //can be 2 namespaces gboolean (*rename) (VPATH *, VPATH *, E2_VFSMonitor *); //NOT same as move gboolean (*symlink) (VPATH *, VPATH *, E2_VFSMonitor *); gboolean (*readlink) (); //CHECKME ultimate target too ? gboolean (*chmod) (VPATH *, mode_t, E2_VFSMonitor *); gboolean (*chown) (VPATH *, uid_t, gid_t, E2_VFSMonitor *); gboolean (*lchown) (VPATH *, uid_t, gid_t, E2_VFSMonitor *); //CHECKME valid for vfs ? gboolean (*touch) (VPATH *, const struct utimbuf *, E2_VFSMonitor *); //aka utime gboolean (*delete) (VPATH *, E2_VFSMonitor *); //cover unlink, remove, rmdir gboolean (*check) (PlaceInfo *, guint); //check if this handler supports a nominated protocol and/or operation gboolean (*prefunc) (void); //gboolean (*starter) (void) if present, to be called before any other function except postfunc gboolean (*postfunc) (void); //gboolean (*ender) (void) if present, to be called after any other function except prefunc // gboolean loaded; //TRUE when handler plugin loaded (also, iface ptr != NULL } E2_FsFuncs; //pointer(s) to installed vfs function-pointer structs, each NULL when not installed typedef struct _E2_VFSInterface { gboolean loaded; //TRUE when the main vfs plugin is loaded gint pane1_spacecurrent; //index of current space in pane1_spacehistory GList *pane1_spacehistory; //list of used-in-session PlaceInfo's, not cached as the data is too complex gint pane2_spacecurrent; GList *pane2_spacehistory; GtkListStore *vtab; //store for history/bookmarks runtime data //pointers to vfs-plugin funcs used in main code void (*show_adjustdialog) (ViewInfo *); void (*show_historydialog) (void); void (*create_placesmenu) (GtkWidget *, ViewInfo *, gboolean); gboolean (*set_space) (ViewInfo *, PlaceInfo *, gboolean); gboolean (*set_namedspace) (ViewInfo *, gchar *); gboolean (*start_operation) (PlaceInfo *, off_t, E2_VFSMonitor *); gboolean (*finish_operation) (E2_VFSMonitor *); void (*clean_history) (void); } E2_VFSInterface; #ifdef E2_VFS E2_VFSInterface vfs; E2_FsFuncs *vfuncs[E2_LIBVFS_MAX]; #endif //E2_VFSProtocol e2_vfs_get_protonum (const gchar *protoname); //E2_VFSProtocol e2_vfs_get_protonum_for_file (gchar *filename); //E2_FSNewType e2_vfs_get_change_type (ViewInfo *view); //void e2_vfs_store_history_data (GtkTreeIter *iter, const gchar *parts[]); //gboolean e2_vfs_initialise (gpointer data); //void e2_vfs_open_local (ViewInfo *view); //void e2_vfs_open_archive (gint index, ViewInfo *view); //void e2_vfs_open_remote (gint index, ViewInfo *view); GList *e2_vfs_read_whole_dir (ViewInfo *view); //void e2_vfs_actions_register (void); void e2_toolbar_update_vfs_toggle_button (E2_FSType fs, gchar *tiptext, ViewInfo *view); void e2_vfs_dialog_create (ViewInfo *view); void e2_vfs_create_history_dialog (void); //PlaceInfo pointer in a v-path, NULL for mounted local filesystem #define e2_fs_item_is_mounted(p) (p->spacedata==NULL) void e2_fs_set_error_from_errno (GError **error); void e2_fs_set_error_custom (GError **error, gint code, const gchar *format, ...); guint32 e2_vfs_create_signature (const gchar *string); #ifdef E2_VFS gint e2_fs_lstat (VPATH *path, struct stat *buf, GError **error); gint e2_fs_access (VPATH *path, gint mode, GError **error); gint e2_fs_unlink (VPATH *localpath, GError **error); gint e2_fs_remove (VPATH *localpath, GError **error); gint e2_fs_rmdir (VPATH *localpath, GError **error); gint e2_fs_mkdir (VPATH *localpath, mode_t mode, GError **error); gint e2_fs_chdir_local (VPATH *localpath, GError **error); gint e2_fs_rename (VPATH *oldpath, VPATH *newpath, GError **error); gint e2_fs_chmod (VPATH *localpath, mode_t mode, GError **error); gint e2_fs_chown (VPATH *localpath, uid_t owner, gid_t group, GError **error); gint e2_fs_lchown (VPATH *localpath, uid_t owner, gid_t group, GError **error); gint e2_fs_utime (VPATH *localpath, const struct utimbuf *buf, GError **error); gint e2_fs_symlink (VPATH *target, VPATH *name, GError **error); gint e2_fs_readlink (VPATH *localpath, gchar *targetbuf, size_t bufsize, GError **error); #endif //parked here for now ... gpointer e2_gvfs_dir_foreach (VPATH *localpath, gpointer callback, gpointer cb_data); //gpointer e2_gvfs_dir_foreach (gchar *localpath); #endif //def E2_VFS #endif //ndef E2_VFS_H