Ticket #3581: various SFTP fixes.
[midnight-commander.git] / src / vfs / sftpfs / vfs_subclass.c
blobb7bb39c5690b379fa3adda665aecabe79bc8e811
1 /* Virtual File System: SFTP file system.
2 The VFS subclass functions
4 Copyright (C) 2011-2016
5 Free Software Foundation, Inc.
7 Written by:
8 Ilia Maslakov <il.smind@gmail.com>, 2011
9 Slava Zanko <slavazanko@gmail.com>, 2011, 2012, 2013
11 This file is part of the Midnight Commander.
13 The Midnight Commander is free software: you can redistribute it
14 and/or modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation, either version 3 of the License,
16 or (at your option) any later version.
18 The Midnight Commander is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include <config.h>
28 #include <errno.h>
29 #include <stdlib.h>
30 #include <string.h> /* memset() */
32 #include "lib/global.h"
33 #include "lib/widget.h"
34 #include "lib/vfs/utilvfs.h"
36 #include "internal.h"
38 /*** global variables ****************************************************************************/
40 struct vfs_s_subclass sftpfs_subclass;
42 /*** file scope macro definitions ****************************************************************/
44 /*** file scope type declarations ****************************************************************/
46 /*** file scope variables ************************************************************************/
48 /*** file scope functions ************************************************************************/
49 /* --------------------------------------------------------------------------------------------- */
50 /**
51 * Callback for checking if connection is equal to existing connection.
53 * @param vpath_element path element with connetion data
54 * @param super data with exists connection
55 * @param vpath unused
56 * @param cookie unused
57 * @return TRUE if connections is equal, FALSE otherwise
60 static gboolean
61 sftpfs_cb_is_equal_connection (const vfs_path_element_t * vpath_element, struct vfs_s_super *super,
62 const vfs_path_t * vpath, void *cookie)
64 int result;
65 vfs_path_element_t *orig_connect_info;
67 (void) vpath;
68 (void) cookie;
70 orig_connect_info = ((sftpfs_super_data_t *) super->data)->original_connection_info;
72 result = ((g_strcmp0 (vpath_element->host, orig_connect_info->host) == 0)
73 && (g_strcmp0 (vpath_element->user, orig_connect_info->user) == 0)
74 && (vpath_element->port == orig_connect_info->port));
76 return result;
79 /* --------------------------------------------------------------------------------------------- */
80 /**
81 * Callback for opening new connection.
83 * @param super connection data
84 * @param vpath unused
85 * @param vpath_element path element with connetion data
86 * @return 0 if success, -1 otherwise
89 static int
90 sftpfs_cb_open_connection (struct vfs_s_super *super,
91 const vfs_path_t * vpath, const vfs_path_element_t * vpath_element)
93 GError *mcerror = NULL;
94 sftpfs_super_data_t *sftpfs_super_data;
95 int ret_value;
97 (void) vpath;
99 if (vpath_element->host == NULL || *vpath_element->host == '\0')
101 vfs_print_message ("%s", _("sftp: Invalid host name."));
102 vpath_element->class->verrno = EPERM;
103 return -1;
106 sftpfs_super_data = g_new0 (sftpfs_super_data_t, 1);
107 sftpfs_super_data->socket_handle = -1;
108 sftpfs_super_data->original_connection_info = vfs_path_element_clone (vpath_element);
109 super->data = sftpfs_super_data;
110 super->path_element = vfs_path_element_clone (vpath_element);
112 sftpfs_fill_connection_data_from_config (super, &mcerror);
113 if (mc_error_message (&mcerror, &ret_value))
115 vpath_element->class->verrno = ret_value;
116 return -1;
119 super->name = g_strdup (PATH_SEP_STR);
120 super->root =
121 vfs_s_new_inode (vpath_element->class, super,
122 vfs_s_default_stat (vpath_element->class, S_IFDIR | 0755));
124 ret_value = sftpfs_open_connection (super, &mcerror);
125 mc_error_message (&mcerror, NULL);
126 return ret_value;
129 /* --------------------------------------------------------------------------------------------- */
131 * Callback for closing connection.
133 * @param me unused
134 * @param super connection data
137 static void
138 sftpfs_cb_close_connection (struct vfs_class *me, struct vfs_s_super *super)
140 GError *mcerror = NULL;
142 (void) me;
143 sftpfs_close_connection (super, "Normal Shutdown", &mcerror);
144 mc_error_message (&mcerror, NULL);
145 g_free (super->data);
148 /* --------------------------------------------------------------------------------------------- */
150 * Callback for getting directory content.
152 * @param me unused
153 * @param dir unused
154 * @param remote_path unused
155 * @return always 0
158 static int
159 sftpfs_cb_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path)
161 (void) me;
162 (void) dir;
163 (void) remote_path;
165 return 0;
168 /* --------------------------------------------------------------------------------------------- */
169 /*** public functions ****************************************************************************/
170 /* --------------------------------------------------------------------------------------------- */
172 * Initialization of VFS subclass structure.
174 * @return VFS subclass structure.
177 void
178 sftpfs_init_subclass (void)
180 memset (&sftpfs_subclass, 0, sizeof (sftpfs_subclass));
181 sftpfs_subclass.flags = VFS_S_REMOTE;
184 /* --------------------------------------------------------------------------------------------- */
186 * Initialization of VFS subclass callbacks.
189 void
190 sftpfs_init_subclass_callbacks (void)
192 sftpfs_subclass.archive_same = sftpfs_cb_is_equal_connection;
193 sftpfs_subclass.open_archive = sftpfs_cb_open_connection;
194 sftpfs_subclass.free_archive = sftpfs_cb_close_connection;
195 sftpfs_subclass.dir_load = sftpfs_cb_dir_load;
198 /* --------------------------------------------------------------------------------------------- */