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:
Andrew Borodin 2019-04-27 20:40:41 +03:00
commit e1d11906b3
105 changed files with 2717 additions and 2723 deletions

View File

@ -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,
_

View File

@ -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)
{

View File

@ -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;
}
}

View File

@ -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)
{

View File

@ -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);
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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;
}
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -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
])

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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/"

View File

@ -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"

View File

@ -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/"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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/"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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/"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

359
po/mc.pot

File diff suppressed because it is too large Load Diff

View File

@ -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"

View File

@ -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/"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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/"

View File

@ -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"

View File

@ -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 "&Устаревшие"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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/"

View File

@ -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/"

View File

@ -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"

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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;
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -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);
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -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;

View File

@ -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 ****************************************************************************/

View File

@ -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;
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -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;

View File

@ -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);

View File

@ -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"

View File

@ -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;
}

View File

@ -1,5 +1,5 @@
/*
lib/vfs - Quote file names
lib - Quote file names
Copyright (C) 2011-2019
Free Software Foundation, Inc.

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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: *************** */

View File

@ -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);
}

View File

@ -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 */

View File

@ -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);

View File

@ -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: *************** */

View File

@ -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 */

View File

@ -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