mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 12:32:40 +03:00
Merge branch '3955_cleanup'
* 3955_cleanup: (43 commits) Update po/*.po files. (mcview_execute_cmd): regroup actions. lib/tty/key.c: fix coding style. (setup_mc): clarify call of add_select_channel(). lib/tty/key.c: (SelectList): rename to select_t and refactor using GSList. src/editor/edit.c: cleanup unused include. (ftpfs_get_proxy_host_and_port): ret rid of host name duplcation. (ftpfs_open_socket): fix memory leak in case of proxy usage src/vfs/ftpfs/ftpfs.c: fix coding style. src/vfs/ftpfs/ftpfs.c: use gboolean instead of int where reasonable. (tar_read_header): refactor loop. Get rid of goto. tar.c: move header decoding to separate function. tar.c: lots of renaming to be close with the GNU tar source code. extfs: change some function arguments. extfs: refactoring: use standard VFS structures. extfs: refactoring of open and read archive. (extfs_find_entry_int): minor optimization. VFS: make vfs_file_handler related macros more readable. VFS: derive VFS-specific file handler class from vfs_file_handler_t. VFS: make vfs_super related macros more readable. ...
This commit is contained in:
commit
e1d11906b3
@ -147,7 +147,7 @@ mc_skin_init (const gchar * skin_override, GError ** mcerror)
|
||||
(void) mc_skin_ini_file_parse (&mc_skin__default);
|
||||
is_good_init = FALSE;
|
||||
}
|
||||
if (is_good_init && !tty_use_truecolors (&error) && mc_skin__default.have_true_colors)
|
||||
if (is_good_init && mc_skin__default.have_true_colors && !tty_use_truecolors (&error))
|
||||
{
|
||||
mc_propagate_error (mcerror, 0,
|
||||
_
|
||||
@ -159,7 +159,7 @@ mc_skin_init (const gchar * skin_override, GError ** mcerror)
|
||||
(void) mc_skin_ini_file_parse (&mc_skin__default);
|
||||
is_good_init = FALSE;
|
||||
}
|
||||
if (is_good_init && !tty_use_256colors () && mc_skin__default.have_256_colors)
|
||||
if (is_good_init && mc_skin__default.have_256_colors && !tty_use_256colors ())
|
||||
{
|
||||
mc_propagate_error (mcerror, 0,
|
||||
_
|
||||
|
292
lib/tty/key.c
292
lib/tty/key.c
@ -252,13 +252,12 @@ typedef struct
|
||||
} key_define_t;
|
||||
|
||||
/* File descriptor monitoring add/remove routines */
|
||||
typedef struct SelectList
|
||||
typedef struct
|
||||
{
|
||||
int fd;
|
||||
select_fn callback;
|
||||
void *info;
|
||||
struct SelectList *next;
|
||||
} SelectList;
|
||||
} select_t;
|
||||
|
||||
typedef enum KeySortType
|
||||
{
|
||||
@ -522,7 +521,7 @@ static key_def *keys = NULL;
|
||||
static int input_fd;
|
||||
static int disabled_channels = 0; /* Disable channels checking */
|
||||
|
||||
static SelectList *select_list = NULL;
|
||||
static GSList *select_list = NULL;
|
||||
|
||||
static int seq_buffer[SEQ_BUFFER_LEN];
|
||||
static int *seq_append = NULL;
|
||||
@ -548,9 +547,32 @@ static const size_t key_conv_tab_size = G_N_ELEMENTS (key_name_conv_tab) - 1;
|
||||
|
||||
static const key_code_name_t *key_conv_tab_sorted[G_N_ELEMENTS (key_name_conv_tab) - 1];
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** file scope functions ************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
select_cmp_by_fd_set (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const select_t *s = (const select_t *) a;
|
||||
const fd_set *f = (const fd_set *) b;
|
||||
|
||||
return (FD_ISSET (s->fd, f) ? 0 : 1);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
select_cmp_by_fd (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const select_t *s = (const select_t *) a;
|
||||
const int fd = GPOINTER_TO_INT (b);
|
||||
|
||||
return (s->fd == fd ? 0 : 1);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
add_selects (fd_set * select_set)
|
||||
{
|
||||
@ -558,10 +580,12 @@ add_selects (fd_set * select_set)
|
||||
|
||||
if (disabled_channels == 0)
|
||||
{
|
||||
SelectList *p;
|
||||
GSList *s;
|
||||
|
||||
for (p = select_list; p != NULL; p = p->next)
|
||||
for (s = select_list; s != NULL; s = g_slist_next (s))
|
||||
{
|
||||
select_t *p = (select_t *) s->data;
|
||||
|
||||
FD_SET (p->fd, select_set);
|
||||
if (p->fd > top_fd)
|
||||
top_fd = p->fd;
|
||||
@ -576,25 +600,18 @@ add_selects (fd_set * select_set)
|
||||
static void
|
||||
check_selects (fd_set * select_set)
|
||||
{
|
||||
if (disabled_channels == 0)
|
||||
while (disabled_channels == 0)
|
||||
{
|
||||
gboolean retry;
|
||||
GSList *s;
|
||||
select_t *p;
|
||||
|
||||
do
|
||||
{
|
||||
SelectList *p;
|
||||
s = g_slist_find_custom (select_list, select_set, select_cmp_by_fd_set);
|
||||
if (s == NULL)
|
||||
break;
|
||||
|
||||
retry = FALSE;
|
||||
for (p = select_list; p; p = p->next)
|
||||
if (FD_ISSET (p->fd, select_set))
|
||||
{
|
||||
FD_CLR (p->fd, select_set);
|
||||
(*p->callback) (p->fd, p->info);
|
||||
retry = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (retry);
|
||||
p = (select_t *) s->data;
|
||||
FD_CLR (p->fd, select_set);
|
||||
p->callback (p->fd, p->info);
|
||||
}
|
||||
}
|
||||
|
||||
@ -602,12 +619,12 @@ check_selects (fd_set * select_set)
|
||||
/* If set timeout is set, then we wait 0.1 seconds, else, we block */
|
||||
|
||||
static void
|
||||
try_channels (int set_timeout)
|
||||
try_channels (gboolean set_timeout)
|
||||
{
|
||||
struct timeval time_out;
|
||||
static fd_set select_set;
|
||||
|
||||
while (1)
|
||||
while (TRUE)
|
||||
{
|
||||
struct timeval *timeptr = NULL;
|
||||
int maxfdp, v;
|
||||
@ -640,7 +657,7 @@ create_sequence (const char *seq, int code, int action)
|
||||
{
|
||||
key_def *base, *p, *attach;
|
||||
|
||||
for (base = attach = NULL; *seq; seq++)
|
||||
for (base = attach = NULL; *seq != '\0'; seq++)
|
||||
{
|
||||
p = g_new (key_def, 1);
|
||||
if (base == NULL)
|
||||
@ -697,18 +714,20 @@ getch_with_delay (void)
|
||||
|
||||
/* This routine could be used on systems without mouse support,
|
||||
so we need to do the select check :-( */
|
||||
while (1)
|
||||
while (TRUE)
|
||||
{
|
||||
if (pending_keys == NULL)
|
||||
try_channels (0);
|
||||
try_channels (FALSE);
|
||||
|
||||
/* Try to get a character */
|
||||
c = get_key_code (0);
|
||||
if (c != -1)
|
||||
break;
|
||||
|
||||
/* Failed -> wait 0.1 secs and try again */
|
||||
try_channels (1);
|
||||
try_channels (TRUE);
|
||||
}
|
||||
|
||||
/* Success -> return the character */
|
||||
return c;
|
||||
}
|
||||
@ -745,8 +764,10 @@ xmouse_get_event (Gpm_Event * ev, gboolean extended)
|
||||
so that the released button can be reported.
|
||||
- Numbers are no longer offset by 32. */
|
||||
char c;
|
||||
|
||||
btn = ev->x = ev->y = 0;
|
||||
ev->type = 0; /* In case we return on an invalid sequence */
|
||||
|
||||
while ((c = tty_lowlevel_getch ()) != ';')
|
||||
{
|
||||
if (c < '0' || c > '9')
|
||||
@ -815,7 +836,7 @@ xmouse_get_event (Gpm_Event * ev, gboolean extended)
|
||||
ev->type = GPM_DOWN;
|
||||
|
||||
GET_TIME (tv2);
|
||||
if (tv1.tv_sec && (DIF_TIME (tv1, tv2) < double_click_speed))
|
||||
if (tv1.tv_sec != 0 && DIF_TIME (tv1, tv2) < double_click_speed)
|
||||
{
|
||||
clicks++;
|
||||
clicks %= 3;
|
||||
@ -866,10 +887,8 @@ get_modifier (void)
|
||||
{
|
||||
int result = 0;
|
||||
#ifdef __QNXNTO__
|
||||
int mod_status;
|
||||
static int in_photon = 0;
|
||||
static int ph_ig = 0;
|
||||
PhCursorInfo_t cursor_info;
|
||||
#endif /* __QNXNTO__ */
|
||||
|
||||
#ifdef HAVE_TEXTMODE_X11_SUPPORT
|
||||
@ -883,44 +902,45 @@ get_modifier (void)
|
||||
mc_XQueryPointer (x11_display, x11_window, &root, &child, &root_x,
|
||||
&root_y, &win_x, &win_y, &mask);
|
||||
|
||||
if (mask & ShiftMask)
|
||||
if ((mask & ShiftMask) != 0)
|
||||
result |= KEY_M_SHIFT;
|
||||
if (mask & ControlMask)
|
||||
if ((mask & ControlMask) != 0)
|
||||
result |= KEY_M_CTRL;
|
||||
return result;
|
||||
}
|
||||
#endif /* HAVE_TEXTMODE_X11_SUPPORT */
|
||||
#ifdef __QNXNTO__
|
||||
|
||||
#ifdef __QNXNTO__
|
||||
if (in_photon == 0)
|
||||
{
|
||||
/* First time here, let's load Photon library and attach
|
||||
to Photon */
|
||||
/* First time here, let's load Photon library and attach to Photon */
|
||||
in_photon = -1;
|
||||
|
||||
if (getenv ("PHOTON2_PATH") != NULL)
|
||||
{
|
||||
/* QNX 6.x has no support for RTLD_LAZY */
|
||||
void *ph_handle = dlopen ("/usr/lib/libph.so", RTLD_NOW);
|
||||
void *ph_handle;
|
||||
|
||||
ph_handle = dlopen ("/usr/lib/libph.so", RTLD_NOW);
|
||||
if (ph_handle != NULL)
|
||||
{
|
||||
ph_attach = (ph_dv_f) dlsym (ph_handle, "PhAttach");
|
||||
ph_input_group = (ph_ov_f) dlsym (ph_handle, "PhInputGroup");
|
||||
ph_query_cursor = (ph_pqc_f) dlsym (ph_handle, "PhQueryCursor");
|
||||
if ((ph_attach != NULL) && (ph_input_group != NULL) && (ph_query_cursor != NULL))
|
||||
if ((ph_attach != NULL) && (ph_input_group != NULL) && (ph_query_cursor != NULL)
|
||||
&& (*ph_attach) (0, 0) != NULL)
|
||||
{
|
||||
if ((*ph_attach) (0, 0))
|
||||
{ /* Attached */
|
||||
ph_ig = (*ph_input_group) (0);
|
||||
in_photon = 1;
|
||||
}
|
||||
/* Attached */
|
||||
ph_ig = (*ph_input_group) (0);
|
||||
in_photon = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* We do not have Photon running. Assume we are in text
|
||||
console or xterm */
|
||||
/* We do not have Photon running. Assume we are in text console or xterm */
|
||||
if (in_photon == -1)
|
||||
{
|
||||
int mod_status;
|
||||
int shift_ext_status;
|
||||
|
||||
if (devctl (fileno (stdin), DCMD_CHR_LINESTATUS, &mod_status, sizeof (mod_status), NULL) ==
|
||||
@ -929,21 +949,23 @@ get_modifier (void)
|
||||
|
||||
shift_ext_status = mod_status & 0xffffff00UL;
|
||||
mod_status &= 0x7f;
|
||||
if (mod_status & _LINESTATUS_CON_ALT)
|
||||
if ((mod_status & _LINESTATUS_CON_ALT) != 0)
|
||||
result |= KEY_M_ALT;
|
||||
if (mod_status & _LINESTATUS_CON_CTRL)
|
||||
if ((mod_status & _LINESTATUS_CON_CTRL) != 0)
|
||||
result |= KEY_M_CTRL;
|
||||
if ((mod_status & _LINESTATUS_CON_SHIFT) || (shift_ext_status & 0x00000800UL))
|
||||
if ((mod_status & _LINESTATUS_CON_SHIFT) != 0 || (shift_ext_status & 0x00000800UL) != 0)
|
||||
result |= KEY_M_SHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
PhCursorInfo_t cursor_info;
|
||||
|
||||
(*ph_query_cursor) (ph_ig, &cursor_info);
|
||||
if (cursor_info.key_mods & 0x04)
|
||||
if ((cursor_info.key_mods & 0x04) != 0)
|
||||
result |= KEY_M_ALT;
|
||||
if (cursor_info.key_mods & 0x02)
|
||||
if ((cursor_info.key_mods & 0x02) != 0)
|
||||
result |= KEY_M_CTRL;
|
||||
if (cursor_info.key_mods & 0x01)
|
||||
if ((cursor_info.key_mods & 0x01) != 0)
|
||||
result |= KEY_M_SHIFT;
|
||||
}
|
||||
#endif /* __QNXNTO__ */
|
||||
@ -956,14 +978,15 @@ get_modifier (void)
|
||||
return 0;
|
||||
|
||||
/* Translate Linux modifiers into mc modifiers */
|
||||
if (modifiers & SHIFT_PRESSED)
|
||||
if ((modifiers & SHIFT_PRESSED) != 0)
|
||||
result |= KEY_M_SHIFT;
|
||||
if (modifiers & (ALTL_PRESSED | ALTR_PRESSED))
|
||||
if ((modifiers & (ALTL_PRESSED | ALTR_PRESSED)) != 0)
|
||||
result |= KEY_M_ALT;
|
||||
if (modifiers & CONTROL_PRESSED)
|
||||
if ((modifiers & CONTROL_PRESSED) != 0)
|
||||
result |= KEY_M_CTRL;
|
||||
}
|
||||
#endif /* !__linux__ */
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -980,7 +1003,7 @@ push_char (int c)
|
||||
if (seq_append != &(seq_buffer[SEQ_BUFFER_LEN - 2]))
|
||||
{
|
||||
*(seq_append++) = c;
|
||||
*seq_append = 0;
|
||||
*seq_append = '\0';
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
@ -1005,9 +1028,7 @@ correct_key_code (int code)
|
||||
* Ordinary characters only get modifiers from sequences.
|
||||
*/
|
||||
if (c < 32 || c >= 256)
|
||||
{
|
||||
mod |= get_modifier ();
|
||||
}
|
||||
|
||||
/* This is needed if the newline is reported as carriage return */
|
||||
if (c == '\r')
|
||||
@ -1041,54 +1062,47 @@ correct_key_code (int code)
|
||||
mod &= ~KEY_M_CTRL;
|
||||
}
|
||||
else if (c < 32 && c != ESC_CHAR && c != '\t' && c != '\n')
|
||||
{
|
||||
mod |= KEY_M_CTRL;
|
||||
}
|
||||
|
||||
#ifdef __QNXNTO__
|
||||
qmod = get_modifier ();
|
||||
|
||||
if ((c == 127) && (mod == 0))
|
||||
{ /* Add Ctrl/Alt/Shift-BackSpace */
|
||||
if (c == 127 && mod == 0)
|
||||
{
|
||||
/* Add Ctrl/Alt/Shift-BackSpace */
|
||||
mod |= get_modifier ();
|
||||
c = KEY_BACKSPACE;
|
||||
}
|
||||
|
||||
if ((c == '0') && (mod == 0))
|
||||
{ /* Add Shift-Insert on key pad */
|
||||
if ((qmod & KEY_M_SHIFT) == KEY_M_SHIFT)
|
||||
{
|
||||
mod = KEY_M_SHIFT;
|
||||
c = KEY_IC;
|
||||
}
|
||||
if (c == '0' && mod == 0 && (qmod & KEY_M_SHIFT) == KEY_M_SHIFT)
|
||||
{
|
||||
/* Add Shift-Insert on key pad */
|
||||
mod = KEY_M_SHIFT;
|
||||
c = KEY_IC;
|
||||
}
|
||||
|
||||
if ((c == '.') && (mod == 0))
|
||||
{ /* Add Shift-Del on key pad */
|
||||
if ((qmod & KEY_M_SHIFT) == KEY_M_SHIFT)
|
||||
{
|
||||
mod = KEY_M_SHIFT;
|
||||
c = KEY_DC;
|
||||
}
|
||||
if (c == '.' && mod == 0 && (qmod & KEY_M_SHIFT) == KEY_M_SHIFT)
|
||||
{
|
||||
/* Add Shift-Del on key pad */
|
||||
mod = KEY_M_SHIFT;
|
||||
c = KEY_DC;
|
||||
}
|
||||
#endif /* __QNXNTO__ */
|
||||
|
||||
/* Unrecognized 0177 is delete (preserve Ctrl) */
|
||||
if (c == 0177)
|
||||
{
|
||||
c = KEY_BACKSPACE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Unrecognized Ctrl-d is delete */
|
||||
if (c == (31 & 'd'))
|
||||
if (c == 'd' & 31)
|
||||
{
|
||||
c = KEY_DC;
|
||||
mod &= ~KEY_M_CTRL;
|
||||
}
|
||||
|
||||
/* Unrecognized Ctrl-h is backspace */
|
||||
if (c == (31 & 'h'))
|
||||
if (c == 'h' & 31)
|
||||
{
|
||||
c = KEY_BACKSPACE;
|
||||
mod &= ~KEY_M_CTRL;
|
||||
@ -1096,22 +1110,16 @@ correct_key_code (int code)
|
||||
#endif
|
||||
|
||||
/* Shift+BackSpace is backspace */
|
||||
if (c == KEY_BACKSPACE && (mod & KEY_M_SHIFT))
|
||||
{
|
||||
if (c == KEY_BACKSPACE && (mod & KEY_M_SHIFT) != 0)
|
||||
mod &= ~KEY_M_SHIFT;
|
||||
}
|
||||
|
||||
/* Convert Shift+Fn to F(n+10) */
|
||||
if (c >= KEY_F (1) && c <= KEY_F (10) && (mod & KEY_M_SHIFT))
|
||||
{
|
||||
if (c >= KEY_F (1) && c <= KEY_F (10) && (mod & KEY_M_SHIFT) != 0)
|
||||
c += 10;
|
||||
}
|
||||
|
||||
/* Remove Shift information from function keys */
|
||||
if (c >= KEY_F (1) && c <= KEY_F (20))
|
||||
{
|
||||
mod &= ~KEY_M_SHIFT;
|
||||
}
|
||||
|
||||
if (!mc_global.tty.alternate_plus_minus)
|
||||
switch (c)
|
||||
@ -1159,6 +1167,7 @@ learn_store_key (char *buffer, char **p, int c)
|
||||
{
|
||||
if (*p - buffer > 253)
|
||||
return;
|
||||
|
||||
if (c == ESC_CHAR)
|
||||
{
|
||||
*(*p)++ = '\\';
|
||||
@ -1193,18 +1202,6 @@ k_dispose (key_def * k)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
s_dispose (SelectList * sel)
|
||||
{
|
||||
if (sel != NULL)
|
||||
{
|
||||
s_dispose (sel->next);
|
||||
g_free (sel);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
key_code_comparator_by_name (const void *p1, const void *p2)
|
||||
{
|
||||
@ -1233,19 +1230,17 @@ sort_key_conv_tab (enum KeySortType type_sort)
|
||||
if (has_been_sorted != type_sort)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < key_conv_tab_size; i++)
|
||||
key_conv_tab_sorted[i] = &key_name_conv_tab[i];
|
||||
|
||||
if (type_sort == KEY_SORTBYNAME)
|
||||
{
|
||||
qsort (key_conv_tab_sorted, key_conv_tab_size, sizeof (key_conv_tab_sorted[0]),
|
||||
&key_code_comparator_by_name);
|
||||
}
|
||||
else if (type_sort == KEY_SORTBYCODE)
|
||||
{
|
||||
qsort (key_conv_tab_sorted, key_conv_tab_size, sizeof (key_conv_tab_sorted[0]),
|
||||
&key_code_comparator_by_code);
|
||||
}
|
||||
|
||||
has_been_sorted = type_sort;
|
||||
}
|
||||
}
|
||||
@ -1319,7 +1314,9 @@ lookup_keycode (const long code, int *idx)
|
||||
void
|
||||
init_key (void)
|
||||
{
|
||||
const char *term = getenv ("TERM");
|
||||
const char *term;
|
||||
|
||||
term = getenv ("TERM");
|
||||
|
||||
/* This has to be the first define_sequence */
|
||||
/* So, we can assume that the first keys member has ESC */
|
||||
@ -1385,7 +1382,7 @@ void
|
||||
done_key (void)
|
||||
{
|
||||
k_dispose (keys);
|
||||
s_dispose (select_list);
|
||||
g_slist_free_full (select_list, g_free);
|
||||
|
||||
#ifdef HAVE_TEXTMODE_X11_SUPPORT
|
||||
if (x11_display)
|
||||
@ -1398,14 +1395,14 @@ done_key (void)
|
||||
void
|
||||
add_select_channel (int fd, select_fn callback, void *info)
|
||||
{
|
||||
SelectList *new;
|
||||
select_t *new;
|
||||
|
||||
new = g_new (SelectList, 1);
|
||||
new = g_new (select_t, 1);
|
||||
new->fd = fd;
|
||||
new->callback = callback;
|
||||
new->info = info;
|
||||
new->next = select_list;
|
||||
select_list = new;
|
||||
|
||||
select_list = g_slist_prepend (select_list, new);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -1413,28 +1410,11 @@ add_select_channel (int fd, select_fn callback, void *info)
|
||||
void
|
||||
delete_select_channel (int fd)
|
||||
{
|
||||
SelectList *p = select_list;
|
||||
SelectList *p_prev = NULL;
|
||||
SelectList *p_next;
|
||||
GSList *p;
|
||||
|
||||
while (p != NULL)
|
||||
if (p->fd == fd)
|
||||
{
|
||||
p_next = p->next;
|
||||
|
||||
if (p_prev != NULL)
|
||||
p_prev->next = p_next;
|
||||
else
|
||||
select_list = p_next;
|
||||
|
||||
g_free (p);
|
||||
p = p_next;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_prev = p;
|
||||
p = p->next;
|
||||
}
|
||||
p = g_slist_find_custom (select_list, GINT_TO_POINTER (fd), select_cmp_by_fd);
|
||||
if (p != NULL)
|
||||
select_list = g_slist_delete_link (select_list, p);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -1592,15 +1572,13 @@ lookup_key_by_code (const int keycode)
|
||||
|
||||
if (lookup_keycode (k, &key_idx) || (k > 0 && k < 256))
|
||||
{
|
||||
if (mod & KEY_M_ALT)
|
||||
if ((mod & KEY_M_ALT) != 0 && lookup_keycode (KEY_M_ALT, &idx))
|
||||
{
|
||||
if (lookup_keycode (KEY_M_ALT, &idx))
|
||||
{
|
||||
g_string_append (s, key_conv_tab_sorted[idx]->name);
|
||||
g_string_append_c (s, '-');
|
||||
}
|
||||
g_string_append (s, key_conv_tab_sorted[idx]->name);
|
||||
g_string_append_c (s, '-');
|
||||
}
|
||||
if (mod & KEY_M_CTRL)
|
||||
|
||||
if ((mod & KEY_M_CTRL) != 0)
|
||||
{
|
||||
/* non printeble chars like a CTRL-[A..Z] */
|
||||
if (k < 32)
|
||||
@ -1612,7 +1590,8 @@ lookup_key_by_code (const int keycode)
|
||||
g_string_append_c (s, '-');
|
||||
}
|
||||
}
|
||||
if (mod & KEY_M_SHIFT)
|
||||
|
||||
if ((mod & KEY_M_SHIFT) != 0)
|
||||
{
|
||||
if (lookup_keycode (KEY_M_ALT, &idx))
|
||||
{
|
||||
@ -1659,7 +1638,7 @@ define_sequence (int code, const char *seq, int action)
|
||||
for (base = keys; (base != NULL) && (*seq != '\0');)
|
||||
if (*seq == base->ch)
|
||||
{
|
||||
if (base->child == 0)
|
||||
if (base->child == NULL)
|
||||
{
|
||||
if (*(seq + 1) != '\0')
|
||||
base->child = create_sequence (seq + 1, code, action);
|
||||
@ -1677,7 +1656,7 @@ define_sequence (int code, const char *seq, int action)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (base->next)
|
||||
if (base->next != NULL)
|
||||
base = base->next;
|
||||
else
|
||||
{
|
||||
@ -1794,7 +1773,7 @@ get_key_code (int no_delay)
|
||||
}
|
||||
|
||||
nodelay_try_again:
|
||||
if (no_delay)
|
||||
if (no_delay != 0)
|
||||
tty_nodelay (TRUE);
|
||||
|
||||
c = tty_lowlevel_getch ();
|
||||
@ -1802,7 +1781,8 @@ get_key_code (int no_delay)
|
||||
if (c == KEY_RESIZE)
|
||||
goto nodelay_try_again;
|
||||
#endif
|
||||
if (no_delay)
|
||||
|
||||
if (no_delay != 0)
|
||||
{
|
||||
tty_nodelay (FALSE);
|
||||
if (c == -1)
|
||||
@ -1813,6 +1793,7 @@ get_key_code (int no_delay)
|
||||
|
||||
if (esctime.tv_sec == -1)
|
||||
return -1;
|
||||
|
||||
GET_TIME (current);
|
||||
time_out.tv_sec = old_esc_mode_timeout / 1000000 + esctime.tv_sec;
|
||||
time_out.tv_usec = old_esc_mode_timeout % 1000000 + esctime.tv_usec;
|
||||
@ -1821,14 +1802,14 @@ get_key_code (int no_delay)
|
||||
time_out.tv_usec -= 1000000;
|
||||
time_out.tv_sec++;
|
||||
}
|
||||
if (current.tv_sec < time_out.tv_sec)
|
||||
return -1;
|
||||
if (current.tv_sec == time_out.tv_sec && current.tv_usec < time_out.tv_usec)
|
||||
if (current.tv_sec < time_out.tv_sec ||
|
||||
(current.tv_sec == time_out.tv_sec && current.tv_usec < time_out.tv_usec))
|
||||
return -1;
|
||||
this = NULL;
|
||||
pending_keys = seq_append = NULL;
|
||||
return ESC_CHAR;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1847,12 +1828,12 @@ get_key_code (int no_delay)
|
||||
}
|
||||
|
||||
/* Search the key on the root */
|
||||
if (!no_delay || this == NULL)
|
||||
if (no_delay == 0 || this == NULL)
|
||||
{
|
||||
this = keys;
|
||||
parent = NULL;
|
||||
|
||||
if ((c > 127 && c < 256) && use_8th_bit_as_meta)
|
||||
if (c > 127 && c < 256 && use_8th_bit_as_meta)
|
||||
{
|
||||
c &= 0x7f;
|
||||
|
||||
@ -1876,21 +1857,24 @@ get_key_code (int no_delay)
|
||||
this = NULL;
|
||||
return correct_key_code (code);
|
||||
}
|
||||
|
||||
/* No match yet, but it may be a prefix for a valid seq */
|
||||
if (!push_char (c))
|
||||
{
|
||||
pending_keys = seq_buffer;
|
||||
goto pend_send;
|
||||
}
|
||||
|
||||
parent = this;
|
||||
this = this->child;
|
||||
if (parent->action == MCKEY_ESCAPE && old_esc_mode)
|
||||
{
|
||||
if (no_delay)
|
||||
if (no_delay != 0)
|
||||
{
|
||||
GET_TIME (esctime);
|
||||
goto nodelay_try_again;
|
||||
}
|
||||
|
||||
esctime.tv_sec = -1;
|
||||
c = getch_with_timeout (old_esc_mode_timeout);
|
||||
if (c == -1)
|
||||
@ -1901,7 +1885,8 @@ get_key_code (int no_delay)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (no_delay)
|
||||
|
||||
if (no_delay != 0)
|
||||
goto nodelay_try_again;
|
||||
c = tty_lowlevel_getch ();
|
||||
continue;
|
||||
@ -1934,7 +1919,6 @@ get_key_code (int no_delay)
|
||||
push_char (c);
|
||||
pending_keys = seq_buffer;
|
||||
goto pend_send;
|
||||
|
||||
} /* while (this != NULL) */
|
||||
|
||||
this = NULL;
|
||||
@ -2075,6 +2059,7 @@ tty_get_event (struct Gpm_Event *event, gboolean redo_event, gboolean block)
|
||||
|
||||
if (FD_ISSET (input_fd, &select_set))
|
||||
break;
|
||||
|
||||
#ifdef HAVE_LIBGPM
|
||||
if (mouse_enabled && use_mouse_p == MOUSE_GPM)
|
||||
{
|
||||
@ -2091,7 +2076,7 @@ tty_get_event (struct Gpm_Event *event, gboolean redo_event, gboolean block)
|
||||
*event = ev;
|
||||
return EV_MOUSE;
|
||||
}
|
||||
else if (status <= 0) /* connection closed; -1 == error */
|
||||
if (status <= 0) /* connection closed; -1 == error */
|
||||
{
|
||||
if (mouse_fd >= 0 && FD_ISSET (mouse_fd, &select_set))
|
||||
FD_CLR (mouse_fd, &select_set);
|
||||
@ -2166,7 +2151,8 @@ tty_getch (void)
|
||||
int key;
|
||||
|
||||
ev.x = -1;
|
||||
while ((key = tty_get_event (&ev, FALSE, TRUE)) == EV_NONE);
|
||||
while ((key = tty_get_event (&ev, FALSE, TRUE)) == EV_NONE)
|
||||
;
|
||||
return key;
|
||||
}
|
||||
|
||||
@ -2190,6 +2176,7 @@ learn_key (void)
|
||||
while (c == -1)
|
||||
c = tty_lowlevel_getch (); /* Sanity check, should be unnecessary */
|
||||
learn_store_key (buffer, &p, c);
|
||||
|
||||
GET_TIME (endtime);
|
||||
endtime.tv_usec += LEARN_TIMEOUT;
|
||||
if (endtime.tv_usec > 1000000)
|
||||
@ -2197,6 +2184,7 @@ learn_key (void)
|
||||
endtime.tv_usec -= 1000000;
|
||||
endtime.tv_sec++;
|
||||
}
|
||||
|
||||
tty_nodelay (TRUE);
|
||||
while (TRUE)
|
||||
{
|
||||
|
@ -956,15 +956,10 @@ custom_canonicalize_pathname (char *path, CANON_PATH_FLAGS flags)
|
||||
vclass = vfs_prefix_to_class (vfs_prefix);
|
||||
*(s - url_delim_len) = *VFS_PATH_URL_DELIMITER;
|
||||
|
||||
if (vclass != NULL)
|
||||
if (vclass != NULL && (vclass->flags & VFS_REMOTE) != 0)
|
||||
{
|
||||
struct vfs_s_subclass *sub = (struct vfs_s_subclass *) vclass->data;
|
||||
|
||||
if (sub != NULL && sub->flags & VFS_S_REMOTE)
|
||||
{
|
||||
s = vfs_prefix;
|
||||
continue;
|
||||
}
|
||||
s = vfs_prefix;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,9 @@
|
||||
|
||||
/*** file scope macro definitions ****************************************************************/
|
||||
|
||||
#define CALL(x) if (MEDATA->x) MEDATA->x
|
||||
#define CALL(x) \
|
||||
if (VFS_SUBCLASS (me)->x != NULL) \
|
||||
VFS_SUBCLASS (me)->x
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
|
||||
@ -92,18 +94,8 @@ struct dirhandle
|
||||
|
||||
/*** file scope variables ************************************************************************/
|
||||
|
||||
/*** file scope functions ************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
vfs_s_entry_compare (const void *a, const void *b)
|
||||
{
|
||||
const struct vfs_s_entry *e = (const struct vfs_s_entry *) a;
|
||||
const char *name = (const char *) b;
|
||||
|
||||
return strcmp (e->name, name);
|
||||
}
|
||||
|
||||
/*** file scope functions ************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* We were asked to create entries automagically */
|
||||
@ -164,7 +156,8 @@ vfs_s_resolve_symlink (struct vfs_class *me, struct vfs_s_entry *entry, int foll
|
||||
}
|
||||
}
|
||||
|
||||
target = MEDATA->find_entry (me, entry->dir->super->root, linkname, follow - 1, FL_NONE);
|
||||
target =
|
||||
VFS_SUBCLASS (me)->find_entry (me, entry->dir->super->root, linkname, follow - 1, FL_NONE);
|
||||
g_free (fullname);
|
||||
return target;
|
||||
}
|
||||
@ -205,13 +198,13 @@ vfs_s_find_entry_tree (struct vfs_class *me, struct vfs_s_inode *root,
|
||||
|
||||
for (iter = root->subdir; iter != NULL; iter = g_list_next (iter))
|
||||
{
|
||||
ent = (struct vfs_s_entry *) iter->data;
|
||||
ent = VFS_ENTRY (iter->data);
|
||||
if (strlen (ent->name) == pseg && strncmp (ent->name, path, pseg) == 0)
|
||||
/* FOUND! */
|
||||
break;
|
||||
}
|
||||
|
||||
ent = iter != NULL ? (struct vfs_s_entry *) iter->data : NULL;
|
||||
ent = iter != NULL ? VFS_ENTRY (iter->data) : NULL;
|
||||
|
||||
if (ent == NULL && (flags & (FL_MKFILE | FL_MKDIR)) != 0)
|
||||
ent = vfs_s_automake (me, root, path, flags);
|
||||
@ -267,9 +260,9 @@ vfs_s_find_entry_linear (struct vfs_class *me, struct vfs_s_inode *root,
|
||||
}
|
||||
|
||||
iter = g_list_find_custom (root->subdir, path, (GCompareFunc) vfs_s_entry_compare);
|
||||
ent = iter != NULL ? (struct vfs_s_entry *) iter->data : NULL;
|
||||
ent = iter != NULL ? VFS_ENTRY (iter->data) : NULL;
|
||||
|
||||
if (ent != NULL && !MEDATA->dir_uptodate (me, ent->ino))
|
||||
if (ent != NULL && !VFS_SUBCLASS (me)->dir_uptodate (me, ent->ino))
|
||||
{
|
||||
#if 1
|
||||
vfs_print_message (_("Directory cache expired for %s"), path);
|
||||
@ -284,7 +277,7 @@ vfs_s_find_entry_linear (struct vfs_class *me, struct vfs_s_inode *root,
|
||||
|
||||
ino = vfs_s_new_inode (me, root->super, vfs_s_default_stat (me, S_IFDIR | 0755));
|
||||
ent = vfs_s_new_entry (me, path, ino);
|
||||
if (MEDATA->dir_load (me, ino, path) == -1)
|
||||
if (VFS_SUBCLASS (me)->dir_load (me, ino, path) == -1)
|
||||
{
|
||||
vfs_s_free_entry (me, ent);
|
||||
g_free (path);
|
||||
@ -294,7 +287,7 @@ vfs_s_find_entry_linear (struct vfs_class *me, struct vfs_s_inode *root,
|
||||
vfs_s_insert_entry (me, root, ent);
|
||||
|
||||
iter = g_list_find_custom (root->subdir, path, (GCompareFunc) vfs_s_entry_compare);
|
||||
ent = iter != NULL ? (struct vfs_s_entry *) iter->data : NULL;
|
||||
ent = iter != NULL ? VFS_ENTRY (iter->data) : NULL;
|
||||
}
|
||||
if (ent == NULL)
|
||||
vfs_die ("find_linear: success but directory is not there\n");
|
||||
@ -329,7 +322,7 @@ vfs_s_new_super (struct vfs_class *me)
|
||||
static inline void
|
||||
vfs_s_insert_super (struct vfs_class *me, struct vfs_s_super *super)
|
||||
{
|
||||
MEDATA->supers = g_list_prepend (MEDATA->supers, super);
|
||||
VFS_SUBCLASS (me)->supers = g_list_prepend (VFS_SUBCLASS (me)->supers, super);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -353,7 +346,7 @@ vfs_s_free_super (struct vfs_class *me, struct vfs_s_super *super)
|
||||
message (D_ERROR, "Direntry warning", "%s", "Super has want_stale set");
|
||||
#endif
|
||||
|
||||
MEDATA->supers = g_list_remove (MEDATA->supers, super);
|
||||
VFS_SUBCLASS (me)->supers = g_list_remove (VFS_SUBCLASS (me)->supers, super);
|
||||
|
||||
CALL (free_archive) (me, super);
|
||||
#ifdef ENABLE_VFS_NET
|
||||
@ -363,6 +356,30 @@ vfs_s_free_super (struct vfs_class *me, struct vfs_s_super *super)
|
||||
g_free (super);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static vfs_file_handler_t *
|
||||
vfs_s_new_fh (struct vfs_s_inode *ino, gboolean changed)
|
||||
{
|
||||
vfs_file_handler_t *fh;
|
||||
|
||||
fh = g_new0 (vfs_file_handler_t, 1);
|
||||
vfs_s_init_fh (fh, ino, changed);
|
||||
|
||||
return fh;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
vfs_s_free_fh (struct vfs_s_subclass *s, vfs_file_handler_t * fh)
|
||||
{
|
||||
if (s->fh_free != NULL)
|
||||
s->fh_free (fh);
|
||||
|
||||
g_free (fh);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* Support of archives */
|
||||
/* ------------------------ readdir & friends ----------------------------- */
|
||||
@ -441,7 +458,7 @@ vfs_s_readdir (void *data)
|
||||
if (info->cur == NULL || info->cur->data == NULL)
|
||||
return NULL;
|
||||
|
||||
name = ((struct vfs_s_entry *) info->cur->data)->name;
|
||||
name = VFS_ENTRY (info->cur->data)->name;
|
||||
if (name != NULL)
|
||||
g_strlcpy (dir.dent.d_name, name, MC_MAXPATHLEN);
|
||||
else
|
||||
@ -534,25 +551,26 @@ vfs_s_readlink (const vfs_path_t * vpath, char *buf, size_t size)
|
||||
static ssize_t
|
||||
vfs_s_read (void *fh, char *buffer, size_t count)
|
||||
{
|
||||
struct vfs_class *me = FH_SUPER->me;
|
||||
vfs_file_handler_t *file = VFS_FILE_HANDLER (fh);
|
||||
struct vfs_class *me = VFS_FILE_HANDLER_SUPER (fh)->me;
|
||||
|
||||
if (FH->linear == LS_LINEAR_PREOPEN)
|
||||
if (file->linear == LS_LINEAR_PREOPEN)
|
||||
{
|
||||
if (MEDATA->linear_start (me, FH, FH->pos) == 0)
|
||||
if (VFS_SUBCLASS (me)->linear_start (me, file, file->pos) == 0)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (FH->linear == LS_LINEAR_CLOSED)
|
||||
if (file->linear == LS_LINEAR_CLOSED)
|
||||
vfs_die ("linear_start() did not set linear_state!");
|
||||
|
||||
if (FH->linear == LS_LINEAR_OPEN)
|
||||
return MEDATA->linear_read (me, FH, buffer, count);
|
||||
if (file->linear == LS_LINEAR_OPEN)
|
||||
return VFS_SUBCLASS (me)->linear_read (me, file, buffer, count);
|
||||
|
||||
if (FH->handle != -1)
|
||||
if (file->handle != -1)
|
||||
{
|
||||
ssize_t n;
|
||||
|
||||
n = read (FH->handle, buffer, count);
|
||||
n = read (file->handle, buffer, count);
|
||||
if (n < 0)
|
||||
me->verrno = errno;
|
||||
return n;
|
||||
@ -566,17 +584,18 @@ vfs_s_read (void *fh, char *buffer, size_t count)
|
||||
static ssize_t
|
||||
vfs_s_write (void *fh, const char *buffer, size_t count)
|
||||
{
|
||||
struct vfs_class *me = FH_SUPER->me;
|
||||
vfs_file_handler_t *file = VFS_FILE_HANDLER (fh);
|
||||
struct vfs_class *me = VFS_FILE_HANDLER_SUPER (fh)->me;
|
||||
|
||||
if (FH->linear != LS_NOT_LINEAR)
|
||||
if (file->linear != LS_NOT_LINEAR)
|
||||
vfs_die ("no writing to linear files, please");
|
||||
|
||||
FH->changed = TRUE;
|
||||
if (FH->handle != -1)
|
||||
file->changed = TRUE;
|
||||
if (file->handle != -1)
|
||||
{
|
||||
ssize_t n;
|
||||
|
||||
n = write (FH->handle, buffer, count);
|
||||
n = write (file->handle, buffer, count);
|
||||
if (n < 0)
|
||||
me->verrno = errno;
|
||||
return n;
|
||||
@ -590,25 +609,26 @@ vfs_s_write (void *fh, const char *buffer, size_t count)
|
||||
static off_t
|
||||
vfs_s_lseek (void *fh, off_t offset, int whence)
|
||||
{
|
||||
off_t size = FH->ino->st.st_size;
|
||||
vfs_file_handler_t *file = VFS_FILE_HANDLER (fh);
|
||||
off_t size = file->ino->st.st_size;
|
||||
|
||||
if (FH->linear == LS_LINEAR_OPEN)
|
||||
if (file->linear == LS_LINEAR_OPEN)
|
||||
vfs_die ("cannot lseek() after linear_read!");
|
||||
|
||||
if (FH->handle != -1)
|
||||
if (file->handle != -1)
|
||||
{ /* If we have local file opened, we want to work with it */
|
||||
off_t retval;
|
||||
|
||||
retval = lseek (FH->handle, offset, whence);
|
||||
retval = lseek (file->handle, offset, whence);
|
||||
if (retval == -1)
|
||||
FH->ino->super->me->verrno = errno;
|
||||
VFS_FILE_HANDLER_SUPER (fh)->me->verrno = errno;
|
||||
return retval;
|
||||
}
|
||||
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_CUR:
|
||||
offset += FH->pos;
|
||||
offset += file->pos;
|
||||
break;
|
||||
case SEEK_END:
|
||||
offset += size;
|
||||
@ -617,12 +637,12 @@ vfs_s_lseek (void *fh, off_t offset, int whence)
|
||||
break;
|
||||
}
|
||||
if (offset < 0)
|
||||
FH->pos = 0;
|
||||
file->pos = 0;
|
||||
else if (offset < size)
|
||||
FH->pos = offset;
|
||||
file->pos = offset;
|
||||
else
|
||||
FH->pos = size;
|
||||
return FH->pos;
|
||||
file->pos = size;
|
||||
return file->pos;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -630,42 +650,44 @@ vfs_s_lseek (void *fh, off_t offset, int whence)
|
||||
static int
|
||||
vfs_s_close (void *fh)
|
||||
{
|
||||
vfs_file_handler_t *file = VFS_FILE_HANDLER (fh);
|
||||
struct vfs_s_super *super = VFS_FILE_HANDLER_SUPER (fh);
|
||||
struct vfs_class *me = super->me;
|
||||
struct vfs_s_subclass *sub = VFS_SUBCLASS (me);
|
||||
int res = 0;
|
||||
struct vfs_class *me = FH_SUPER->me;
|
||||
|
||||
if (me == NULL)
|
||||
return (-1);
|
||||
|
||||
FH_SUPER->fd_usage--;
|
||||
if (FH_SUPER->fd_usage == 0)
|
||||
vfs_stamp_create (me, FH_SUPER);
|
||||
super->fd_usage--;
|
||||
if (super->fd_usage == 0)
|
||||
vfs_stamp_create (me, VFS_FILE_HANDLER_SUPER (fh));
|
||||
|
||||
if (FH->linear == LS_LINEAR_OPEN)
|
||||
MEDATA->linear_close (me, fh);
|
||||
if (MEDATA->fh_close != NULL)
|
||||
res = MEDATA->fh_close (me, fh);
|
||||
if ((MEDATA->flags & VFS_S_USETMP) != 0 && FH->changed && MEDATA->file_store != NULL)
|
||||
if (file->linear == LS_LINEAR_OPEN)
|
||||
sub->linear_close (me, fh);
|
||||
if (sub->fh_close != NULL)
|
||||
res = sub->fh_close (me, fh);
|
||||
if ((me->flags & VFS_USETMP) != 0 && file->changed && sub->file_store != NULL)
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = vfs_s_fullpath (me, FH->ino);
|
||||
s = vfs_s_fullpath (me, file->ino);
|
||||
|
||||
if (s == NULL)
|
||||
res = -1;
|
||||
else
|
||||
{
|
||||
res = MEDATA->file_store (me, fh, s, FH->ino->localname);
|
||||
res = sub->file_store (me, fh, s, file->ino->localname);
|
||||
g_free (s);
|
||||
}
|
||||
vfs_s_invalidate (me, FH_SUPER);
|
||||
vfs_s_invalidate (me, super);
|
||||
}
|
||||
if (FH->handle != -1)
|
||||
close (FH->handle);
|
||||
if (file->handle != -1)
|
||||
close (file->handle);
|
||||
|
||||
vfs_s_free_inode (me, file->ino);
|
||||
vfs_s_free_fh (sub, fh);
|
||||
|
||||
vfs_s_free_inode (me, FH->ino);
|
||||
if (MEDATA->fh_free_data != NULL)
|
||||
MEDATA->fh_free_data (fh);
|
||||
g_free (fh);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -691,7 +713,7 @@ vfs_s_fill_names (struct vfs_class *me, fill_names_f func)
|
||||
{
|
||||
GList *iter;
|
||||
|
||||
for (iter = MEDATA->supers; iter != NULL; iter = g_list_next (iter))
|
||||
for (iter = VFS_SUBCLASS (me)->supers; iter != NULL; iter = g_list_next (iter))
|
||||
{
|
||||
const struct vfs_s_super *super = (const struct vfs_s_super *) iter->data;
|
||||
char *name;
|
||||
@ -733,7 +755,7 @@ vfs_s_getlocalcopy (const vfs_path_t * vpath)
|
||||
const struct vfs_class *me;
|
||||
|
||||
me = vfs_path_get_by_index (vpath, -1)->class;
|
||||
if ((MEDATA->flags & VFS_S_USETMP) != 0 && fh->ino != NULL)
|
||||
if ((me->flags & VFS_USETMP) != 0 && fh->ino != NULL)
|
||||
local = vfs_path_from_str_flags (fh->ino->localname, VPF_NO_CANON);
|
||||
|
||||
vfs_s_close (fh);
|
||||
@ -785,10 +807,10 @@ vfs_s_setctl (const vfs_path_t * vpath, int ctlop, void *arg)
|
||||
return 1;
|
||||
}
|
||||
case VFS_SETCTL_LOGFILE:
|
||||
((struct vfs_s_subclass *) path_element->class->data)->logfile = fopen ((char *) arg, "w");
|
||||
VFS_SUBCLASS (path_element->class)->logfile = fopen ((char *) arg, "w");
|
||||
return 1;
|
||||
case VFS_SETCTL_FLUSH:
|
||||
((struct vfs_s_subclass *) path_element->class->data)->flush = 1;
|
||||
VFS_SUBCLASS (path_element->class)->flush = 1;
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
@ -826,7 +848,7 @@ vfs_s_nothingisopen (vfsid id)
|
||||
static void
|
||||
vfs_s_free (vfsid id)
|
||||
{
|
||||
vfs_s_free_super (((struct vfs_s_super *) id)->me, (struct vfs_s_super *) id);
|
||||
vfs_s_free_super (VFS_SUPER (id)->me, VFS_SUPER (id));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -836,9 +858,9 @@ vfs_s_dir_uptodate (struct vfs_class *me, struct vfs_s_inode *ino)
|
||||
{
|
||||
struct timeval tim;
|
||||
|
||||
if (MEDATA->flush != 0)
|
||||
if (VFS_SUBCLASS (me)->flush != 0)
|
||||
{
|
||||
MEDATA->flush = 0;
|
||||
VFS_SUBCLASS (me)->flush = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -865,8 +887,8 @@ vfs_s_new_inode (struct vfs_class *me, struct vfs_s_super *super, struct stat *i
|
||||
ino->st = *initstat;
|
||||
ino->super = super;
|
||||
ino->st.st_nlink = 0;
|
||||
ino->st.st_ino = MEDATA->inode_counter++;
|
||||
ino->st.st_dev = MEDATA->rdev;
|
||||
ino->st.st_ino = VFS_SUBCLASS (me)->inode_counter++;
|
||||
ino->st.st_dev = VFS_SUBCLASS (me)->rdev;
|
||||
|
||||
super->ino_usage++;
|
||||
|
||||
@ -891,11 +913,11 @@ vfs_s_free_inode (struct vfs_class *me, struct vfs_s_inode *ino)
|
||||
}
|
||||
|
||||
while (ino->subdir != NULL)
|
||||
vfs_s_free_entry (me, (struct vfs_s_entry *) ino->subdir->data);
|
||||
vfs_s_free_entry (me, VFS_ENTRY (ino->subdir->data));
|
||||
|
||||
CALL (free_inode) (me, ino);
|
||||
g_free (ino->linkname);
|
||||
if ((MEDATA->flags & VFS_S_USETMP) != 0 && ino->localname != NULL)
|
||||
if ((me->flags & VFS_USETMP) != 0 && ino->localname != NULL)
|
||||
{
|
||||
unlink (ino->localname);
|
||||
g_free (ino->localname);
|
||||
@ -955,6 +977,17 @@ vfs_s_insert_entry (struct vfs_class *me, struct vfs_s_inode *dir, struct vfs_s_
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
vfs_s_entry_compare (const void *a, const void *b)
|
||||
{
|
||||
const struct vfs_s_entry *e = (const struct vfs_s_entry *) a;
|
||||
const char *name = (const char *) b;
|
||||
|
||||
return strcmp (e->name, name);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
struct stat *
|
||||
vfs_s_default_stat (struct vfs_class *me, mode_t mode)
|
||||
{
|
||||
@ -1047,10 +1080,10 @@ vfs_s_find_inode (struct vfs_class *me, const struct vfs_s_super *super,
|
||||
{
|
||||
struct vfs_s_entry *ent;
|
||||
|
||||
if (((MEDATA->flags & VFS_S_REMOTE) == 0) && (*path == '\0'))
|
||||
if (((me->flags & VFS_REMOTE) == 0) && (*path == '\0'))
|
||||
return super->root;
|
||||
|
||||
ent = MEDATA->find_entry (me, super->root, path, follow, flags);
|
||||
ent = VFS_SUBCLASS (me)->find_entry (me, super->root, path, follow, flags);
|
||||
return (ent != NULL ? ent->ino : NULL);
|
||||
}
|
||||
|
||||
@ -1075,9 +1108,7 @@ vfs_get_super_by_vpath (const vfs_path_t * vpath)
|
||||
vfs_path_t *vpath_archive;
|
||||
|
||||
path_element = vfs_path_get_by_index (vpath, -1);
|
||||
subclass = (struct vfs_s_subclass *) path_element->class->data;
|
||||
if (subclass == NULL)
|
||||
return NULL;
|
||||
subclass = VFS_SUBCLASS (path_element->class);
|
||||
|
||||
vpath_archive = vfs_path_clone (vpath);
|
||||
vfs_path_remove_element_by_index (vpath_archive, -1);
|
||||
@ -1089,11 +1120,14 @@ vfs_get_super_by_vpath (const vfs_path_t * vpath)
|
||||
goto ret;
|
||||
}
|
||||
|
||||
if (subclass->archive_same == NULL)
|
||||
goto ret;
|
||||
|
||||
for (iter = subclass->supers; iter != NULL; iter = g_list_next (iter))
|
||||
{
|
||||
int i;
|
||||
|
||||
super = (struct vfs_s_super *) iter->data;
|
||||
super = VFS_SUPER (iter->data);
|
||||
|
||||
/* 0 == other, 1 == same, return it, 2 == other but stop scanning */
|
||||
i = subclass->archive_same (path_element, super, vpath_archive, cookie);
|
||||
@ -1144,9 +1178,11 @@ vfs_s_get_path (const vfs_path_t * vpath, struct vfs_s_super **archive, int flag
|
||||
return NULL;
|
||||
}
|
||||
|
||||
super = vfs_s_new_super (path_element->class);
|
||||
subclass = VFS_SUBCLASS (path_element->class);
|
||||
|
||||
super = subclass->new_archive != NULL ?
|
||||
subclass->new_archive (path_element->class) : vfs_s_new_super (path_element->class);
|
||||
|
||||
subclass = (struct vfs_s_subclass *) path_element->class->data;
|
||||
if (subclass->open_archive != NULL)
|
||||
{
|
||||
vfs_path_t *vpath_archive;
|
||||
@ -1196,7 +1232,7 @@ vfs_s_fullpath (struct vfs_class *me, struct vfs_s_inode *ino)
|
||||
if (ino->ent == NULL)
|
||||
ERRNOR (EAGAIN, NULL);
|
||||
|
||||
if ((MEDATA->flags & VFS_S_USETMP) == 0)
|
||||
if ((me->flags & VFS_USETMP) == 0)
|
||||
{
|
||||
/* archives */
|
||||
char *path;
|
||||
@ -1225,6 +1261,17 @@ vfs_s_fullpath (struct vfs_class *me, struct vfs_s_inode *ino)
|
||||
return g_strconcat (ino->ent->dir->ent->name, PATH_SEP_STR, ino->ent->name, (char *) NULL);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
vfs_s_init_fh (vfs_file_handler_t * fh, struct vfs_s_inode *ino, gboolean changed)
|
||||
{
|
||||
fh->ino = ino;
|
||||
fh->handle = -1;
|
||||
fh->changed = changed;
|
||||
fh->linear = LS_NOT_LINEAR;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* --------------------------- stat and friends ---------------------------- */
|
||||
|
||||
@ -1237,6 +1284,7 @@ vfs_s_open (const vfs_path_t * vpath, int flags, mode_t mode)
|
||||
const char *q;
|
||||
struct vfs_s_inode *ino;
|
||||
const vfs_path_element_t *path_element;
|
||||
struct vfs_s_subclass *s;
|
||||
|
||||
path_element = vfs_path_get_by_index (vpath, -1);
|
||||
|
||||
@ -1250,6 +1298,8 @@ vfs_s_open (const vfs_path_t * vpath, int flags, mode_t mode)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s = VFS_SUBCLASS (path_element->class);
|
||||
|
||||
if (ino == NULL)
|
||||
{
|
||||
char *dirname, *name;
|
||||
@ -1273,7 +1323,7 @@ vfs_s_open (const vfs_path_t * vpath, int flags, mode_t mode)
|
||||
ent = vfs_s_generate_entry (path_element->class, name, dir, 0755);
|
||||
ino = ent->ino;
|
||||
vfs_s_insert_entry (path_element->class, dir, ent);
|
||||
if ((VFSDATA (path_element)->flags & VFS_S_USETMP) != 0)
|
||||
if ((VFS_CLASS (s)->flags & VFS_USETMP) != 0)
|
||||
{
|
||||
int tmp_handle;
|
||||
vfs_path_t *tmp_vpath;
|
||||
@ -1301,17 +1351,11 @@ vfs_s_open (const vfs_path_t * vpath, int flags, mode_t mode)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fh = g_new (vfs_file_handler_t, 1);
|
||||
fh->pos = 0;
|
||||
fh->ino = ino;
|
||||
fh->handle = -1;
|
||||
fh->changed = was_changed;
|
||||
fh->linear = LS_NOT_LINEAR;
|
||||
fh->data = NULL;
|
||||
fh = s->fh_new != NULL ? s->fh_new (ino, was_changed) : vfs_s_new_fh (ino, was_changed);
|
||||
|
||||
if (IS_LINEAR (flags))
|
||||
{
|
||||
if (VFSDATA (path_element)->linear_start != NULL)
|
||||
if (s->linear_start != NULL)
|
||||
{
|
||||
vfs_print_message ("%s", _("Starting linear transfer..."));
|
||||
fh->linear = LS_LINEAR_PREOPEN;
|
||||
@ -1319,24 +1363,19 @@ vfs_s_open (const vfs_path_t * vpath, int flags, mode_t mode)
|
||||
}
|
||||
else
|
||||
{
|
||||
struct vfs_s_subclass *s;
|
||||
|
||||
s = VFSDATA (path_element);
|
||||
if (s->fh_open != NULL && s->fh_open (path_element->class, fh, flags, mode) != 0)
|
||||
{
|
||||
if (s->fh_free_data != NULL)
|
||||
s->fh_free_data (fh);
|
||||
g_free (fh);
|
||||
vfs_s_free_fh (s, fh);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((VFSDATA (path_element)->flags & VFS_S_USETMP) != 0 && fh->ino->localname != NULL)
|
||||
if ((VFS_CLASS (s)->flags & VFS_USETMP) != 0 && fh->ino->localname != NULL)
|
||||
{
|
||||
fh->handle = open (fh->ino->localname, NO_LINEAR (flags), mode);
|
||||
if (fh->handle == -1)
|
||||
{
|
||||
g_free (fh);
|
||||
vfs_s_free_fh (s, fh);
|
||||
path_element->class->verrno = errno;
|
||||
return NULL;
|
||||
}
|
||||
@ -1370,7 +1409,7 @@ vfs_s_lstat (const vfs_path_t * vpath, struct stat *buf)
|
||||
int
|
||||
vfs_s_fstat (void *fh, struct stat *buf)
|
||||
{
|
||||
*buf = FH->ino->st;
|
||||
*buf = VFS_FILE_HANDLER (fh)->ino->st;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1385,17 +1424,13 @@ vfs_s_retrieve_file (struct vfs_class *me, struct vfs_s_inode *ino)
|
||||
int handle;
|
||||
ssize_t n;
|
||||
off_t stat_size = ino->st.st_size;
|
||||
vfs_file_handler_t fh;
|
||||
vfs_file_handler_t *fh = NULL;
|
||||
vfs_path_t *tmp_vpath;
|
||||
struct vfs_s_subclass *s = VFS_SUBCLASS (me);
|
||||
|
||||
if ((MEDATA->flags & VFS_S_USETMP) == 0)
|
||||
if ((me->flags & VFS_USETMP) == 0)
|
||||
return (-1);
|
||||
|
||||
memset (&fh, 0, sizeof (fh));
|
||||
|
||||
fh.ino = ino;
|
||||
fh.handle = -1;
|
||||
|
||||
handle = vfs_mkstemps (&tmp_vpath, me->name, ino->ent->name);
|
||||
ino->localname = g_strdup (vfs_path_as_str (tmp_vpath));
|
||||
vfs_path_free (tmp_vpath);
|
||||
@ -1405,14 +1440,16 @@ vfs_s_retrieve_file (struct vfs_class *me, struct vfs_s_inode *ino)
|
||||
goto error_4;
|
||||
}
|
||||
|
||||
if (MEDATA->linear_start (me, &fh, 0) == 0)
|
||||
fh = s->fh_new != NULL ? s->fh_new (ino, FALSE) : vfs_s_new_fh (ino, FALSE);
|
||||
|
||||
if (s->linear_start (me, fh, 0) == 0)
|
||||
goto error_3;
|
||||
|
||||
/* Clear the interrupt status */
|
||||
tty_got_interrupt ();
|
||||
tty_enable_interrupt_key ();
|
||||
|
||||
while ((n = MEDATA->linear_read (me, &fh, buffer, sizeof (buffer))) != 0)
|
||||
while ((n = s->linear_read (me, fh, buffer, sizeof (buffer))) != 0)
|
||||
{
|
||||
int t;
|
||||
|
||||
@ -1433,22 +1470,23 @@ vfs_s_retrieve_file (struct vfs_class *me, struct vfs_s_inode *ino)
|
||||
goto error_1;
|
||||
}
|
||||
}
|
||||
MEDATA->linear_close (me, &fh);
|
||||
s->linear_close (me, fh);
|
||||
close (handle);
|
||||
|
||||
tty_disable_interrupt_key ();
|
||||
g_free (fh.data);
|
||||
vfs_s_free_fh (s, fh);
|
||||
return 0;
|
||||
|
||||
error_1:
|
||||
MEDATA->linear_close (me, &fh);
|
||||
s->linear_close (me, fh);
|
||||
error_3:
|
||||
tty_disable_interrupt_key ();
|
||||
close (handle);
|
||||
unlink (ino->localname);
|
||||
error_4:
|
||||
MC_PTR_FREE (ino->localname);
|
||||
g_free (fh.data);
|
||||
if (fh != NULL)
|
||||
vfs_s_free_fh (s, fh);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -1457,14 +1495,19 @@ vfs_s_retrieve_file (struct vfs_class *me, struct vfs_s_inode *ino)
|
||||
|
||||
/* Initialize one of our subclasses - fill common functions */
|
||||
void
|
||||
vfs_s_init_class (struct vfs_class *vclass, struct vfs_s_subclass *sub)
|
||||
vfs_init_class (struct vfs_class *vclass, const char *name, vfs_flags_t flags, const char *prefix)
|
||||
{
|
||||
vclass->data = sub;
|
||||
memset (vclass, 0, sizeof (struct vfs_class));
|
||||
|
||||
vclass->name = name;
|
||||
vclass->flags = flags;
|
||||
vclass->prefix = prefix;
|
||||
|
||||
vclass->fill_names = vfs_s_fill_names;
|
||||
vclass->open = vfs_s_open;
|
||||
vclass->close = vfs_s_close;
|
||||
vclass->read = vfs_s_read;
|
||||
if ((sub->flags & VFS_S_READONLY) == 0)
|
||||
if ((vclass->flags & VFS_READONLY) == 0)
|
||||
vclass->write = vfs_s_write;
|
||||
vclass->opendir = vfs_s_opendir;
|
||||
vclass->readdir = vfs_s_readdir;
|
||||
@ -1479,17 +1522,36 @@ vfs_s_init_class (struct vfs_class *vclass, struct vfs_s_subclass *sub)
|
||||
vclass->getid = vfs_s_getid;
|
||||
vclass->nothingisopen = vfs_s_nothingisopen;
|
||||
vclass->free = vfs_s_free;
|
||||
if ((sub->flags & VFS_S_USETMP) != 0)
|
||||
vclass->setctl = vfs_s_setctl;
|
||||
if ((vclass->flags & VFS_USETMP) != 0)
|
||||
{
|
||||
vclass->getlocalcopy = vfs_s_getlocalcopy;
|
||||
vclass->ungetlocalcopy = vfs_s_ungetlocalcopy;
|
||||
sub->find_entry = vfs_s_find_entry_linear;
|
||||
}
|
||||
else if ((sub->flags & VFS_S_REMOTE) != 0)
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
vfs_init_subclass (struct vfs_s_subclass *sub, const char *name, vfs_flags_t flags,
|
||||
const char *prefix)
|
||||
{
|
||||
struct vfs_class *vclass = VFS_CLASS (sub);
|
||||
size_t len;
|
||||
char *start;
|
||||
|
||||
vfs_init_class (vclass, name, flags, prefix);
|
||||
|
||||
len = sizeof (struct vfs_s_subclass) - sizeof (struct vfs_class);
|
||||
start = (char *) sub + sizeof (struct vfs_class);
|
||||
memset (start, 0, len);
|
||||
|
||||
if ((vclass->flags & VFS_USETMP) != 0)
|
||||
sub->find_entry = vfs_s_find_entry_linear;
|
||||
else if ((vclass->flags & VFS_REMOTE) != 0)
|
||||
sub->find_entry = vfs_s_find_entry_linear;
|
||||
else
|
||||
sub->find_entry = vfs_s_find_entry_tree;
|
||||
vclass->setctl = vfs_s_setctl;
|
||||
sub->dir_uptodate = vfs_s_dir_uptodate;
|
||||
}
|
||||
|
||||
@ -1541,7 +1603,7 @@ vfs_s_select_on_two (int fd1, int fd2)
|
||||
int
|
||||
vfs_s_get_line (struct vfs_class *me, int sock, char *buf, int buf_len, char term)
|
||||
{
|
||||
FILE *logfile = MEDATA->logfile;
|
||||
FILE *logfile = VFS_SUBCLASS (me)->logfile;
|
||||
int i;
|
||||
char c;
|
||||
|
||||
@ -1645,7 +1707,7 @@ vfs_s_normalize_filename_leading_spaces (struct vfs_s_inode *root_inode, size_t
|
||||
|
||||
for (iter = root_inode->subdir; iter != NULL; iter = g_list_next (iter))
|
||||
{
|
||||
struct vfs_s_entry *entry = (struct vfs_s_entry *) iter->data;
|
||||
struct vfs_s_entry *entry = VFS_ENTRY (iter->data);
|
||||
|
||||
if ((size_t) entry->ino->data_offset > final_num_spaces)
|
||||
{
|
||||
|
99
lib/vfs/gc.c
99
lib/vfs/gc.c
@ -39,11 +39,12 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdlib.h> /* For atol() */
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h> /* gettimeofday() */
|
||||
|
||||
#include "lib/global.h"
|
||||
#include "lib/event.h"
|
||||
#include "lib/timer.h"
|
||||
|
||||
#include "vfs.h"
|
||||
#include "utilvfs.h"
|
||||
@ -97,7 +98,7 @@ struct vfs_stamping
|
||||
{
|
||||
struct vfs_class *v;
|
||||
vfsid id;
|
||||
guint64 time;
|
||||
struct timeval time;
|
||||
};
|
||||
|
||||
/*** file scope variables ************************************************************************/
|
||||
@ -108,6 +109,16 @@ static GSList *stamps = NULL;
|
||||
/*** file scope functions ************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/** Compare two timeval structures. Return TRUE is t1 is less than t2. */
|
||||
static gboolean
|
||||
timeoutcmp (const struct timeval *t1, const struct timeval *t2)
|
||||
{
|
||||
return ((t1->tv_sec < t2->tv_sec)
|
||||
|| ((t1->tv_sec == t2->tv_sec) && (t1->tv_usec <= t2->tv_usec)));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static gint
|
||||
vfs_stamp_compare (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
@ -119,44 +130,17 @@ vfs_stamp_compare (gconstpointer a, gconstpointer b)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
vfs_stamp_free (gpointer data, gpointer user_data)
|
||||
{
|
||||
struct vfs_stamping *stamp = VFS_STAMPING (data);
|
||||
|
||||
(void) user_data;
|
||||
|
||||
if (stamp->v->free != NULL)
|
||||
stamp->v->free (stamp->id);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
vfs_stamp_expire (gpointer data, gpointer user_data)
|
||||
{
|
||||
struct vfs_stamping *stamp = VFS_STAMPING (data);
|
||||
|
||||
if (user_data == NULL || stamp->time <= *(guint64 *) user_data)
|
||||
{
|
||||
vfs_stamp_free (data, NULL);
|
||||
vfs_rmstamp (stamp->v, stamp->id);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
vfs_addstamp (struct vfs_class *v, vfsid id)
|
||||
{
|
||||
if ((v->flags & VFSF_LOCAL) == 0 && id != NULL && !vfs_stamp (v, id))
|
||||
if ((v->flags & VFS_LOCAL) == 0 && id != NULL && !vfs_stamp (v, id))
|
||||
{
|
||||
struct vfs_stamping *stamp;
|
||||
|
||||
stamp = g_new (struct vfs_stamping, 1);
|
||||
stamp->v = v;
|
||||
stamp->id = id;
|
||||
stamp->time = mc_timer_elapsed (mc_global.timer);
|
||||
gettimeofday (&(stamp->time), NULL);
|
||||
|
||||
stamps = g_slist_append (stamps, stamp);
|
||||
}
|
||||
@ -179,7 +163,7 @@ vfs_stamp (struct vfs_class *v, vfsid id)
|
||||
stamp = g_slist_find_custom (stamps, &what, vfs_stamp_compare);
|
||||
if (stamp != NULL)
|
||||
{
|
||||
VFS_STAMPING (stamp->data)->time = mc_timer_elapsed (mc_global.timer);
|
||||
gettimeofday (&(VFS_STAMPING (stamp->data)->time), NULL);
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
@ -258,8 +242,8 @@ vfs_stamp_create (struct vfs_class *vclass, vfsid id)
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/** This is called from timeout handler with now = 0, or can be called
|
||||
with now = 1 to force freeing all filesystems that are not in use */
|
||||
/** This is called from timeout handler with now == FALSE,
|
||||
or can be called with now == TRUE to force freeing all filesystems */
|
||||
|
||||
void
|
||||
vfs_expire (gboolean now)
|
||||
@ -270,17 +254,48 @@ vfs_expire (gboolean now)
|
||||
calls message */
|
||||
if (locked)
|
||||
return;
|
||||
|
||||
locked = TRUE;
|
||||
|
||||
if (now)
|
||||
g_slist_foreach (stamps, vfs_stamp_expire, NULL);
|
||||
{
|
||||
/* reverse list to free nested VFSes at first */
|
||||
stamps = g_slist_reverse (stamps);
|
||||
|
||||
while (stamps != NULL)
|
||||
{
|
||||
struct vfs_stamping *stamping = VFS_STAMPING (stamps->data);
|
||||
|
||||
if (stamping->v->free != NULL)
|
||||
stamping->v->free (stamping->id);
|
||||
g_free (stamping);
|
||||
stamps = g_slist_delete_link (stamps, stamps);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
guint64 lc_time;
|
||||
struct timeval lc_time;
|
||||
GSList *stamp;
|
||||
|
||||
lc_time = mc_timer_elapsed (mc_global.timer) - vfs_timeout * G_USEC_PER_SEC;
|
||||
g_slist_foreach (stamps, vfs_stamp_expire, &lc_time);
|
||||
gettimeofday (&lc_time, NULL);
|
||||
lc_time.tv_sec -= vfs_timeout;
|
||||
|
||||
for (stamp = stamps; stamp != NULL;)
|
||||
{
|
||||
struct vfs_stamping *stamping = VFS_STAMPING (stamp->data);
|
||||
|
||||
if (!timeoutcmp (&stamping->time, &lc_time))
|
||||
stamp = g_slist_next (stamp);
|
||||
else
|
||||
{
|
||||
GSList *st;
|
||||
|
||||
st = g_slist_next (stamp);
|
||||
if (stamping->v->free != NULL)
|
||||
stamping->v->free (stamping->id);
|
||||
vfs_rmstamp (stamping->v, stamping->id);
|
||||
stamp = st;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
locked = FALSE;
|
||||
@ -324,9 +339,7 @@ vfs_release_path (const vfs_path_t * vpath)
|
||||
void
|
||||
vfs_gc_done (void)
|
||||
{
|
||||
g_slist_foreach (stamps, vfs_stamp_free, NULL);
|
||||
g_slist_free_full (stamps, g_free);
|
||||
stamps = NULL;
|
||||
vfs_expire (TRUE);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -336,7 +336,7 @@ vfs_get_class_by_name (const char *class_name)
|
||||
|
||||
for (i = 0; i < vfs__classes_list->len; i++)
|
||||
{
|
||||
struct vfs_class *vfs = (struct vfs_class *) g_ptr_array_index (vfs__classes_list, i);
|
||||
struct vfs_class *vfs = VFS_CLASS (g_ptr_array_index (vfs__classes_list, i));
|
||||
if ((vfs->name != NULL) && (strcmp (vfs->name, class_name) == 0))
|
||||
return vfs;
|
||||
}
|
||||
@ -461,8 +461,8 @@ vfs_path_from_str_uri_parser (char *path)
|
||||
element->vfs_prefix = g_strdup (vfs_prefix_start);
|
||||
|
||||
url_delimiter += strlen (VFS_PATH_URL_DELIMITER);
|
||||
sub = VFSDATA (element);
|
||||
if (sub != NULL && (sub->flags & VFS_S_REMOTE) != 0)
|
||||
sub = VFS_SUBCLASS (element->class);
|
||||
if (sub != NULL && (VFS_CLASS (sub)->flags & VFS_REMOTE) != 0)
|
||||
{
|
||||
char *slash_pointer;
|
||||
|
||||
@ -531,7 +531,7 @@ static void
|
||||
vfs_path_tokens_add_class_info (const vfs_path_element_t * element, GString * ret_tokens,
|
||||
GString * element_tokens)
|
||||
{
|
||||
if (((element->class->flags & VFSF_LOCAL) == 0 || ret_tokens->len > 0)
|
||||
if (((element->class->flags & VFS_LOCAL) == 0 || ret_tokens->len > 0)
|
||||
&& element_tokens->len > 0)
|
||||
{
|
||||
char *url_str;
|
||||
@ -596,7 +596,7 @@ vfs_path_strip_home (const char *dir)
|
||||
|
||||
#define vfs_append_from_path(appendfrom, is_relative) \
|
||||
{ \
|
||||
if ((flags & VPF_STRIP_HOME) && element_index == 0 && (element->class->flags & VFSF_LOCAL) != 0) \
|
||||
if ((flags & VPF_STRIP_HOME) && element_index == 0 && (element->class->flags & VFS_LOCAL) != 0) \
|
||||
{ \
|
||||
char *stripped_home_str; \
|
||||
stripped_home_str = vfs_path_strip_home (appendfrom); \
|
||||
@ -1004,7 +1004,7 @@ vfs_prefix_to_class (const char *prefix)
|
||||
{
|
||||
struct vfs_class *vfs;
|
||||
|
||||
vfs = (struct vfs_class *) g_ptr_array_index (vfs__classes_list, i);
|
||||
vfs = VFS_CLASS (g_ptr_array_index (vfs__classes_list, i));
|
||||
if (vfs->which != NULL)
|
||||
{
|
||||
if (vfs->which (vfs, prefix) == -1)
|
||||
|
@ -315,6 +315,17 @@ vfs_register_class (struct vfs_class * vfs)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
vfs_unregister_class (struct vfs_class *vfs)
|
||||
{
|
||||
if (vfs->done != NULL)
|
||||
vfs->done (vfs);
|
||||
|
||||
g_ptr_array_remove (vfs__classes_list, vfs);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/** Strip known vfs suffixes from a filename (possible improvement: strip
|
||||
* suffix from last path component).
|
||||
@ -427,20 +438,20 @@ vfs_set_raw_current_dir (const vfs_path_t * vpath)
|
||||
gboolean
|
||||
vfs_current_is_local (void)
|
||||
{
|
||||
return (current_vfs->flags & VFSF_LOCAL) != 0;
|
||||
return (current_vfs->flags & VFS_LOCAL) != 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* Return flags of the VFS class of the given filename */
|
||||
|
||||
vfs_class_flags_t
|
||||
vfs_flags_t
|
||||
vfs_file_class_flags (const vfs_path_t * vpath)
|
||||
{
|
||||
const vfs_path_element_t *path_element;
|
||||
|
||||
path_element = vfs_path_get_by_index (vpath, -1);
|
||||
if (!vfs_path_element_valid (path_element))
|
||||
return VFSF_UNKNOWN;
|
||||
return VFS_UNKNOWN;
|
||||
|
||||
return path_element->class->flags;
|
||||
}
|
||||
@ -492,7 +503,7 @@ vfs_shut (void)
|
||||
|
||||
for (i = 0; i < vfs__classes_list->len; i++)
|
||||
{
|
||||
struct vfs_class *vfs = (struct vfs_class *) g_ptr_array_index (vfs__classes_list, i);
|
||||
struct vfs_class *vfs = VFS_CLASS (g_ptr_array_index (vfs__classes_list, i));
|
||||
|
||||
if (vfs->done != NULL)
|
||||
vfs->done (vfs);
|
||||
@ -523,7 +534,7 @@ vfs_fill_names (fill_names_f func)
|
||||
|
||||
for (i = 0; i < vfs__classes_list->len; i++)
|
||||
{
|
||||
struct vfs_class *vfs = (struct vfs_class *) g_ptr_array_index (vfs__classes_list, i);
|
||||
struct vfs_class *vfs = VFS_CLASS (g_ptr_array_index (vfs__classes_list, i));
|
||||
|
||||
if (vfs->fill_names != NULL)
|
||||
vfs->fill_names (vfs, func);
|
||||
@ -531,10 +542,11 @@ vfs_fill_names (fill_names_f func)
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
gboolean
|
||||
vfs_file_is_local (const vfs_path_t * vpath)
|
||||
{
|
||||
return (vfs_file_class_flags (vpath) & VFSF_LOCAL) != 0;
|
||||
return (vfs_file_class_flags (vpath) & VFS_LOCAL) != 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -585,7 +597,7 @@ vfs_setup_cwd (void)
|
||||
|
||||
path_element = vfs_path_get_by_index (vfs_get_raw_current_dir (), -1);
|
||||
|
||||
if ((path_element->class->flags & VFSF_LOCAL) != 0)
|
||||
if ((path_element->class->flags & VFS_LOCAL) != 0)
|
||||
{
|
||||
current_dir = g_get_current_dir ();
|
||||
tmp_vpath = vfs_path_from_str (current_dir);
|
||||
@ -650,7 +662,7 @@ vfs_preallocate (int dest_vfs_fd, off_t src_fsize, off_t dest_fsize)
|
||||
return 0;
|
||||
|
||||
dest_class = vfs_class_find_by_handle (dest_vfs_fd, &dest_fd);
|
||||
if ((dest_class->flags & VFSF_LOCAL) == 0 || dest_fd == NULL)
|
||||
if ((dest_class->flags & VFS_LOCAL) == 0 || dest_fd == NULL)
|
||||
return 0;
|
||||
|
||||
return posix_fallocate (*(int *) dest_fd, dest_fsize, src_fsize - dest_fsize);
|
||||
@ -670,7 +682,7 @@ vfs_clone_file (int dest_vfs_fd, int src_vfs_fd)
|
||||
struct vfs_class *src_class;
|
||||
|
||||
dest_class = vfs_class_find_by_handle (dest_vfs_fd, &dest_fd);
|
||||
if ((dest_class->flags & VFSF_LOCAL) == 0)
|
||||
if ((dest_class->flags & VFS_LOCAL) == 0)
|
||||
{
|
||||
errno = EOPNOTSUPP;
|
||||
return (-1);
|
||||
@ -682,7 +694,7 @@ vfs_clone_file (int dest_vfs_fd, int src_vfs_fd)
|
||||
}
|
||||
|
||||
src_class = vfs_class_find_by_handle (src_vfs_fd, &src_fd);
|
||||
if ((src_class->flags & VFSF_LOCAL) == 0)
|
||||
if ((src_class->flags & VFS_LOCAL) == 0)
|
||||
{
|
||||
errno = EOPNOTSUPP;
|
||||
return (-1);
|
||||
|
@ -26,6 +26,8 @@
|
||||
|
||||
/*** typedefs(not structures) and defined constants **********************************************/
|
||||
|
||||
#define VFS_CLASS(a) ((struct vfs_class *) (a))
|
||||
|
||||
#if defined (ENABLE_VFS_FTP) || defined (ENABLE_VFS_FISH) || defined (ENABLE_VFS_SMB)
|
||||
#define ENABLE_VFS_NET 1
|
||||
#endif
|
||||
@ -107,13 +109,16 @@ typedef struct utimbuf mc_timesbuf_t;
|
||||
|
||||
/*** enums ***************************************************************************************/
|
||||
|
||||
/* Flags of VFS classes */
|
||||
typedef enum
|
||||
{
|
||||
VFSF_UNKNOWN = 0,
|
||||
VFSF_LOCAL = 1 << 0, /* Class is local (not virtual) filesystem */
|
||||
VFSF_NOLINKS = 1 << 1 /* Hard links not supported */
|
||||
} vfs_class_flags_t;
|
||||
VFS_UNKNOWN = 0,
|
||||
VFS_LOCAL = 1 << 0, /* Class is local (not virtual) filesystem */
|
||||
VFS_NOLINKS = 1 << 1, /* Hard links not supported */
|
||||
|
||||
VFS_REMOTE = 1 << 2,
|
||||
VFS_READONLY = 1 << 3,
|
||||
VFS_USETMP = 1 << 4
|
||||
} vfs_flags_t;
|
||||
|
||||
/* Operations for mc_ctl - on open file */
|
||||
enum
|
||||
@ -139,9 +144,8 @@ enum
|
||||
typedef struct vfs_class
|
||||
{
|
||||
const char *name; /* "FIles over SHell" */
|
||||
vfs_class_flags_t flags;
|
||||
vfs_flags_t flags;
|
||||
const char *prefix; /* "fish:" */
|
||||
void *data; /* this is for filesystem's own use */
|
||||
int verrno; /* can't use errno because glibc2 might define errno as function */
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
@ -225,6 +229,9 @@ extern int use_netrc;
|
||||
/*** declarations of public functions ************************************************************/
|
||||
|
||||
/* lib/vfs/direntry.c: */
|
||||
void vfs_init_class (struct vfs_class *vclass, const char *name, vfs_flags_t flags,
|
||||
const char *prefix);
|
||||
|
||||
void *vfs_s_open (const vfs_path_t * vpath, int flags, mode_t mode);
|
||||
int vfs_s_stat (const vfs_path_t * vpath, struct stat *buf);
|
||||
int vfs_s_lstat (const vfs_path_t * vpath, struct stat *buf);
|
||||
@ -238,6 +245,7 @@ void vfs_init (void);
|
||||
void vfs_shut (void);
|
||||
/* Register a file system class */
|
||||
gboolean vfs_register_class (struct vfs_class *vfs);
|
||||
void vfs_unregister_class (struct vfs_class *vfs);
|
||||
|
||||
void vfs_setup_work_dir (void);
|
||||
|
||||
@ -255,7 +263,7 @@ gboolean vfs_file_is_local (const vfs_path_t * vpath);
|
||||
|
||||
char *vfs_strip_suffix_from_filename (const char *filename);
|
||||
|
||||
vfs_class_flags_t vfs_file_class_flags (const vfs_path_t * vpath);
|
||||
vfs_flags_t vfs_file_class_flags (const vfs_path_t * vpath);
|
||||
|
||||
/* translate path back to terminal encoding, remove all #enc:
|
||||
* every invalid character is replaced with question mark
|
||||
|
@ -34,23 +34,17 @@
|
||||
|
||||
#define ERRNOR(a, b) do { me->verrno = a; return b; } while (0)
|
||||
|
||||
#define MEDATA ((struct vfs_s_subclass *) me->data)
|
||||
#define VFS_SUBCLASS(a) ((struct vfs_s_subclass *) (a))
|
||||
|
||||
#define VFSDATA(a) ((a->class != NULL) ? (struct vfs_s_subclass *) a->class->data : NULL)
|
||||
#define VFS_SUPER(a) ((struct vfs_s_super *) (a))
|
||||
#define VFS_ENTRY(a) ((struct vfs_s_entry *) (a))
|
||||
#define VFS_INODE(a) ((struct vfs_s_inode *) (a))
|
||||
|
||||
#define FH ((vfs_file_handler_t *) fh)
|
||||
#define FH_SUPER FH->ino->super
|
||||
#define VFS_FILE_HANDLER(a) ((vfs_file_handler_t *) a)
|
||||
#define VFS_FILE_HANDLER_SUPER(a) VFS_FILE_HANDLER (a)->ino->super
|
||||
|
||||
/*** enums ***************************************************************************************/
|
||||
|
||||
/* For vfs_s_subclass->flags */
|
||||
typedef enum
|
||||
{
|
||||
VFS_S_REMOTE = 1L << 0,
|
||||
VFS_S_READONLY = 1L << 1,
|
||||
VFS_S_USETMP = 1L << 2,
|
||||
} vfs_subclass_flags_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LS_NOT_LINEAR = 0,
|
||||
@ -73,8 +67,6 @@ struct vfs_s_super
|
||||
#ifdef ENABLE_VFS_NET
|
||||
vfs_path_element_t *path_element;
|
||||
#endif /* ENABLE_VFS_NET */
|
||||
|
||||
void *data; /* This is for filesystem-specific use */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -111,18 +103,18 @@ typedef struct
|
||||
int handle; /* This is for module's use, but if != -1, will be mc_close()d */
|
||||
gboolean changed; /* Did this file change? */
|
||||
vfs_linear_state_t linear; /* Is that file open with O_LINEAR? */
|
||||
void *data; /* This is for filesystem-specific use */
|
||||
} vfs_file_handler_t;
|
||||
|
||||
/*
|
||||
* One of our subclasses (tar, cpio, fish, ftpfs) with data and methods.
|
||||
* Extends vfs_class. Stored in the "data" field of vfs_class.
|
||||
* Extends vfs_class.
|
||||
*/
|
||||
struct vfs_s_subclass
|
||||
{
|
||||
struct vfs_class base; /* base class */
|
||||
|
||||
GList *supers;
|
||||
int inode_counter;
|
||||
vfs_subclass_flags_t flags; /* whether the subclass is remove, read-only etc */
|
||||
dev_t rdev;
|
||||
FILE *logfile;
|
||||
int flush; /* if set to 1, invalidate directory cache */
|
||||
@ -135,13 +127,15 @@ struct vfs_s_subclass
|
||||
void *(*archive_check) (const vfs_path_t * vpath); /* optional */
|
||||
int (*archive_same) (const vfs_path_element_t * vpath_element, struct vfs_s_super * psup,
|
||||
const vfs_path_t * vpath, void *cookie);
|
||||
struct vfs_s_super *(*new_archive) (struct vfs_class * me);
|
||||
int (*open_archive) (struct vfs_s_super * psup,
|
||||
const vfs_path_t * vpath, const vfs_path_element_t * vpath_element);
|
||||
void (*free_archive) (struct vfs_class * me, struct vfs_s_super * psup);
|
||||
|
||||
vfs_file_handler_t *(*fh_new) (struct vfs_s_inode * ino, gboolean changed);
|
||||
int (*fh_open) (struct vfs_class * me, vfs_file_handler_t * fh, int flags, mode_t mode);
|
||||
int (*fh_close) (struct vfs_class * me, vfs_file_handler_t * fh);
|
||||
void (*fh_free_data) (vfs_file_handler_t * fh);
|
||||
void (*fh_free) (vfs_file_handler_t * fh);
|
||||
|
||||
struct vfs_s_entry *(*find_entry) (struct vfs_class * me,
|
||||
struct vfs_s_inode * root,
|
||||
@ -169,6 +163,7 @@ struct vfs_s_entry *vfs_s_new_entry (struct vfs_class *me, const char *name,
|
||||
struct vfs_s_inode *inode);
|
||||
void vfs_s_free_entry (struct vfs_class *me, struct vfs_s_entry *ent);
|
||||
void vfs_s_insert_entry (struct vfs_class *me, struct vfs_s_inode *dir, struct vfs_s_entry *ent);
|
||||
int vfs_s_entry_compare (const void *a, const void *b);
|
||||
struct stat *vfs_s_default_stat (struct vfs_class *me, mode_t mode);
|
||||
|
||||
struct vfs_s_entry *vfs_s_generate_entry (struct vfs_class *me, const char *name,
|
||||
@ -179,13 +174,16 @@ struct vfs_s_inode *vfs_s_find_inode (struct vfs_class *me,
|
||||
struct vfs_s_inode *vfs_s_find_root (struct vfs_class *me, struct vfs_s_entry *entry);
|
||||
|
||||
/* outside interface */
|
||||
void vfs_s_init_class (struct vfs_class *vclass, struct vfs_s_subclass *sub);
|
||||
void vfs_init_subclass (struct vfs_s_subclass *sub, const char *name, vfs_flags_t flags,
|
||||
const char *prefix);
|
||||
const char *vfs_s_get_path (const vfs_path_t * vpath, struct vfs_s_super **archive, int flags);
|
||||
struct vfs_s_super *vfs_get_super_by_vpath (const vfs_path_t * vpath);
|
||||
|
||||
void vfs_s_invalidate (struct vfs_class *me, struct vfs_s_super *super);
|
||||
char *vfs_s_fullpath (struct vfs_class *me, struct vfs_s_inode *ino);
|
||||
|
||||
void vfs_s_init_fh (vfs_file_handler_t * fh, struct vfs_s_inode *ino, gboolean changed);
|
||||
|
||||
/* network filesystems support */
|
||||
int vfs_s_select_on_two (int fd1, int fd2);
|
||||
int vfs_s_get_line (struct vfs_class *me, int sock, char *buf, int buf_len, char term);
|
||||
|
@ -230,6 +230,10 @@ static cb_ret_t
|
||||
dlg_execute_cmd (WDialog * h, long command)
|
||||
{
|
||||
cb_ret_t ret = MSG_HANDLED;
|
||||
|
||||
if (send_message (h, NULL, MSG_ACTION, command, NULL) == MSG_HANDLED)
|
||||
return MSG_HANDLED;
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case CK_Ok:
|
||||
@ -299,13 +303,8 @@ dlg_handle_key (WDialog * h, int d_key)
|
||||
long command;
|
||||
|
||||
command = keybind_lookup_keymap_command (dialog_map, d_key);
|
||||
|
||||
if (command == CK_IgnoreKey)
|
||||
return MSG_NOT_HANDLED;
|
||||
|
||||
if (send_message (h, NULL, MSG_ACTION, command, NULL) == MSG_HANDLED
|
||||
|| dlg_execute_cmd (h, command) == MSG_HANDLED)
|
||||
return MSG_HANDLED;
|
||||
if (command != CK_IgnoreKey)
|
||||
return dlg_execute_cmd (h, command);
|
||||
|
||||
return MSG_NOT_HANDLED;
|
||||
}
|
||||
@ -1150,16 +1149,21 @@ dlg_init (WDialog * h)
|
||||
void
|
||||
dlg_process_event (WDialog * h, int key, Gpm_Event * event)
|
||||
{
|
||||
if (key == EV_NONE)
|
||||
switch (key)
|
||||
{
|
||||
case EV_NONE:
|
||||
if (tty_got_interrupt ())
|
||||
if (send_message (h, NULL, MSG_ACTION, CK_Cancel, NULL) != MSG_HANDLED)
|
||||
dlg_execute_cmd (h, CK_Cancel);
|
||||
}
|
||||
else if (key == EV_MOUSE)
|
||||
dlg_execute_cmd (h, CK_Cancel);
|
||||
break;
|
||||
|
||||
case EV_MOUSE:
|
||||
h->mouse_status = dlg_mouse_event (h, event);
|
||||
else
|
||||
break;
|
||||
|
||||
default:
|
||||
dlg_key_event (h, key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -16,7 +16,7 @@ AC_DEFUN([mc_UNIT_TESTS],[
|
||||
|
||||
dnl 'tests_msg' holds the human-readable message to show in configure's summary text.
|
||||
|
||||
if test x$enable_tests == xno; then
|
||||
if test x"$enable_tests" = "xno"; then
|
||||
dnl The user explicitly specified '--disable-tests'.
|
||||
tests_msg="no"
|
||||
else
|
||||
@ -33,7 +33,7 @@ AC_DEFUN([mc_UNIT_TESTS],[
|
||||
|
||||
dnl The following behavior, of "exit if feature requested but not found", is just a
|
||||
dnl preference and can be safely removed.
|
||||
if test x$enable_tests == xyes; then
|
||||
if test x"$enable_tests" = "xyes"; then
|
||||
AC_MSG_ERROR([You explicitly specified '--enable-tests', but this requirement cannot be met.])
|
||||
fi
|
||||
])
|
||||
|
2
po/az.po
2
po/az.po
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Azerbaijani (http://www.transifex.com/mc/mc/language/az/)\n"
|
||||
|
2
po/be.po
2
po/be.po
@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Belarusian (http://www.transifex.com/mc/mc/language/be/)\n"
|
||||
|
2
po/bg.po
2
po/bg.po
@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Bulgarian (http://www.transifex.com/mc/mc/language/bg/)\n"
|
||||
|
2
po/ca.po
2
po/ca.po
@ -16,7 +16,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-22 11:52+0000\n"
|
||||
"Last-Translator: Antoni Bella Pérez <antonibella5@yahoo.com>\n"
|
||||
"Language-Team: Catalan (http://www.transifex.com/mc/mc/language/ca/)\n"
|
||||
|
2
po/cs.po
2
po/cs.po
@ -13,7 +13,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 09:38+0000\n"
|
||||
"Last-Translator: Pavel Borecki <pavel.borecki@gmail.com>\n"
|
||||
"Language-Team: Czech (http://www.transifex.com/mc/mc/language/cs/)\n"
|
||||
|
2
po/da.po
2
po/da.po
@ -13,7 +13,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-26 11:43+0000\n"
|
||||
"Last-Translator: Morten Bo Johansen <mortenbo@hotmail.com>\n"
|
||||
"Language-Team: Danish (http://www.transifex.com/mc/mc/language/da/)\n"
|
||||
|
2
po/de.po
2
po/de.po
@ -18,7 +18,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 17:54+0000\n"
|
||||
"Last-Translator: Ettore Atalan <atalanttore@googlemail.com>\n"
|
||||
"Language-Team: German (http://www.transifex.com/mc/mc/language/de/)\n"
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2015-02-26 09:48+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: German (Switzerland) (http://www.transifex.com/projects/p/mc/"
|
||||
|
2
po/el.po
2
po/el.po
@ -12,7 +12,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Greek (http://www.transifex.com/mc/mc/language/el/)\n"
|
||||
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: English (United Kingdom) (http://www.transifex.com/mc/mc/"
|
||||
|
2
po/eo.po
2
po/eo.po
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Esperanto (http://www.transifex.com/mc/mc/language/eo/)\n"
|
||||
|
2
po/es.po
2
po/es.po
@ -13,7 +13,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 20:17+0000\n"
|
||||
"Last-Translator: David Martin <dhmartina@yahoo.es>\n"
|
||||
"Language-Team: Spanish (http://www.transifex.com/mc/mc/language/es/)\n"
|
||||
|
2
po/et.po
2
po/et.po
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Estonian (http://www.transifex.com/mc/mc/language/et/)\n"
|
||||
|
2
po/eu.po
2
po/eu.po
@ -9,7 +9,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Basque (http://www.transifex.com/mc/mc/language/eu/)\n"
|
||||
|
2
po/fa.po
2
po/fa.po
@ -12,7 +12,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Persian (http://www.transifex.com/mc/mc/language/fa/)\n"
|
||||
|
2
po/fi.po
2
po/fi.po
@ -10,7 +10,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-12-07 20:42+0000\n"
|
||||
"Last-Translator: Nikolay Korotkiy <sikmir@gmail.com>\n"
|
||||
"Language-Team: Finnish (http://www.transifex.com/mc/mc/language/fi/)\n"
|
||||
|
2
po/fr.po
2
po/fr.po
@ -17,7 +17,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: French (http://www.transifex.com/mc/mc/language/fr/)\n"
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2015-02-26 09:48+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: French (Canada) (http://www.transifex.com/projects/p/mc/"
|
||||
|
2
po/gl.po
2
po/gl.po
@ -12,7 +12,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Galician (http://www.transifex.com/mc/mc/language/gl/)\n"
|
||||
|
2
po/hr.po
2
po/hr.po
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Croatian (http://www.transifex.com/mc/mc/language/hr/)\n"
|
||||
|
2
po/hu.po
2
po/hu.po
@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Hungarian (http://www.transifex.com/mc/mc/language/hu/)\n"
|
||||
|
2
po/ia.po
2
po/ia.po
@ -10,7 +10,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Interlingua (http://www.transifex.com/mc/mc/language/ia/)\n"
|
||||
|
2
po/id.po
2
po/id.po
@ -10,7 +10,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Indonesian (http://www.transifex.com/mc/mc/language/id/)\n"
|
||||
|
2
po/it.po
2
po/it.po
@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-09-10 08:38+0200\n"
|
||||
"Last-Translator: Marco Ciampa <ciampix@libero.it>\n"
|
||||
"Language-Team: Italian (http://www.transifex.com/projects/p/mc/language/"
|
||||
|
2
po/ja.po
2
po/ja.po
@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Japanese (http://www.transifex.com/mc/mc/language/ja/)\n"
|
||||
|
2
po/ka.po
2
po/ka.po
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Georgian (http://www.transifex.com/mc/mc/language/ka/)\n"
|
||||
|
2
po/kk.po
2
po/kk.po
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Kazakh (http://www.transifex.com/mc/mc/language/kk/)\n"
|
||||
|
2
po/ko.po
2
po/ko.po
@ -9,7 +9,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Korean (http://www.transifex.com/mc/mc/language/ko/)\n"
|
||||
|
2
po/lt.po
2
po/lt.po
@ -12,7 +12,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Lithuanian (http://www.transifex.com/mc/mc/language/lt/)\n"
|
||||
|
2
po/lv.po
2
po/lv.po
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Latvian (http://www.transifex.com/mc/mc/language/lv/)\n"
|
||||
|
2
po/mn.po
2
po/mn.po
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Mongolian (http://www.transifex.com/mc/mc/language/mn/)\n"
|
||||
|
2
po/nb.po
2
po/nb.po
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Norwegian Bokmål (http://www.transifex.com/mc/mc/language/"
|
||||
|
2
po/nl.po
2
po/nl.po
@ -14,7 +14,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Dutch (http://www.transifex.com/mc/mc/language/nl/)\n"
|
||||
|
2
po/pl.po
2
po/pl.po
@ -9,7 +9,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 15:33+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Polish (http://www.transifex.com/mc/mc/language/pl/)\n"
|
||||
|
2
po/pt.po
2
po/pt.po
@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 14:51+0000\n"
|
||||
"Last-Translator: Gilberto Jorge <gmj125@gmail.com>\n"
|
||||
"Language-Team: Portuguese (http://www.transifex.com/mc/mc/language/pt/)\n"
|
||||
|
@ -13,7 +13,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/mc/mc/language/"
|
||||
|
2
po/ro.po
2
po/ro.po
@ -15,7 +15,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Romanian (http://www.transifex.com/mc/mc/language/ro/)\n"
|
||||
|
8
po/ru.po
8
po/ru.po
@ -26,7 +26,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-11-24 15:03+0000\n"
|
||||
"Last-Translator: aborodin <aborodin@vmail.ru>\n"
|
||||
"Language-Team: Russian (http://www.transifex.com/mc/mc/language/ru/)\n"
|
||||
@ -4558,9 +4558,3 @@ msgstr "Продолжить с начала?"
|
||||
|
||||
msgid "Cannot fetch a local copy of /ftp://some.host/editme.txt"
|
||||
msgstr "Невозможно получить локальную копию /ftp://some.host/editme.txt"
|
||||
|
||||
#~ msgid "Target file already exists!"
|
||||
#~ msgstr "Целевой файл уже существует!"
|
||||
|
||||
#~ msgid "&Update"
|
||||
#~ msgstr "&Устаревшие"
|
||||
|
2
po/sk.po
2
po/sk.po
@ -14,7 +14,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Slovak (http://www.transifex.com/mc/mc/language/sk/)\n"
|
||||
|
2
po/sl.po
2
po/sl.po
@ -10,7 +10,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Slovenian (http://www.transifex.com/mc/mc/language/sl/)\n"
|
||||
|
2
po/sr.po
2
po/sr.po
@ -9,7 +9,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Serbian (http://www.transifex.com/mc/mc/language/sr/)\n"
|
||||
|
2
po/sv.po
2
po/sv.po
@ -14,7 +14,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Swedish (http://www.transifex.com/mc/mc/language/sv/)\n"
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Silesian (http://www.transifex.com/mc/mc/language/szl/)\n"
|
||||
|
2
po/ta.po
2
po/ta.po
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Tamil (http://www.transifex.com/mc/mc/language/ta/)\n"
|
||||
|
2
po/te.po
2
po/te.po
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Telugu (http://www.transifex.com/mc/mc/language/te/)\n"
|
||||
|
2
po/tr.po
2
po/tr.po
@ -13,7 +13,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Turkish (http://www.transifex.com/mc/mc/language/tr/)\n"
|
||||
|
2
po/uk.po
2
po/uk.po
@ -12,7 +12,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Ukrainian (http://www.transifex.com/mc/mc/language/uk/)\n"
|
||||
|
2
po/vi.po
2
po/vi.po
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Vietnamese (http://www.transifex.com/mc/mc/language/vi/)\n"
|
||||
|
2
po/wa.po
2
po/wa.po
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Walloon (http://www.transifex.com/mc/mc/language/wa/)\n"
|
||||
|
@ -17,7 +17,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Chinese (China) (http://www.transifex.com/mc/mc/language/"
|
||||
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Midnight Commander\n"
|
||||
"Report-Msgid-Bugs-To: http://www.midnight-commander.org/\n"
|
||||
"POT-Creation-Date: 2019-03-02 12:28+0300\n"
|
||||
"POT-Creation-Date: 2019-04-27 19:55+0300\n"
|
||||
"PO-Revision-Date: 2018-10-21 01:34+0000\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Chinese (Taiwan) (http://www.transifex.com/mc/mc/language/"
|
||||
|
@ -64,7 +64,6 @@
|
||||
#include "src/usermenu.h" /* user_menu_cmd() */
|
||||
|
||||
#include "src/setup.h" /* option_tab_spacing */
|
||||
#include "src/learn.h" /* learn_keys */
|
||||
#include "src/keybind-defaults.h"
|
||||
|
||||
#include "edit-impl.h"
|
||||
|
@ -82,14 +82,15 @@ gboolean option_auto_syntax = TRUE;
|
||||
#define SYNTAX_TOKEN_BRACKET '\003'
|
||||
#define SYNTAX_TOKEN_BRACE '\004'
|
||||
|
||||
#define free_args(x)
|
||||
#define break_a {result=line;break;}
|
||||
#define check_a {if(!*a){result=line;break;}}
|
||||
#define check_not_a {if(*a){result=line;break;}}
|
||||
#define break_a { result = line; break; }
|
||||
#define check_a { if (*a == NULL) { result = line; break; } }
|
||||
#define check_not_a { if (*a != NULL) { result = line ;break; } }
|
||||
|
||||
#define SYNTAX_KEYWORD(x) ((syntax_keyword_t *) (x))
|
||||
#define CONTEXT_RULE(x) ((context_rule_t *) (x))
|
||||
|
||||
#define ARGS_LEN 1024
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
|
||||
typedef struct
|
||||
@ -97,7 +98,7 @@ typedef struct
|
||||
char *keyword;
|
||||
char *whole_word_chars_left;
|
||||
char *whole_word_chars_right;
|
||||
long line_start;
|
||||
gboolean line_start;
|
||||
int color;
|
||||
} syntax_keyword_t;
|
||||
|
||||
@ -107,9 +108,9 @@ typedef struct
|
||||
unsigned char first_left;
|
||||
char *right;
|
||||
unsigned char first_right;
|
||||
char line_start_left;
|
||||
char line_start_right;
|
||||
int between_delimiters;
|
||||
gboolean line_start_left;
|
||||
gboolean line_start_right;
|
||||
gboolean between_delimiters;
|
||||
char *whole_word_chars_left;
|
||||
char *whole_word_chars_right;
|
||||
char *keyword_first_chars;
|
||||
@ -203,26 +204,23 @@ xx_tolower (const WEdit * edit, int c)
|
||||
static void
|
||||
subst_defines (GTree * defines, char **argv, char **argv_end)
|
||||
{
|
||||
char **t, **p;
|
||||
int argc;
|
||||
|
||||
while (*argv != NULL && argv < argv_end)
|
||||
for (; *argv != NULL && argv < argv_end; argv++)
|
||||
{
|
||||
char **t;
|
||||
|
||||
t = g_tree_lookup (defines, *argv);
|
||||
if (t != NULL)
|
||||
{
|
||||
int count = 0;
|
||||
int argc, count;
|
||||
char **p;
|
||||
|
||||
/* Count argv array members */
|
||||
argc = 0;
|
||||
for (p = &argv[1]; *p != NULL; p++)
|
||||
argc++;
|
||||
argc = g_strv_length (argv + 1);
|
||||
|
||||
/* Count members of definition array */
|
||||
for (p = t; *p != NULL; p++)
|
||||
count++;
|
||||
p = &argv[count + argc];
|
||||
count = g_strv_length (t);
|
||||
|
||||
p = argv + count + argc;
|
||||
/* Buffer overflow or infinitive loop in define */
|
||||
if (p >= argv_end)
|
||||
break;
|
||||
@ -235,7 +233,6 @@ subst_defines (GTree * defines, char **argv, char **argv_end)
|
||||
for (p = argv; *t != NULL; *p++ = *t++)
|
||||
;
|
||||
}
|
||||
argv++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -243,7 +240,7 @@ subst_defines (GTree * defines, char **argv, char **argv_end)
|
||||
|
||||
static off_t
|
||||
compare_word_to_right (const WEdit * edit, off_t i, const char *text,
|
||||
const char *whole_left, const char *whole_right, long line_start)
|
||||
const char *whole_left, const char *whole_right, gboolean line_start)
|
||||
{
|
||||
const unsigned char *p, *q;
|
||||
int c, d, j;
|
||||
@ -252,7 +249,7 @@ compare_word_to_right (const WEdit * edit, off_t i, const char *text,
|
||||
return -1;
|
||||
|
||||
c = xx_tolower (edit, edit_buffer_get_byte (&edit->buffer, i - 1));
|
||||
if ((line_start != 0 && c != '\n') || (whole_left != NULL && strchr (whole_left, c) != NULL))
|
||||
if ((line_start && c != '\n') || (whole_left != NULL && strchr (whole_left, c) != NULL))
|
||||
return -1;
|
||||
|
||||
for (p = (const unsigned char *) text, q = p + strlen ((const char *) p); p < q; p++, i++)
|
||||
@ -284,7 +281,7 @@ compare_word_to_right (const WEdit * edit, off_t i, const char *text,
|
||||
if (c == *p)
|
||||
{
|
||||
j = i;
|
||||
if (*p == *text && p[1] == '\0') /* handle eg '+' and @+@ keywords properly */
|
||||
if (p[0] == text[0] && p[1] == '\0') /* handle eg '+' and @+@ keywords properly */
|
||||
break;
|
||||
}
|
||||
if (j != 0 && strchr ((const char *) p + 1, c) != NULL) /* c exists further down, so it will get matched later */
|
||||
@ -312,7 +309,7 @@ compare_word_to_right (const WEdit * edit, off_t i, const char *text,
|
||||
{
|
||||
d = c;
|
||||
c = xx_tolower (edit, edit_buffer_get_byte (&edit->buffer, i));
|
||||
for (j = 0; p[j] != SYNTAX_TOKEN_BRACKET && p[j]; j++)
|
||||
for (j = 0; p[j] != SYNTAX_TOKEN_BRACKET && p[j] != '\0'; j++)
|
||||
if (c == p[j])
|
||||
goto found_char2;
|
||||
break;
|
||||
@ -331,7 +328,7 @@ compare_word_to_right (const WEdit * edit, off_t i, const char *text,
|
||||
if (++p > q)
|
||||
return -1;
|
||||
c = xx_tolower (edit, edit_buffer_get_byte (&edit->buffer, i));
|
||||
for (; *p != SYNTAX_TOKEN_BRACE && *p; p++)
|
||||
for (; *p != SYNTAX_TOKEN_BRACE && *p != '\0'; p++)
|
||||
if (c == *p)
|
||||
goto found_char3;
|
||||
return -1;
|
||||
@ -448,11 +445,12 @@ apply_rules_going_right (WEdit * edit, off_t i)
|
||||
{
|
||||
/* when both context and keyword terminate with a newline,
|
||||
the context overflows to the next line and colorizes it incorrectly */
|
||||
if (_rule._context != 0 && k->keyword[strlen (k->keyword) - 1] == '\n')
|
||||
if (e > i + 1 && _rule._context != 0
|
||||
&& k->keyword[strlen (k->keyword) - 1] == '\n')
|
||||
{
|
||||
r = CONTEXT_RULE (g_ptr_array_index (edit->rules, _rule._context));
|
||||
if (r->right != NULL && r->right[0] != '\0'
|
||||
&& r->right[strlen (r->right) - 1] == '\n' && e > i + 1)
|
||||
&& r->right[strlen (r->right) - 1] == '\n')
|
||||
e--;
|
||||
}
|
||||
|
||||
@ -778,6 +776,7 @@ get_args (char *l, char **args, int args_size)
|
||||
while (argc < args_size)
|
||||
{
|
||||
char *p = l;
|
||||
|
||||
while (*p != '\0' && whiteness (*p))
|
||||
p++;
|
||||
if (*p == '\0')
|
||||
@ -877,7 +876,7 @@ open_include_file (const char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
MC_PTR_FREE (error_file_name);
|
||||
g_free (error_file_name);
|
||||
error_file_name = g_strdup (filename);
|
||||
if (g_path_is_absolute (filename))
|
||||
return fopen (filename, "r");
|
||||
@ -910,6 +909,7 @@ xx_lowerize_line (WEdit * edit, char *line, size_t len)
|
||||
if (edit->is_case_insensitive)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
line[i] = tolower (line[i]);
|
||||
}
|
||||
@ -926,7 +926,7 @@ edit_read_syntax_rules (WEdit * edit, FILE * f, char **args, int args_size)
|
||||
char last_fg[32] = "", last_bg[32] = "", last_attrs[64] = "";
|
||||
char whole_right[512];
|
||||
char whole_left[512];
|
||||
char *l = 0;
|
||||
char *l = NULL;
|
||||
int save_line = 0, line = 0;
|
||||
context_rule_t *c = NULL;
|
||||
gboolean no_words = TRUE;
|
||||
@ -940,7 +940,7 @@ edit_read_syntax_rules (WEdit * edit, FILE * f, char **args, int args_size)
|
||||
|
||||
edit->rules = g_ptr_array_new ();
|
||||
|
||||
if (!edit->defines)
|
||||
if (edit->defines == NULL)
|
||||
edit->defines = g_tree_new ((GCompareFunc) strcmp);
|
||||
|
||||
while (TRUE)
|
||||
@ -950,7 +950,7 @@ edit_read_syntax_rules (WEdit * edit, FILE * f, char **args, int args_size)
|
||||
int argc;
|
||||
|
||||
line++;
|
||||
l = 0;
|
||||
l = NULL;
|
||||
|
||||
len = read_one_line (&l, f);
|
||||
if (len != 0)
|
||||
@ -1046,7 +1046,7 @@ edit_read_syntax_rules (WEdit * edit, FILE * f, char **args, int args_size)
|
||||
if (strcmp (*a, "exclusive") == 0)
|
||||
{
|
||||
a++;
|
||||
c->between_delimiters = 1;
|
||||
c->between_delimiters = TRUE;
|
||||
}
|
||||
check_a;
|
||||
if (strcmp (*a, "whole") == 0)
|
||||
@ -1069,7 +1069,7 @@ edit_read_syntax_rules (WEdit * edit, FILE * f, char **args, int args_size)
|
||||
if (strcmp (*a, "linestart") == 0)
|
||||
{
|
||||
a++;
|
||||
c->line_start_left = 1;
|
||||
c->line_start_left = TRUE;
|
||||
}
|
||||
check_a;
|
||||
c->left = g_strdup (*a++);
|
||||
@ -1077,7 +1077,7 @@ edit_read_syntax_rules (WEdit * edit, FILE * f, char **args, int args_size)
|
||||
if (strcmp (*a, "linestart") == 0)
|
||||
{
|
||||
a++;
|
||||
c->line_start_right = 1;
|
||||
c->line_start_right = TRUE;
|
||||
}
|
||||
check_a;
|
||||
c->right = g_strdup (*a++);
|
||||
@ -1088,7 +1088,7 @@ edit_read_syntax_rules (WEdit * edit, FILE * f, char **args, int args_size)
|
||||
k = g_new0 (syntax_keyword_t, 1);
|
||||
g_ptr_array_add (c->keyword, k);
|
||||
no_words = FALSE;
|
||||
subst_defines (edit->defines, a, &args[1024]);
|
||||
subst_defines (edit->defines, a, &args[ARGS_LEN]);
|
||||
fg = *a;
|
||||
if (*a != NULL)
|
||||
a++;
|
||||
@ -1145,15 +1145,14 @@ edit_read_syntax_rules (WEdit * edit, FILE * f, char **args, int args_size)
|
||||
if (strcmp (*a, "linestart") == 0)
|
||||
{
|
||||
a++;
|
||||
k->line_start = 1;
|
||||
k->line_start = TRUE;
|
||||
}
|
||||
check_a;
|
||||
if (strcmp (*a, "whole") == 0)
|
||||
{
|
||||
break_a;
|
||||
}
|
||||
|
||||
k->keyword = g_strdup (*a++);
|
||||
subst_defines (edit->defines, a, &args[1024]);
|
||||
subst_defines (edit->defines, a, &args[ARGS_LEN]);
|
||||
fg = *a;
|
||||
if (*a != NULL)
|
||||
a++;
|
||||
@ -1200,13 +1199,12 @@ edit_read_syntax_rules (WEdit * edit, FILE * f, char **args, int args_size)
|
||||
*argv = NULL;
|
||||
}
|
||||
else
|
||||
{ /* anything else is an error */
|
||||
{
|
||||
/* anything else is an error */
|
||||
break_a;
|
||||
}
|
||||
free_args (args);
|
||||
MC_PTR_FREE (l);
|
||||
}
|
||||
free_args (args);
|
||||
MC_PTR_FREE (l);
|
||||
|
||||
if (edit->rules->len == 0)
|
||||
@ -1259,7 +1257,7 @@ edit_read_syntax_file (WEdit * edit, GPtrArray * pnames, const char *syntax_file
|
||||
const char *editor_file, const char *first_line, const char *type)
|
||||
{
|
||||
FILE *f, *g = NULL;
|
||||
char *args[1024], *l = NULL;
|
||||
char *args[ARGS_LEN], *l = NULL;
|
||||
long line = 0;
|
||||
int result = 0;
|
||||
char *lib_file;
|
||||
@ -1282,7 +1280,7 @@ edit_read_syntax_file (WEdit * edit, GPtrArray * pnames, const char *syntax_file
|
||||
MC_PTR_FREE (l);
|
||||
if (read_one_line (&l, f) == 0)
|
||||
break;
|
||||
(void) get_args (l, args, 1023); /* Final NULL */
|
||||
(void) get_args (l, args, ARGS_LEN - 1); /* Final NULL */
|
||||
if (args[0] == NULL)
|
||||
continue;
|
||||
|
||||
@ -1292,7 +1290,7 @@ edit_read_syntax_file (WEdit * edit, GPtrArray * pnames, const char *syntax_file
|
||||
if (g != NULL)
|
||||
continue;
|
||||
|
||||
if (!args[1] || !(g = open_include_file (args[1])))
|
||||
if (args[1] == NULL || (g = open_include_file (args[1])) == NULL)
|
||||
{
|
||||
result = line;
|
||||
break;
|
||||
@ -1307,7 +1305,7 @@ edit_read_syntax_file (WEdit * edit, GPtrArray * pnames, const char *syntax_file
|
||||
found = TRUE;
|
||||
|
||||
/* must have two args or report error */
|
||||
if (!args[1] || !args[2])
|
||||
if (args[1] == NULL || args[2] == NULL)
|
||||
{
|
||||
result = line;
|
||||
break;
|
||||
@ -1318,20 +1316,20 @@ edit_read_syntax_file (WEdit * edit, GPtrArray * pnames, const char *syntax_file
|
||||
/* 1: just collecting a list of names of rule sets */
|
||||
g_ptr_array_add (pnames, g_strdup (args[2]));
|
||||
}
|
||||
else if (type)
|
||||
else if (type != NULL)
|
||||
{
|
||||
/* 2: rule set was explicitly specified by the caller */
|
||||
if (strcmp (type, args[2]) == 0)
|
||||
goto found_type;
|
||||
}
|
||||
else if (editor_file && edit)
|
||||
else if (editor_file != NULL && edit != NULL)
|
||||
{
|
||||
/* 3: auto-detect rule set from regular expressions */
|
||||
int q;
|
||||
gboolean q;
|
||||
|
||||
q = mc_search (args[1], DEFAULT_CHARSET, editor_file, MC_SEARCH_T_REGEX);
|
||||
/* does filename match arg 1 ? */
|
||||
if (!q && args[3])
|
||||
if (!q && args[3] != NULL)
|
||||
{
|
||||
/* does first line match arg 3 ? */
|
||||
q = mc_search (args[3], DEFAULT_CHARSET, first_line, MC_SEARCH_T_REGEX);
|
||||
@ -1340,12 +1338,13 @@ edit_read_syntax_file (WEdit * edit, GPtrArray * pnames, const char *syntax_file
|
||||
{
|
||||
int line_error;
|
||||
char *syntax_type;
|
||||
|
||||
found_type:
|
||||
syntax_type = args[2];
|
||||
line_error = edit_read_syntax_rules (edit, g ? g : f, args, 1023);
|
||||
if (line_error)
|
||||
line_error = edit_read_syntax_rules (edit, g ? g : f, args, ARGS_LEN - 1);
|
||||
if (line_error != 0)
|
||||
{
|
||||
if (!error_file_name) /* an included file */
|
||||
if (error_file_name == NULL) /* an included file */
|
||||
result = line + line_error;
|
||||
else
|
||||
result = line_error;
|
||||
@ -1505,7 +1504,8 @@ edit_load_syntax (WEdit * edit, GPtrArray * pnames, const char *type)
|
||||
{
|
||||
edit_free_syntax_rules (edit);
|
||||
message (D_ERROR, _("Load syntax file"),
|
||||
_("Error in file %s on line %d"), error_file_name ? error_file_name : f, r);
|
||||
_("Error in file %s on line %d"), error_file_name != NULL ? error_file_name : f,
|
||||
r);
|
||||
MC_PTR_FREE (error_file_name);
|
||||
}
|
||||
|
||||
|
@ -353,7 +353,7 @@ check_hardlinks (const vfs_path_t * src_vpath, const struct stat *src_stat,
|
||||
|
||||
if (src_stat->st_nlink < 2)
|
||||
return HARDLINK_NOTLINK;
|
||||
if ((vfs_file_class_flags (src_vpath) & VFSF_NOLINKS) != 0)
|
||||
if ((vfs_file_class_flags (src_vpath) & VFS_NOLINKS) != 0)
|
||||
return HARDLINK_UNSUPPORTED;
|
||||
|
||||
lnk = (struct link *) is_in_linklist (linklist, src_vpath, src_stat);
|
||||
|
@ -504,7 +504,7 @@ find_parm_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, voi
|
||||
&& !find_check_regexp (in_name->buffer))
|
||||
{
|
||||
/* Don't stop the dialog */
|
||||
widget_set_state (WIDGET (h), WST_ACTIVE, TRUE);
|
||||
widget_set_state (w, WST_ACTIVE, TRUE);
|
||||
message (D_ERROR, MSG_ERROR, _("Malformed regular expression"));
|
||||
widget_select (WIDGET (in_name));
|
||||
return MSG_HANDLED;
|
||||
@ -514,7 +514,7 @@ find_parm_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, voi
|
||||
if (content_regexp_cbox->state && !content_is_empty && !find_check_regexp (in_with->buffer))
|
||||
{
|
||||
/* Don't stop the dialog */
|
||||
widget_set_state (WIDGET (h), WST_ACTIVE, TRUE);
|
||||
widget_set_state (w, WST_ACTIVE, TRUE);
|
||||
message (D_ERROR, MSG_ERROR, _("Malformed regular expression"));
|
||||
widget_select (WIDGET (in_with));
|
||||
return MSG_HANDLED;
|
||||
|
@ -140,7 +140,7 @@ stop_dialogs (void)
|
||||
{
|
||||
dlg_stop (midnight_dlg);
|
||||
|
||||
if ((top_dlg != NULL) && (top_dlg->data != NULL))
|
||||
if (top_dlg != NULL)
|
||||
dlg_stop (DIALOG (top_dlg->data));
|
||||
}
|
||||
|
||||
@ -864,7 +864,7 @@ setup_mc (void)
|
||||
|
||||
#ifdef ENABLE_SUBSHELL
|
||||
if (mc_global.tty.use_subshell)
|
||||
add_select_channel (mc_global.tty.subshell_pty, load_prompt, 0);
|
||||
add_select_channel (mc_global.tty.subshell_pty, load_prompt, NULL);
|
||||
#endif /* !ENABLE_SUBSHELL */
|
||||
|
||||
if ((tty_baudrate () < 9600) || mc_global.tty.slow_terminal)
|
||||
|
@ -52,23 +52,19 @@
|
||||
|
||||
/*** file scope macro definitions ****************************************************************/
|
||||
|
||||
#define CPIO_SUPER(super) ((cpio_super_t *) (super))
|
||||
|
||||
#define CPIO_POS(super) cpio_position
|
||||
/* If some time reentrancy should be needed change it to */
|
||||
/* #define CPIO_POS(super) (super)->u.arch.fd */
|
||||
|
||||
#define CPIO_SEEK_SET(super, where) \
|
||||
mc_lseek (((cpio_super_data_t *)(super)->data)->fd, \
|
||||
CPIO_POS(super) = (where), SEEK_SET)
|
||||
#define CPIO_SEEK_CUR(super, where) \
|
||||
mc_lseek (((cpio_super_data_t *)(super)->data)->fd, \
|
||||
CPIO_POS(super) += (where), SEEK_SET)
|
||||
#define CPIO_SEEK_SET(super, where) mc_lseek (CPIO_SUPER(super)->fd, CPIO_POS(super) = (where), SEEK_SET)
|
||||
#define CPIO_SEEK_CUR(super, where) mc_lseek (CPIO_SUPER(super)->fd, CPIO_POS(super) += (where), SEEK_SET)
|
||||
|
||||
#define MAGIC_LENGTH (6) /* How many bytes we have to read ahead */
|
||||
#define SEEKBACK CPIO_SEEK_CUR(super, ptr - top)
|
||||
#define RETURN(x) return (((cpio_super_data_t *)super->data)->type = (x))
|
||||
#define TYPEIS(x) \
|
||||
((((cpio_super_data_t *)super->data)->type == CPIO_UNKNOWN) || \
|
||||
(((cpio_super_data_t *)super->data)->type == (x)))
|
||||
#define RETURN(x) return (CPIO_SUPER(super)->type = (x))
|
||||
#define TYPEIS(x) ((CPIO_SUPER(super)->type == CPIO_UNKNOWN) || (CPIO_SUPER(super)->type == (x)))
|
||||
|
||||
#define HEAD_LENGTH (26)
|
||||
|
||||
@ -135,18 +131,22 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct vfs_s_super base; /* base class */
|
||||
|
||||
int fd;
|
||||
struct stat st;
|
||||
int type; /* Type of the archive */
|
||||
GSList *deferred; /* List of inodes for which another entries may appear */
|
||||
} cpio_super_data_t;
|
||||
} cpio_super_t;
|
||||
|
||||
/*** file scope variables ************************************************************************/
|
||||
|
||||
static struct vfs_class vfs_cpiofs_ops;
|
||||
static struct vfs_s_subclass cpio_subclass;
|
||||
static struct vfs_class *vfs_cpiofs_ops = VFS_CLASS (&cpio_subclass);
|
||||
|
||||
static off_t cpio_position;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** file scope functions ************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
@ -172,7 +172,7 @@ cpio_defer_find (const void *a, const void *b)
|
||||
static ssize_t
|
||||
cpio_skip_padding (struct vfs_s_super *super)
|
||||
{
|
||||
switch (((cpio_super_data_t *) super->data)->type)
|
||||
switch (CPIO_SUPER (super)->type)
|
||||
{
|
||||
case CPIO_BIN:
|
||||
case CPIO_BINRE:
|
||||
@ -190,22 +190,33 @@ cpio_skip_padding (struct vfs_s_super *super)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static struct vfs_s_super *
|
||||
cpio_new_archive (struct vfs_class *me)
|
||||
{
|
||||
cpio_super_t *arch;
|
||||
|
||||
arch = g_new0 (cpio_super_t, 1);
|
||||
arch->base.me = me;
|
||||
arch->fd = -1; /* for now */
|
||||
arch->type = CPIO_UNKNOWN;
|
||||
|
||||
return VFS_SUPER (arch);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
cpio_free_archive (struct vfs_class *me, struct vfs_s_super *super)
|
||||
{
|
||||
cpio_super_data_t *arch = (cpio_super_data_t *) super->data;
|
||||
cpio_super_t *arch = CPIO_SUPER (super);
|
||||
|
||||
(void) me;
|
||||
|
||||
if (super->data == NULL)
|
||||
return;
|
||||
|
||||
if (arch->fd != -1)
|
||||
mc_close (arch->fd);
|
||||
arch->fd = -1;
|
||||
g_slist_free_full (arch->deferred, g_free);
|
||||
arch->deferred = NULL;
|
||||
MC_PTR_FREE (super->data);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -214,7 +225,7 @@ static int
|
||||
cpio_open_cpio_file (struct vfs_class *me, struct vfs_s_super *super, const vfs_path_t * vpath)
|
||||
{
|
||||
int fd, type;
|
||||
cpio_super_data_t *arch;
|
||||
cpio_super_t *arch;
|
||||
mode_t mode;
|
||||
struct vfs_s_inode *root;
|
||||
|
||||
@ -226,12 +237,8 @@ cpio_open_cpio_file (struct vfs_class *me, struct vfs_s_super *super, const vfs_
|
||||
}
|
||||
|
||||
super->name = g_strdup (vfs_path_as_str (vpath));
|
||||
super->data = g_new (cpio_super_data_t, 1);
|
||||
arch = (cpio_super_data_t *) super->data;
|
||||
arch->fd = -1; /* for now */
|
||||
arch = CPIO_SUPER (super);
|
||||
mc_stat (vpath, &arch->st);
|
||||
arch->type = CPIO_UNKNOWN;
|
||||
arch->deferred = NULL;
|
||||
|
||||
type = get_compression_type (fd, super->name);
|
||||
if (type == COMPRESSION_NONE)
|
||||
@ -265,7 +272,7 @@ cpio_open_cpio_file (struct vfs_class *me, struct vfs_s_super *super, const vfs_
|
||||
root->st.st_mode = mode;
|
||||
root->data_offset = -1;
|
||||
root->st.st_nlink++;
|
||||
root->st.st_dev = MEDATA->rdev++;
|
||||
root->st.st_dev = VFS_SUBCLASS (me)->rdev++;
|
||||
|
||||
super->root = root;
|
||||
|
||||
@ -302,7 +309,7 @@ cpio_read_head (struct vfs_class *me, struct vfs_s_super *super)
|
||||
static ssize_t
|
||||
cpio_find_head (struct vfs_class *me, struct vfs_s_super *super)
|
||||
{
|
||||
cpio_super_data_t *arch = (cpio_super_data_t *) super->data;
|
||||
cpio_super_t *arch = CPIO_SUPER (super);
|
||||
char buf[BUF_SMALL * 2];
|
||||
ssize_t ptr = 0;
|
||||
ssize_t top;
|
||||
@ -366,7 +373,7 @@ cpio_find_head (struct vfs_class *me, struct vfs_s_super *super)
|
||||
static int
|
||||
cpio_create_entry (struct vfs_class *me, struct vfs_s_super *super, struct stat *st, char *name)
|
||||
{
|
||||
cpio_super_data_t *arch = (cpio_super_data_t *) super->data;
|
||||
cpio_super_t *arch = CPIO_SUPER (super);
|
||||
struct vfs_s_inode *inode = NULL;
|
||||
struct vfs_s_inode *root = super->root;
|
||||
struct vfs_s_entry *entry = NULL;
|
||||
@ -443,7 +450,7 @@ cpio_create_entry (struct vfs_class *me, struct vfs_s_super *super, struct stat
|
||||
tn++;
|
||||
}
|
||||
|
||||
entry = MEDATA->find_entry (me, root, tn, LINK_FOLLOW, FL_NONE); /* In case entry is already there */
|
||||
entry = VFS_SUBCLASS (me)->find_entry (me, root, tn, LINK_FOLLOW, FL_NONE); /* In case entry is already there */
|
||||
|
||||
if (entry != NULL)
|
||||
{
|
||||
@ -547,7 +554,7 @@ cpio_read_bin_head (struct vfs_class *me, struct vfs_s_super *super)
|
||||
short shorts[HEAD_LENGTH >> 1];
|
||||
} u;
|
||||
|
||||
cpio_super_data_t *arch = (cpio_super_data_t *) super->data;
|
||||
cpio_super_t *arch = CPIO_SUPER (super);
|
||||
ssize_t len;
|
||||
char *name;
|
||||
struct stat st;
|
||||
@ -611,7 +618,7 @@ cpio_read_bin_head (struct vfs_class *me, struct vfs_s_super *super)
|
||||
static ssize_t
|
||||
cpio_read_oldc_head (struct vfs_class *me, struct vfs_s_super *super)
|
||||
{
|
||||
cpio_super_data_t *arch = (cpio_super_data_t *) super->data;
|
||||
cpio_super_t *arch = CPIO_SUPER (super);
|
||||
struct new_cpio_header hd;
|
||||
union
|
||||
{
|
||||
@ -683,7 +690,7 @@ cpio_read_oldc_head (struct vfs_class *me, struct vfs_s_super *super)
|
||||
static ssize_t
|
||||
cpio_read_crc_head (struct vfs_class *me, struct vfs_s_super *super)
|
||||
{
|
||||
cpio_super_data_t *arch = (cpio_super_data_t *) super->data;
|
||||
cpio_super_t *arch = CPIO_SUPER (super);
|
||||
struct new_cpio_header hd;
|
||||
union
|
||||
{
|
||||
@ -824,16 +831,15 @@ cpio_super_same (const vfs_path_element_t * vpath_element, struct vfs_s_super *p
|
||||
return 0;
|
||||
|
||||
/* Has the cached archive been changed on the disk? */
|
||||
if (parc->data != NULL
|
||||
&& ((cpio_super_data_t *) parc->data)->st.st_mtime < archive_stat->st_mtime)
|
||||
if (parc != NULL && CPIO_SUPER (parc)->st.st_mtime < archive_stat->st_mtime)
|
||||
{
|
||||
/* Yes, reload! */
|
||||
(*vfs_cpiofs_ops.free) ((vfsid) parc);
|
||||
vfs_rmstamp (&vfs_cpiofs_ops, (vfsid) parc);
|
||||
vfs_cpiofs_ops->free ((vfsid) parc);
|
||||
vfs_rmstamp (vfs_cpiofs_ops, (vfsid) parc);
|
||||
return 2;
|
||||
}
|
||||
/* Hasn't been modified, give it a new timeout */
|
||||
vfs_stamp (&vfs_cpiofs_ops, (vfsid) parc);
|
||||
vfs_stamp (vfs_cpiofs_ops, (vfsid) parc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -842,21 +848,22 @@ cpio_super_same (const vfs_path_element_t * vpath_element, struct vfs_s_super *p
|
||||
static ssize_t
|
||||
cpio_read (void *fh, char *buffer, size_t count)
|
||||
{
|
||||
off_t begin = FH->ino->data_offset;
|
||||
int fd = ((cpio_super_data_t *) FH_SUPER->data)->fd;
|
||||
struct vfs_class *me = FH_SUPER->me;
|
||||
vfs_file_handler_t *file = VFS_FILE_HANDLER (fh);
|
||||
struct vfs_class *me = VFS_FILE_HANDLER_SUPER (fh)->me;
|
||||
int fd = CPIO_SUPER (VFS_FILE_HANDLER_SUPER (fh))->fd;
|
||||
off_t begin = file->ino->data_offset;
|
||||
ssize_t res;
|
||||
|
||||
if (mc_lseek (fd, begin + FH->pos, SEEK_SET) != begin + FH->pos)
|
||||
if (mc_lseek (fd, begin + file->pos, SEEK_SET) != begin + file->pos)
|
||||
ERRNOR (EIO, -1);
|
||||
|
||||
count = MIN (count, (size_t) (FH->ino->st.st_size - FH->pos));
|
||||
count = MIN (count, (size_t) (file->ino->st.st_size - file->pos));
|
||||
|
||||
res = mc_read (fd, buffer, count);
|
||||
if (res == -1)
|
||||
ERRNOR (errno, -1);
|
||||
|
||||
FH->pos += res;
|
||||
file->pos += res;
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -865,10 +872,9 @@ cpio_read (void *fh, char *buffer, size_t count)
|
||||
static int
|
||||
cpio_fh_open (struct vfs_class *me, vfs_file_handler_t * fh, int flags, mode_t mode)
|
||||
{
|
||||
(void) fh;
|
||||
(void) mode;
|
||||
|
||||
fh->data = NULL;
|
||||
|
||||
if ((flags & O_ACCMODE) != O_RDONLY)
|
||||
ERRNOR (EROFS, -1);
|
||||
return 0;
|
||||
@ -881,21 +887,17 @@ cpio_fh_open (struct vfs_class *me, vfs_file_handler_t * fh, int flags, mode_t m
|
||||
void
|
||||
init_cpiofs (void)
|
||||
{
|
||||
static struct vfs_s_subclass cpio_subclass;
|
||||
|
||||
cpio_subclass.flags = VFS_S_READONLY; /* FIXME: cpiofs used own temp files */
|
||||
/* FIXME: cpiofs used own temp files */
|
||||
vfs_init_subclass (&cpio_subclass, "cpiofs", VFS_READONLY, "ucpio");
|
||||
vfs_cpiofs_ops->read = cpio_read;
|
||||
vfs_cpiofs_ops->setctl = NULL;
|
||||
cpio_subclass.archive_check = cpio_super_check;
|
||||
cpio_subclass.archive_same = cpio_super_same;
|
||||
cpio_subclass.new_archive = cpio_new_archive;
|
||||
cpio_subclass.open_archive = cpio_open_archive;
|
||||
cpio_subclass.free_archive = cpio_free_archive;
|
||||
cpio_subclass.fh_open = cpio_fh_open;
|
||||
|
||||
vfs_s_init_class (&vfs_cpiofs_ops, &cpio_subclass);
|
||||
vfs_cpiofs_ops.name = "cpiofs";
|
||||
vfs_cpiofs_ops.prefix = "ucpio";
|
||||
vfs_cpiofs_ops.read = cpio_read;
|
||||
vfs_cpiofs_ops.setctl = NULL;
|
||||
vfs_register_class (&vfs_cpiofs_ops);
|
||||
vfs_register_class (vfs_cpiofs_ops);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -117,12 +117,15 @@ int fish_directory_timeout = 900;
|
||||
#define FISH_HAVE_DATE_MDYT 32
|
||||
#define FISH_HAVE_TAIL 64
|
||||
|
||||
#define SUP ((fish_super_data_t *) super->data)
|
||||
#define FISH_SUPER(super) ((fish_super_t *) (super))
|
||||
#define FISH_FILE_HANDLER(fh) ((fish_file_handler_t *) fh)
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct vfs_s_super base; /* base class */
|
||||
|
||||
int sockr;
|
||||
int sockw;
|
||||
char *scr_ls;
|
||||
@ -142,20 +145,23 @@ typedef struct
|
||||
char *scr_info;
|
||||
int host_flags;
|
||||
char *scr_env;
|
||||
} fish_super_data_t;
|
||||
} fish_super_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vfs_file_handler_t base; /* base class */
|
||||
|
||||
off_t got;
|
||||
off_t total;
|
||||
gboolean append;
|
||||
} fish_fh_data_t;
|
||||
} fish_file_handler_t;
|
||||
|
||||
/*** file scope variables ************************************************************************/
|
||||
|
||||
static char reply_str[80];
|
||||
|
||||
static struct vfs_class vfs_fish_ops;
|
||||
static struct vfs_s_subclass fish_subclass;
|
||||
static struct vfs_class *vfs_fish_ops = VFS_CLASS (&fish_subclass);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** file scope functions ************************************************************************/
|
||||
@ -266,7 +272,7 @@ fish_command (struct vfs_class *me, struct vfs_s_super *super, int wait_reply, c
|
||||
size_t cmd_len)
|
||||
{
|
||||
ssize_t status;
|
||||
FILE *logfile = MEDATA->logfile;
|
||||
FILE *logfile = VFS_SUBCLASS (me)->logfile;
|
||||
|
||||
if (cmd_len == (size_t) (-1))
|
||||
cmd_len = strlen (cmd);
|
||||
@ -281,14 +287,14 @@ fish_command (struct vfs_class *me, struct vfs_s_super *super, int wait_reply, c
|
||||
}
|
||||
|
||||
tty_enable_interrupt_key ();
|
||||
status = write (SUP->sockw, cmd, cmd_len);
|
||||
status = write (FISH_SUPER (super)->sockw, cmd, cmd_len);
|
||||
tty_disable_interrupt_key ();
|
||||
|
||||
if (status < 0)
|
||||
return TRANSIENT;
|
||||
|
||||
if (wait_reply)
|
||||
return fish_get_reply (me, SUP->sockr,
|
||||
return fish_get_reply (me, FISH_SUPER (super)->sockr,
|
||||
(wait_reply & WANT_STRING) != 0 ? reply_str :
|
||||
NULL, sizeof (reply_str) - 1);
|
||||
return COMPLETE;
|
||||
@ -304,7 +310,7 @@ fish_command_va (struct vfs_class *me, struct vfs_s_super *super, int wait_reply
|
||||
int r;
|
||||
GString *command;
|
||||
|
||||
command = g_string_new (SUP->scr_env);
|
||||
command = g_string_new (FISH_SUPER (super)->scr_env);
|
||||
g_string_append_vprintf (command, vars, ap);
|
||||
g_string_append (command, scr);
|
||||
r = fish_command (me, super, wait_reply, command->str, command->len);
|
||||
@ -343,7 +349,7 @@ fish_send_command (struct vfs_class *me, struct vfs_s_super *super, int flags, c
|
||||
va_start (ap, vars);
|
||||
r = fish_command_va (me, super, WAIT_REPLY, scr, vars, ap);
|
||||
va_end (ap);
|
||||
vfs_stamp_create (&vfs_fish_ops, super);
|
||||
vfs_stamp_create (vfs_fish_ops, super);
|
||||
|
||||
if (r != COMPLETE)
|
||||
ERRNOR (E_REMOTE, -1);
|
||||
@ -355,35 +361,48 @@ fish_send_command (struct vfs_class *me, struct vfs_s_super *super, int flags, c
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static struct vfs_s_super *
|
||||
fish_new_archive (struct vfs_class *me)
|
||||
{
|
||||
fish_super_t *arch;
|
||||
|
||||
arch = g_new0 (fish_super_t, 1);
|
||||
arch->base.me = me;
|
||||
|
||||
return VFS_SUPER (arch);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
fish_free_archive (struct vfs_class *me, struct vfs_s_super *super)
|
||||
{
|
||||
if ((SUP->sockw != -1) || (SUP->sockr != -1))
|
||||
fish_super_t *fish_super = FISH_SUPER (super);
|
||||
|
||||
if ((fish_super->sockw != -1) || (fish_super->sockr != -1))
|
||||
{
|
||||
vfs_print_message (_("fish: Disconnecting from %s"), super->name ? super->name : "???");
|
||||
fish_command (me, super, NONE, "#BYE\nexit\n", -1);
|
||||
close (SUP->sockw);
|
||||
close (SUP->sockr);
|
||||
SUP->sockw = SUP->sockr = -1;
|
||||
close (fish_super->sockw);
|
||||
close (fish_super->sockr);
|
||||
fish_super->sockw = fish_super->sockr = -1;
|
||||
}
|
||||
g_free (SUP->scr_ls);
|
||||
g_free (SUP->scr_exists);
|
||||
g_free (SUP->scr_mkdir);
|
||||
g_free (SUP->scr_unlink);
|
||||
g_free (SUP->scr_chown);
|
||||
g_free (SUP->scr_chmod);
|
||||
g_free (SUP->scr_utime);
|
||||
g_free (SUP->scr_rmdir);
|
||||
g_free (SUP->scr_ln);
|
||||
g_free (SUP->scr_mv);
|
||||
g_free (SUP->scr_hardlink);
|
||||
g_free (SUP->scr_get);
|
||||
g_free (SUP->scr_send);
|
||||
g_free (SUP->scr_append);
|
||||
g_free (SUP->scr_info);
|
||||
g_free (SUP->scr_env);
|
||||
g_free (SUP);
|
||||
super->data = NULL;
|
||||
g_free (fish_super->scr_ls);
|
||||
g_free (fish_super->scr_exists);
|
||||
g_free (fish_super->scr_mkdir);
|
||||
g_free (fish_super->scr_unlink);
|
||||
g_free (fish_super->scr_chown);
|
||||
g_free (fish_super->scr_chmod);
|
||||
g_free (fish_super->scr_utime);
|
||||
g_free (fish_super->scr_rmdir);
|
||||
g_free (fish_super->scr_ln);
|
||||
g_free (fish_super->scr_mv);
|
||||
g_free (fish_super->scr_hardlink);
|
||||
g_free (fish_super->scr_get);
|
||||
g_free (fish_super->scr_send);
|
||||
g_free (fish_super->scr_append);
|
||||
g_free (fish_super->scr_info);
|
||||
g_free (fish_super->scr_env);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -405,9 +424,9 @@ fish_pipeopen (struct vfs_s_super *super, const char *path, const char *argv[])
|
||||
vfs_die ("Cannot fork(): %m.");
|
||||
/* We are the parent */
|
||||
close (fileset1[0]);
|
||||
SUP->sockw = fileset1[1];
|
||||
FISH_SUPER (super)->sockw = fileset1[1];
|
||||
close (fileset2[1]);
|
||||
SUP->sockr = fileset2[0];
|
||||
FISH_SUPER (super)->sockr = fileset2[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -464,19 +483,21 @@ fish_set_env (int flags)
|
||||
static gboolean
|
||||
fish_info (struct vfs_class *me, struct vfs_s_super *super)
|
||||
{
|
||||
if (fish_command (me, super, NONE, SUP->scr_info, -1) == COMPLETE)
|
||||
fish_super_t *fish_super = FISH_SUPER (super);
|
||||
|
||||
if (fish_command (me, super, NONE, fish_super->scr_info, -1) == COMPLETE)
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
int res;
|
||||
char buffer[BUF_8K];
|
||||
|
||||
res = vfs_s_get_line_interruptible (me, buffer, sizeof (buffer), SUP->sockr);
|
||||
res = vfs_s_get_line_interruptible (me, buffer, sizeof (buffer), fish_super->sockr);
|
||||
if ((res == 0) || (res == EINTR))
|
||||
ERRNOR (ECONNRESET, FALSE);
|
||||
if (strncmp (buffer, "### ", 4) == 0)
|
||||
break;
|
||||
SUP->host_flags = atol (buffer);
|
||||
fish_super->host_flags = atol (buffer);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@ -534,11 +555,12 @@ fish_open_archive_pipeopen (struct vfs_s_super *super)
|
||||
static gboolean
|
||||
fish_open_archive_talk (struct vfs_class *me, struct vfs_s_super *super)
|
||||
{
|
||||
fish_super_t *fish_super = FISH_SUPER (super);
|
||||
char answer[2048];
|
||||
|
||||
printf ("\n%s\n", _("fish: Waiting for initial line..."));
|
||||
|
||||
if (vfs_s_get_line (me, SUP->sockr, answer, sizeof (answer), ':') == 0)
|
||||
if (vfs_s_get_line (me, fish_super->sockr, answer, sizeof (answer), ':') == 0)
|
||||
return FALSE;
|
||||
|
||||
if (strstr (answer, "assword") != NULL)
|
||||
@ -568,8 +590,8 @@ fish_open_archive_talk (struct vfs_class *me, struct vfs_s_super *super)
|
||||
size_t str_len;
|
||||
|
||||
str_len = strlen (super->path_element->password);
|
||||
if ((write (SUP.sockw, super->path_element->password, str_len) != (ssize_t) str_len)
|
||||
|| (write (SUP->sockw, "\n", 1) != 1))
|
||||
if ((write (fish_super.sockw, super->path_element->password, str_len) !=
|
||||
(ssize_t) str_len) || (write (fish_super->sockw, "\n", 1) != 1))
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
@ -623,7 +645,7 @@ fish_open_archive_int (struct vfs_class *me, struct vfs_s_super *super)
|
||||
|
||||
vfs_print_message ("%s", _("fish: Getting host info..."));
|
||||
if (fish_info (me, super))
|
||||
SUP->scr_env = fish_set_env (SUP->host_flags);
|
||||
FISH_SUPER (super)->scr_env = fish_set_env (FISH_SUPER (super)->host_flags);
|
||||
|
||||
#if 0
|
||||
super->name =
|
||||
@ -644,53 +666,54 @@ static int
|
||||
fish_open_archive (struct vfs_s_super *super,
|
||||
const vfs_path_t * vpath, const vfs_path_element_t * vpath_element)
|
||||
{
|
||||
fish_super_t *fish_super = FISH_SUPER (super);
|
||||
|
||||
(void) vpath;
|
||||
|
||||
super->data = g_new0 (fish_super_data_t, 1);
|
||||
super->path_element = vfs_path_element_clone (vpath_element);
|
||||
|
||||
if (strncmp (vpath_element->vfs_prefix, "rsh", 3) == 0)
|
||||
super->path_element->port = FISH_FLAG_RSH;
|
||||
|
||||
SUP->scr_ls =
|
||||
fish_super->scr_ls =
|
||||
fish_load_script_from_file (super->path_element->host, FISH_LS_FILE, FISH_LS_DEF_CONTENT);
|
||||
SUP->scr_exists =
|
||||
fish_super->scr_exists =
|
||||
fish_load_script_from_file (super->path_element->host, FISH_EXISTS_FILE,
|
||||
FISH_EXISTS_DEF_CONTENT);
|
||||
SUP->scr_mkdir =
|
||||
fish_super->scr_mkdir =
|
||||
fish_load_script_from_file (super->path_element->host, FISH_MKDIR_FILE,
|
||||
FISH_MKDIR_DEF_CONTENT);
|
||||
SUP->scr_unlink =
|
||||
fish_super->scr_unlink =
|
||||
fish_load_script_from_file (super->path_element->host, FISH_UNLINK_FILE,
|
||||
FISH_UNLINK_DEF_CONTENT);
|
||||
SUP->scr_chown =
|
||||
fish_super->scr_chown =
|
||||
fish_load_script_from_file (super->path_element->host, FISH_CHOWN_FILE,
|
||||
FISH_CHOWN_DEF_CONTENT);
|
||||
SUP->scr_chmod =
|
||||
fish_super->scr_chmod =
|
||||
fish_load_script_from_file (super->path_element->host, FISH_CHMOD_FILE,
|
||||
FISH_CHMOD_DEF_CONTENT);
|
||||
SUP->scr_utime =
|
||||
fish_super->scr_utime =
|
||||
fish_load_script_from_file (super->path_element->host, FISH_UTIME_FILE,
|
||||
FISH_UTIME_DEF_CONTENT);
|
||||
SUP->scr_rmdir =
|
||||
fish_super->scr_rmdir =
|
||||
fish_load_script_from_file (super->path_element->host, FISH_RMDIR_FILE,
|
||||
FISH_RMDIR_DEF_CONTENT);
|
||||
SUP->scr_ln =
|
||||
fish_super->scr_ln =
|
||||
fish_load_script_from_file (super->path_element->host, FISH_LN_FILE, FISH_LN_DEF_CONTENT);
|
||||
SUP->scr_mv =
|
||||
fish_super->scr_mv =
|
||||
fish_load_script_from_file (super->path_element->host, FISH_MV_FILE, FISH_MV_DEF_CONTENT);
|
||||
SUP->scr_hardlink =
|
||||
fish_super->scr_hardlink =
|
||||
fish_load_script_from_file (super->path_element->host, FISH_HARDLINK_FILE,
|
||||
FISH_HARDLINK_DEF_CONTENT);
|
||||
SUP->scr_get =
|
||||
fish_super->scr_get =
|
||||
fish_load_script_from_file (super->path_element->host, FISH_GET_FILE, FISH_GET_DEF_CONTENT);
|
||||
SUP->scr_send =
|
||||
fish_super->scr_send =
|
||||
fish_load_script_from_file (super->path_element->host, FISH_SEND_FILE,
|
||||
FISH_SEND_DEF_CONTENT);
|
||||
SUP->scr_append =
|
||||
fish_super->scr_append =
|
||||
fish_load_script_from_file (super->path_element->host, FISH_APPEND_FILE,
|
||||
FISH_APPEND_DEF_CONTENT);
|
||||
SUP->scr_info =
|
||||
fish_super->scr_info =
|
||||
fish_load_script_from_file (super->path_element->host, FISH_INFO_FILE,
|
||||
FISH_INFO_DEF_CONTENT);
|
||||
|
||||
@ -739,10 +762,10 @@ fish_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path)
|
||||
* Simple FISH debug interface :]
|
||||
*/
|
||||
#if 0
|
||||
if (MEDATA->logfile == NULL)
|
||||
MEDATA->logfile = fopen ("/tmp/mc-FISH.sh", "w");
|
||||
if (VFS_SUBCLASS (me)->logfile == NULL)
|
||||
VFS_SUBCLASS (me)->logfile = fopen ("/tmp/mc-FISH.sh", "w");
|
||||
#endif
|
||||
logfile = MEDATA->logfile;
|
||||
logfile = VFS_SUBCLASS (me)->logfile;
|
||||
|
||||
vfs_print_message (_("fish: Reading directory %s..."), remote_path);
|
||||
|
||||
@ -750,7 +773,8 @@ fish_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path)
|
||||
dir->timestamp.tv_sec += fish_directory_timeout;
|
||||
|
||||
quoted_path = strutils_shell_escape (remote_path);
|
||||
(void) fish_command_v (me, super, NONE, SUP->scr_ls, "FISH_FILENAME=%s;\n", quoted_path);
|
||||
(void) fish_command_v (me, super, NONE, FISH_SUPER (super)->scr_ls, "FISH_FILENAME=%s;\n",
|
||||
quoted_path);
|
||||
g_free (quoted_path);
|
||||
|
||||
ent = vfs_s_generate_entry (me, NULL, dir, 0);
|
||||
@ -759,7 +783,7 @@ fish_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = vfs_s_get_line_interruptible (me, buffer, sizeof (buffer), SUP->sockr);
|
||||
res = vfs_s_get_line_interruptible (me, buffer, sizeof (buffer), FISH_SUPER (super)->sockr);
|
||||
|
||||
if ((res == 0) || (res == EINTR))
|
||||
{
|
||||
@ -944,8 +968,9 @@ fish_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path)
|
||||
static int
|
||||
fish_file_store (struct vfs_class *me, vfs_file_handler_t * fh, char *name, char *localname)
|
||||
{
|
||||
fish_fh_data_t *fish = (fish_fh_data_t *) fh->data;
|
||||
struct vfs_s_super *super = FH_SUPER;
|
||||
fish_file_handler_t *fish = FISH_FILE_HANDLER (fh);
|
||||
struct vfs_s_super *super = VFS_FILE_HANDLER_SUPER (fh);
|
||||
fish_super_t *fish_super = FISH_SUPER (super);
|
||||
int code;
|
||||
off_t total = 0;
|
||||
char buffer[BUF_8K];
|
||||
@ -995,9 +1020,11 @@ fish_file_store (struct vfs_class *me, vfs_file_handler_t * fh, char *name, char
|
||||
vfs_print_message (_("fish: store %s: sending command..."), quoted_name);
|
||||
|
||||
/* FIXME: File size is limited to ULONG_MAX */
|
||||
code = fish_command_v (me, super, WAIT_REPLY, fish->append ? SUP->scr_append : SUP->scr_send,
|
||||
"FISH_FILENAME=%s FISH_FILESIZE=%" PRIuMAX ";\n", quoted_name,
|
||||
(uintmax_t) s.st_size);
|
||||
code =
|
||||
fish_command_v (me, super, WAIT_REPLY,
|
||||
fish->append ? fish_super->scr_append : fish_super->scr_send,
|
||||
"FISH_FILENAME=%s FISH_FILESIZE=%" PRIuMAX ";\n", quoted_name,
|
||||
(uintmax_t) s.st_size);
|
||||
g_free (quoted_name);
|
||||
|
||||
if (code != PRELIM)
|
||||
@ -1022,7 +1049,7 @@ fish_file_store (struct vfs_class *me, vfs_file_handler_t * fh, char *name, char
|
||||
if (n == 0)
|
||||
break;
|
||||
|
||||
t = write (SUP->sockw, buffer, n);
|
||||
t = write (fish_super->sockw, buffer, n);
|
||||
if (t != n)
|
||||
{
|
||||
if (t == -1)
|
||||
@ -1038,13 +1065,13 @@ fish_file_store (struct vfs_class *me, vfs_file_handler_t * fh, char *name, char
|
||||
}
|
||||
close (h);
|
||||
|
||||
if (fish_get_reply (me, SUP->sockr, NULL, 0) != COMPLETE)
|
||||
if (fish_get_reply (me, fish_super->sockr, NULL, 0) != COMPLETE)
|
||||
ERRNOR (E_REMOTE, -1);
|
||||
return 0;
|
||||
|
||||
error_return:
|
||||
close (h);
|
||||
fish_get_reply (me, SUP->sockr, NULL, 0);
|
||||
fish_get_reply (me, fish_super->sockr, NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1053,16 +1080,11 @@ fish_file_store (struct vfs_class *me, vfs_file_handler_t * fh, char *name, char
|
||||
static int
|
||||
fish_linear_start (struct vfs_class *me, vfs_file_handler_t * fh, off_t offset)
|
||||
{
|
||||
fish_fh_data_t *fish;
|
||||
struct vfs_s_super *super = FH_SUPER;
|
||||
fish_file_handler_t *fish = FISH_FILE_HANDLER (fh);
|
||||
struct vfs_s_super *super = VFS_FILE_HANDLER_SUPER (fh);
|
||||
char *name;
|
||||
char *quoted_name;
|
||||
|
||||
if (fh->data == NULL)
|
||||
fh->data = g_new0 (fish_fh_data_t, 1);
|
||||
|
||||
fish = (fish_fh_data_t *) fh->data;
|
||||
|
||||
name = vfs_s_fullpath (me, fh->ino);
|
||||
if (name == NULL)
|
||||
return 0;
|
||||
@ -1078,7 +1100,7 @@ fish_linear_start (struct vfs_class *me, vfs_file_handler_t * fh, off_t offset)
|
||||
*/
|
||||
|
||||
offset =
|
||||
fish_command_v (me, super, WANT_STRING, SUP->scr_get,
|
||||
fish_command_v (me, super, WANT_STRING, FISH_SUPER (super)->scr_get,
|
||||
"FISH_FILENAME=%s FISH_START_OFFSET=%" PRIuMAX ";\n", quoted_name,
|
||||
(uintmax_t) offset);
|
||||
g_free (quoted_name);
|
||||
@ -1103,8 +1125,8 @@ fish_linear_start (struct vfs_class *me, vfs_file_handler_t * fh, off_t offset)
|
||||
static void
|
||||
fish_linear_abort (struct vfs_class *me, vfs_file_handler_t * fh)
|
||||
{
|
||||
fish_fh_data_t *fish = (fish_fh_data_t *) fh->data;
|
||||
struct vfs_s_super *super = FH_SUPER;
|
||||
fish_file_handler_t *fish = FISH_FILE_HANDLER (fh);
|
||||
struct vfs_s_super *super = VFS_FILE_HANDLER_SUPER (fh);
|
||||
char buffer[BUF_8K];
|
||||
ssize_t n;
|
||||
|
||||
@ -1115,7 +1137,7 @@ fish_linear_abort (struct vfs_class *me, vfs_file_handler_t * fh)
|
||||
n = MIN ((off_t) sizeof (buffer), (fish->total - fish->got));
|
||||
if (n != 0)
|
||||
{
|
||||
n = read (SUP->sockr, buffer, n);
|
||||
n = read (FISH_SUPER (super)->sockr, buffer, n);
|
||||
if (n < 0)
|
||||
return;
|
||||
fish->got += n;
|
||||
@ -1123,7 +1145,7 @@ fish_linear_abort (struct vfs_class *me, vfs_file_handler_t * fh)
|
||||
}
|
||||
while (n != 0);
|
||||
|
||||
if (fish_get_reply (me, SUP->sockr, NULL, 0) != COMPLETE)
|
||||
if (fish_get_reply (me, FISH_SUPER (super)->sockr, NULL, 0) != COMPLETE)
|
||||
vfs_print_message ("%s", _("Error reported after abort."));
|
||||
else
|
||||
vfs_print_message ("%s", _("Aborted transfer would be successful."));
|
||||
@ -1134,13 +1156,13 @@ fish_linear_abort (struct vfs_class *me, vfs_file_handler_t * fh)
|
||||
static ssize_t
|
||||
fish_linear_read (struct vfs_class *me, vfs_file_handler_t * fh, void *buf, size_t len)
|
||||
{
|
||||
fish_fh_data_t *fish = (fish_fh_data_t *) fh->data;
|
||||
struct vfs_s_super *super = FH_SUPER;
|
||||
fish_file_handler_t *fish = FISH_FILE_HANDLER (fh);
|
||||
struct vfs_s_super *super = VFS_FILE_HANDLER_SUPER (fh);
|
||||
ssize_t n = 0;
|
||||
|
||||
len = MIN ((size_t) (fish->total - fish->got), len);
|
||||
tty_disable_interrupt_key ();
|
||||
while (len != 0 && ((n = read (SUP->sockr, buf, len)) < 0))
|
||||
while (len != 0 && ((n = read (FISH_SUPER (super)->sockr, buf, len)) < 0))
|
||||
{
|
||||
if ((errno == EINTR) && !tty_got_interrupt ())
|
||||
continue;
|
||||
@ -1152,7 +1174,7 @@ fish_linear_read (struct vfs_class *me, vfs_file_handler_t * fh, void *buf, size
|
||||
fish->got += n;
|
||||
else if (n < 0)
|
||||
fish_linear_abort (me, fh);
|
||||
else if (fish_get_reply (me, SUP->sockr, NULL, 0) != COMPLETE)
|
||||
else if (fish_get_reply (me, FISH_SUPER (super)->sockr, NULL, 0) != COMPLETE)
|
||||
ERRNOR (E_REMOTE, -1);
|
||||
ERRNOR (errno, n);
|
||||
}
|
||||
@ -1162,7 +1184,7 @@ fish_linear_read (struct vfs_class *me, vfs_file_handler_t * fh, void *buf, size
|
||||
static void
|
||||
fish_linear_close (struct vfs_class *me, vfs_file_handler_t * fh)
|
||||
{
|
||||
fish_fh_data_t *fish = (fish_fh_data_t *) fh->data;
|
||||
fish_file_handler_t *fish = FISH_FILE_HANDLER (fh);
|
||||
|
||||
if (fish->total != fish->got)
|
||||
fish_linear_abort (me, fh);
|
||||
@ -1184,14 +1206,15 @@ fish_ctl (void *fh, int ctlop, void *arg)
|
||||
{
|
||||
case VFS_CTL_IS_NOTREADY:
|
||||
{
|
||||
vfs_file_handler_t *file = VFS_FILE_HANDLER (fh);
|
||||
int v;
|
||||
|
||||
if (FH->linear == LS_NOT_LINEAR)
|
||||
if (file->linear == LS_NOT_LINEAR)
|
||||
vfs_die ("You may not do this");
|
||||
if (FH->linear == LS_LINEAR_CLOSED || FH->linear == LS_LINEAR_PREOPEN)
|
||||
if (file->linear == LS_LINEAR_CLOSED || file->linear == LS_LINEAR_PREOPEN)
|
||||
return 0;
|
||||
|
||||
v = vfs_s_select_on_two (FH_SUPER->u.fish.sockr, 0);
|
||||
v = vfs_s_select_on_two (VFS_FILE_HANDLER_SUPER (fh)->u.fish.sockr, 0);
|
||||
|
||||
return (((v < 0) && (errno == EINTR)) || v == 0) ? 1 : 0;
|
||||
}
|
||||
@ -1226,7 +1249,7 @@ fish_rename (const vfs_path_t * vpath1, const vfs_path_t * vpath2)
|
||||
rpath2 = strutils_shell_escape (crpath2);
|
||||
|
||||
ret =
|
||||
fish_send_command (path_element->class, super2, OPT_FLUSH, SUP->scr_mv,
|
||||
fish_send_command (path_element->class, super2, OPT_FLUSH, FISH_SUPER (super)->scr_mv,
|
||||
"FISH_FILEFROM=%s FISH_FILETO=%s;\n", rpath1, rpath2);
|
||||
|
||||
g_free (rpath1);
|
||||
@ -1260,7 +1283,7 @@ fish_link (const vfs_path_t * vpath1, const vfs_path_t * vpath2)
|
||||
rpath2 = strutils_shell_escape (crpath2);
|
||||
|
||||
ret =
|
||||
fish_send_command (path_element->class, super2, OPT_FLUSH, SUP->scr_hardlink,
|
||||
fish_send_command (path_element->class, super2, OPT_FLUSH, FISH_SUPER (super)->scr_hardlink,
|
||||
"FISH_FILEFROM=%s FISH_FILETO=%s;\n", rpath1, rpath2);
|
||||
|
||||
g_free (rpath1);
|
||||
@ -1291,7 +1314,7 @@ fish_symlink (const vfs_path_t * vpath1, const vfs_path_t * vpath2)
|
||||
qsetto = strutils_shell_escape (vfs_path_get_by_index (vpath1, -1)->path);
|
||||
|
||||
ret =
|
||||
fish_send_command (path_element->class, super, OPT_FLUSH, SUP->scr_ln,
|
||||
fish_send_command (path_element->class, super, OPT_FLUSH, FISH_SUPER (super)->scr_ln,
|
||||
"FISH_FILEFROM=%s FISH_FILETO=%s;\n", qsetto, rpath);
|
||||
|
||||
g_free (qsetto);
|
||||
@ -1356,7 +1379,7 @@ fish_chmod (const vfs_path_t * vpath, mode_t mode)
|
||||
rpath = strutils_shell_escape (crpath);
|
||||
|
||||
ret =
|
||||
fish_send_command (path_element->class, super, OPT_FLUSH, SUP->scr_chmod,
|
||||
fish_send_command (path_element->class, super, OPT_FLUSH, FISH_SUPER (super)->scr_chmod,
|
||||
"FISH_FILENAME=%s FISH_FILEMODE=%4.4o;\n", rpath,
|
||||
(unsigned int) (mode & 07777));
|
||||
|
||||
@ -1400,7 +1423,7 @@ fish_chown (const vfs_path_t * vpath, uid_t owner, gid_t group)
|
||||
|
||||
/* FIXME: what should we report if chgrp succeeds but chown fails? */
|
||||
ret =
|
||||
fish_send_command (path_element->class, super, OPT_FLUSH, SUP->scr_chown,
|
||||
fish_send_command (path_element->class, super, OPT_FLUSH, FISH_SUPER (super)->scr_chown,
|
||||
"FISH_FILENAME=%s FISH_FILEOWNER=%s FISH_FILEGROUP=%s;\n", rpath, sowner,
|
||||
sgroup);
|
||||
|
||||
@ -1479,7 +1502,7 @@ fish_utime (const vfs_path_t * vpath, mc_timesbuf_t * times)
|
||||
gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday,
|
||||
gmt->tm_hour, gmt->tm_min, gmt->tm_sec, mtime_nsec);
|
||||
|
||||
ret = fish_send_command (path_element->class, super, OPT_FLUSH, SUP->scr_utime,
|
||||
ret = fish_send_command (path_element->class, super, OPT_FLUSH, FISH_SUPER (super)->scr_utime,
|
||||
"FISH_FILENAME=%s FISH_FILEATIME=%ld FISH_FILEMTIME=%ld "
|
||||
"FISH_TOUCHATIME=%s FISH_TOUCHMTIME=%s FISH_TOUCHATIME_W_NSEC=\"%s\" "
|
||||
"FISH_TOUCHMTIME_W_NSEC=\"%s\";\n", rpath, (long) atime, (long) mtime,
|
||||
@ -1510,7 +1533,7 @@ fish_unlink (const vfs_path_t * vpath)
|
||||
rpath = strutils_shell_escape (crpath);
|
||||
|
||||
ret =
|
||||
fish_send_command (path_element->class, super, OPT_FLUSH, SUP->scr_unlink,
|
||||
fish_send_command (path_element->class, super, OPT_FLUSH, FISH_SUPER (super)->scr_unlink,
|
||||
"FISH_FILENAME=%s;\n", rpath);
|
||||
|
||||
g_free (rpath);
|
||||
@ -1538,7 +1561,7 @@ fish_exists (const vfs_path_t * vpath)
|
||||
rpath = strutils_shell_escape (crpath);
|
||||
|
||||
ret =
|
||||
fish_send_command (path_element->class, super, OPT_FLUSH, SUP->scr_exists,
|
||||
fish_send_command (path_element->class, super, OPT_FLUSH, FISH_SUPER (super)->scr_exists,
|
||||
"FISH_FILENAME=%s;\n", rpath);
|
||||
|
||||
g_free (rpath);
|
||||
@ -1568,7 +1591,7 @@ fish_mkdir (const vfs_path_t * vpath, mode_t mode)
|
||||
rpath = strutils_shell_escape (crpath);
|
||||
|
||||
ret =
|
||||
fish_send_command (path_element->class, super, OPT_FLUSH, SUP->scr_mkdir,
|
||||
fish_send_command (path_element->class, super, OPT_FLUSH, FISH_SUPER (super)->scr_mkdir,
|
||||
"FISH_FILENAME=%s;\n", rpath);
|
||||
g_free (rpath);
|
||||
|
||||
@ -1603,7 +1626,7 @@ fish_rmdir (const vfs_path_t * vpath)
|
||||
rpath = strutils_shell_escape (crpath);
|
||||
|
||||
ret =
|
||||
fish_send_command (path_element->class, super, OPT_FLUSH, SUP->scr_rmdir,
|
||||
fish_send_command (path_element->class, super, OPT_FLUSH, FISH_SUPER (super)->scr_rmdir,
|
||||
"FISH_FILENAME=%s;\n", rpath);
|
||||
|
||||
g_free (rpath);
|
||||
@ -1613,11 +1636,15 @@ fish_rmdir (const vfs_path_t * vpath)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
fish_fh_free_data (vfs_file_handler_t * fh)
|
||||
static vfs_file_handler_t *
|
||||
fish_fh_new (struct vfs_s_inode *ino, gboolean changed)
|
||||
{
|
||||
if (fh != NULL)
|
||||
MC_PTR_FREE (fh->data);
|
||||
fish_file_handler_t *fh;
|
||||
|
||||
fh = g_new0 (fish_file_handler_t, 1);
|
||||
vfs_s_init_fh (VFS_FILE_HANDLER (fh), ino, changed);
|
||||
|
||||
return VFS_FILE_HANDLER (fh);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -1625,13 +1652,10 @@ fish_fh_free_data (vfs_file_handler_t * fh)
|
||||
static int
|
||||
fish_fh_open (struct vfs_class *me, vfs_file_handler_t * fh, int flags, mode_t mode)
|
||||
{
|
||||
fish_fh_data_t *fish;
|
||||
fish_file_handler_t *fish = FISH_FILE_HANDLER (fh);
|
||||
|
||||
(void) mode;
|
||||
|
||||
fh->data = g_new0 (fish_fh_data_t, 1);
|
||||
fish = (fish_fh_data_t *) fh->data;
|
||||
|
||||
/* File will be written only, so no need to retrieve it */
|
||||
if (((flags & O_WRONLY) == O_WRONLY) && ((flags & (O_RDONLY | O_RDWR)) == 0))
|
||||
{
|
||||
@ -1663,7 +1687,6 @@ fish_fh_open (struct vfs_class *me, vfs_file_handler_t * fh, int flags, mode_t m
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
fish_fh_free_data (fh);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1674,7 +1697,7 @@ fish_fill_names (struct vfs_class *me, fill_names_f func)
|
||||
{
|
||||
GList *iter;
|
||||
|
||||
for (iter = MEDATA->supers; iter != NULL; iter = g_list_next (iter))
|
||||
for (iter = VFS_SUBCLASS (me)->supers; iter != NULL; iter = g_list_next (iter))
|
||||
{
|
||||
const struct vfs_s_super *super = (const struct vfs_s_super *) iter->data;
|
||||
|
||||
@ -1700,7 +1723,7 @@ fish_fill_names (struct vfs_class *me, fill_names_f func)
|
||||
}
|
||||
|
||||
name =
|
||||
g_strconcat (vfs_fish_ops.prefix, VFS_PATH_URL_DELIMITER,
|
||||
g_strconcat (vfs_fish_ops->prefix, VFS_PATH_URL_DELIMITER,
|
||||
super->path_element->user, "@", super->path_element->host, flags,
|
||||
PATH_SEP_STR, super->path_element->path, (char *) NULL);
|
||||
func (name);
|
||||
@ -1728,41 +1751,36 @@ fish_open (const vfs_path_t * vpath, int flags, mode_t mode)
|
||||
void
|
||||
init_fish (void)
|
||||
{
|
||||
static struct vfs_s_subclass fish_subclass;
|
||||
|
||||
tcp_init ();
|
||||
|
||||
fish_subclass.flags = VFS_S_REMOTE | VFS_S_USETMP;
|
||||
vfs_init_subclass (&fish_subclass, "fish", VFS_REMOTE | VFS_USETMP, "sh");
|
||||
vfs_fish_ops->fill_names = fish_fill_names;
|
||||
vfs_fish_ops->stat = fish_stat;
|
||||
vfs_fish_ops->lstat = fish_lstat;
|
||||
vfs_fish_ops->fstat = fish_fstat;
|
||||
vfs_fish_ops->chmod = fish_chmod;
|
||||
vfs_fish_ops->chown = fish_chown;
|
||||
vfs_fish_ops->utime = fish_utime;
|
||||
vfs_fish_ops->open = fish_open;
|
||||
vfs_fish_ops->symlink = fish_symlink;
|
||||
vfs_fish_ops->link = fish_link;
|
||||
vfs_fish_ops->unlink = fish_unlink;
|
||||
vfs_fish_ops->rename = fish_rename;
|
||||
vfs_fish_ops->mkdir = fish_mkdir;
|
||||
vfs_fish_ops->rmdir = fish_rmdir;
|
||||
vfs_fish_ops->ctl = fish_ctl;
|
||||
fish_subclass.archive_same = fish_archive_same;
|
||||
fish_subclass.new_archive = fish_new_archive;
|
||||
fish_subclass.open_archive = fish_open_archive;
|
||||
fish_subclass.free_archive = fish_free_archive;
|
||||
fish_subclass.fh_new = fish_fh_new;
|
||||
fish_subclass.fh_open = fish_fh_open;
|
||||
fish_subclass.fh_free_data = fish_fh_free_data;
|
||||
fish_subclass.dir_load = fish_dir_load;
|
||||
fish_subclass.file_store = fish_file_store;
|
||||
fish_subclass.linear_start = fish_linear_start;
|
||||
fish_subclass.linear_read = fish_linear_read;
|
||||
fish_subclass.linear_close = fish_linear_close;
|
||||
|
||||
vfs_s_init_class (&vfs_fish_ops, &fish_subclass);
|
||||
vfs_fish_ops.name = "fish";
|
||||
vfs_fish_ops.prefix = "sh";
|
||||
vfs_fish_ops.fill_names = fish_fill_names;
|
||||
vfs_fish_ops.stat = fish_stat;
|
||||
vfs_fish_ops.lstat = fish_lstat;
|
||||
vfs_fish_ops.fstat = fish_fstat;
|
||||
vfs_fish_ops.chmod = fish_chmod;
|
||||
vfs_fish_ops.chown = fish_chown;
|
||||
vfs_fish_ops.utime = fish_utime;
|
||||
vfs_fish_ops.open = fish_open;
|
||||
vfs_fish_ops.symlink = fish_symlink;
|
||||
vfs_fish_ops.link = fish_link;
|
||||
vfs_fish_ops.unlink = fish_unlink;
|
||||
vfs_fish_ops.rename = fish_rename;
|
||||
vfs_fish_ops.mkdir = fish_mkdir;
|
||||
vfs_fish_ops.rmdir = fish_rmdir;
|
||||
vfs_fish_ops.ctl = fish_ctl;
|
||||
vfs_register_class (&vfs_fish_ops);
|
||||
vfs_register_class (vfs_fish_ops);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -34,6 +34,7 @@
|
||||
|
||||
#include "lib/global.h"
|
||||
|
||||
#include "lib/vfs/xdirentry.h" /* vfs_s_subclass */
|
||||
#include "lib/vfs/utilvfs.h"
|
||||
|
||||
#include "local.h"
|
||||
@ -421,8 +422,7 @@ local_lseek (void *data, off_t offset, int whence)
|
||||
void
|
||||
init_localfs (void)
|
||||
{
|
||||
vfs_local_ops.name = "localfs";
|
||||
vfs_local_ops.flags = VFSF_LOCAL;
|
||||
vfs_init_class (&vfs_local_ops, "localfs", VFS_LOCAL, NULL);
|
||||
vfs_local_ops.which = local_which;
|
||||
vfs_local_ops.open = local_open;
|
||||
vfs_local_ops.close = local_close;
|
||||
|
@ -52,6 +52,7 @@
|
||||
|
||||
#include "lib/vfs/vfs.h"
|
||||
#include "lib/vfs/utilvfs.h"
|
||||
#include "lib/vfs/xdirentry.h"
|
||||
#include "src/vfs/local/local.h"
|
||||
#include "lib/vfs/gc.h" /* vfs_stamp_create */
|
||||
|
||||
@ -100,6 +101,7 @@ typedef struct cachedfile
|
||||
/*** file scope variables ************************************************************************/
|
||||
|
||||
static GSList *head;
|
||||
|
||||
static struct vfs_class vfs_sfs_ops;
|
||||
|
||||
static int sfs_no = 0;
|
||||
@ -547,7 +549,7 @@ sfs_which (struct vfs_class *me, const char *path)
|
||||
void
|
||||
init_sfs (void)
|
||||
{
|
||||
vfs_sfs_ops.name = "sfs";
|
||||
vfs_init_class (&vfs_sfs_ops, "sfs", VFS_UNKNOWN, NULL);
|
||||
vfs_sfs_ops.init = sfs_init;
|
||||
vfs_sfs_ops.done = sfs_done;
|
||||
vfs_sfs_ops.fill_names = sfs_fill_names;
|
||||
|
@ -354,21 +354,18 @@ sftpfs_get_config_entity (const vfs_path_element_t * vpath_element, GError ** mc
|
||||
void
|
||||
sftpfs_fill_connection_data_from_config (struct vfs_s_super *super, GError ** mcerror)
|
||||
{
|
||||
sftpfs_super_data_t *super_data;
|
||||
sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
|
||||
sftpfs_ssh_config_entity_t *config_entity;
|
||||
|
||||
mc_return_if_error (mcerror);
|
||||
|
||||
super_data = (sftpfs_super_data_t *) super->data;
|
||||
|
||||
config_entity = sftpfs_get_config_entity (super->path_element, mcerror);
|
||||
if (config_entity == NULL)
|
||||
return;
|
||||
|
||||
super_data->config_auth_type = NONE;
|
||||
super_data->config_auth_type |= (config_entity->pubkey_auth) ? PUBKEY : 0;
|
||||
super_data->config_auth_type |= (config_entity->identities_only) ? 0 : AGENT;
|
||||
super_data->config_auth_type |= (config_entity->password_auth) ? PASSWORD : 0;
|
||||
sftpfs_super->config_auth_type = (config_entity->pubkey_auth) ? PUBKEY : 0;
|
||||
sftpfs_super->config_auth_type |= (config_entity->identities_only) ? 0 : AGENT;
|
||||
sftpfs_super->config_auth_type |= (config_entity->password_auth) ? PASSWORD : 0;
|
||||
|
||||
if (super->path_element->port == 0)
|
||||
super->path_element->port = config_entity->port;
|
||||
@ -384,8 +381,8 @@ sftpfs_fill_connection_data_from_config (struct vfs_s_super *super, GError ** mc
|
||||
|
||||
if (config_entity->identity_file != NULL)
|
||||
{
|
||||
super_data->privkey = g_strdup (config_entity->identity_file);
|
||||
super_data->pubkey = g_strdup_printf ("%s.pub", config_entity->identity_file);
|
||||
sftpfs_super->privkey = g_strdup (config_entity->identity_file);
|
||||
sftpfs_super->pubkey = g_strdup_printf ("%s.pub", config_entity->identity_file);
|
||||
}
|
||||
|
||||
sftpfs_ssh_config_entity_free (config_entity);
|
||||
|
@ -168,15 +168,11 @@ static gboolean
|
||||
sftpfs_recognize_auth_types (struct vfs_s_super *super)
|
||||
{
|
||||
char *userauthlist;
|
||||
sftpfs_super_data_t *super_data;
|
||||
|
||||
super_data = (sftpfs_super_data_t *) super->data;
|
||||
|
||||
super_data->auth_type = NONE;
|
||||
sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
|
||||
|
||||
/* check what authentication methods are available */
|
||||
/* userauthlist is internally managed by libssh2 and freed by libssh2_session_free() */
|
||||
userauthlist = libssh2_userauth_list (super_data->session, super->path_element->user,
|
||||
userauthlist = libssh2_userauth_list (sftpfs_super->session, super->path_element->user,
|
||||
strlen (super->path_element->user));
|
||||
|
||||
if (userauthlist == NULL)
|
||||
@ -184,14 +180,15 @@ sftpfs_recognize_auth_types (struct vfs_s_super *super)
|
||||
|
||||
if ((strstr (userauthlist, "password") != NULL
|
||||
|| strstr (userauthlist, "keyboard-interactive") != NULL)
|
||||
&& (super_data->config_auth_type & PASSWORD) != 0)
|
||||
super_data->auth_type |= PASSWORD;
|
||||
&& (sftpfs_super->config_auth_type & PASSWORD) != 0)
|
||||
sftpfs_super->auth_type |= PASSWORD;
|
||||
|
||||
if (strstr (userauthlist, "publickey") != NULL && (super_data->config_auth_type & PUBKEY) != 0)
|
||||
super_data->auth_type |= PUBKEY;
|
||||
if (strstr (userauthlist, "publickey") != NULL
|
||||
&& (sftpfs_super->config_auth_type & PUBKEY) != 0)
|
||||
sftpfs_super->auth_type |= PUBKEY;
|
||||
|
||||
if ((super_data->config_auth_type & AGENT) != 0)
|
||||
super_data->auth_type |= AGENT;
|
||||
if ((sftpfs_super->config_auth_type & AGENT) != 0)
|
||||
sftpfs_super->auth_type |= AGENT;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -208,39 +205,38 @@ sftpfs_recognize_auth_types (struct vfs_s_super *super)
|
||||
static gboolean
|
||||
sftpfs_open_connection_ssh_agent (struct vfs_s_super *super, GError ** mcerror)
|
||||
{
|
||||
sftpfs_super_data_t *super_data;
|
||||
sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
|
||||
struct libssh2_agent_publickey *identity, *prev_identity = NULL;
|
||||
int rc;
|
||||
|
||||
mc_return_val_if_error (mcerror, FALSE);
|
||||
|
||||
super_data = (sftpfs_super_data_t *) super->data;
|
||||
super_data->agent = NULL;
|
||||
sftpfs_super->agent = NULL;
|
||||
|
||||
if ((super_data->auth_type & AGENT) == 0)
|
||||
if ((sftpfs_super->auth_type & AGENT) == 0)
|
||||
return FALSE;
|
||||
|
||||
/* Connect to the ssh-agent */
|
||||
super_data->agent = libssh2_agent_init (super_data->session);
|
||||
if (super_data->agent == NULL)
|
||||
sftpfs_super->agent = libssh2_agent_init (sftpfs_super->session);
|
||||
if (sftpfs_super->agent == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (libssh2_agent_connect (super_data->agent) != 0)
|
||||
if (libssh2_agent_connect (sftpfs_super->agent) != 0)
|
||||
return FALSE;
|
||||
|
||||
if (libssh2_agent_list_identities (super_data->agent) != 0)
|
||||
if (libssh2_agent_list_identities (sftpfs_super->agent) != 0)
|
||||
return FALSE;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
rc = libssh2_agent_get_identity (super_data->agent, &identity, prev_identity);
|
||||
rc = libssh2_agent_get_identity (sftpfs_super->agent, &identity, prev_identity);
|
||||
if (rc == 1)
|
||||
break;
|
||||
|
||||
if (rc < 0)
|
||||
return FALSE;
|
||||
|
||||
if (libssh2_agent_userauth (super_data->agent, super->path_element->user, identity) == 0)
|
||||
if (libssh2_agent_userauth (sftpfs_super->agent, super->path_element->user, identity) == 0)
|
||||
break;
|
||||
|
||||
prev_identity = identity;
|
||||
@ -261,22 +257,20 @@ sftpfs_open_connection_ssh_agent (struct vfs_s_super *super, GError ** mcerror)
|
||||
static gboolean
|
||||
sftpfs_open_connection_ssh_key (struct vfs_s_super *super, GError ** mcerror)
|
||||
{
|
||||
sftpfs_super_data_t *super_data;
|
||||
sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
|
||||
char *p, *passwd;
|
||||
gboolean ret_value = FALSE;
|
||||
|
||||
mc_return_val_if_error (mcerror, FALSE);
|
||||
|
||||
super_data = (sftpfs_super_data_t *) super->data;
|
||||
|
||||
if ((super_data->auth_type & PUBKEY) == 0)
|
||||
if ((sftpfs_super->auth_type & PUBKEY) == 0)
|
||||
return FALSE;
|
||||
|
||||
if (super_data->privkey == NULL)
|
||||
if (sftpfs_super->privkey == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (libssh2_userauth_publickey_fromfile (super_data->session, super->path_element->user,
|
||||
super_data->pubkey, super_data->privkey,
|
||||
if (libssh2_userauth_publickey_fromfile (sftpfs_super->session, super->path_element->user,
|
||||
sftpfs_super->pubkey, sftpfs_super->privkey,
|
||||
super->path_element->password) == 0)
|
||||
return TRUE;
|
||||
|
||||
@ -288,10 +282,10 @@ sftpfs_open_connection_ssh_key (struct vfs_s_super *super, GError ** mcerror)
|
||||
mc_propagate_error (mcerror, 0, "%s", _("sftp: Passphrase is empty."));
|
||||
else
|
||||
{
|
||||
ret_value = (libssh2_userauth_publickey_fromfile (super_data->session,
|
||||
ret_value = (libssh2_userauth_publickey_fromfile (sftpfs_super->session,
|
||||
super->path_element->user,
|
||||
super_data->pubkey, super_data->privkey,
|
||||
passwd) == 0);
|
||||
sftpfs_super->pubkey,
|
||||
sftpfs_super->privkey, passwd) == 0);
|
||||
g_free (passwd);
|
||||
}
|
||||
|
||||
@ -310,21 +304,19 @@ sftpfs_open_connection_ssh_key (struct vfs_s_super *super, GError ** mcerror)
|
||||
static gboolean
|
||||
sftpfs_open_connection_ssh_password (struct vfs_s_super *super, GError ** mcerror)
|
||||
{
|
||||
sftpfs_super_data_t *super_data;
|
||||
sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
|
||||
char *p, *passwd;
|
||||
gboolean ret_value = FALSE;
|
||||
int rc;
|
||||
|
||||
mc_return_val_if_error (mcerror, FALSE);
|
||||
|
||||
super_data = (sftpfs_super_data_t *) super->data;
|
||||
|
||||
if ((super_data->auth_type & PASSWORD) == 0)
|
||||
if ((sftpfs_super->auth_type & PASSWORD) == 0)
|
||||
return FALSE;
|
||||
|
||||
if (super->path_element->password != NULL)
|
||||
{
|
||||
while ((rc = libssh2_userauth_password (super_data->session, super->path_element->user,
|
||||
while ((rc = libssh2_userauth_password (sftpfs_super->session, super->path_element->user,
|
||||
super->path_element->password)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (rc == 0)
|
||||
@ -339,7 +331,7 @@ sftpfs_open_connection_ssh_password (struct vfs_s_super *super, GError ** mcerro
|
||||
mc_propagate_error (mcerror, 0, "%s", _("sftp: Password is empty."));
|
||||
else
|
||||
{
|
||||
while ((rc = libssh2_userauth_password (super_data->session, super->path_element->user,
|
||||
while ((rc = libssh2_userauth_password (sftpfs_super->session, super->path_element->user,
|
||||
passwd)) == LIBSSH2_ERROR_EAGAIN)
|
||||
;
|
||||
|
||||
@ -371,33 +363,31 @@ int
|
||||
sftpfs_open_connection (struct vfs_s_super *super, GError ** mcerror)
|
||||
{
|
||||
int rc;
|
||||
sftpfs_super_data_t *super_data;
|
||||
sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
|
||||
|
||||
mc_return_val_if_error (mcerror, -1);
|
||||
|
||||
super_data = (sftpfs_super_data_t *) super->data;
|
||||
|
||||
/*
|
||||
* The application code is responsible for creating the socket
|
||||
* and establishing the connection
|
||||
*/
|
||||
super_data->socket_handle = sftpfs_open_socket (super, mcerror);
|
||||
if (super_data->socket_handle == LIBSSH2_INVALID_SOCKET)
|
||||
sftpfs_super->socket_handle = sftpfs_open_socket (super, mcerror);
|
||||
if (sftpfs_super->socket_handle == LIBSSH2_INVALID_SOCKET)
|
||||
return (-1);
|
||||
|
||||
/* Create a session instance */
|
||||
super_data->session = libssh2_session_init ();
|
||||
if (super_data->session == NULL)
|
||||
sftpfs_super->session = libssh2_session_init ();
|
||||
if (sftpfs_super->session == NULL)
|
||||
return (-1);
|
||||
|
||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||
* and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
#if LIBSSH2_VERSION_NUM < 0x010208
|
||||
rc = libssh2_session_startup (super_data->session, super_data->socket_handle);
|
||||
rc = libssh2_session_startup (sftpfs_super->session, sftpfs_super->socket_handle);
|
||||
#else
|
||||
rc = libssh2_session_handshake (super_data->session,
|
||||
(libssh2_socket_t) super_data->socket_handle);
|
||||
rc = libssh2_session_handshake (sftpfs_super->session,
|
||||
(libssh2_socket_t) sftpfs_super->socket_handle);
|
||||
#endif
|
||||
if (rc != 0)
|
||||
{
|
||||
@ -410,14 +400,15 @@ sftpfs_open_connection (struct vfs_s_super *super, GError ** mcerror)
|
||||
* may have it hard coded, may go to a file, may present it to the
|
||||
* user, that's your call
|
||||
*/
|
||||
super_data->fingerprint = libssh2_hostkey_hash (super_data->session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||
sftpfs_super->fingerprint =
|
||||
libssh2_hostkey_hash (sftpfs_super->session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||
|
||||
if (!sftpfs_recognize_auth_types (super))
|
||||
{
|
||||
int sftp_errno;
|
||||
|
||||
sftp_errno = libssh2_session_last_errno (super_data->session);
|
||||
sftpfs_ssherror_to_gliberror (super_data, sftp_errno, mcerror);
|
||||
sftp_errno = libssh2_session_last_errno (sftpfs_super->session);
|
||||
sftpfs_ssherror_to_gliberror (sftpfs_super, sftp_errno, mcerror);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -426,13 +417,13 @@ sftpfs_open_connection (struct vfs_s_super *super, GError ** mcerror)
|
||||
&& !sftpfs_open_connection_ssh_password (super, mcerror))
|
||||
return (-1);
|
||||
|
||||
super_data->sftp_session = libssh2_sftp_init (super_data->session);
|
||||
sftpfs_super->sftp_session = libssh2_sftp_init (sftpfs_super->session);
|
||||
|
||||
if (super_data->sftp_session == NULL)
|
||||
if (sftpfs_super->sftp_session == NULL)
|
||||
return (-1);
|
||||
|
||||
/* Since we have not set non-blocking, tell libssh2 we are blocking */
|
||||
libssh2_session_set_blocking (super_data->session, 1);
|
||||
libssh2_session_set_blocking (sftpfs_super->session, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -449,41 +440,37 @@ sftpfs_open_connection (struct vfs_s_super *super, GError ** mcerror)
|
||||
void
|
||||
sftpfs_close_connection (struct vfs_s_super *super, const char *shutdown_message, GError ** mcerror)
|
||||
{
|
||||
sftpfs_super_data_t *super_data;
|
||||
sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
|
||||
|
||||
/* no mc_return_*_if_error() here because of abort open_connection handling too */
|
||||
(void) mcerror;
|
||||
|
||||
super_data = (sftpfs_super_data_t *) super->data;
|
||||
if (super_data == NULL)
|
||||
return;
|
||||
|
||||
if (super_data->sftp_session != NULL)
|
||||
if (sftpfs_super->sftp_session != NULL)
|
||||
{
|
||||
libssh2_sftp_shutdown (super_data->sftp_session);
|
||||
super_data->sftp_session = NULL;
|
||||
libssh2_sftp_shutdown (sftpfs_super->sftp_session);
|
||||
sftpfs_super->sftp_session = NULL;
|
||||
}
|
||||
|
||||
if (super_data->agent != NULL)
|
||||
if (sftpfs_super->agent != NULL)
|
||||
{
|
||||
libssh2_agent_disconnect (super_data->agent);
|
||||
libssh2_agent_free (super_data->agent);
|
||||
super_data->agent = NULL;
|
||||
libssh2_agent_disconnect (sftpfs_super->agent);
|
||||
libssh2_agent_free (sftpfs_super->agent);
|
||||
sftpfs_super->agent = NULL;
|
||||
}
|
||||
|
||||
super_data->fingerprint = NULL;
|
||||
sftpfs_super->fingerprint = NULL;
|
||||
|
||||
if (super_data->session != NULL)
|
||||
if (sftpfs_super->session != NULL)
|
||||
{
|
||||
libssh2_session_disconnect (super_data->session, shutdown_message);
|
||||
libssh2_session_free (super_data->session);
|
||||
super_data->session = NULL;
|
||||
libssh2_session_disconnect (sftpfs_super->session, shutdown_message);
|
||||
libssh2_session_free (sftpfs_super->session);
|
||||
sftpfs_super->session = NULL;
|
||||
}
|
||||
|
||||
if (super_data->socket_handle != LIBSSH2_INVALID_SOCKET)
|
||||
if (sftpfs_super->socket_handle != LIBSSH2_INVALID_SOCKET)
|
||||
{
|
||||
close (super_data->socket_handle);
|
||||
super_data->socket_handle = LIBSSH2_INVALID_SOCKET;
|
||||
close (sftpfs_super->socket_handle);
|
||||
sftpfs_super->socket_handle = LIBSSH2_INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@
|
||||
typedef struct
|
||||
{
|
||||
LIBSSH2_SFTP_HANDLE *handle;
|
||||
sftpfs_super_data_t *super_data;
|
||||
sftpfs_super_t *super;
|
||||
} sftpfs_dir_data_t;
|
||||
|
||||
/*** file scope variables ************************************************************************/
|
||||
@ -67,7 +67,7 @@ sftpfs_opendir (const vfs_path_t * vpath, GError ** mcerror)
|
||||
{
|
||||
sftpfs_dir_data_t *sftpfs_dir;
|
||||
struct vfs_s_super *super;
|
||||
sftpfs_super_data_t *super_data;
|
||||
sftpfs_super_t *sftpfs_super;
|
||||
const vfs_path_element_t *path_element;
|
||||
LIBSSH2_SFTP_HANDLE *handle;
|
||||
|
||||
@ -78,7 +78,7 @@ sftpfs_opendir (const vfs_path_t * vpath, GError ** mcerror)
|
||||
if (vfs_s_get_path (vpath, &super, 0) == NULL)
|
||||
return NULL;
|
||||
|
||||
super_data = (sftpfs_super_data_t *) super->data;
|
||||
sftpfs_super = SFTP_SUPER (super);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
@ -89,19 +89,19 @@ sftpfs_opendir (const vfs_path_t * vpath, GError ** mcerror)
|
||||
fixfname = sftpfs_fix_filename (path_element->path, &fixfname_len);
|
||||
|
||||
handle =
|
||||
libssh2_sftp_open_ex (super_data->sftp_session, fixfname, fixfname_len, 0, 0,
|
||||
libssh2_sftp_open_ex (sftpfs_super->sftp_session, fixfname, fixfname_len, 0, 0,
|
||||
LIBSSH2_SFTP_OPENDIR);
|
||||
if (handle != NULL)
|
||||
break;
|
||||
|
||||
libssh_errno = libssh2_session_last_errno (super_data->session);
|
||||
if (!sftpfs_waitsocket (super_data, libssh_errno, mcerror))
|
||||
libssh_errno = libssh2_session_last_errno (sftpfs_super->session);
|
||||
if (!sftpfs_waitsocket (sftpfs_super, libssh_errno, mcerror))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sftpfs_dir = g_new0 (sftpfs_dir_data_t, 1);
|
||||
sftpfs_dir->handle = handle;
|
||||
sftpfs_dir->super_data = super_data;
|
||||
sftpfs_dir->super = sftpfs_super;
|
||||
|
||||
return (void *) sftpfs_dir;
|
||||
}
|
||||
@ -132,7 +132,7 @@ sftpfs_readdir (void *data, GError ** mcerror)
|
||||
if (rc >= 0)
|
||||
break;
|
||||
|
||||
if (!sftpfs_waitsocket (sftpfs_dir->super_data, rc, mcerror))
|
||||
if (!sftpfs_waitsocket (sftpfs_dir->super, rc, mcerror))
|
||||
return NULL;
|
||||
}
|
||||
while (rc == LIBSSH2_ERROR_EAGAIN);
|
||||
@ -181,7 +181,7 @@ sftpfs_mkdir (const vfs_path_t * vpath, mode_t mode, GError ** mcerror)
|
||||
{
|
||||
int res;
|
||||
struct vfs_s_super *super;
|
||||
sftpfs_super_data_t *super_data;
|
||||
sftpfs_super_t *sftpfs_super;
|
||||
const vfs_path_element_t *path_element;
|
||||
|
||||
mc_return_val_if_error (mcerror, -1);
|
||||
@ -194,8 +194,8 @@ sftpfs_mkdir (const vfs_path_t * vpath, mode_t mode, GError ** mcerror)
|
||||
if (super == NULL)
|
||||
return -1;
|
||||
|
||||
super_data = (sftpfs_super_data_t *) super->data;
|
||||
if (super_data->sftp_session == NULL)
|
||||
sftpfs_super = SFTP_SUPER (super);
|
||||
if (sftpfs_super->sftp_session == NULL)
|
||||
return -1;
|
||||
|
||||
do
|
||||
@ -205,11 +205,11 @@ sftpfs_mkdir (const vfs_path_t * vpath, mode_t mode, GError ** mcerror)
|
||||
|
||||
fixfname = sftpfs_fix_filename (path_element->path, &fixfname_len);
|
||||
|
||||
res = libssh2_sftp_mkdir_ex (super_data->sftp_session, fixfname, fixfname_len, mode);
|
||||
res = libssh2_sftp_mkdir_ex (sftpfs_super->sftp_session, fixfname, fixfname_len, mode);
|
||||
if (res >= 0)
|
||||
break;
|
||||
|
||||
if (!sftpfs_waitsocket (super_data, res, mcerror))
|
||||
if (!sftpfs_waitsocket (sftpfs_super, res, mcerror))
|
||||
return -1;
|
||||
}
|
||||
while (res == LIBSSH2_ERROR_EAGAIN);
|
||||
@ -231,7 +231,7 @@ sftpfs_rmdir (const vfs_path_t * vpath, GError ** mcerror)
|
||||
{
|
||||
int res;
|
||||
struct vfs_s_super *super;
|
||||
sftpfs_super_data_t *super_data;
|
||||
sftpfs_super_t *sftpfs_super;
|
||||
const vfs_path_element_t *path_element;
|
||||
|
||||
mc_return_val_if_error (mcerror, -1);
|
||||
@ -244,8 +244,8 @@ sftpfs_rmdir (const vfs_path_t * vpath, GError ** mcerror)
|
||||
if (super == NULL)
|
||||
return -1;
|
||||
|
||||
super_data = (sftpfs_super_data_t *) super->data;
|
||||
if (super_data->sftp_session == NULL)
|
||||
sftpfs_super = SFTP_SUPER (super);
|
||||
if (sftpfs_super->sftp_session == NULL)
|
||||
return -1;
|
||||
|
||||
do
|
||||
@ -255,11 +255,11 @@ sftpfs_rmdir (const vfs_path_t * vpath, GError ** mcerror)
|
||||
|
||||
fixfname = sftpfs_fix_filename (path_element->path, &fixfname_len);
|
||||
|
||||
res = libssh2_sftp_rmdir_ex (super_data->sftp_session, fixfname, fixfname_len);
|
||||
res = libssh2_sftp_rmdir_ex (sftpfs_super->sftp_session, fixfname, fixfname_len);
|
||||
if (res >= 0)
|
||||
break;
|
||||
|
||||
if (!sftpfs_waitsocket (super_data, res, mcerror))
|
||||
if (!sftpfs_waitsocket (sftpfs_super, res, mcerror))
|
||||
return -1;
|
||||
}
|
||||
while (res == LIBSSH2_ERROR_EAGAIN);
|
||||
|
@ -39,14 +39,18 @@
|
||||
|
||||
/*** file scope macro definitions ****************************************************************/
|
||||
|
||||
#define SFTP_FILE_HANDLER(a) ((sftpfs_file_handler_t *) a)
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vfs_file_handler_t base; /* base class */
|
||||
|
||||
LIBSSH2_SFTP_HANDLE *handle;
|
||||
int flags;
|
||||
mode_t mode;
|
||||
} sftpfs_file_handler_data_t;
|
||||
} sftpfs_file_handler_t;
|
||||
|
||||
/*** file scope variables ************************************************************************/
|
||||
|
||||
@ -56,38 +60,37 @@ typedef struct
|
||||
/**
|
||||
* Reopen file by file handle.
|
||||
*
|
||||
* @param file_handler the file handler data
|
||||
* @param mcerror pointer to the error handler
|
||||
* @param fh the file handler
|
||||
* @param mcerror pointer to the error handler
|
||||
*/
|
||||
static void
|
||||
sftpfs_reopen (vfs_file_handler_t * file_handler, GError ** mcerror)
|
||||
sftpfs_reopen (vfs_file_handler_t * fh, GError ** mcerror)
|
||||
{
|
||||
sftpfs_file_handler_data_t *file_handler_data;
|
||||
sftpfs_file_handler_t *file = SFTP_FILE_HANDLER (fh);
|
||||
int flags;
|
||||
mode_t mode;
|
||||
|
||||
g_return_if_fail (mcerror == NULL || *mcerror == NULL);
|
||||
|
||||
file_handler_data = (sftpfs_file_handler_data_t *) file_handler->data;
|
||||
flags = file_handler_data->flags;
|
||||
mode = file_handler_data->mode;
|
||||
flags = file->flags;
|
||||
mode = file->mode;
|
||||
|
||||
sftpfs_close_file (file_handler, mcerror);
|
||||
sftpfs_open_file (file_handler, flags, mode, mcerror);
|
||||
sftpfs_close_file (fh, mcerror);
|
||||
sftpfs_open_file (fh, flags, mode, mcerror);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
sftpfs_file__handle_error (sftpfs_super_data_t * super_data, int sftp_res, GError ** mcerror)
|
||||
sftpfs_file__handle_error (sftpfs_super_t * super, int sftp_res, GError ** mcerror)
|
||||
{
|
||||
if (sftpfs_is_sftp_error (super_data->sftp_session, sftp_res, LIBSSH2_FX_PERMISSION_DENIED))
|
||||
if (sftpfs_is_sftp_error (super->sftp_session, sftp_res, LIBSSH2_FX_PERMISSION_DENIED))
|
||||
return -EACCES;
|
||||
|
||||
if (sftpfs_is_sftp_error (super_data->sftp_session, sftp_res, LIBSSH2_FX_NO_SUCH_FILE))
|
||||
if (sftpfs_is_sftp_error (super->sftp_session, sftp_res, LIBSSH2_FX_NO_SUCH_FILE))
|
||||
return -ENOENT;
|
||||
|
||||
if (!sftpfs_waitsocket (super_data, sftp_res, mcerror))
|
||||
if (!sftpfs_waitsocket (super, sftp_res, mcerror))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
@ -95,37 +98,47 @@ sftpfs_file__handle_error (sftpfs_super_data_t * super_data, int sftp_res, GErro
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** public functions ****************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
vfs_file_handler_t *
|
||||
sftpfs_fh_new (struct vfs_s_inode * ino, gboolean changed)
|
||||
{
|
||||
sftpfs_file_handler_t *fh;
|
||||
|
||||
fh = g_new0 (sftpfs_file_handler_t, 1);
|
||||
vfs_s_init_fh (VFS_FILE_HANDLER (fh), ino, changed);
|
||||
|
||||
return VFS_FILE_HANDLER (fh);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Open new SFTP file.
|
||||
*
|
||||
* @param file_handler the file handler data
|
||||
* @param flags flags (see man 2 open)
|
||||
* @param mode mode (see man 2 open)
|
||||
* @param mcerror pointer to the error handler
|
||||
* @param fh the file handler
|
||||
* @param flags flags (see man 2 open)
|
||||
* @param mode mode (see man 2 open)
|
||||
* @param mcerror pointer to the error handler
|
||||
* @return TRUE if connection was created successfully, FALSE otherwise
|
||||
*/
|
||||
|
||||
gboolean
|
||||
sftpfs_open_file (vfs_file_handler_t * file_handler, int flags, mode_t mode, GError ** mcerror)
|
||||
sftpfs_open_file (vfs_file_handler_t * fh, int flags, mode_t mode, GError ** mcerror)
|
||||
{
|
||||
unsigned long sftp_open_flags = 0;
|
||||
int sftp_open_mode = 0;
|
||||
gboolean do_append = FALSE;
|
||||
sftpfs_file_handler_data_t *file_handler_data;
|
||||
sftpfs_super_data_t *super_data;
|
||||
sftpfs_file_handler_t *file = SFTP_FILE_HANDLER (fh);
|
||||
sftpfs_super_t *super = SFTP_SUPER (fh->ino->super);
|
||||
char *name;
|
||||
|
||||
(void) mode;
|
||||
mc_return_val_if_error (mcerror, FALSE);
|
||||
|
||||
name = vfs_s_fullpath (&sftpfs_class, file_handler->ino);
|
||||
name = vfs_s_fullpath (sftpfs_class, fh->ino);
|
||||
if (name == NULL)
|
||||
return FALSE;
|
||||
|
||||
super_data = (sftpfs_super_data_t *) file_handler->ino->super->data;
|
||||
file_handler_data = g_new0 (sftpfs_file_handler_data_t, 1);
|
||||
|
||||
if ((flags & O_CREAT) != 0 || (flags & O_WRONLY) != 0)
|
||||
{
|
||||
sftp_open_flags = (flags & O_WRONLY) != 0 ? LIBSSH2_FXF_WRITE : 0;
|
||||
@ -151,27 +164,26 @@ sftpfs_open_file (vfs_file_handler_t * file_handler, int flags, mode_t mode, GEr
|
||||
|
||||
fixfname = sftpfs_fix_filename (name, &fixfname_len);
|
||||
|
||||
file_handler_data->handle =
|
||||
libssh2_sftp_open_ex (super_data->sftp_session, fixfname, fixfname_len, sftp_open_flags,
|
||||
file->handle =
|
||||
libssh2_sftp_open_ex (super->sftp_session, fixfname, fixfname_len, sftp_open_flags,
|
||||
sftp_open_mode, LIBSSH2_SFTP_OPENFILE);
|
||||
if (file_handler_data->handle != NULL)
|
||||
if (file->handle != NULL)
|
||||
break;
|
||||
|
||||
libssh_errno = libssh2_session_last_errno (super_data->session);
|
||||
libssh_errno = libssh2_session_last_errno (super->session);
|
||||
if (libssh_errno != LIBSSH2_ERROR_EAGAIN)
|
||||
{
|
||||
sftpfs_ssherror_to_gliberror (super_data, libssh_errno, mcerror);
|
||||
sftpfs_ssherror_to_gliberror (super, libssh_errno, mcerror);
|
||||
g_free (name);
|
||||
g_free (file_handler_data);
|
||||
g_free (file);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
|
||||
file_handler_data->flags = flags;
|
||||
file_handler_data->mode = mode;
|
||||
file_handler->data = file_handler_data;
|
||||
file->flags = flags;
|
||||
file->mode = mode;
|
||||
|
||||
if (do_append)
|
||||
{
|
||||
@ -190,8 +202,8 @@ sftpfs_open_file (vfs_file_handler_t * file_handler, int flags, mode_t mode, GEr
|
||||
[1] http://stackoverflow.com/questions/13373695/how-to-remove-the-warning-in-gcc-4-6-missing-initializer-wmissing-field-initi/27461062#27461062
|
||||
*/
|
||||
|
||||
if (sftpfs_fstat (file_handler, &file_info, mcerror) == 0)
|
||||
libssh2_sftp_seek64 (file_handler_data->handle, file_info.st_size);
|
||||
if (sftpfs_fstat (fh, &file_info, mcerror) == 0)
|
||||
libssh2_sftp_seek64 (file->handle, file_info.st_size);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@ -200,7 +212,7 @@ sftpfs_open_file (vfs_file_handler_t * file_handler, int flags, mode_t mode, GEr
|
||||
/**
|
||||
* Stats the file specified by the file descriptor.
|
||||
*
|
||||
* @param data file data handler
|
||||
* @param data file handler
|
||||
* @param buf buffer for store stat-info
|
||||
* @param mcerror pointer to the error handler
|
||||
* @return 0 if success, negative value otherwise
|
||||
@ -211,10 +223,10 @@ sftpfs_fstat (void *data, struct stat *buf, GError ** mcerror)
|
||||
{
|
||||
int res;
|
||||
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
||||
vfs_file_handler_t *fh = (vfs_file_handler_t *) data;
|
||||
sftpfs_file_handler_data_t *sftpfs_fh = fh->data;
|
||||
struct vfs_s_super *super = fh->ino->super;
|
||||
sftpfs_super_data_t *super_data = (sftpfs_super_data_t *) super->data;
|
||||
vfs_file_handler_t *fh = VFS_FILE_HANDLER (data);
|
||||
sftpfs_file_handler_t *sftpfs_fh = (sftpfs_file_handler_t *) data;
|
||||
struct vfs_s_super *super = VFS_FILE_HANDLER_SUPER (fh);
|
||||
sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
|
||||
|
||||
mc_return_val_if_error (mcerror, -1);
|
||||
|
||||
@ -229,7 +241,7 @@ sftpfs_fstat (void *data, struct stat *buf, GError ** mcerror)
|
||||
if (res >= 0)
|
||||
break;
|
||||
|
||||
err = sftpfs_file__handle_error (super_data, res, mcerror);
|
||||
err = sftpfs_file__handle_error (sftpfs_super, res, mcerror);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
@ -242,50 +254,49 @@ sftpfs_fstat (void *data, struct stat *buf, GError ** mcerror)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Read up to 'count' bytes from the file descriptor 'file_handler' to the buffer starting at 'buffer'.
|
||||
* Read up to 'count' bytes from the file descriptor 'fh' to the buffer starting at 'buffer'.
|
||||
*
|
||||
* @param file_handler file data handler
|
||||
* @param buffer buffer for data
|
||||
* @param count data size
|
||||
* @param mcerror pointer to the error handler
|
||||
* @param fh file handler
|
||||
* @param buffer buffer for data
|
||||
* @param count data size
|
||||
* @param mcerror pointer to the error handler
|
||||
*
|
||||
* @return 0 on success, negative value otherwise
|
||||
*/
|
||||
|
||||
ssize_t
|
||||
sftpfs_read_file (vfs_file_handler_t * file_handler, char *buffer, size_t count, GError ** mcerror)
|
||||
sftpfs_read_file (vfs_file_handler_t * fh, char *buffer, size_t count, GError ** mcerror)
|
||||
{
|
||||
ssize_t rc;
|
||||
sftpfs_file_handler_data_t *file_handler_data;
|
||||
sftpfs_super_data_t *super_data;
|
||||
sftpfs_file_handler_t *file = SFTP_FILE_HANDLER (fh);
|
||||
sftpfs_super_t *super;
|
||||
|
||||
mc_return_val_if_error (mcerror, -1);
|
||||
|
||||
if (file_handler == NULL || file_handler->data == NULL)
|
||||
if (fh == NULL)
|
||||
{
|
||||
mc_propagate_error (mcerror, 0, "%s",
|
||||
_("sftp: No file handler data present for reading file"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
file_handler_data = file_handler->data;
|
||||
super_data = (sftpfs_super_data_t *) file_handler->ino->super->data;
|
||||
super = SFTP_SUPER (VFS_FILE_HANDLER_SUPER (fh));
|
||||
|
||||
do
|
||||
{
|
||||
int err;
|
||||
|
||||
rc = libssh2_sftp_read (file_handler_data->handle, buffer, count);
|
||||
rc = libssh2_sftp_read (file->handle, buffer, count);
|
||||
if (rc >= 0)
|
||||
break;
|
||||
|
||||
err = sftpfs_file__handle_error (super_data, (int) rc, mcerror);
|
||||
err = sftpfs_file__handle_error (super, (int) rc, mcerror);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
while (rc == LIBSSH2_ERROR_EAGAIN);
|
||||
|
||||
file_handler->pos = (off_t) libssh2_sftp_tell64 (file_handler_data->handle);
|
||||
fh->pos = (off_t) libssh2_sftp_tell64 (file->handle);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -293,40 +304,36 @@ sftpfs_read_file (vfs_file_handler_t * file_handler, char *buffer, size_t count,
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Write up to 'count' bytes from the buffer starting at 'buffer' to the descriptor 'file_handler'.
|
||||
* Write up to 'count' bytes from the buffer starting at 'buffer' to the descriptor 'fh'.
|
||||
*
|
||||
* @param file_handler file data handler
|
||||
* @param buffer buffer for data
|
||||
* @param count data size
|
||||
* @param mcerror pointer to the error handler
|
||||
* @param fh file handler
|
||||
* @param buffer buffer for data
|
||||
* @param count data size
|
||||
* @param mcerror pointer to the error handler
|
||||
*
|
||||
* @return 0 on success, negative value otherwise
|
||||
*/
|
||||
|
||||
ssize_t
|
||||
sftpfs_write_file (vfs_file_handler_t * file_handler, const char *buffer, size_t count,
|
||||
GError ** mcerror)
|
||||
sftpfs_write_file (vfs_file_handler_t * fh, const char *buffer, size_t count, GError ** mcerror)
|
||||
{
|
||||
ssize_t rc;
|
||||
sftpfs_file_handler_data_t *file_handler_data;
|
||||
sftpfs_super_data_t *super_data;
|
||||
sftpfs_file_handler_t *file = SFTP_FILE_HANDLER (fh);
|
||||
sftpfs_super_t *super = SFTP_SUPER (VFS_FILE_HANDLER_SUPER (fh));
|
||||
|
||||
mc_return_val_if_error (mcerror, -1);
|
||||
|
||||
file_handler_data = (sftpfs_file_handler_data_t *) file_handler->data;
|
||||
super_data = (sftpfs_super_data_t *) file_handler->ino->super->data;
|
||||
|
||||
file_handler->pos = (off_t) libssh2_sftp_tell64 (file_handler_data->handle);
|
||||
fh->pos = (off_t) libssh2_sftp_tell64 (file->handle);
|
||||
|
||||
do
|
||||
{
|
||||
int err;
|
||||
|
||||
rc = libssh2_sftp_write (file_handler_data->handle, buffer, count);
|
||||
rc = libssh2_sftp_write (file->handle, buffer, count);
|
||||
if (rc >= 0)
|
||||
break;
|
||||
|
||||
err = sftpfs_file__handle_error (super_data, (int) rc, mcerror);
|
||||
err = sftpfs_file__handle_error (super, (int) rc, mcerror);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
@ -340,28 +347,22 @@ sftpfs_write_file (vfs_file_handler_t * file_handler, const char *buffer, size_t
|
||||
/**
|
||||
* Close a file descriptor.
|
||||
*
|
||||
* @param file_handler file data handler
|
||||
* @param mcerror pointer to the error handler
|
||||
* @param fh file handler
|
||||
* @param mcerror pointer to the error handler
|
||||
*
|
||||
* @return 0 on success, negative value otherwise
|
||||
*/
|
||||
|
||||
int
|
||||
sftpfs_close_file (vfs_file_handler_t * file_handler, GError ** mcerror)
|
||||
sftpfs_close_file (vfs_file_handler_t * fh, GError ** mcerror)
|
||||
{
|
||||
sftpfs_file_handler_data_t *file_handler_data;
|
||||
int ret = -1;
|
||||
int ret;
|
||||
|
||||
mc_return_val_if_error (mcerror, -1);
|
||||
|
||||
file_handler_data = (sftpfs_file_handler_data_t *) file_handler->data;
|
||||
if (file_handler_data != NULL)
|
||||
{
|
||||
ret = libssh2_sftp_close (file_handler_data->handle);
|
||||
g_free (file_handler_data);
|
||||
}
|
||||
ret = libssh2_sftp_close (SFTP_FILE_HANDLER (fh)->handle);
|
||||
|
||||
return ret;
|
||||
return ret == 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -369,18 +370,18 @@ sftpfs_close_file (vfs_file_handler_t * file_handler, GError ** mcerror)
|
||||
/**
|
||||
* Reposition the offset of the open file associated with the file descriptor.
|
||||
*
|
||||
* @param file_handler file data handler
|
||||
* @param offset file offset
|
||||
* @param whence method of seek (at begin, at current, at end)
|
||||
* @param mcerror pointer to the error handler
|
||||
* @param fh file handler
|
||||
* @param offset file offset
|
||||
* @param whence method of seek (at begin, at current, at end)
|
||||
* @param mcerror pointer to the error handler
|
||||
*
|
||||
* @return 0 on success, negative value otherwise
|
||||
*/
|
||||
|
||||
off_t
|
||||
sftpfs_lseek (vfs_file_handler_t * file_handler, off_t offset, int whence, GError ** mcerror)
|
||||
sftpfs_lseek (vfs_file_handler_t * fh, off_t offset, int whence, GError ** mcerror)
|
||||
{
|
||||
sftpfs_file_handler_data_t *file_handler_data;
|
||||
sftpfs_file_handler_t *file = SFTP_FILE_HANDLER (fh);
|
||||
|
||||
mc_return_val_if_error (mcerror, 0);
|
||||
|
||||
@ -391,34 +392,32 @@ sftpfs_lseek (vfs_file_handler_t * file_handler, off_t offset, int whence, GErro
|
||||
"You MUST NOT seek during writing or reading a file with SFTP, as the internals use
|
||||
outstanding packets and changing the "file position" during transit will results in
|
||||
badness." */
|
||||
if (file_handler->pos > offset || offset == 0)
|
||||
if (fh->pos > offset || offset == 0)
|
||||
{
|
||||
sftpfs_reopen (file_handler, mcerror);
|
||||
sftpfs_reopen (fh, mcerror);
|
||||
mc_return_val_if_error (mcerror, 0);
|
||||
}
|
||||
file_handler->pos = offset;
|
||||
fh->pos = offset;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
file_handler->pos += offset;
|
||||
fh->pos += offset;
|
||||
break;
|
||||
case SEEK_END:
|
||||
if (file_handler->pos > file_handler->ino->st.st_size - offset)
|
||||
if (fh->pos > fh->ino->st.st_size - offset)
|
||||
{
|
||||
sftpfs_reopen (file_handler, mcerror);
|
||||
sftpfs_reopen (fh, mcerror);
|
||||
mc_return_val_if_error (mcerror, 0);
|
||||
}
|
||||
file_handler->pos = file_handler->ino->st.st_size - offset;
|
||||
fh->pos = fh->ino->st.st_size - offset;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
file_handler_data = (sftpfs_file_handler_data_t *) file_handler->data;
|
||||
libssh2_sftp_seek64 (file->handle, fh->pos);
|
||||
fh->pos = (off_t) libssh2_sftp_tell64 (file->handle);
|
||||
|
||||
libssh2_sftp_seek64 (file_handler_data->handle, file_handler->pos);
|
||||
file_handler->pos = (off_t) libssh2_sftp_tell64 (file_handler_data->handle);
|
||||
|
||||
return file_handler->pos;
|
||||
return fh->pos;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -34,6 +34,9 @@
|
||||
|
||||
/*** global variables ****************************************************************************/
|
||||
|
||||
struct vfs_s_subclass sftpfs_subclass;
|
||||
struct vfs_class *sftpfs_class = VFS_CLASS (&sftpfs_subclass);
|
||||
|
||||
/*** file scope macro definitions ****************************************************************/
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
@ -55,15 +58,10 @@ init_sftpfs (void)
|
||||
{
|
||||
tcp_init ();
|
||||
|
||||
vfs_init_subclass (&sftpfs_subclass, "sftpfs", VFS_NOLINKS | VFS_REMOTE, "sftp");
|
||||
sftpfs_init_class ();
|
||||
sftpfs_init_subclass ();
|
||||
|
||||
vfs_s_init_class (&sftpfs_class, &sftpfs_subclass);
|
||||
|
||||
sftpfs_init_class_callbacks ();
|
||||
sftpfs_init_subclass_callbacks ();
|
||||
|
||||
vfs_register_class (&sftpfs_class);
|
||||
vfs_register_class (sftpfs_class);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -61,13 +61,13 @@ sftpfs_blksize (struct stat *s)
|
||||
/**
|
||||
* Awaiting for any activity on socket.
|
||||
*
|
||||
* @param super_data extra data for SFTP connection
|
||||
* @param super extra data for SFTP connection
|
||||
* @param mcerror pointer to the error object
|
||||
* @return 0 if success, negative value otherwise
|
||||
*/
|
||||
|
||||
static int
|
||||
sftpfs_internal_waitsocket (sftpfs_super_data_t * super_data, GError ** mcerror)
|
||||
sftpfs_internal_waitsocket (sftpfs_super_t * super, GError ** mcerror)
|
||||
{
|
||||
struct timeval timeout = { 10, 0 };
|
||||
fd_set fd;
|
||||
@ -78,10 +78,10 @@ sftpfs_internal_waitsocket (sftpfs_super_data_t * super_data, GError ** mcerror)
|
||||
mc_return_val_if_error (mcerror, -1);
|
||||
|
||||
FD_ZERO (&fd);
|
||||
FD_SET (super_data->socket_handle, &fd);
|
||||
FD_SET (super->socket_handle, &fd);
|
||||
|
||||
/* now make sure we wait in the correct direction */
|
||||
dir = libssh2_session_block_directions (super_data->session);
|
||||
dir = libssh2_session_block_directions (super->session);
|
||||
|
||||
if ((dir & LIBSSH2_SESSION_BLOCK_INBOUND) != 0)
|
||||
readfd = &fd;
|
||||
@ -89,7 +89,7 @@ sftpfs_internal_waitsocket (sftpfs_super_data_t * super_data, GError ** mcerror)
|
||||
if ((dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) != 0)
|
||||
writefd = &fd;
|
||||
|
||||
ret = select (super_data->socket_handle + 1, readfd, writefd, NULL, &timeout);
|
||||
ret = select (super->socket_handle + 1, readfd, writefd, NULL, &timeout);
|
||||
if (ret < 0)
|
||||
{
|
||||
int my_errno = errno;
|
||||
@ -104,22 +104,22 @@ sftpfs_internal_waitsocket (sftpfs_super_data_t * super_data, GError ** mcerror)
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static gboolean
|
||||
sftpfs_op_init (sftpfs_super_data_t ** super_data, const vfs_path_element_t ** path_element,
|
||||
sftpfs_op_init (sftpfs_super_t ** super, const vfs_path_element_t ** path_element,
|
||||
const vfs_path_t * vpath, GError ** mcerror)
|
||||
{
|
||||
struct vfs_s_super *super = NULL;
|
||||
struct vfs_s_super *lc_super = NULL;
|
||||
|
||||
mc_return_val_if_error (mcerror, FALSE);
|
||||
|
||||
if (vfs_s_get_path (vpath, &super, 0) == NULL)
|
||||
if (vfs_s_get_path (vpath, &lc_super, 0) == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (super == NULL)
|
||||
if (lc_super == NULL)
|
||||
return FALSE;
|
||||
|
||||
*super_data = (sftpfs_super_data_t *) super->data;
|
||||
*super = SFTP_SUPER (lc_super);
|
||||
|
||||
if ((*super_data)->sftp_session == NULL)
|
||||
if ((*super)->sftp_session == NULL)
|
||||
return FALSE;
|
||||
|
||||
*path_element = vfs_path_get_by_index (vpath, -1);
|
||||
@ -130,13 +130,13 @@ sftpfs_op_init (sftpfs_super_data_t ** super_data, const vfs_path_element_t ** p
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
sftpfs_stat_init (sftpfs_super_data_t ** super_data, const vfs_path_element_t ** path_element,
|
||||
sftpfs_stat_init (sftpfs_super_t ** super, const vfs_path_element_t ** path_element,
|
||||
const vfs_path_t * vpath, GError ** mcerror, int stat_type,
|
||||
LIBSSH2_SFTP_ATTRIBUTES * attrs)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (!sftpfs_op_init (super_data, path_element, vpath, mcerror))
|
||||
if (!sftpfs_op_init (super, path_element, vpath, mcerror))
|
||||
return -1;
|
||||
|
||||
do
|
||||
@ -146,18 +146,18 @@ sftpfs_stat_init (sftpfs_super_data_t ** super_data, const vfs_path_element_t **
|
||||
|
||||
fixfname = sftpfs_fix_filename ((*path_element)->path, &fixfname_len);
|
||||
|
||||
res = libssh2_sftp_stat_ex ((*super_data)->sftp_session, fixfname, fixfname_len,
|
||||
res = libssh2_sftp_stat_ex ((*super)->sftp_session, fixfname, fixfname_len,
|
||||
stat_type, attrs);
|
||||
if (res >= 0)
|
||||
break;
|
||||
|
||||
if (sftpfs_is_sftp_error ((*super_data)->sftp_session, res, LIBSSH2_FX_PERMISSION_DENIED))
|
||||
if (sftpfs_is_sftp_error ((*super)->sftp_session, res, LIBSSH2_FX_PERMISSION_DENIED))
|
||||
return -EACCES;
|
||||
|
||||
if (sftpfs_is_sftp_error ((*super_data)->sftp_session, res, LIBSSH2_FX_NO_SUCH_FILE))
|
||||
if (sftpfs_is_sftp_error ((*super)->sftp_session, res, LIBSSH2_FX_NO_SUCH_FILE))
|
||||
return -ENOENT;
|
||||
|
||||
if (!sftpfs_waitsocket (*super_data, res, mcerror))
|
||||
if (!sftpfs_waitsocket (*super, res, mcerror))
|
||||
return -1;
|
||||
}
|
||||
while (res == LIBSSH2_ERROR_EAGAIN);
|
||||
@ -170,15 +170,15 @@ sftpfs_stat_init (sftpfs_super_data_t ** super_data, const vfs_path_element_t **
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
gboolean
|
||||
sftpfs_waitsocket (sftpfs_super_data_t * super_data, int sftp_res, GError ** mcerror)
|
||||
sftpfs_waitsocket (sftpfs_super_t * super, int sftp_res, GError ** mcerror)
|
||||
{
|
||||
if (sftp_res != LIBSSH2_ERROR_EAGAIN)
|
||||
{
|
||||
sftpfs_ssherror_to_gliberror (super_data, sftp_res, mcerror);
|
||||
sftpfs_ssherror_to_gliberror (super, sftp_res, mcerror);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sftpfs_internal_waitsocket (super_data, mcerror);
|
||||
sftpfs_internal_waitsocket (super, mcerror);
|
||||
|
||||
return (mcerror == NULL || *mcerror == NULL);
|
||||
}
|
||||
@ -196,23 +196,23 @@ sftpfs_is_sftp_error (LIBSSH2_SFTP * sftp_session, int sftp_res, int sftp_error)
|
||||
/**
|
||||
* Convert libssh error to GError object.
|
||||
*
|
||||
* @param super_data extra data for SFTP connection
|
||||
* @param super extra data for SFTP connection
|
||||
* @param libssh_errno errno from libssh
|
||||
* @param mcerror pointer to the error object
|
||||
*/
|
||||
|
||||
void
|
||||
sftpfs_ssherror_to_gliberror (sftpfs_super_data_t * super_data, int libssh_errno, GError ** mcerror)
|
||||
sftpfs_ssherror_to_gliberror (sftpfs_super_t * super, int libssh_errno, GError ** mcerror)
|
||||
{
|
||||
char *err = NULL;
|
||||
int err_len;
|
||||
|
||||
mc_return_if_error (mcerror);
|
||||
|
||||
libssh2_session_last_error (super_data->session, &err, &err_len, 1);
|
||||
if (libssh_errno == LIBSSH2_ERROR_SFTP_PROTOCOL && super_data->sftp_session != NULL)
|
||||
libssh2_session_last_error (super->session, &err, &err_len, 1);
|
||||
if (libssh_errno == LIBSSH2_ERROR_SFTP_PROTOCOL && super->sftp_session != NULL)
|
||||
mc_propagate_error (mcerror, libssh_errno, "%s %lu", err,
|
||||
libssh2_sftp_last_error (super_data->sftp_session));
|
||||
libssh2_sftp_last_error (super->sftp_session));
|
||||
else
|
||||
mc_propagate_error (mcerror, libssh_errno, "%s", err);
|
||||
g_free (err);
|
||||
@ -280,12 +280,12 @@ sftpfs_attr_to_stat (const LIBSSH2_SFTP_ATTRIBUTES * attrs, struct stat *s)
|
||||
int
|
||||
sftpfs_lstat (const vfs_path_t * vpath, struct stat *buf, GError ** mcerror)
|
||||
{
|
||||
sftpfs_super_data_t *super_data = NULL;
|
||||
sftpfs_super_t *super = NULL;
|
||||
const vfs_path_element_t *path_element = NULL;
|
||||
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
||||
int res;
|
||||
|
||||
res = sftpfs_stat_init (&super_data, &path_element, vpath, mcerror, LIBSSH2_SFTP_LSTAT, &attrs);
|
||||
res = sftpfs_stat_init (&super, &path_element, vpath, mcerror, LIBSSH2_SFTP_LSTAT, &attrs);
|
||||
if (res >= 0)
|
||||
{
|
||||
sftpfs_attr_to_stat (&attrs, buf);
|
||||
@ -308,12 +308,12 @@ sftpfs_lstat (const vfs_path_t * vpath, struct stat *buf, GError ** mcerror)
|
||||
int
|
||||
sftpfs_stat (const vfs_path_t * vpath, struct stat *buf, GError ** mcerror)
|
||||
{
|
||||
sftpfs_super_data_t *super_data = NULL;
|
||||
sftpfs_super_t *super = NULL;
|
||||
const vfs_path_element_t *path_element = NULL;
|
||||
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
||||
int res;
|
||||
|
||||
res = sftpfs_stat_init (&super_data, &path_element, vpath, mcerror, LIBSSH2_SFTP_STAT, &attrs);
|
||||
res = sftpfs_stat_init (&super, &path_element, vpath, mcerror, LIBSSH2_SFTP_STAT, &attrs);
|
||||
if (res >= 0)
|
||||
{
|
||||
buf->st_nlink = 1;
|
||||
@ -338,11 +338,11 @@ sftpfs_stat (const vfs_path_t * vpath, struct stat *buf, GError ** mcerror)
|
||||
int
|
||||
sftpfs_readlink (const vfs_path_t * vpath, char *buf, size_t size, GError ** mcerror)
|
||||
{
|
||||
sftpfs_super_data_t *super_data = NULL;
|
||||
sftpfs_super_t *super = NULL;
|
||||
const vfs_path_element_t *path_element = NULL;
|
||||
int res;
|
||||
|
||||
if (!sftpfs_op_init (&super_data, &path_element, vpath, mcerror))
|
||||
if (!sftpfs_op_init (&super, &path_element, vpath, mcerror))
|
||||
return -1;
|
||||
|
||||
do
|
||||
@ -353,12 +353,12 @@ sftpfs_readlink (const vfs_path_t * vpath, char *buf, size_t size, GError ** mce
|
||||
fixfname = sftpfs_fix_filename (path_element->path, &fixfname_len);
|
||||
|
||||
res =
|
||||
libssh2_sftp_symlink_ex (super_data->sftp_session, fixfname, fixfname_len, buf, size,
|
||||
libssh2_sftp_symlink_ex (super->sftp_session, fixfname, fixfname_len, buf, size,
|
||||
LIBSSH2_SFTP_READLINK);
|
||||
if (res >= 0)
|
||||
break;
|
||||
|
||||
if (!sftpfs_waitsocket (super_data, res, mcerror))
|
||||
if (!sftpfs_waitsocket (super, res, mcerror))
|
||||
return -1;
|
||||
}
|
||||
while (res == LIBSSH2_ERROR_EAGAIN);
|
||||
@ -379,14 +379,14 @@ sftpfs_readlink (const vfs_path_t * vpath, char *buf, size_t size, GError ** mce
|
||||
int
|
||||
sftpfs_symlink (const vfs_path_t * vpath1, const vfs_path_t * vpath2, GError ** mcerror)
|
||||
{
|
||||
sftpfs_super_data_t *super_data = NULL;
|
||||
sftpfs_super_t *super = NULL;
|
||||
const vfs_path_element_t *path_element1;
|
||||
const vfs_path_element_t *path_element2 = NULL;
|
||||
char *tmp_path;
|
||||
unsigned int tmp_path_len;
|
||||
int res;
|
||||
|
||||
if (!sftpfs_op_init (&super_data, &path_element2, vpath2, mcerror))
|
||||
if (!sftpfs_op_init (&super, &path_element2, vpath2, mcerror))
|
||||
return -1;
|
||||
|
||||
tmp_path = (char *) sftpfs_fix_filename (path_element2->path, &tmp_path_len);
|
||||
@ -402,12 +402,12 @@ sftpfs_symlink (const vfs_path_t * vpath1, const vfs_path_t * vpath2, GError **
|
||||
fixfname = sftpfs_fix_filename (path_element1->path, &fixfname_len);
|
||||
|
||||
res =
|
||||
libssh2_sftp_symlink_ex (super_data->sftp_session, fixfname, fixfname_len, tmp_path,
|
||||
libssh2_sftp_symlink_ex (super->sftp_session, fixfname, fixfname_len, tmp_path,
|
||||
tmp_path_len, LIBSSH2_SFTP_SYMLINK);
|
||||
if (res >= 0)
|
||||
break;
|
||||
|
||||
if (!sftpfs_waitsocket (super_data, res, mcerror))
|
||||
if (!sftpfs_waitsocket (super, res, mcerror))
|
||||
{
|
||||
g_free (tmp_path);
|
||||
return -1;
|
||||
@ -433,12 +433,12 @@ sftpfs_symlink (const vfs_path_t * vpath1, const vfs_path_t * vpath2, GError **
|
||||
int
|
||||
sftpfs_utime (const vfs_path_t * vpath, time_t atime, time_t mtime, GError ** mcerror)
|
||||
{
|
||||
sftpfs_super_data_t *super_data = NULL;
|
||||
sftpfs_super_t *super = NULL;
|
||||
const vfs_path_element_t *path_element = NULL;
|
||||
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
||||
int res;
|
||||
|
||||
res = sftpfs_stat_init (&super_data, &path_element, vpath, mcerror, LIBSSH2_SFTP_LSTAT, &attrs);
|
||||
res = sftpfs_stat_init (&super, &path_element, vpath, mcerror, LIBSSH2_SFTP_LSTAT, &attrs);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
@ -453,21 +453,21 @@ sftpfs_utime (const vfs_path_t * vpath, time_t atime, time_t mtime, GError ** mc
|
||||
fixfname = sftpfs_fix_filename (path_element->path, &fixfname_len);
|
||||
|
||||
res =
|
||||
libssh2_sftp_stat_ex (super_data->sftp_session, fixfname, fixfname_len,
|
||||
libssh2_sftp_stat_ex (super->sftp_session, fixfname, fixfname_len,
|
||||
LIBSSH2_SFTP_SETSTAT, &attrs);
|
||||
if (res >= 0)
|
||||
break;
|
||||
|
||||
if (sftpfs_is_sftp_error (super_data->sftp_session, res, LIBSSH2_FX_NO_SUCH_FILE))
|
||||
if (sftpfs_is_sftp_error (super->sftp_session, res, LIBSSH2_FX_NO_SUCH_FILE))
|
||||
return -ENOENT;
|
||||
|
||||
if (sftpfs_is_sftp_error (super_data->sftp_session, res, LIBSSH2_FX_FAILURE))
|
||||
if (sftpfs_is_sftp_error (super->sftp_session, res, LIBSSH2_FX_FAILURE))
|
||||
{
|
||||
res = 0; /* need something like ftpfs_ignore_chattr_errors */
|
||||
break;
|
||||
}
|
||||
|
||||
if (!sftpfs_waitsocket (super_data, res, mcerror))
|
||||
if (!sftpfs_waitsocket (super, res, mcerror))
|
||||
return -1;
|
||||
}
|
||||
while (res == LIBSSH2_ERROR_EAGAIN);
|
||||
@ -488,12 +488,12 @@ sftpfs_utime (const vfs_path_t * vpath, time_t atime, time_t mtime, GError ** mc
|
||||
int
|
||||
sftpfs_chmod (const vfs_path_t * vpath, mode_t mode, GError ** mcerror)
|
||||
{
|
||||
sftpfs_super_data_t *super_data = NULL;
|
||||
sftpfs_super_t *super = NULL;
|
||||
const vfs_path_element_t *path_element = NULL;
|
||||
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
||||
int res;
|
||||
|
||||
res = sftpfs_stat_init (&super_data, &path_element, vpath, mcerror, LIBSSH2_SFTP_LSTAT, &attrs);
|
||||
res = sftpfs_stat_init (&super, &path_element, vpath, mcerror, LIBSSH2_SFTP_LSTAT, &attrs);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
@ -507,21 +507,21 @@ sftpfs_chmod (const vfs_path_t * vpath, mode_t mode, GError ** mcerror)
|
||||
fixfname = sftpfs_fix_filename (path_element->path, &fixfname_len);
|
||||
|
||||
res =
|
||||
libssh2_sftp_stat_ex (super_data->sftp_session, fixfname, fixfname_len,
|
||||
libssh2_sftp_stat_ex (super->sftp_session, fixfname, fixfname_len,
|
||||
LIBSSH2_SFTP_SETSTAT, &attrs);
|
||||
if (res >= 0)
|
||||
break;
|
||||
|
||||
if (sftpfs_is_sftp_error (super_data->sftp_session, res, LIBSSH2_FX_NO_SUCH_FILE))
|
||||
if (sftpfs_is_sftp_error (super->sftp_session, res, LIBSSH2_FX_NO_SUCH_FILE))
|
||||
return -ENOENT;
|
||||
|
||||
if (sftpfs_is_sftp_error (super_data->sftp_session, res, LIBSSH2_FX_FAILURE))
|
||||
if (sftpfs_is_sftp_error (super->sftp_session, res, LIBSSH2_FX_FAILURE))
|
||||
{
|
||||
res = 0; /* need something like ftpfs_ignore_chattr_errors */
|
||||
break;
|
||||
}
|
||||
|
||||
if (!sftpfs_waitsocket (super_data, res, mcerror))
|
||||
if (!sftpfs_waitsocket (super, res, mcerror))
|
||||
return -1;
|
||||
}
|
||||
while (res == LIBSSH2_ERROR_EAGAIN);
|
||||
@ -541,11 +541,11 @@ sftpfs_chmod (const vfs_path_t * vpath, mode_t mode, GError ** mcerror)
|
||||
int
|
||||
sftpfs_unlink (const vfs_path_t * vpath, GError ** mcerror)
|
||||
{
|
||||
sftpfs_super_data_t *super_data = NULL;
|
||||
sftpfs_super_t *super = NULL;
|
||||
const vfs_path_element_t *path_element = NULL;
|
||||
int res;
|
||||
|
||||
if (!sftpfs_op_init (&super_data, &path_element, vpath, mcerror))
|
||||
if (!sftpfs_op_init (&super, &path_element, vpath, mcerror))
|
||||
return -1;
|
||||
|
||||
do
|
||||
@ -555,11 +555,11 @@ sftpfs_unlink (const vfs_path_t * vpath, GError ** mcerror)
|
||||
|
||||
fixfname = sftpfs_fix_filename (path_element->path, &fixfname_len);
|
||||
|
||||
res = libssh2_sftp_unlink_ex (super_data->sftp_session, fixfname, fixfname_len);
|
||||
res = libssh2_sftp_unlink_ex (super->sftp_session, fixfname, fixfname_len);
|
||||
if (res >= 0)
|
||||
break;
|
||||
|
||||
if (!sftpfs_waitsocket (super_data, res, mcerror))
|
||||
if (!sftpfs_waitsocket (super, res, mcerror))
|
||||
return -1;
|
||||
}
|
||||
while (res == LIBSSH2_ERROR_EAGAIN);
|
||||
@ -580,14 +580,14 @@ sftpfs_unlink (const vfs_path_t * vpath, GError ** mcerror)
|
||||
int
|
||||
sftpfs_rename (const vfs_path_t * vpath1, const vfs_path_t * vpath2, GError ** mcerror)
|
||||
{
|
||||
sftpfs_super_data_t *super_data = NULL;
|
||||
sftpfs_super_t *super = NULL;
|
||||
const vfs_path_element_t *path_element1;
|
||||
const vfs_path_element_t *path_element2 = NULL;
|
||||
char *tmp_path;
|
||||
unsigned int tmp_path_len;
|
||||
int res;
|
||||
|
||||
if (!sftpfs_op_init (&super_data, &path_element2, vpath2, mcerror))
|
||||
if (!sftpfs_op_init (&super, &path_element2, vpath2, mcerror))
|
||||
return -1;
|
||||
|
||||
tmp_path = (char *) sftpfs_fix_filename (path_element2->path, &tmp_path_len);
|
||||
@ -603,12 +603,12 @@ sftpfs_rename (const vfs_path_t * vpath1, const vfs_path_t * vpath2, GError ** m
|
||||
fixfname = sftpfs_fix_filename (path_element1->path, &fixfname_len);
|
||||
|
||||
res =
|
||||
libssh2_sftp_rename_ex (super_data->sftp_session, fixfname, fixfname_len, tmp_path,
|
||||
libssh2_sftp_rename_ex (super->sftp_session, fixfname, fixfname_len, tmp_path,
|
||||
tmp_path_len, LIBSSH2_SFTP_SYMLINK);
|
||||
if (res >= 0)
|
||||
break;
|
||||
|
||||
if (!sftpfs_waitsocket (super_data, res, mcerror))
|
||||
if (!sftpfs_waitsocket (super, res, mcerror))
|
||||
{
|
||||
g_free (tmp_path);
|
||||
return -1;
|
||||
|
@ -21,6 +21,8 @@
|
||||
#define LIBSSH2_INVALID_SOCKET -1
|
||||
#endif
|
||||
|
||||
#define SFTP_SUPER(super) ((sftpfs_super_t *) (super))
|
||||
|
||||
/*** enums ***************************************************************************************/
|
||||
|
||||
typedef enum
|
||||
@ -35,6 +37,8 @@ typedef enum
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct vfs_s_super base;
|
||||
|
||||
sftpfs_auth_type_t auth_type;
|
||||
sftpfs_auth_type_t config_auth_type;
|
||||
|
||||
@ -49,27 +53,24 @@ typedef struct
|
||||
int socket_handle;
|
||||
const char *fingerprint;
|
||||
vfs_path_element_t *original_connection_info;
|
||||
} sftpfs_super_data_t;
|
||||
} sftpfs_super_t;
|
||||
|
||||
/*** global variables defined in .c file *********************************************************/
|
||||
|
||||
extern GString *sftpfs_filename_buffer;
|
||||
extern struct vfs_class sftpfs_class;
|
||||
extern struct vfs_s_subclass sftpfs_subclass;
|
||||
extern struct vfs_class *sftpfs_class;
|
||||
|
||||
/*** declarations of public functions ************************************************************/
|
||||
|
||||
void sftpfs_init_class (void);
|
||||
void sftpfs_init_subclass (void);
|
||||
void sftpfs_init_class_callbacks (void);
|
||||
void sftpfs_init_subclass_callbacks (void);
|
||||
void sftpfs_init_config_variables_patterns (void);
|
||||
void sftpfs_deinit_config_variables_patterns (void);
|
||||
|
||||
gboolean sftpfs_is_sftp_error (LIBSSH2_SFTP * sftp_session, int sftp_res, int sftp_error);
|
||||
void sftpfs_ssherror_to_gliberror (sftpfs_super_data_t * super_data, int libssh_errno,
|
||||
GError ** mcerror);
|
||||
gboolean sftpfs_waitsocket (sftpfs_super_data_t * super_data, int sftp_res, GError ** mcerror);
|
||||
void sftpfs_ssherror_to_gliberror (sftpfs_super_t * super, int libssh_errno, GError ** mcerror);
|
||||
gboolean sftpfs_waitsocket (sftpfs_super_t * super, int sftp_res, GError ** mcerror);
|
||||
|
||||
const char *sftpfs_fix_filename (const char *file_name, unsigned int *length);
|
||||
void sftpfs_attr_to_stat (const LIBSSH2_SFTP_ATTRIBUTES * attrs, struct stat *s);
|
||||
@ -87,21 +88,21 @@ int sftpfs_open_connection (struct vfs_s_super *super, GError ** mcerror);
|
||||
void sftpfs_close_connection (struct vfs_s_super *super, const char *shutdown_message,
|
||||
GError ** mcerror);
|
||||
|
||||
vfs_file_handler_t *sftpfs_fh_new (struct vfs_s_inode *ino, gboolean changed);
|
||||
|
||||
void *sftpfs_opendir (const vfs_path_t * vpath, GError ** mcerror);
|
||||
void *sftpfs_readdir (void *data, GError ** mcerror);
|
||||
int sftpfs_closedir (void *data, GError ** mcerror);
|
||||
int sftpfs_mkdir (const vfs_path_t * vpath, mode_t mode, GError ** mcerror);
|
||||
int sftpfs_rmdir (const vfs_path_t * vpath, GError ** mcerror);
|
||||
|
||||
gboolean sftpfs_open_file (vfs_file_handler_t * file_handler, int flags, mode_t mode,
|
||||
gboolean sftpfs_open_file (vfs_file_handler_t * fh, int flags, mode_t mode, GError ** mcerror);
|
||||
ssize_t sftpfs_read_file (vfs_file_handler_t * fh, char *buffer, size_t count, GError ** mcerror);
|
||||
ssize_t sftpfs_write_file (vfs_file_handler_t * fh, const char *buffer, size_t count,
|
||||
GError ** mcerror);
|
||||
ssize_t sftpfs_read_file (vfs_file_handler_t * file_handler, char *buffer, size_t count,
|
||||
GError ** mcerror);
|
||||
ssize_t sftpfs_write_file (vfs_file_handler_t * file_handler, const char *buffer, size_t count,
|
||||
GError ** mcerror);
|
||||
int sftpfs_close_file (vfs_file_handler_t * file_handler, GError ** mcerror);
|
||||
int sftpfs_close_file (vfs_file_handler_t * fh, GError ** mcerror);
|
||||
int sftpfs_fstat (void *data, struct stat *buf, GError ** mcerror);
|
||||
off_t sftpfs_lseek (vfs_file_handler_t * file_handler, off_t offset, int whence, GError ** mcerror);
|
||||
off_t sftpfs_lseek (vfs_file_handler_t * fh, off_t offset, int whence, GError ** mcerror);
|
||||
|
||||
/*** inline functions ****************************************************************************/
|
||||
|
||||
|
@ -36,8 +36,6 @@
|
||||
|
||||
/*** global variables ****************************************************************************/
|
||||
|
||||
struct vfs_class sftpfs_class;
|
||||
|
||||
/*** file scope macro definitions ****************************************************************/
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
@ -95,7 +93,7 @@ sftpfs_cb_done (struct vfs_class *me)
|
||||
static void *
|
||||
sftpfs_cb_open (const vfs_path_t * vpath, int flags, mode_t mode)
|
||||
{
|
||||
vfs_file_handler_t *file_handler;
|
||||
vfs_file_handler_t *fh;
|
||||
const vfs_path_element_t *path_element;
|
||||
struct vfs_s_super *super;
|
||||
const char *path_super;
|
||||
@ -145,25 +143,19 @@ sftpfs_cb_open (const vfs_path_t * vpath, int flags, mode_t mode)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
file_handler = g_new0 (vfs_file_handler_t, 1);
|
||||
file_handler->pos = 0;
|
||||
file_handler->ino = path_inode;
|
||||
file_handler->handle = -1;
|
||||
file_handler->changed = is_changed;
|
||||
file_handler->linear = LS_NOT_LINEAR;
|
||||
file_handler->data = NULL;
|
||||
fh = sftpfs_fh_new (path_inode, is_changed);
|
||||
|
||||
if (!sftpfs_open_file (file_handler, flags, mode, &mcerror))
|
||||
if (!sftpfs_open_file (fh, flags, mode, &mcerror))
|
||||
{
|
||||
mc_error_message (&mcerror, NULL);
|
||||
g_free (file_handler);
|
||||
g_free (fh);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vfs_rmstamp (path_element->class, (vfsid) super);
|
||||
super->fd_usage++;
|
||||
file_handler->ino->st.st_nlink++;
|
||||
return file_handler;
|
||||
fh->ino->st.st_nlink++;
|
||||
return fh;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -440,7 +432,7 @@ sftpfs_cb_read (void *data, char *buffer, size_t count)
|
||||
{
|
||||
int rc;
|
||||
GError *mcerror = NULL;
|
||||
vfs_file_handler_t *fh = (vfs_file_handler_t *) data;
|
||||
vfs_file_handler_t *fh = VFS_FILE_HANDLER (data);
|
||||
|
||||
if (tty_got_interrupt ())
|
||||
{
|
||||
@ -468,7 +460,7 @@ sftpfs_cb_write (void *data, const char *buf, size_t nbyte)
|
||||
{
|
||||
int rc;
|
||||
GError *mcerror = NULL;
|
||||
vfs_file_handler_t *fh = (vfs_file_handler_t *) data;
|
||||
vfs_file_handler_t *fh = VFS_FILE_HANDLER (data);
|
||||
|
||||
rc = sftpfs_write_file (fh, buf, nbyte, &mcerror);
|
||||
mc_error_message (&mcerror, NULL);
|
||||
@ -488,23 +480,20 @@ sftpfs_cb_close (void *data)
|
||||
{
|
||||
int rc;
|
||||
GError *mcerror = NULL;
|
||||
struct vfs_s_super *super;
|
||||
vfs_file_handler_t *file_handler = (vfs_file_handler_t *) data;
|
||||
|
||||
super = file_handler->ino->super;
|
||||
struct vfs_s_super *super = VFS_FILE_HANDLER_SUPER (data);
|
||||
vfs_file_handler_t *fh = VFS_FILE_HANDLER (data);
|
||||
|
||||
super->fd_usage--;
|
||||
if (super->fd_usage == 0)
|
||||
vfs_stamp_create (&sftpfs_class, super);
|
||||
vfs_stamp_create (sftpfs_class, super);
|
||||
|
||||
rc = sftpfs_close_file (file_handler, &mcerror);
|
||||
rc = sftpfs_close_file (fh, &mcerror);
|
||||
mc_error_message (&mcerror, NULL);
|
||||
|
||||
if (file_handler->handle != -1)
|
||||
close (file_handler->handle);
|
||||
if (fh->handle != -1)
|
||||
close (fh->handle);
|
||||
|
||||
vfs_s_free_inode (&sftpfs_class, file_handler->ino);
|
||||
g_free (file_handler);
|
||||
vfs_s_free_inode (sftpfs_class, fh->ino);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -582,10 +571,10 @@ static off_t
|
||||
sftpfs_cb_lseek (void *data, off_t offset, int whence)
|
||||
{
|
||||
off_t ret_offset;
|
||||
vfs_file_handler_t *file_handler = (vfs_file_handler_t *) data;
|
||||
vfs_file_handler_t *fh = VFS_FILE_HANDLER (data);
|
||||
GError *mcerror = NULL;
|
||||
|
||||
ret_offset = sftpfs_lseek (file_handler, offset, whence, &mcerror);
|
||||
ret_offset = sftpfs_lseek (fh, offset, whence, &mcerror);
|
||||
mc_error_message (&mcerror, NULL);
|
||||
return ret_offset;
|
||||
}
|
||||
@ -684,50 +673,36 @@ sftpfs_cb_fill_names (struct vfs_class *me, fill_names_f func)
|
||||
void
|
||||
sftpfs_init_class (void)
|
||||
{
|
||||
memset (&sftpfs_class, 0, sizeof (sftpfs_class));
|
||||
sftpfs_class.name = "sftpfs";
|
||||
sftpfs_class.prefix = "sftp";
|
||||
sftpfs_class.flags = VFSF_NOLINKS;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Initialization of VFS class callbacks.
|
||||
*/
|
||||
|
||||
void
|
||||
sftpfs_init_class_callbacks (void)
|
||||
{
|
||||
sftpfs_class.init = sftpfs_cb_init;
|
||||
sftpfs_class.done = sftpfs_cb_done;
|
||||
|
||||
sftpfs_class.fill_names = sftpfs_cb_fill_names;
|
||||
|
||||
sftpfs_class.opendir = sftpfs_cb_opendir;
|
||||
sftpfs_class.readdir = sftpfs_cb_readdir;
|
||||
sftpfs_class.closedir = sftpfs_cb_closedir;
|
||||
sftpfs_class.mkdir = sftpfs_cb_mkdir;
|
||||
sftpfs_class.rmdir = sftpfs_cb_rmdir;
|
||||
|
||||
sftpfs_class.stat = sftpfs_cb_stat;
|
||||
sftpfs_class.lstat = sftpfs_cb_lstat;
|
||||
sftpfs_class.fstat = sftpfs_cb_fstat;
|
||||
sftpfs_class.readlink = sftpfs_cb_readlink;
|
||||
sftpfs_class.symlink = sftpfs_cb_symlink;
|
||||
sftpfs_class.link = sftpfs_cb_link;
|
||||
sftpfs_class.utime = sftpfs_cb_utime;
|
||||
sftpfs_class.mknod = sftpfs_cb_mknod;
|
||||
sftpfs_class.chown = sftpfs_cb_chown;
|
||||
sftpfs_class.chmod = sftpfs_cb_chmod;
|
||||
|
||||
sftpfs_class.open = sftpfs_cb_open;
|
||||
sftpfs_class.read = sftpfs_cb_read;
|
||||
sftpfs_class.write = sftpfs_cb_write;
|
||||
sftpfs_class.close = sftpfs_cb_close;
|
||||
sftpfs_class.lseek = sftpfs_cb_lseek;
|
||||
sftpfs_class.unlink = sftpfs_cb_unlink;
|
||||
sftpfs_class.rename = sftpfs_cb_rename;
|
||||
sftpfs_class.ferrno = sftpfs_cb_errno;
|
||||
sftpfs_class->init = sftpfs_cb_init;
|
||||
sftpfs_class->done = sftpfs_cb_done;
|
||||
|
||||
sftpfs_class->fill_names = sftpfs_cb_fill_names;
|
||||
|
||||
sftpfs_class->opendir = sftpfs_cb_opendir;
|
||||
sftpfs_class->readdir = sftpfs_cb_readdir;
|
||||
sftpfs_class->closedir = sftpfs_cb_closedir;
|
||||
sftpfs_class->mkdir = sftpfs_cb_mkdir;
|
||||
sftpfs_class->rmdir = sftpfs_cb_rmdir;
|
||||
|
||||
sftpfs_class->stat = sftpfs_cb_stat;
|
||||
sftpfs_class->lstat = sftpfs_cb_lstat;
|
||||
sftpfs_class->fstat = sftpfs_cb_fstat;
|
||||
sftpfs_class->readlink = sftpfs_cb_readlink;
|
||||
sftpfs_class->symlink = sftpfs_cb_symlink;
|
||||
sftpfs_class->link = sftpfs_cb_link;
|
||||
sftpfs_class->utime = sftpfs_cb_utime;
|
||||
sftpfs_class->mknod = sftpfs_cb_mknod;
|
||||
sftpfs_class->chown = sftpfs_cb_chown;
|
||||
sftpfs_class->chmod = sftpfs_cb_chmod;
|
||||
|
||||
sftpfs_class->open = sftpfs_cb_open;
|
||||
sftpfs_class->read = sftpfs_cb_read;
|
||||
sftpfs_class->write = sftpfs_cb_write;
|
||||
sftpfs_class->close = sftpfs_cb_close;
|
||||
sftpfs_class->lseek = sftpfs_cb_lseek;
|
||||
sftpfs_class->unlink = sftpfs_cb_unlink;
|
||||
sftpfs_class->rename = sftpfs_cb_rename;
|
||||
sftpfs_class->ferrno = sftpfs_cb_errno;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -37,8 +37,6 @@
|
||||
|
||||
/*** global variables ****************************************************************************/
|
||||
|
||||
struct vfs_s_subclass sftpfs_subclass;
|
||||
|
||||
/*** file scope macro definitions ****************************************************************/
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
@ -67,7 +65,7 @@ sftpfs_cb_is_equal_connection (const vfs_path_element_t * vpath_element, struct
|
||||
(void) vpath;
|
||||
(void) cookie;
|
||||
|
||||
orig_connect_info = ((sftpfs_super_data_t *) super->data)->original_connection_info;
|
||||
orig_connect_info = SFTP_SUPER (super)->original_connection_info;
|
||||
|
||||
result = ((g_strcmp0 (vpath_element->host, orig_connect_info->host) == 0)
|
||||
&& (g_strcmp0 (vpath_element->user, orig_connect_info->user) == 0)
|
||||
@ -76,6 +74,23 @@ sftpfs_cb_is_equal_connection (const vfs_path_element_t * vpath_element, struct
|
||||
return result;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static struct vfs_s_super *
|
||||
sftpfs_cb_init_connection (struct vfs_class *me)
|
||||
{
|
||||
sftpfs_super_t *arch;
|
||||
|
||||
arch = g_new0 (sftpfs_super_t, 1);
|
||||
arch->base.me = me;
|
||||
arch->base.name = g_strdup (PATH_SEP_STR);
|
||||
arch->auth_type = NONE;
|
||||
arch->config_auth_type = NONE;
|
||||
arch->socket_handle = LIBSSH2_INVALID_SOCKET;
|
||||
|
||||
return VFS_SUPER (arch);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Callback for opening new connection.
|
||||
@ -91,7 +106,7 @@ sftpfs_cb_open_connection (struct vfs_s_super *super,
|
||||
const vfs_path_t * vpath, const vfs_path_element_t * vpath_element)
|
||||
{
|
||||
GError *mcerror = NULL;
|
||||
sftpfs_super_data_t *sftpfs_super_data;
|
||||
sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
|
||||
int ret_value;
|
||||
|
||||
(void) vpath;
|
||||
@ -103,10 +118,7 @@ sftpfs_cb_open_connection (struct vfs_s_super *super,
|
||||
return -1;
|
||||
}
|
||||
|
||||
sftpfs_super_data = g_new0 (sftpfs_super_data_t, 1);
|
||||
sftpfs_super_data->socket_handle = LIBSSH2_INVALID_SOCKET;
|
||||
sftpfs_super_data->original_connection_info = vfs_path_element_clone (vpath_element);
|
||||
super->data = sftpfs_super_data;
|
||||
sftpfs_super->original_connection_info = vfs_path_element_clone (vpath_element);
|
||||
super->path_element = vfs_path_element_clone (vpath_element);
|
||||
|
||||
sftpfs_fill_connection_data_from_config (super, &mcerror);
|
||||
@ -116,7 +128,6 @@ sftpfs_cb_open_connection (struct vfs_s_super *super,
|
||||
return -1;
|
||||
}
|
||||
|
||||
super->name = g_strdup (PATH_SEP_STR);
|
||||
super->root =
|
||||
vfs_s_new_inode (vpath_element->class, super,
|
||||
vfs_s_default_stat (vpath_element->class, S_IFDIR | 0755));
|
||||
@ -138,18 +149,13 @@ static void
|
||||
sftpfs_cb_close_connection (struct vfs_class *me, struct vfs_s_super *super)
|
||||
{
|
||||
GError *mcerror = NULL;
|
||||
sftpfs_super_data_t *sftpfs_super_data;
|
||||
|
||||
(void) me;
|
||||
sftpfs_close_connection (super, "Normal Shutdown", &mcerror);
|
||||
|
||||
sftpfs_super_data = (sftpfs_super_data_t *) super->data;
|
||||
if (sftpfs_super_data != NULL)
|
||||
vfs_path_element_free (sftpfs_super_data->original_connection_info);
|
||||
vfs_path_element_free (SFTP_SUPER (super)->original_connection_info);
|
||||
|
||||
mc_error_message (&mcerror, NULL);
|
||||
|
||||
g_free (sftpfs_super_data);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -183,22 +189,12 @@ sftpfs_cb_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_
|
||||
|
||||
void
|
||||
sftpfs_init_subclass (void)
|
||||
{
|
||||
memset (&sftpfs_subclass, 0, sizeof (sftpfs_subclass));
|
||||
sftpfs_subclass.flags = VFS_S_REMOTE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Initialization of VFS subclass callbacks.
|
||||
*/
|
||||
|
||||
void
|
||||
sftpfs_init_subclass_callbacks (void)
|
||||
{
|
||||
sftpfs_subclass.archive_same = sftpfs_cb_is_equal_connection;
|
||||
sftpfs_subclass.new_archive = sftpfs_cb_init_connection;
|
||||
sftpfs_subclass.open_archive = sftpfs_cb_open_connection;
|
||||
sftpfs_subclass.free_archive = sftpfs_cb_close_connection;
|
||||
sftpfs_subclass.fh_new = sftpfs_fh_new;
|
||||
sftpfs_subclass.dir_load = sftpfs_cb_dir_load;
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,7 @@
|
||||
#include "helpers/include/includes.h"
|
||||
|
||||
#include "lib/vfs/vfs.h"
|
||||
#include "lib/vfs/xdirentry.h" /* vfs_s_subclass */
|
||||
#include "lib/vfs/netutil.h"
|
||||
#include "lib/vfs/utilvfs.h"
|
||||
|
||||
@ -136,6 +137,7 @@ static gboolean got_user = FALSE;
|
||||
static gboolean got_pass = FALSE;
|
||||
static pstring password;
|
||||
static pstring username;
|
||||
|
||||
static struct vfs_class vfs_smbfs_ops;
|
||||
|
||||
static struct _smbfs_connection
|
||||
@ -2238,9 +2240,7 @@ init_smbfs (void)
|
||||
{
|
||||
tcp_init ();
|
||||
|
||||
vfs_smbfs_ops.name = "smbfs";
|
||||
vfs_smbfs_ops.prefix = "smb";
|
||||
vfs_smbfs_ops.flags = VFSF_NOLINKS;
|
||||
vfs_init_class (&vfs_smbfs_ops, "smbfs", VFS_NOLINKS, "smb");
|
||||
vfs_smbfs_ops.init = smbfs_init;
|
||||
vfs_smbfs_ops.fill_names = smbfs_fill_names;
|
||||
vfs_smbfs_ops.open = smbfs_open;
|
||||
|
@ -61,53 +61,180 @@
|
||||
|
||||
/*** file scope macro definitions ****************************************************************/
|
||||
|
||||
/*
|
||||
* Header block on tape.
|
||||
*
|
||||
* I'm going to use traditional DP naming conventions here.
|
||||
* A "block" is a big chunk of stuff that we do I/O on.
|
||||
* A "record" is a piece of info that we care about.
|
||||
* Typically many "record"s fit into a "block".
|
||||
*/
|
||||
#define RECORDSIZE 512
|
||||
#define NAMSIZ 100
|
||||
#define PREFIX_SIZE 155
|
||||
#define TUNMLEN 32
|
||||
#define TGNMLEN 32
|
||||
#define SPARSE_IN_HDR 4
|
||||
#define TAR_SUPER(super) ((tar_super_t *) (super))
|
||||
|
||||
|
||||
/* tar Header Block, from POSIX 1003.1-1990. */
|
||||
|
||||
/* The magic field is filled with this if uname and gname are valid. */
|
||||
#define TMAGIC "ustar" /* ustar and a null */
|
||||
#define OLDGNU_MAGIC "ustar " /* 7 chars and a null */
|
||||
#define TMAGIC "ustar" /* ustar and a null */
|
||||
|
||||
/* The linkflag defines the type of file */
|
||||
#define LF_LINK '1' /* Link to previously dumped file */
|
||||
#define LF_SYMLINK '2' /* Symbolic link */
|
||||
#define LF_CHR '3' /* Character special file */
|
||||
#define LF_BLK '4' /* Block special file */
|
||||
#define LF_DIR '5' /* Directory */
|
||||
#define LF_FIFO '6' /* FIFO special file */
|
||||
#define LF_EXTHDR 'x' /* pax Extended Header */
|
||||
#define LF_GLOBAL_EXTHDR 'g' /* pax Global Extended Header */
|
||||
/* Further link types may be defined later. */
|
||||
#define XHDTYPE 'x' /* Extended header referring to the next file in the archive */
|
||||
#define XGLTYPE 'g' /* Global extended header */
|
||||
|
||||
/* Note that the standards committee allows only capital A through
|
||||
capital Z for user-defined expansion. This means that defining something
|
||||
as, say '8' is a *bad* idea. */
|
||||
#define LF_DUMPDIR 'D' /* This is a dir entry that contains
|
||||
the names of files that were in
|
||||
the dir at the time the dump
|
||||
was made */
|
||||
#define LF_LONGLINK 'K' /* Identifies the NEXT file on the tape
|
||||
as having a long linkname */
|
||||
#define LF_LONGNAME 'L' /* Identifies the NEXT file on the tape
|
||||
as having a long name. */
|
||||
/* Values used in typeflag field. */
|
||||
#define LNKTYPE '1' /* link */
|
||||
#define SYMTYPE '2' /* symbolic link */
|
||||
#define CHRTYPE '3' /* character special */
|
||||
#define BLKTYPE '4' /* block special */
|
||||
#define DIRTYPE '5' /* directory */
|
||||
#define FIFOTYPE '6' /* FIFO special */
|
||||
|
||||
#define isodigit(c) ( ((c) >= '0') && ((c) <= '7') )
|
||||
|
||||
/* tar Header Block, GNU extensions. */
|
||||
|
||||
/* *BEWARE* *BEWARE* *BEWARE* that the following information is still
|
||||
boiling, and may change. Even if the OLDGNU format description should be
|
||||
accurate, the so-called GNU format is not yet fully decided. It is
|
||||
surely meant to use only extensions allowed by POSIX, but the sketch
|
||||
below repeats some ugliness from the OLDGNU format, which should rather
|
||||
go away. Sparse files should be saved in such a way that they do *not*
|
||||
require two passes at archive creation time. Huge files get some POSIX
|
||||
fields to overflow, alternate solutions have to be sought for this. */
|
||||
|
||||
|
||||
/* Sparse files are not supported in POSIX ustar format. For sparse files
|
||||
with a POSIX header, a GNU extra header is provided which holds overall
|
||||
sparse information and a few sparse descriptors. When an old GNU header
|
||||
replaces both the POSIX header and the GNU extra header, it holds some
|
||||
sparse descriptors too. Whether POSIX or not, if more sparse descriptors
|
||||
are still needed, they are put into as many successive sparse headers as
|
||||
necessary. The following constants tell how many sparse descriptors fit
|
||||
in each kind of header able to hold them. */
|
||||
|
||||
#define SPARSES_IN_EXTRA_HEADER 16
|
||||
#define SPARSES_IN_OLDGNU_HEADER 4
|
||||
#define SPARSES_IN_SPARSE_HEADER 21
|
||||
|
||||
/* OLDGNU_MAGIC uses both magic and version fields, which are contiguous.
|
||||
Found in an archive, it indicates an old GNU header format, which will be
|
||||
hopefully become obsolescent. With OLDGNU_MAGIC, uname and gname are
|
||||
valid, though the header is not truly POSIX conforming. */
|
||||
#define OLDGNU_MAGIC "ustar " /* 7 chars and a null */
|
||||
|
||||
/* The standards committee allows only capital A through capital Z for user-defined expansion. */
|
||||
|
||||
/* This is a dir entry that contains the names of files that were in the
|
||||
dir at the time the dump was made. */
|
||||
#define GNUTYPE_DUMPDIR 'D'
|
||||
|
||||
/* Identifies the *next* file on the tape as having a long linkname. */
|
||||
#define GNUTYPE_LONGLINK 'K'
|
||||
|
||||
/* Identifies the *next* file on the tape as having a long name. */
|
||||
#define GNUTYPE_LONGNAME 'L'
|
||||
|
||||
|
||||
/* tar Header Block, overall structure. */
|
||||
|
||||
/* tar files are made in basic blocks of this size. */
|
||||
#define BLOCKSIZE 512
|
||||
|
||||
|
||||
#define isodigit(c) ( ((c) >= '0') && ((c) <= '7') )
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
|
||||
enum
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
/* POSIX header */
|
||||
struct posix_header
|
||||
{ /* byte offset */
|
||||
char name[100]; /* 0 */
|
||||
char mode[8]; /* 100 */
|
||||
char uid[8]; /* 108 */
|
||||
char gid[8]; /* 116 */
|
||||
char size[12]; /* 124 */
|
||||
char mtime[12]; /* 136 */
|
||||
char chksum[8]; /* 148 */
|
||||
char typeflag; /* 156 */
|
||||
char linkname[100]; /* 157 */
|
||||
char magic[6]; /* 257 */
|
||||
char version[2]; /* 263 */
|
||||
char uname[32]; /* 265 */
|
||||
char gname[32]; /* 297 */
|
||||
char devmajor[8]; /* 329 */
|
||||
char devminor[8]; /* 337 */
|
||||
char prefix[155]; /* 345 */
|
||||
/* 500 */
|
||||
};
|
||||
|
||||
/* Descriptor for a single file hole */
|
||||
struct sparse
|
||||
{ /* byte offset */
|
||||
/* cppcheck-suppress unusedStructMember */
|
||||
char offset[12]; /* 0 */
|
||||
/* cppcheck-suppress unusedStructMember */
|
||||
char numbytes[12]; /* 12 */
|
||||
/* 24 */
|
||||
};
|
||||
|
||||
/* The GNU extra header contains some information GNU tar needs, but not
|
||||
foreseen in POSIX header format. It is only used after a POSIX header
|
||||
(and never with old GNU headers), and immediately follows this POSIX
|
||||
header, when typeflag is a letter rather than a digit, so signaling a GNU
|
||||
extension. */
|
||||
struct extra_header
|
||||
{ /* byte offset */
|
||||
char atime[12]; /* 0 */
|
||||
char ctime[12]; /* 12 */
|
||||
char offset[12]; /* 24 */
|
||||
char realsize[12]; /* 36 */
|
||||
char longnames[4]; /* 48 */
|
||||
char unused_pad1[68]; /* 52 */
|
||||
struct sparse sp[SPARSES_IN_EXTRA_HEADER];
|
||||
/* 120 */
|
||||
char isextended; /* 504 */
|
||||
/* 505 */
|
||||
};
|
||||
|
||||
/* Extension header for sparse files, used immediately after the GNU extra
|
||||
header, and used only if all sparse information cannot fit into that
|
||||
extra header. There might even be many such extension headers, one after
|
||||
the other, until all sparse information has been recorded. */
|
||||
struct sparse_header
|
||||
{ /* byte offset */
|
||||
struct sparse sp[SPARSES_IN_SPARSE_HEADER];
|
||||
/* 0 */
|
||||
char isextended; /* 504 */
|
||||
/* 505 */
|
||||
};
|
||||
|
||||
/* The old GNU format header conflicts with POSIX format in such a way that
|
||||
POSIX archives may fool old GNU tar's, and POSIX tar's might well be
|
||||
fooled by old GNU tar archives. An old GNU format header uses the space
|
||||
used by the prefix field in a POSIX header, and cumulates information
|
||||
normally found in a GNU extra header. With an old GNU tar header, we
|
||||
never see any POSIX header nor GNU extra header. Supplementary sparse
|
||||
headers are allowed, however. */
|
||||
struct oldgnu_header
|
||||
{ /* byte offset */
|
||||
char unused_pad1[345]; /* 0 */
|
||||
char atime[12]; /* 345 */
|
||||
char ctime[12]; /* 357 */
|
||||
char offset[12]; /* 369 */
|
||||
char longnames[4]; /* 381 */
|
||||
char unused_pad2; /* 385 */
|
||||
struct sparse sp[SPARSES_IN_OLDGNU_HEADER];
|
||||
/* 386 */
|
||||
char isextended; /* 482 */
|
||||
char realsize[12]; /* 483 */
|
||||
/* 495 */
|
||||
};
|
||||
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* tar Header Block, overall structure */
|
||||
union block
|
||||
{
|
||||
char buffer[BLOCKSIZE];
|
||||
struct posix_header header;
|
||||
struct extra_header extra_header;
|
||||
struct oldgnu_header oldgnu_header;
|
||||
struct sparse_header sparse_header;
|
||||
};
|
||||
|
||||
enum archive_format
|
||||
{
|
||||
TAR_UNKNOWN = 0,
|
||||
TAR_V7,
|
||||
@ -116,68 +243,6 @@ enum
|
||||
TAR_GNU
|
||||
};
|
||||
|
||||
struct sparse
|
||||
{
|
||||
/* cppcheck-suppress unusedStructMember */
|
||||
char offset[12];
|
||||
/* cppcheck-suppress unusedStructMember */
|
||||
char numbytes[12];
|
||||
};
|
||||
|
||||
union record
|
||||
{
|
||||
char charptr[RECORDSIZE];
|
||||
struct header
|
||||
{
|
||||
char arch_name[NAMSIZ];
|
||||
char mode[8];
|
||||
char uid[8];
|
||||
char gid[8];
|
||||
char size[12];
|
||||
char mtime[12];
|
||||
char chksum[8];
|
||||
char linkflag;
|
||||
char arch_linkname[NAMSIZ];
|
||||
char magic[8];
|
||||
char uname[TUNMLEN];
|
||||
char gname[TGNMLEN];
|
||||
char devmajor[8];
|
||||
char devminor[8];
|
||||
/* The following bytes of the tar header record were originally unused.
|
||||
|
||||
Archives following the ustar specification use almost all of those
|
||||
bytes to support pathnames of 256 characters in length.
|
||||
|
||||
GNU tar archives use the "unused" space to support incremental
|
||||
archives and sparse files. */
|
||||
union unused
|
||||
{
|
||||
char prefix[PREFIX_SIZE];
|
||||
/* GNU extensions to the ustar (POSIX.1-1988) archive format. */
|
||||
struct oldgnu
|
||||
{
|
||||
char atime[12];
|
||||
char ctime[12];
|
||||
/* cppcheck-suppress unusedStructMember */
|
||||
char offset[12];
|
||||
/* cppcheck-suppress unusedStructMember */
|
||||
char longnames[4];
|
||||
/* cppcheck-suppress unusedStructMember */
|
||||
char pad;
|
||||
struct sparse sp[SPARSE_IN_HDR];
|
||||
char isextended;
|
||||
/* cppcheck-suppress unusedStructMember */
|
||||
char realsize[12]; /* true size of the sparse file */
|
||||
} oldgnu;
|
||||
} unused;
|
||||
} header;
|
||||
struct extended_header
|
||||
{
|
||||
struct sparse sp[21];
|
||||
char isextended;
|
||||
} ext_hdr;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STATUS_BADCHECKSUM,
|
||||
@ -188,20 +253,24 @@ typedef enum
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct vfs_s_super base; /* base class */
|
||||
|
||||
int fd;
|
||||
struct stat st;
|
||||
int type; /* Type of the archive */
|
||||
} tar_super_data_t;
|
||||
enum archive_format type; /* Type of the archive */
|
||||
} tar_super_t;
|
||||
|
||||
/*** file scope variables ************************************************************************/
|
||||
|
||||
static struct vfs_class vfs_tarfs_ops;
|
||||
static struct vfs_s_subclass tarfs_subclass;
|
||||
static struct vfs_class *vfs_tarfs_ops = VFS_CLASS (&tarfs_subclass);
|
||||
|
||||
/* As we open one archive at a time, it is safe to have this static */
|
||||
static off_t current_tar_position = 0;
|
||||
|
||||
static union record rec_buf;
|
||||
static union block block_buf;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** file scope functions ************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
@ -235,19 +304,30 @@ tar_from_oct (int digs, const char *where)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static struct vfs_s_super *
|
||||
tar_new_archive (struct vfs_class *me)
|
||||
{
|
||||
tar_super_t *arch;
|
||||
|
||||
arch = g_new0 (tar_super_t, 1);
|
||||
arch->base.me = me;
|
||||
arch->fd = -1;
|
||||
arch->type = TAR_UNKNOWN;
|
||||
|
||||
return VFS_SUPER (arch);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
tar_free_archive (struct vfs_class *me, struct vfs_s_super *archive)
|
||||
{
|
||||
tar_super_t *arch = TAR_SUPER (archive);
|
||||
|
||||
(void) me;
|
||||
|
||||
if (archive->data != NULL)
|
||||
{
|
||||
tar_super_data_t *arch = (tar_super_data_t *) archive->data;
|
||||
|
||||
if (arch->fd != -1)
|
||||
mc_close (arch->fd);
|
||||
g_free (archive->data);
|
||||
}
|
||||
if (arch->fd != -1)
|
||||
mc_close (arch->fd);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -257,7 +337,7 @@ static int
|
||||
tar_open_archive_int (struct vfs_class *me, const vfs_path_t * vpath, struct vfs_s_super *archive)
|
||||
{
|
||||
int result, type;
|
||||
tar_super_data_t *arch;
|
||||
tar_super_t *arch;
|
||||
mode_t mode;
|
||||
struct vfs_s_inode *root;
|
||||
|
||||
@ -269,11 +349,8 @@ tar_open_archive_int (struct vfs_class *me, const vfs_path_t * vpath, struct vfs
|
||||
}
|
||||
|
||||
archive->name = g_strdup (vfs_path_as_str (vpath));
|
||||
archive->data = g_new (tar_super_data_t, 1);
|
||||
arch = (tar_super_data_t *) archive->data;
|
||||
arch = TAR_SUPER (archive);
|
||||
mc_stat (vpath, &arch->st);
|
||||
arch->fd = -1;
|
||||
arch->type = TAR_UNKNOWN;
|
||||
|
||||
/* Find out the method to handle this tar file */
|
||||
type = get_compression_type (result, archive->name);
|
||||
@ -313,7 +390,7 @@ tar_open_archive_int (struct vfs_class *me, const vfs_path_t * vpath, struct vfs
|
||||
root->st.st_mode = mode;
|
||||
root->data_offset = -1;
|
||||
root->st.st_nlink++;
|
||||
root->st.st_dev = MEDATA->rdev++;
|
||||
root->st.st_dev = VFS_SUBCLASS (me)->rdev++;
|
||||
|
||||
archive->root = root;
|
||||
|
||||
@ -322,18 +399,18 @@ tar_open_archive_int (struct vfs_class *me, const vfs_path_t * vpath, struct vfs
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static union record *
|
||||
tar_get_next_record (struct vfs_s_super *archive, int tard)
|
||||
static union block *
|
||||
tar_get_next_block (struct vfs_s_super *archive, int tard)
|
||||
{
|
||||
int n;
|
||||
|
||||
(void) archive;
|
||||
|
||||
n = mc_read (tard, rec_buf.charptr, sizeof (rec_buf.charptr));
|
||||
if (n != sizeof (rec_buf.charptr))
|
||||
n = mc_read (tard, block_buf.buffer, sizeof (block_buf.buffer));
|
||||
if (n != sizeof (block_buf.buffer))
|
||||
return NULL; /* An error has occurred */
|
||||
current_tar_position += sizeof (rec_buf.charptr);
|
||||
return &rec_buf;
|
||||
current_tar_position += sizeof (block_buf.buffer);
|
||||
return &block_buf;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -343,20 +420,20 @@ tar_skip_n_records (struct vfs_s_super *archive, int tard, size_t n)
|
||||
{
|
||||
(void) archive;
|
||||
|
||||
mc_lseek (tard, n * sizeof (rec_buf.charptr), SEEK_CUR);
|
||||
current_tar_position += n * sizeof (rec_buf.charptr);
|
||||
mc_lseek (tard, n * sizeof (block_buf.buffer), SEEK_CUR);
|
||||
current_tar_position += n * sizeof (block_buf.buffer);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static ReadStatus
|
||||
tar_checksum (const union record *header)
|
||||
tar_checksum (const union block *header)
|
||||
{
|
||||
long recsum;
|
||||
long signed_sum = 0;
|
||||
long sum = 0;
|
||||
int i;
|
||||
const char *p = header->charptr;
|
||||
const char *p = header->buffer;
|
||||
|
||||
recsum = tar_from_oct (8, header->header.chksum);
|
||||
|
||||
@ -381,7 +458,7 @@ tar_checksum (const union record *header)
|
||||
signed_sum += ' ' * sizeof (header->header.chksum);
|
||||
|
||||
/*
|
||||
* This is a zeroed record...whole record is 0's except
|
||||
* This is a zeroed block... whole block is 0's except
|
||||
* for the 8 blanks we faked for the checksum field.
|
||||
*/
|
||||
if (sum == 8 * ' ')
|
||||
@ -395,27 +472,81 @@ tar_checksum (const union record *header)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
tar_fill_stat (struct vfs_s_super *archive, struct stat *st, union record *header, size_t h_size)
|
||||
static size_t
|
||||
tar_decode_header (union block *header, tar_super_t * arch)
|
||||
{
|
||||
tar_super_data_t *arch = (tar_super_data_t *) archive->data;
|
||||
size_t size;
|
||||
|
||||
/*
|
||||
* Try to determine the archive format.
|
||||
*/
|
||||
if (arch->type == TAR_UNKNOWN)
|
||||
{
|
||||
if (strcmp (header->header.magic, TMAGIC) == 0)
|
||||
{
|
||||
if (header->header.typeflag == XGLTYPE)
|
||||
arch->type = TAR_POSIX;
|
||||
else
|
||||
arch->type = TAR_USTAR;
|
||||
}
|
||||
else if (strcmp (header->header.magic, OLDGNU_MAGIC) == 0)
|
||||
arch->type = TAR_GNU;
|
||||
}
|
||||
|
||||
/*
|
||||
* typeflag on BSDI tar (pax) always '\000'
|
||||
*/
|
||||
if (header->header.typeflag == '\000')
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (header->header.name[sizeof (header->header.name) - 1] != '\0')
|
||||
len = sizeof (header->header.name);
|
||||
else
|
||||
len = strlen (header->header.name);
|
||||
|
||||
if (len != 0 && IS_PATH_SEP (header->header.name[len - 1]))
|
||||
header->header.typeflag = DIRTYPE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Good block. Decode file size and return.
|
||||
*/
|
||||
if (header->header.typeflag == LNKTYPE || header->header.typeflag == DIRTYPE)
|
||||
size = 0; /* Links 0 size on tape */
|
||||
else
|
||||
size = tar_from_oct (1 + 12, header->header.size);
|
||||
|
||||
if (header->header.typeflag == GNUTYPE_DUMPDIR)
|
||||
if (arch->type == TAR_UNKNOWN)
|
||||
arch->type = TAR_GNU;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
tar_fill_stat (struct vfs_s_super *archive, struct stat *st, union block *header, size_t h_size)
|
||||
{
|
||||
tar_super_t *arch = TAR_SUPER (archive);
|
||||
|
||||
st->st_mode = tar_from_oct (8, header->header.mode);
|
||||
|
||||
/* Adjust st->st_mode because there are tar-files with
|
||||
* linkflag==LF_SYMLINK and S_ISLNK(mod)==0. I don't
|
||||
* typeflag==SYMTYPE and S_ISLNK(mod)==0. I don't
|
||||
* know about the other modes but I think I cause no new
|
||||
* problem when I adjust them, too. -- Norbert.
|
||||
*/
|
||||
if (header->header.linkflag == LF_DIR || header->header.linkflag == LF_DUMPDIR)
|
||||
if (header->header.typeflag == DIRTYPE || header->header.typeflag == GNUTYPE_DUMPDIR)
|
||||
st->st_mode |= S_IFDIR;
|
||||
else if (header->header.linkflag == LF_SYMLINK)
|
||||
else if (header->header.typeflag == SYMTYPE)
|
||||
st->st_mode |= S_IFLNK;
|
||||
else if (header->header.linkflag == LF_CHR)
|
||||
else if (header->header.typeflag == CHRTYPE)
|
||||
st->st_mode |= S_IFCHR;
|
||||
else if (header->header.linkflag == LF_BLK)
|
||||
else if (header->header.typeflag == BLKTYPE)
|
||||
st->st_mode |= S_IFBLK;
|
||||
else if (header->header.linkflag == LF_FIFO)
|
||||
else if (header->header.typeflag == FIFOTYPE)
|
||||
st->st_mode |= S_IFIFO;
|
||||
else
|
||||
st->st_mode |= S_IFREG;
|
||||
@ -439,10 +570,10 @@ tar_fill_stat (struct vfs_s_super *archive, struct stat *st, union record *heade
|
||||
: tar_from_oct (8,header->header.gid);
|
||||
/* *INDENT-ON* */
|
||||
|
||||
switch (header->header.linkflag)
|
||||
switch (header->header.typeflag)
|
||||
{
|
||||
case LF_BLK:
|
||||
case LF_CHR:
|
||||
case BLKTYPE:
|
||||
case CHRTYPE:
|
||||
#ifdef HAVE_STRUCT_STAT_ST_RDEV
|
||||
st->st_rdev =
|
||||
makedev (tar_from_oct (8, header->header.devmajor),
|
||||
@ -469,8 +600,8 @@ tar_fill_stat (struct vfs_s_super *archive, struct stat *st, union record *heade
|
||||
st->st_ctime = 0;
|
||||
if (arch->type == TAR_GNU)
|
||||
{
|
||||
st->st_atime = tar_from_oct (1 + 12, header->header.unused.oldgnu.atime);
|
||||
st->st_ctime = tar_from_oct (1 + 12, header->header.unused.oldgnu.ctime);
|
||||
st->st_atime = tar_from_oct (1 + 12, header->oldgnu_header.atime);
|
||||
st->st_ctime = tar_from_oct (1 + 12, header->oldgnu_header.ctime);
|
||||
}
|
||||
|
||||
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
|
||||
@ -482,132 +613,89 @@ tar_fill_stat (struct vfs_s_super *archive, struct stat *st, union record *heade
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Return 1 for success, 0 if the checksum is bad, EOF on eof,
|
||||
* 2 for a record full of zeros (EOF marker).
|
||||
* 2 for a block full of zeros (EOF marker).
|
||||
*
|
||||
*/
|
||||
static ReadStatus
|
||||
tar_read_header (struct vfs_class *me, struct vfs_s_super *archive, int tard, size_t * h_size)
|
||||
{
|
||||
tar_super_data_t *arch = (tar_super_data_t *) archive->data;
|
||||
tar_super_t *arch = TAR_SUPER (archive);
|
||||
ReadStatus checksum_status;
|
||||
union record *header;
|
||||
union block *header;
|
||||
static char *next_long_name = NULL, *next_long_link = NULL;
|
||||
|
||||
recurse:
|
||||
|
||||
header = tar_get_next_record (archive, tard);
|
||||
if (NULL == header)
|
||||
return STATUS_EOF;
|
||||
|
||||
checksum_status = tar_checksum (header);
|
||||
if (checksum_status != STATUS_SUCCESS)
|
||||
return checksum_status;
|
||||
|
||||
/*
|
||||
* Try to determine the archive format.
|
||||
*/
|
||||
if (arch->type == TAR_UNKNOWN)
|
||||
while (TRUE)
|
||||
{
|
||||
if (strcmp (header->header.magic, TMAGIC) == 0)
|
||||
header = tar_get_next_block (archive, tard);
|
||||
if (header == NULL)
|
||||
return STATUS_EOF;
|
||||
|
||||
checksum_status = tar_checksum (header);
|
||||
if (checksum_status != STATUS_SUCCESS)
|
||||
return checksum_status;
|
||||
|
||||
*h_size = tar_decode_header (header, arch);
|
||||
|
||||
/* Skip over pax extended header and global extended header records. */
|
||||
if (header->header.typeflag == XHDTYPE || header->header.typeflag == XGLTYPE)
|
||||
{
|
||||
if (header->header.linkflag == LF_GLOBAL_EXTHDR)
|
||||
if (arch->type == TAR_UNKNOWN)
|
||||
arch->type = TAR_POSIX;
|
||||
else
|
||||
arch->type = TAR_USTAR;
|
||||
}
|
||||
else if (strcmp (header->header.magic, OLDGNU_MAGIC) == 0)
|
||||
arch->type = TAR_GNU;
|
||||
}
|
||||
|
||||
/*
|
||||
* linkflag on BSDI tar (pax) always '\000'
|
||||
*/
|
||||
if (header->header.linkflag == '\000')
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (header->header.arch_name[NAMSIZ - 1] != '\0')
|
||||
len = NAMSIZ;
|
||||
else
|
||||
len = strlen (header->header.arch_name);
|
||||
|
||||
if (len != 0 && IS_PATH_SEP (header->header.arch_name[len - 1]))
|
||||
header->header.linkflag = LF_DIR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Good record. Decode file size and return.
|
||||
*/
|
||||
if (header->header.linkflag == LF_LINK || header->header.linkflag == LF_DIR)
|
||||
*h_size = 0; /* Links 0 size on tape */
|
||||
else
|
||||
*h_size = tar_from_oct (1 + 12, header->header.size);
|
||||
|
||||
if (header->header.linkflag == LF_DUMPDIR)
|
||||
{
|
||||
if (arch->type == TAR_UNKNOWN)
|
||||
arch->type = TAR_GNU;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip over pax extended header and global extended
|
||||
* header records.
|
||||
*/
|
||||
if (header->header.linkflag == LF_EXTHDR || header->header.linkflag == LF_GLOBAL_EXTHDR)
|
||||
{
|
||||
if (arch->type == TAR_UNKNOWN)
|
||||
arch->type = TAR_POSIX;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (header->header.linkflag == LF_LONGNAME || header->header.linkflag == LF_LONGLINK)
|
||||
{
|
||||
char **longp;
|
||||
char *bp, *data;
|
||||
off_t size;
|
||||
size_t written;
|
||||
|
||||
if (arch->type == TAR_UNKNOWN)
|
||||
arch->type = TAR_GNU;
|
||||
|
||||
if (*h_size > MC_MAXPATHLEN)
|
||||
{
|
||||
message (D_ERROR, MSG_ERROR, _("Inconsistent tar archive"));
|
||||
return STATUS_BADCHECKSUM;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
longp = ((header->header.linkflag == LF_LONGNAME) ? &next_long_name : &next_long_link);
|
||||
|
||||
g_free (*longp);
|
||||
bp = *longp = g_malloc (*h_size + 1);
|
||||
|
||||
for (size = *h_size; size > 0; size -= written)
|
||||
if (header->header.typeflag == GNUTYPE_LONGNAME
|
||||
|| header->header.typeflag == GNUTYPE_LONGLINK)
|
||||
{
|
||||
data = tar_get_next_record (archive, tard)->charptr;
|
||||
if (data == NULL)
|
||||
char **longp;
|
||||
char *bp, *data;
|
||||
off_t size;
|
||||
size_t written;
|
||||
|
||||
if (arch->type == TAR_UNKNOWN)
|
||||
arch->type = TAR_GNU;
|
||||
|
||||
if (*h_size > MC_MAXPATHLEN)
|
||||
{
|
||||
MC_PTR_FREE (*longp);
|
||||
message (D_ERROR, MSG_ERROR, _("Unexpected EOF on archive file"));
|
||||
message (D_ERROR, MSG_ERROR, _("Inconsistent tar archive"));
|
||||
return STATUS_BADCHECKSUM;
|
||||
}
|
||||
written = RECORDSIZE;
|
||||
if ((off_t) written > size)
|
||||
written = (size_t) size;
|
||||
|
||||
memcpy (bp, data, written);
|
||||
bp += written;
|
||||
}
|
||||
longp = header->header.typeflag == GNUTYPE_LONGNAME ? &next_long_name : &next_long_link;
|
||||
|
||||
if (bp - *longp == MC_MAXPATHLEN && bp[-1] != '\0')
|
||||
{
|
||||
MC_PTR_FREE (*longp);
|
||||
message (D_ERROR, MSG_ERROR, _("Inconsistent tar archive"));
|
||||
return STATUS_BADCHECKSUM;
|
||||
g_free (*longp);
|
||||
bp = *longp = g_malloc (*h_size + 1);
|
||||
|
||||
for (size = *h_size; size > 0; size -= written)
|
||||
{
|
||||
data = tar_get_next_block (archive, tard)->buffer;
|
||||
if (data == NULL)
|
||||
{
|
||||
MC_PTR_FREE (*longp);
|
||||
message (D_ERROR, MSG_ERROR, _("Unexpected EOF on archive file"));
|
||||
return STATUS_BADCHECKSUM;
|
||||
}
|
||||
written = BLOCKSIZE;
|
||||
if ((off_t) written > size)
|
||||
written = (size_t) size;
|
||||
|
||||
memcpy (bp, data, written);
|
||||
bp += written;
|
||||
}
|
||||
|
||||
if (bp - *longp == MC_MAXPATHLEN && bp[-1] != '\0')
|
||||
{
|
||||
MC_PTR_FREE (*longp);
|
||||
message (D_ERROR, MSG_ERROR, _("Inconsistent tar archive"));
|
||||
return STATUS_BADCHECKSUM;
|
||||
}
|
||||
|
||||
*bp = '\0';
|
||||
}
|
||||
*bp = 0;
|
||||
goto recurse;
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
||||
{
|
||||
struct stat st;
|
||||
struct vfs_s_entry *entry;
|
||||
@ -618,7 +706,8 @@ tar_read_header (struct vfs_class *me, struct vfs_s_super *archive, int tard, si
|
||||
char *current_file_name, *current_link_name;
|
||||
|
||||
current_link_name =
|
||||
(next_long_link ? next_long_link : g_strndup (header->header.arch_linkname, NAMSIZ));
|
||||
next_long_link != NULL ? next_long_link : g_strndup (header->header.linkname,
|
||||
sizeof (header->header.linkname));
|
||||
len = strlen (current_link_name);
|
||||
if (len > 1 && IS_PATH_SEP (current_link_name[len - 1]))
|
||||
current_link_name[len - 1] = '\0';
|
||||
@ -630,20 +719,20 @@ tar_read_header (struct vfs_class *me, struct vfs_s_super *archive, int tard, si
|
||||
case TAR_POSIX:
|
||||
/* The ustar archive format supports pathnames of upto 256
|
||||
* characters in length. This is achieved by concatenating
|
||||
* the contents of the 'prefix' and 'arch_name' fields like
|
||||
* the contents of the 'prefix' and 'name' fields like
|
||||
* this:
|
||||
*
|
||||
* prefix + path_separator + arch_name
|
||||
* prefix + path_separator + name
|
||||
*
|
||||
* If the 'prefix' field contains an empty string i.e. its
|
||||
* first characters is '\0' the prefix field is ignored.
|
||||
*/
|
||||
if (header->header.unused.prefix[0] != '\0')
|
||||
if (header->header.prefix[0] != '\0')
|
||||
{
|
||||
char *temp_name, *temp_prefix;
|
||||
|
||||
temp_name = g_strndup (header->header.arch_name, NAMSIZ);
|
||||
temp_prefix = g_strndup (header->header.unused.prefix, PREFIX_SIZE);
|
||||
temp_name = g_strndup (header->header.name, sizeof (header->header.name));
|
||||
temp_prefix = g_strndup (header->header.prefix, sizeof (header->header.prefix));
|
||||
current_file_name = g_strconcat (temp_prefix, PATH_SEP_STR,
|
||||
temp_name, (char *) NULL);
|
||||
g_free (temp_name);
|
||||
@ -663,7 +752,7 @@ tar_read_header (struct vfs_class *me, struct vfs_s_super *archive, int tard, si
|
||||
if (next_long_name != NULL)
|
||||
current_file_name = g_strdup (next_long_name);
|
||||
else
|
||||
current_file_name = g_strndup (header->header.arch_name, NAMSIZ);
|
||||
current_file_name = g_strndup (header->header.name, sizeof (header->header.name));
|
||||
}
|
||||
|
||||
canonicalize_pathname (current_file_name);
|
||||
@ -679,7 +768,7 @@ tar_read_header (struct vfs_class *me, struct vfs_s_super *archive, int tard, si
|
||||
}
|
||||
else
|
||||
{
|
||||
*(p++) = 0;
|
||||
*(p++) = '\0';
|
||||
q = current_file_name;
|
||||
}
|
||||
|
||||
@ -690,13 +779,11 @@ tar_read_header (struct vfs_class *me, struct vfs_s_super *archive, int tard, si
|
||||
return STATUS_BADCHECKSUM;
|
||||
}
|
||||
|
||||
if (header->header.linkflag == LF_LINK)
|
||||
if (header->header.typeflag == LNKTYPE)
|
||||
{
|
||||
inode = vfs_s_find_inode (me, archive, current_link_name, LINK_NO_FOLLOW, FL_NONE);
|
||||
if (inode == NULL)
|
||||
{
|
||||
message (D_ERROR, MSG_ERROR, _("Inconsistent tar archive"));
|
||||
}
|
||||
else
|
||||
{
|
||||
entry = vfs_s_new_entry (me, p, inode);
|
||||
@ -709,32 +796,29 @@ tar_read_header (struct vfs_class *me, struct vfs_s_super *archive, int tard, si
|
||||
tar_fill_stat (archive, &st, header, *h_size);
|
||||
if (S_ISDIR (st.st_mode))
|
||||
{
|
||||
entry = MEDATA->find_entry (me, parent, p, LINK_NO_FOLLOW, FL_NONE);
|
||||
if (entry)
|
||||
entry = VFS_SUBCLASS (me)->find_entry (me, parent, p, LINK_NO_FOLLOW, FL_NONE);
|
||||
if (entry != NULL)
|
||||
goto done;
|
||||
}
|
||||
|
||||
inode = vfs_s_new_inode (me, archive, &st);
|
||||
|
||||
inode->data_offset = data_position;
|
||||
if (*current_link_name)
|
||||
{
|
||||
inode->linkname = current_link_name;
|
||||
}
|
||||
else if (current_link_name != next_long_link)
|
||||
{
|
||||
g_free (current_link_name);
|
||||
}
|
||||
entry = vfs_s_new_entry (me, p, inode);
|
||||
|
||||
if (*current_link_name != '\0')
|
||||
inode->linkname = current_link_name;
|
||||
else if (current_link_name != next_long_link)
|
||||
g_free (current_link_name);
|
||||
|
||||
entry = vfs_s_new_entry (me, p, inode);
|
||||
vfs_s_insert_entry (me, parent, entry);
|
||||
g_free (current_file_name);
|
||||
|
||||
done:
|
||||
next_long_link = next_long_name = NULL;
|
||||
|
||||
if (arch->type == TAR_GNU && header->header.unused.oldgnu.isextended)
|
||||
if (arch->type == TAR_GNU && header->oldgnu_header.isextended)
|
||||
{
|
||||
while (tar_get_next_record (archive, tard)->ext_hdr.isextended != 0)
|
||||
while (tar_get_next_block (archive, tard)->sparse_header.isextended != 0)
|
||||
;
|
||||
|
||||
if (inode != NULL)
|
||||
@ -773,7 +857,7 @@ tar_open_archive (struct vfs_s_super *archive, const vfs_path_t * vpath,
|
||||
switch (status)
|
||||
{
|
||||
case STATUS_SUCCESS:
|
||||
tar_skip_n_records (archive, tard, (h_size + RECORDSIZE - 1) / RECORDSIZE);
|
||||
tar_skip_n_records (archive, tard, (h_size + BLOCKSIZE - 1) / BLOCKSIZE);
|
||||
continue;
|
||||
|
||||
/*
|
||||
@ -785,7 +869,7 @@ tar_open_archive (struct vfs_s_super *archive, const vfs_path_t * vpath,
|
||||
case STATUS_BADCHECKSUM:
|
||||
switch (prev_status)
|
||||
{
|
||||
/* Error on first record */
|
||||
/* Error on first block */
|
||||
case STATUS_EOFMARK:
|
||||
{
|
||||
message (D_ERROR, MSG_ERROR, _("%s\ndoesn't look like a tar archive."),
|
||||
@ -849,15 +933,15 @@ tar_super_same (const vfs_path_element_t * vpath_element, struct vfs_s_super *pa
|
||||
return 0;
|
||||
|
||||
/* Has the cached archive been changed on the disk? */
|
||||
if (((tar_super_data_t *) parc->data)->st.st_mtime < archive_stat->st_mtime)
|
||||
if (parc != NULL && TAR_SUPER (parc)->st.st_mtime < archive_stat->st_mtime)
|
||||
{
|
||||
/* Yes, reload! */
|
||||
(*vfs_tarfs_ops.free) ((vfsid) parc);
|
||||
vfs_rmstamp (&vfs_tarfs_ops, (vfsid) parc);
|
||||
vfs_tarfs_ops->free ((vfsid) parc);
|
||||
vfs_rmstamp (vfs_tarfs_ops, (vfsid) parc);
|
||||
return 2;
|
||||
}
|
||||
/* Hasn't been modified, give it a new timeout */
|
||||
vfs_stamp (&vfs_tarfs_ops, (vfsid) parc);
|
||||
vfs_stamp (vfs_tarfs_ops, (vfsid) parc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -866,21 +950,22 @@ tar_super_same (const vfs_path_element_t * vpath_element, struct vfs_s_super *pa
|
||||
static ssize_t
|
||||
tar_read (void *fh, char *buffer, size_t count)
|
||||
{
|
||||
off_t begin = FH->ino->data_offset;
|
||||
int fd = ((tar_super_data_t *) FH_SUPER->data)->fd;
|
||||
struct vfs_class *me = FH_SUPER->me;
|
||||
struct vfs_class *me = VFS_FILE_HANDLER_SUPER (fh)->me;
|
||||
vfs_file_handler_t *file = VFS_FILE_HANDLER (fh);
|
||||
off_t begin = file->ino->data_offset;
|
||||
int fd = TAR_SUPER (VFS_FILE_HANDLER_SUPER (fh))->fd;
|
||||
ssize_t res;
|
||||
|
||||
if (mc_lseek (fd, begin + FH->pos, SEEK_SET) != begin + FH->pos)
|
||||
if (mc_lseek (fd, begin + file->pos, SEEK_SET) != begin + file->pos)
|
||||
ERRNOR (EIO, -1);
|
||||
|
||||
count = MIN (count, (size_t) (FH->ino->st.st_size - FH->pos));
|
||||
count = MIN (count, (size_t) (file->ino->st.st_size - file->pos));
|
||||
|
||||
res = mc_read (fd, buffer, count);
|
||||
if (res == -1)
|
||||
ERRNOR (errno, -1);
|
||||
|
||||
FH->pos += res;
|
||||
file->pos += res;
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -904,21 +989,17 @@ tar_fh_open (struct vfs_class *me, vfs_file_handler_t * fh, int flags, mode_t mo
|
||||
void
|
||||
init_tarfs (void)
|
||||
{
|
||||
static struct vfs_s_subclass tarfs_subclass;
|
||||
|
||||
tarfs_subclass.flags = VFS_S_READONLY; /* FIXME: tarfs used own temp files */
|
||||
/* FIXME: tarfs used own temp files */
|
||||
vfs_init_subclass (&tarfs_subclass, "tarfs", VFS_READONLY, "utar");
|
||||
vfs_tarfs_ops->read = tar_read;
|
||||
vfs_tarfs_ops->setctl = NULL;
|
||||
tarfs_subclass.archive_check = tar_super_check;
|
||||
tarfs_subclass.archive_same = tar_super_same;
|
||||
tarfs_subclass.new_archive = tar_new_archive;
|
||||
tarfs_subclass.open_archive = tar_open_archive;
|
||||
tarfs_subclass.free_archive = tar_free_archive;
|
||||
tarfs_subclass.fh_open = tar_fh_open;
|
||||
|
||||
vfs_s_init_class (&vfs_tarfs_ops, &tarfs_subclass);
|
||||
vfs_tarfs_ops.name = "tarfs";
|
||||
vfs_tarfs_ops.prefix = "utar";
|
||||
vfs_tarfs_ops.read = tar_read;
|
||||
vfs_tarfs_ops.setctl = NULL;
|
||||
vfs_register_class (&vfs_tarfs_ops);
|
||||
vfs_register_class (vfs_tarfs_ops);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -64,6 +64,7 @@
|
||||
|
||||
#include "lib/util.h"
|
||||
#include "lib/widget.h" /* message() */
|
||||
#include "lib/vfs/xdirentry.h"
|
||||
#include "lib/vfs/utilvfs.h"
|
||||
#include "lib/vfs/vfs.h"
|
||||
|
||||
@ -129,8 +130,10 @@ static char *block_buf;
|
||||
static const char *undelfserr = N_("undelfs: error");
|
||||
static int readdir_ptr;
|
||||
static int undelfs_usage;
|
||||
|
||||
static struct vfs_class vfs_undelfs_ops;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** file scope functions ************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
@ -820,8 +823,7 @@ com_err (const char *whoami, long err_code, const char *fmt, ...)
|
||||
void
|
||||
init_undelfs (void)
|
||||
{
|
||||
vfs_undelfs_ops.name = "undelfs";
|
||||
vfs_undelfs_ops.prefix = "undel";
|
||||
vfs_init_class (&vfs_undelfs_ops, "undelfs", VFS_UNKNOWN, "undel");
|
||||
vfs_undelfs_ops.init = undelfs_init;
|
||||
vfs_undelfs_ops.open = undelfs_open;
|
||||
vfs_undelfs_ops.close = undelfs_close;
|
||||
|
@ -394,17 +394,25 @@ mcview_execute_cmd (WView * view, long command)
|
||||
mc_event_raise (MCEVENT_GROUP_CORE, "help", &event_data);
|
||||
}
|
||||
break;
|
||||
case CK_WrapMode:
|
||||
/* Toggle between wrapped and unwrapped view */
|
||||
mcview_toggle_wrap_mode (view);
|
||||
case CK_HexMode:
|
||||
/* Toggle between hex view and text view */
|
||||
mcview_toggle_hex_mode (view);
|
||||
break;
|
||||
case CK_HexEditMode:
|
||||
/* Toggle between hexview and hexedit mode */
|
||||
mcview_toggle_hexedit_mode (view);
|
||||
break;
|
||||
case CK_HexMode:
|
||||
/* Toggle between hex view and text view */
|
||||
mcview_toggle_hex_mode (view);
|
||||
case CK_ToggleNavigation:
|
||||
view->hexview_in_text = !view->hexview_in_text;
|
||||
view->dirty++;
|
||||
break;
|
||||
case CK_LeftQuick:
|
||||
if (!view->mode_flags.hex)
|
||||
mcview_move_left (view, 10);
|
||||
break;
|
||||
case CK_RightQuick:
|
||||
if (!view->mode_flags.hex)
|
||||
mcview_move_right (view, 10);
|
||||
break;
|
||||
case CK_Goto:
|
||||
{
|
||||
@ -428,24 +436,35 @@ mcview_execute_cmd (WView * view, long command)
|
||||
case CK_Search:
|
||||
mcview_search (view, TRUE);
|
||||
break;
|
||||
case CK_SearchContinue:
|
||||
mcview_continue_search_cmd (view);
|
||||
break;
|
||||
case CK_SearchForward:
|
||||
mcview_search_options.backwards = FALSE;
|
||||
mcview_search (view, TRUE);
|
||||
break;
|
||||
case CK_SearchForwardContinue:
|
||||
mcview_search_options.backwards = FALSE;
|
||||
mcview_continue_search_cmd (view);
|
||||
break;
|
||||
case CK_SearchBackward:
|
||||
mcview_search_options.backwards = TRUE;
|
||||
mcview_search (view, TRUE);
|
||||
break;
|
||||
case CK_SearchBackwardContinue:
|
||||
mcview_search_options.backwards = TRUE;
|
||||
mcview_continue_search_cmd (view);
|
||||
break;
|
||||
case CK_WrapMode:
|
||||
/* Toggle between wrapped and unwrapped view */
|
||||
mcview_toggle_wrap_mode (view);
|
||||
break;
|
||||
case CK_MagicMode:
|
||||
mcview_toggle_magic_mode (view);
|
||||
break;
|
||||
case CK_NroffMode:
|
||||
mcview_toggle_nroff_mode (view);
|
||||
break;
|
||||
case CK_ToggleNavigation:
|
||||
view->hexview_in_text = !view->hexview_in_text;
|
||||
view->dirty++;
|
||||
break;
|
||||
case CK_Home:
|
||||
mcview_moveto_bol (view);
|
||||
break;
|
||||
@ -458,28 +477,6 @@ mcview_execute_cmd (WView * view, long command)
|
||||
case CK_Right:
|
||||
mcview_move_right (view, 1);
|
||||
break;
|
||||
case CK_LeftQuick:
|
||||
if (!view->mode_flags.hex)
|
||||
mcview_move_left (view, 10);
|
||||
break;
|
||||
case CK_RightQuick:
|
||||
if (!view->mode_flags.hex)
|
||||
mcview_move_right (view, 10);
|
||||
break;
|
||||
case CK_SearchContinue:
|
||||
mcview_continue_search_cmd (view);
|
||||
break;
|
||||
case CK_SearchForwardContinue:
|
||||
mcview_search_options.backwards = FALSE;
|
||||
mcview_continue_search_cmd (view);
|
||||
break;
|
||||
case CK_SearchBackwardContinue:
|
||||
mcview_search_options.backwards = TRUE;
|
||||
mcview_continue_search_cmd (view);
|
||||
break;
|
||||
case CK_Ruler:
|
||||
mcview_display_toggle_ruler (view);
|
||||
break;
|
||||
case CK_Up:
|
||||
mcview_move_up (view, 1);
|
||||
break;
|
||||
@ -507,8 +504,8 @@ mcview_execute_cmd (WView * view, long command)
|
||||
case CK_Shell:
|
||||
view_other_cmd ();
|
||||
break;
|
||||
case CK_BookmarkGoto:
|
||||
view->marks[view->marker] = view->dpy_start;
|
||||
case CK_Ruler:
|
||||
mcview_display_toggle_ruler (view);
|
||||
break;
|
||||
case CK_Bookmark:
|
||||
view->dpy_start = view->marks[view->marker];
|
||||
@ -516,6 +513,9 @@ mcview_execute_cmd (WView * view, long command)
|
||||
view->dpy_wrap_dirty = TRUE;
|
||||
view->dirty++;
|
||||
break;
|
||||
case CK_BookmarkGoto:
|
||||
view->marks[view->marker] = view->dpy_start;
|
||||
break;
|
||||
#ifdef HAVE_CHARSET
|
||||
case CK_SelectCodepage:
|
||||
mcview_select_encoding (view);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
lib/vfs - mc_build_filename() function testing
|
||||
lib - mc_build_filename() function testing
|
||||
|
||||
Copyright (C) 2011-2019
|
||||
Free Software Foundation, Inc.
|
||||
@ -23,7 +23,7 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define TEST_SUITE_NAME "/lib"
|
||||
#define TEST_SUITE_NAME "/lib/util"
|
||||
|
||||
#include "tests/mctest.h"
|
||||
|
||||
|
@ -110,14 +110,15 @@ int
|
||||
main (void)
|
||||
{
|
||||
int number_failed;
|
||||
char *cwd, *logname;
|
||||
char *cwd;
|
||||
|
||||
Suite *s = suite_create (TEST_SUITE_NAME);
|
||||
TCase *tc_core = tcase_create ("Core");
|
||||
SRunner *sr;
|
||||
|
||||
/* writable directory where check creates temporary files */
|
||||
cwd = g_get_current_dir ();
|
||||
logname = g_strconcat (cwd, "realpath.log", (char *) NULL);
|
||||
g_setenv ("TEMP", cwd, TRUE);
|
||||
g_free (cwd);
|
||||
|
||||
tcase_add_checked_fixture (tc_core, setup, teardown);
|
||||
@ -128,11 +129,10 @@ main (void)
|
||||
|
||||
suite_add_tcase (s, tc_core);
|
||||
sr = srunner_create (s);
|
||||
srunner_set_log (sr, logname);
|
||||
srunner_set_log (sr, "mc_realpath.log");
|
||||
srunner_run_all (sr, CK_ENV);
|
||||
number_failed = srunner_ntests_failed (sr);
|
||||
srunner_free (sr);
|
||||
g_free (logname);
|
||||
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
lib/vfs - Quote file names
|
||||
lib - Quote file names
|
||||
|
||||
Copyright (C) 2011-2019
|
||||
Free Software Foundation, Inc.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
lib/vfs - common serialize/deserialize functions
|
||||
lib - common serialize/deserialize functions
|
||||
|
||||
Copyright (C) 2011-2019
|
||||
Free Software Foundation, Inc.
|
||||
@ -97,6 +97,8 @@ START_PARAMETRIZED_TEST (test_serialize, test_serialize_ds)
|
||||
|
||||
g_free (actual_result);
|
||||
|
||||
if (error != NULL)
|
||||
g_error_free (error);
|
||||
}
|
||||
/* *INDENT-OFF* */
|
||||
END_PARAMETRIZED_TEST
|
||||
|
@ -49,7 +49,7 @@ teardown (void)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* @DataSource("str_replace_all_test_ds") */
|
||||
/* @DataSource("parse_integer_test_ds") */
|
||||
/* *INDENT-OFF* */
|
||||
static const struct parse_integer_test_ds
|
||||
{
|
||||
@ -117,15 +117,14 @@ static const struct parse_integer_test_ds
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* @Test(dataSource = "str_replace_all_test_ds") */
|
||||
/* @Test(dataSource = "parse_integer_test_ds") */
|
||||
/* *INDENT-OFF* */
|
||||
START_TEST (parse_integer_test)
|
||||
START_PARAMETRIZED_TEST (parse_integer_test, parse_integer_test_ds)
|
||||
/* *INDENT-ON* */
|
||||
{
|
||||
/* given */
|
||||
uintmax_t actual_result;
|
||||
gboolean invalid = FALSE;
|
||||
const struct parse_integer_test_ds *data = &parse_integer_test_ds[_i];
|
||||
|
||||
/* when */
|
||||
actual_result = parse_integer (data->haystack, &invalid);
|
||||
@ -136,7 +135,7 @@ START_TEST (parse_integer_test)
|
||||
actual_result, data->expected_result);
|
||||
}
|
||||
/* *INDENT-OFF* */
|
||||
END_TEST
|
||||
END_PARAMETRIZED_TEST
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -153,7 +152,7 @@ main (void)
|
||||
tcase_add_checked_fixture (tc_core, setup, teardown);
|
||||
|
||||
/* Add new tests here: *************** */
|
||||
tcase_add_loop_test (tc_core, parse_integer_test, 0, G_N_ELEMENTS (parse_integer_test_ds));
|
||||
mctest_add_parameterized_test (tc_core, parse_integer_test, parse_integer_test_ds);
|
||||
/* *********************************** */
|
||||
|
||||
suite_add_tcase (s, tc_core);
|
||||
|
@ -37,7 +37,6 @@
|
||||
|
||||
#include "src/vfs/local/local.c"
|
||||
|
||||
static struct vfs_s_subclass test_subclass;
|
||||
static struct vfs_class vfs_test_ops;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -57,12 +56,7 @@ setup (void)
|
||||
load_codepages_list ();
|
||||
#endif
|
||||
|
||||
vfs_s_init_class (&vfs_test_ops, &test_subclass);
|
||||
|
||||
vfs_test_ops.name = "testfs";
|
||||
vfs_test_ops.flags = VFSF_NOLINKS;
|
||||
vfs_test_ops.prefix = "ftp";
|
||||
test_subclass.flags = VFS_S_REMOTE;
|
||||
vfs_init_class (&vfs_test_ops, "testfs", VFS_NOLINKS | VFS_REMOTE, "ftp");
|
||||
vfs_register_class (&vfs_test_ops);
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,6 @@
|
||||
|
||||
#include "src/vfs/local/local.c"
|
||||
|
||||
static struct vfs_s_subclass test_subclass;
|
||||
static struct vfs_class vfs_test_ops;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -59,12 +58,8 @@ setup (void)
|
||||
init_localfs ();
|
||||
vfs_setup_work_dir ();
|
||||
|
||||
vfs_s_init_class (&vfs_test_ops, &test_subclass);
|
||||
|
||||
vfs_test_ops.name = "testfs";
|
||||
vfs_test_ops.prefix = "test";
|
||||
vfs_init_class (&vfs_test_ops, "testfs", VFS_UNKNOWN, "test");
|
||||
vfs_test_ops.chdir = test_chdir;
|
||||
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -85,8 +80,7 @@ static const struct test_cd_ds
|
||||
{
|
||||
const char *input_initial_path;
|
||||
const char *input_cd_path;
|
||||
const vfs_class_flags_t input_class_flags;
|
||||
const vfs_subclass_flags_t input_subclass_flags;
|
||||
const vfs_flags_t input_class_flags;
|
||||
|
||||
const char *expected_cd_path;
|
||||
} test_cd_ds[] =
|
||||
@ -94,64 +88,55 @@ static const struct test_cd_ds
|
||||
{ /* 0. */
|
||||
"/",
|
||||
"/dev/some.file/test://",
|
||||
VFSF_NOLINKS,
|
||||
0,
|
||||
VFS_NOLINKS,
|
||||
"/dev/some.file/test://"
|
||||
},
|
||||
{ /* 1. */
|
||||
"/",
|
||||
"/dev/some.file/test://bla-bla",
|
||||
VFSF_NOLINKS,
|
||||
0,
|
||||
VFS_NOLINKS,
|
||||
"/dev/some.file/test://bla-bla"
|
||||
},
|
||||
{ /* 2. */
|
||||
"/dev/some.file/test://bla-bla",
|
||||
"..",
|
||||
VFSF_NOLINKS,
|
||||
0,
|
||||
VFS_NOLINKS,
|
||||
"/dev/some.file/test://"
|
||||
},
|
||||
{ /* 3. */
|
||||
"/dev/some.file/test://",
|
||||
"..",
|
||||
VFSF_NOLINKS,
|
||||
0,
|
||||
VFS_NOLINKS,
|
||||
"/dev"
|
||||
},
|
||||
{ /* 4. */
|
||||
"/dev",
|
||||
"..",
|
||||
VFSF_NOLINKS,
|
||||
0,
|
||||
VFS_NOLINKS,
|
||||
"/"
|
||||
},
|
||||
{ /* 5. */
|
||||
"/",
|
||||
"..",
|
||||
VFSF_NOLINKS,
|
||||
0,
|
||||
VFS_NOLINKS,
|
||||
"/"
|
||||
},
|
||||
{ /* 6. */
|
||||
"/",
|
||||
"/test://user:pass@host.net/path",
|
||||
VFSF_NOLINKS,
|
||||
VFS_S_REMOTE,
|
||||
VFS_NOLINKS | VFS_REMOTE,
|
||||
"/test://user:pass@host.net/path"
|
||||
},
|
||||
{ /* 7. */
|
||||
"/test://user:pass@host.net/path",
|
||||
"..",
|
||||
VFSF_NOLINKS,
|
||||
VFS_S_REMOTE,
|
||||
VFS_NOLINKS | VFS_REMOTE,
|
||||
"/test://user:pass@host.net/"
|
||||
},
|
||||
{ /* 8. */
|
||||
"/test://user:pass@host.net/",
|
||||
"..",
|
||||
VFSF_NOLINKS,
|
||||
VFS_S_REMOTE,
|
||||
VFS_NOLINKS | VFS_REMOTE,
|
||||
"/"
|
||||
},
|
||||
};
|
||||
@ -166,9 +151,8 @@ START_PARAMETRIZED_TEST (test_cd, test_cd_ds)
|
||||
vfs_path_t *vpath;
|
||||
|
||||
vfs_test_ops.flags = data->input_class_flags;
|
||||
test_subclass.flags = data->input_subclass_flags;
|
||||
|
||||
vfs_register_class (&vfs_test_ops);
|
||||
|
||||
vfs_set_raw_current_dir (vfs_path_from_str (data->input_initial_path));
|
||||
|
||||
vpath = vfs_path_from_str (data->input_cd_path);
|
||||
@ -185,6 +169,8 @@ START_PARAMETRIZED_TEST (test_cd, test_cd_ds)
|
||||
g_free (actual_cd_path);
|
||||
}
|
||||
vfs_path_free (vpath);
|
||||
|
||||
vfs_unregister_class (&vfs_test_ops);
|
||||
}
|
||||
/* *INDENT-OFF* */
|
||||
END_PARAMETRIZED_TEST
|
||||
@ -196,11 +182,17 @@ int
|
||||
main (void)
|
||||
{
|
||||
int number_failed;
|
||||
char *cwd;
|
||||
|
||||
Suite *s = suite_create (TEST_SUITE_NAME);
|
||||
TCase *tc_core = tcase_create ("Core");
|
||||
SRunner *sr;
|
||||
|
||||
/* writable directory where check creates temporary files */
|
||||
cwd = g_get_current_dir ();
|
||||
g_setenv ("TEMP", cwd, TRUE);
|
||||
g_free (cwd);
|
||||
|
||||
tcase_add_checked_fixture (tc_core, setup, teardown);
|
||||
|
||||
/* Add new tests here: *************** */
|
||||
|
@ -37,31 +37,20 @@
|
||||
#include "src/vfs/local/local.c"
|
||||
|
||||
|
||||
struct vfs_s_subclass test_subclass1, test_subclass2, test_subclass3;
|
||||
struct vfs_class vfs_test_ops1, vfs_test_ops2, vfs_test_ops3;
|
||||
static struct vfs_class vfs_test_ops1, vfs_test_ops2, vfs_test_ops3;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
init_test_classes (void)
|
||||
{
|
||||
test_subclass1.flags = VFS_S_REMOTE;
|
||||
vfs_s_init_class (&vfs_test_ops1, &test_subclass1);
|
||||
|
||||
vfs_test_ops1.name = "testfs1";
|
||||
vfs_test_ops1.flags = VFSF_NOLINKS;
|
||||
vfs_test_ops1.prefix = "test1";
|
||||
vfs_init_class (&vfs_test_ops1, "testfs1", VFS_NOLINKS | VFS_REMOTE, "test1");
|
||||
vfs_register_class (&vfs_test_ops1);
|
||||
|
||||
vfs_s_init_class (&vfs_test_ops2, &test_subclass2);
|
||||
vfs_test_ops2.name = "testfs2";
|
||||
vfs_test_ops2.prefix = "test2";
|
||||
vfs_init_class (&vfs_test_ops2, "testfs2", VFS_UNKNOWN, "test2");
|
||||
vfs_register_class (&vfs_test_ops2);
|
||||
|
||||
vfs_s_init_class (&vfs_test_ops3, &test_subclass3);
|
||||
vfs_test_ops3.name = "testfs3";
|
||||
vfs_test_ops3.prefix = "test3";
|
||||
vfs_test_ops3.flags = VFSF_LOCAL;
|
||||
vfs_init_class (&vfs_test_ops3, "testfs3", VFS_LOCAL, "test3");
|
||||
vfs_register_class (&vfs_test_ops3);
|
||||
}
|
||||
|
||||
|
@ -164,10 +164,8 @@ END_PARAMETRIZED_TEST
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static struct vfs_s_subclass test_subclass1;
|
||||
static struct vfs_class vfs_test_ops1;
|
||||
|
||||
|
||||
/* @DataSource("test_path_to_str_flags_ds") */
|
||||
/* *INDENT-OFF* */
|
||||
static const struct test_path_to_str_flags_ds
|
||||
@ -246,11 +244,7 @@ START_PARAMETRIZED_TEST (test_path_to_str_flags, test_path_to_str_flags_ds)
|
||||
|
||||
test_init_vfs ("UTF-8");
|
||||
|
||||
test_subclass1.flags = VFS_S_REMOTE;
|
||||
vfs_s_init_class (&vfs_test_ops1, &test_subclass1);
|
||||
vfs_test_ops1.name = "testfs1";
|
||||
vfs_test_ops1.flags = VFSF_NOLINKS;
|
||||
vfs_test_ops1.prefix = "test1";
|
||||
vfs_init_class (&vfs_test_ops1, "testfs1", VFS_NOLINKS | VFS_REMOTE, "test1");
|
||||
vfs_register_class (&vfs_test_ops1);
|
||||
|
||||
/* when */
|
||||
|
@ -37,8 +37,7 @@
|
||||
|
||||
#include "src/vfs/local/local.c"
|
||||
|
||||
struct vfs_s_subclass test_subclass1, test_subclass2, test_subclass3;
|
||||
struct vfs_class vfs_test_ops1, vfs_test_ops2, vfs_test_ops3;
|
||||
static struct vfs_class vfs_test_ops1, vfs_test_ops2, vfs_test_ops3;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
@ -46,30 +45,19 @@ struct vfs_class vfs_test_ops1, vfs_test_ops2, vfs_test_ops3;
|
||||
static void
|
||||
setup (void)
|
||||
{
|
||||
|
||||
str_init_strings (NULL);
|
||||
|
||||
vfs_init ();
|
||||
init_localfs ();
|
||||
vfs_setup_work_dir ();
|
||||
|
||||
|
||||
test_subclass1.flags = VFS_S_REMOTE;
|
||||
vfs_s_init_class (&vfs_test_ops1, &test_subclass1);
|
||||
|
||||
vfs_test_ops1.name = "testfs1";
|
||||
vfs_test_ops1.flags = VFSF_NOLINKS;
|
||||
vfs_test_ops1.prefix = "test1";
|
||||
vfs_init_class (&vfs_test_ops1, "testfs1", VFS_NOLINKS | VFS_REMOTE, "test1");
|
||||
vfs_register_class (&vfs_test_ops1);
|
||||
|
||||
vfs_s_init_class (&vfs_test_ops2, &test_subclass2);
|
||||
vfs_test_ops2.name = "testfs2";
|
||||
vfs_test_ops2.prefix = "test2";
|
||||
vfs_init_class (&vfs_test_ops2, "testfs2", VFS_UNKNOWN, "test2");
|
||||
vfs_register_class (&vfs_test_ops2);
|
||||
|
||||
vfs_s_init_class (&vfs_test_ops3, &test_subclass3);
|
||||
vfs_test_ops3.name = "testfs3";
|
||||
vfs_test_ops3.prefix = "test3";
|
||||
vfs_init_class (&vfs_test_ops3, "testfs3", VFS_UNKNOWN, "test3");
|
||||
vfs_register_class (&vfs_test_ops3);
|
||||
|
||||
mc_global.sysconfig_dir = (char *) TEST_SHARE_DIR;
|
||||
@ -155,8 +143,12 @@ START_TEST (test_path_serialize)
|
||||
/* when */
|
||||
vpath = vfs_path_from_str_flags (ETALON_PATH_STR, VPF_USE_DEPRECATED_PARSER);
|
||||
serialized_vpath = vfs_path_serialize (vpath, &error);
|
||||
|
||||
vfs_path_free (vpath);
|
||||
|
||||
if (error != NULL)
|
||||
g_error_free (error);
|
||||
|
||||
/* then */
|
||||
mctest_assert_ptr_ne (serialized_vpath, NULL);
|
||||
mctest_assert_str_eq (serialized_vpath, ETALON_SERIALIZED_PATH);
|
||||
|
@ -33,8 +33,7 @@
|
||||
#include "src/vfs/local/local.c"
|
||||
|
||||
|
||||
struct vfs_s_subclass test_subclass1;
|
||||
struct vfs_class vfs_test_ops1;
|
||||
static struct vfs_class vfs_test_ops1;
|
||||
|
||||
static int test_chdir (const vfs_path_t * vpath);
|
||||
|
||||
@ -71,19 +70,13 @@ test_chdir__deinit (void)
|
||||
static void
|
||||
setup (void)
|
||||
{
|
||||
|
||||
str_init_strings (NULL);
|
||||
|
||||
vfs_init ();
|
||||
init_localfs ();
|
||||
vfs_setup_work_dir ();
|
||||
|
||||
test_subclass1.flags = VFS_S_REMOTE;
|
||||
vfs_s_init_class (&vfs_test_ops1, &test_subclass1);
|
||||
|
||||
vfs_test_ops1.name = "testfs1";
|
||||
vfs_test_ops1.flags = VFSF_NOLINKS;
|
||||
vfs_test_ops1.prefix = "test1";
|
||||
vfs_init_class (&vfs_test_ops1, "testfs1", VFS_NOLINKS | VFS_REMOTE, "test1");
|
||||
vfs_test_ops1.chdir = test_chdir;
|
||||
vfs_register_class (&vfs_test_ops1);
|
||||
|
||||
@ -202,11 +195,17 @@ int
|
||||
main (void)
|
||||
{
|
||||
int number_failed;
|
||||
char *cwd;
|
||||
|
||||
Suite *s = suite_create (TEST_SUITE_NAME);
|
||||
TCase *tc_core = tcase_create ("Core");
|
||||
SRunner *sr;
|
||||
|
||||
/* writable directory where check creates temporary files */
|
||||
cwd = g_get_current_dir ();
|
||||
g_setenv ("TEMP", cwd, TRUE);
|
||||
g_free (cwd);
|
||||
|
||||
tcase_add_checked_fixture (tc_core, setup, teardown);
|
||||
|
||||
/* Add new tests here: *************** */
|
||||
|
@ -39,10 +39,6 @@
|
||||
|
||||
#include "src/vfs/local/local.c"
|
||||
|
||||
|
||||
struct vfs_s_subclass test_subclass1, test_subclass2, test_subclass3;
|
||||
struct vfs_class vfs_test_ops1, vfs_test_ops2, vfs_test_ops3;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* @Before */
|
||||
|
@ -37,7 +37,7 @@
|
||||
|
||||
|
||||
struct vfs_s_subclass test_subclass1;
|
||||
struct vfs_class vfs_test_ops1;
|
||||
static struct vfs_class *vfs_test_ops1 = VFS_CLASS (&test_subclass1);
|
||||
|
||||
struct vfs_s_entry *vfs_root_entry;
|
||||
static struct vfs_s_inode *vfs_root_inode;
|
||||
@ -61,18 +61,14 @@ setup (void)
|
||||
init_localfs ();
|
||||
vfs_setup_work_dir ();
|
||||
|
||||
test_subclass1.flags = VFS_S_REMOTE;
|
||||
vfs_s_init_class (&vfs_test_ops1, &test_subclass1);
|
||||
vfs_test_ops1.name = "testfs1";
|
||||
vfs_test_ops1.flags = VFSF_NOLINKS;
|
||||
vfs_test_ops1.prefix = "test1:";
|
||||
vfs_register_class (&vfs_test_ops1);
|
||||
vfs_init_subclass (&test_subclass1, "testfs1", VFS_NOLINKS | VFS_REMOTE, "test1");
|
||||
vfs_register_class (vfs_test_ops1);
|
||||
|
||||
vfs_test_super = g_new0 (struct vfs_s_super, 1);
|
||||
vfs_test_super->me = &vfs_test_ops1;
|
||||
vfs_test_super->me = vfs_test_ops1;
|
||||
|
||||
vfs_root_inode = vfs_s_new_inode (&vfs_test_ops1, vfs_test_super, &initstat);
|
||||
vfs_root_entry = vfs_s_new_entry (&vfs_test_ops1, "/", vfs_root_inode);
|
||||
vfs_root_inode = vfs_s_new_inode (vfs_test_ops1, vfs_test_super, &initstat);
|
||||
vfs_root_entry = vfs_s_new_entry (vfs_test_ops1, "/", vfs_root_inode);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -81,7 +77,7 @@ setup (void)
|
||||
static void
|
||||
teardown (void)
|
||||
{
|
||||
vfs_s_free_entry (&vfs_test_ops1, vfs_root_entry);
|
||||
vfs_s_free_entry (vfs_test_ops1, vfs_root_entry);
|
||||
vfs_shut ();
|
||||
str_uninit_strings ();
|
||||
}
|
||||
@ -330,27 +326,27 @@ START_TEST (test_vfs_parse_ls_lga_reorder)
|
||||
vfs_parse_ls_lga_init ();
|
||||
|
||||
/* init ent1 */
|
||||
ent1 = vfs_s_generate_entry (&vfs_test_ops1, NULL, vfs_root_inode, 0);
|
||||
ent1 = vfs_s_generate_entry (vfs_test_ops1, NULL, vfs_root_inode, 0);
|
||||
vfs_parse_ls_lga
|
||||
("drwxrwxr-x 10 500 500 4096 Jun 23 17:09 build_root1", &ent1->ino->st,
|
||||
&ent1->name, &ent1->ino->linkname, &filepos);
|
||||
vfs_s_store_filename_leading_spaces (ent1, filepos);
|
||||
vfs_s_insert_entry (&vfs_test_ops1, vfs_root_inode, ent1);
|
||||
vfs_s_insert_entry (vfs_test_ops1, vfs_root_inode, ent1);
|
||||
|
||||
|
||||
/* init ent2 */
|
||||
ent2 = vfs_s_generate_entry (&vfs_test_ops1, NULL, vfs_root_inode, 0);
|
||||
ent2 = vfs_s_generate_entry (vfs_test_ops1, NULL, vfs_root_inode, 0);
|
||||
vfs_parse_ls_lga ("drwxrwxr-x 10 500 500 4096 Jun 23 17:09 build_root2",
|
||||
&ent2->ino->st, &ent2->name, &ent2->ino->linkname, &filepos);
|
||||
vfs_s_store_filename_leading_spaces (ent2, filepos);
|
||||
vfs_s_insert_entry (&vfs_test_ops1, vfs_root_inode, ent2);
|
||||
vfs_s_insert_entry (vfs_test_ops1, vfs_root_inode, ent2);
|
||||
|
||||
/* init ent3 */
|
||||
ent3 = vfs_s_generate_entry (&vfs_test_ops1, NULL, vfs_root_inode, 0);
|
||||
ent3 = vfs_s_generate_entry (vfs_test_ops1, NULL, vfs_root_inode, 0);
|
||||
vfs_parse_ls_lga ("drwxrwxr-x 10 500 500 4096 Jun 23 17:09 ..",
|
||||
&ent3->ino->st, &ent3->name, &ent3->ino->linkname, &filepos);
|
||||
vfs_s_store_filename_leading_spaces (ent3, filepos);
|
||||
vfs_s_insert_entry (&vfs_test_ops1, vfs_root_inode, ent3);
|
||||
vfs_s_insert_entry (vfs_test_ops1, vfs_root_inode, ent3);
|
||||
|
||||
/* when */
|
||||
vfs_s_normalize_filename_leading_spaces (vfs_root_inode, vfs_parse_ls_lga_get_final_spaces ());
|
||||
@ -365,7 +361,7 @@ END_TEST
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
#define parce_one_line(ent_index, ls_output) {\
|
||||
ent[ent_index] = vfs_s_generate_entry (&vfs_test_ops1, NULL, vfs_root_inode, 0);\
|
||||
ent[ent_index] = vfs_s_generate_entry (vfs_test_ops1, NULL, vfs_root_inode, 0);\
|
||||
if (! vfs_parse_ls_lga (ls_output,\
|
||||
&ent[ent_index]->ino->st, &ent[ent_index]->name, &ent[ent_index]->ino->linkname, &filepos))\
|
||||
{\
|
||||
@ -373,7 +369,7 @@ END_TEST
|
||||
return;\
|
||||
}\
|
||||
vfs_s_store_filename_leading_spaces (ent[ent_index], filepos);\
|
||||
vfs_s_insert_entry (&vfs_test_ops1, vfs_root_inode, ent[ent_index]);\
|
||||
vfs_s_insert_entry (vfs_test_ops1, vfs_root_inode, ent[ent_index]);\
|
||||
\
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user