Merge branch '2398_save_as_tilde_expand'
* 2398_save_as_tilde_expand: lib/lock.c: applied MC indentation policy. Expand tilde while locking and unlocking files. (edit_set_filename): expand tilde while setting file name. Ticket #2398: tilde is not treated as home directory in editor "Save As" dialog.
Этот коммит содержится в:
Коммит
f8a47dae4c
159
lib/lock.c
159
lib/lock.c
@ -19,7 +19,7 @@
|
|||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
02110-1301, USA.
|
02110-1301, USA.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \file
|
/** \file
|
||||||
* \brief Source: file locking
|
* \brief Source: file locking
|
||||||
@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <signal.h> /* kill() */
|
#include <signal.h> /* kill() */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -54,14 +54,16 @@
|
|||||||
|
|
||||||
#include "lib/global.h"
|
#include "lib/global.h"
|
||||||
#include "lib/vfs/mc-vfs/vfs.h"
|
#include "lib/vfs/mc-vfs/vfs.h"
|
||||||
|
#include "lib/util.h" /* tilde_expand() */
|
||||||
#include "lib/lock.h"
|
#include "lib/lock.h"
|
||||||
|
|
||||||
#include "src/wtools.h" /* query_dialog() */
|
#include "src/wtools.h" /* query_dialog() */
|
||||||
|
|
||||||
#define BUF_SIZE 255
|
#define BUF_SIZE 255
|
||||||
#define PID_BUF_SIZE 10
|
#define PID_BUF_SIZE 10
|
||||||
|
|
||||||
struct lock_s {
|
struct lock_s
|
||||||
|
{
|
||||||
char *who;
|
char *who;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
};
|
};
|
||||||
@ -78,15 +80,20 @@ lock_build_name (void)
|
|||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
|
|
||||||
pw = getpwuid (getuid ());
|
pw = getpwuid (getuid ());
|
||||||
if (pw) user = pw->pw_name;
|
if (pw)
|
||||||
if (!user) user = getenv ("USER");
|
user = pw->pw_name;
|
||||||
if (!user) user = getenv ("USERNAME");
|
if (!user)
|
||||||
if (!user) user = getenv ("LOGNAME");
|
user = getenv ("USER");
|
||||||
if (!user) user = "";
|
if (!user)
|
||||||
|
user = getenv ("USERNAME");
|
||||||
|
if (!user)
|
||||||
|
user = getenv ("LOGNAME");
|
||||||
|
if (!user)
|
||||||
|
user = "";
|
||||||
|
|
||||||
/** \todo Use FQDN, no clean interface, so requires lot of code */
|
/** \todo Use FQDN, no clean interface, so requires lot of code */
|
||||||
if (gethostname (host, BUF_SIZE - 1) == -1)
|
if (gethostname (host, BUF_SIZE - 1) == -1)
|
||||||
*host = '\0';
|
*host = '\0';
|
||||||
|
|
||||||
return g_strdup_printf ("%s@%s.%d", user, host, (int) getpid ());
|
return g_strdup_printf ("%s@%s.%d", user, host, (int) getpid ());
|
||||||
}
|
}
|
||||||
@ -98,7 +105,7 @@ lock_build_symlink_name (const char *fname)
|
|||||||
char absolute_fname[PATH_MAX];
|
char absolute_fname[PATH_MAX];
|
||||||
|
|
||||||
if (mc_realpath (fname, absolute_fname) == NULL)
|
if (mc_realpath (fname, absolute_fname) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
fname = x_basename (absolute_fname);
|
fname = x_basename (absolute_fname);
|
||||||
fname_copy = g_strdup (fname);
|
fname_copy = g_strdup (fname);
|
||||||
@ -121,19 +128,19 @@ lock_extract_info (const char *str)
|
|||||||
len = strlen (str);
|
len = strlen (str);
|
||||||
|
|
||||||
for (p = str + len - 1; p >= str; p--)
|
for (p = str + len - 1; p >= str; p--)
|
||||||
if (*p == '.')
|
if (*p == '.')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Everything before last '.' is user@host */
|
/* Everything before last '.' is user@host */
|
||||||
i = 0;
|
i = 0;
|
||||||
for (s = str; s < p && i < BUF_SIZE; s++)
|
for (s = str; s < p && i < BUF_SIZE; s++)
|
||||||
who[i++] = *s;
|
who[i++] = *s;
|
||||||
who[i] = '\0';
|
who[i] = '\0';
|
||||||
|
|
||||||
/* Treat text between '.' and ':' or '\0' as pid */
|
/* Treat text between '.' and ':' or '\0' as pid */
|
||||||
i = 0;
|
i = 0;
|
||||||
for (p = p + 1; (p < str + len) && (*p != ':') && (i < PID_BUF_SIZE); p++)
|
for (p = p + 1; (p < str + len) && (*p != ':') && (i < PID_BUF_SIZE); p++)
|
||||||
pid[i++] = *p;
|
pid[i++] = *p;
|
||||||
pid[i] = '\0';
|
pid[i] = '\0';
|
||||||
|
|
||||||
lock.pid = (pid_t) atol (pid);
|
lock.pid = (pid_t) atol (pid);
|
||||||
@ -150,7 +157,7 @@ lock_get_info (const char *lockfname)
|
|||||||
|
|
||||||
cnt = readlink (lockfname, buf, BUF_SIZE - 1);
|
cnt = readlink (lockfname, buf, BUF_SIZE - 1);
|
||||||
if (cnt == -1 || *buf == '\0')
|
if (cnt == -1 || *buf == '\0')
|
||||||
return NULL;
|
return NULL;
|
||||||
buf[cnt] = '\0';
|
buf[cnt] = '\0';
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
@ -165,63 +172,69 @@ lock_file (const char *fname)
|
|||||||
char *lockfname, *newlock, *msg, *lock;
|
char *lockfname, *newlock, *msg, *lock;
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
struct lock_s *lockinfo;
|
struct lock_s *lockinfo;
|
||||||
|
gboolean symlink_ok;
|
||||||
|
|
||||||
/* Just to be sure (and don't lock new file) */
|
/* Just to be sure (and don't lock new file) */
|
||||||
if (!fname || !*fname)
|
if (fname == NULL || *fname == '\0')
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fname = tilde_expand (fname);
|
||||||
|
|
||||||
/* Locking on VFS is not supported */
|
/* Locking on VFS is not supported */
|
||||||
if (!vfs_file_is_local (fname))
|
if (!vfs_file_is_local (fname))
|
||||||
return 0;
|
{
|
||||||
|
g_free (fname);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if already locked */
|
/* Check if already locked */
|
||||||
lockfname = lock_build_symlink_name (fname);
|
lockfname = lock_build_symlink_name (fname);
|
||||||
|
g_free (fname);
|
||||||
if (lockfname == NULL)
|
if (lockfname == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
if (lstat (lockfname, &statbuf) == 0) {
|
|
||||||
lock = lock_get_info (lockfname);
|
|
||||||
if (!lock) {
|
|
||||||
g_free (lockfname);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
lockinfo = lock_extract_info (lock);
|
|
||||||
|
|
||||||
/* Check if locking process alive, ask user if required */
|
if (lstat (lockfname, &statbuf) == 0)
|
||||||
if (!lockinfo->pid
|
{
|
||||||
|| !(kill (lockinfo->pid, 0) == -1 && errno == ESRCH)) {
|
lock = lock_get_info (lockfname);
|
||||||
msg =
|
if (lock == NULL)
|
||||||
g_strdup_printf (_
|
{
|
||||||
("File \"%s\" is already being edited.\n"
|
g_free (lockfname);
|
||||||
"User: %s\nProcess ID: %d"), x_basename (lockfname) + 2,
|
return 0;
|
||||||
lockinfo->who, (int) lockinfo->pid);
|
}
|
||||||
/* TODO: Implement "Abort" - needs to rewind undo stack */
|
lockinfo = lock_extract_info (lock);
|
||||||
switch (query_dialog
|
|
||||||
(_("File locked"), msg, D_NORMAL, 2, _("&Grab lock"),
|
/* Check if locking process alive, ask user if required */
|
||||||
_("&Ignore lock"))) {
|
if (lockinfo->pid == 0 || !(kill (lockinfo->pid, 0) == -1 && errno == ESRCH))
|
||||||
case 0:
|
{
|
||||||
break;
|
msg =
|
||||||
case 1:
|
g_strdup_printf (_
|
||||||
case -1:
|
("File \"%s\" is already being edited.\n"
|
||||||
g_free (lockfname);
|
"User: %s\nProcess ID: %d"), x_basename (lockfname) + 2,
|
||||||
g_free (msg);
|
lockinfo->who, (int) lockinfo->pid);
|
||||||
return 0;
|
/* TODO: Implement "Abort" - needs to rewind undo stack */
|
||||||
}
|
switch (query_dialog
|
||||||
g_free (msg);
|
(_("File locked"), msg, D_NORMAL, 2, _("&Grab lock"), _("&Ignore lock")))
|
||||||
}
|
{
|
||||||
unlink (lockfname);
|
case 0:
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
case -1:
|
||||||
|
g_free (lockfname);
|
||||||
|
g_free (msg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
g_free (msg);
|
||||||
|
}
|
||||||
|
unlink (lockfname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create lock symlink */
|
/* Create lock symlink */
|
||||||
newlock = lock_build_name ();
|
newlock = lock_build_name ();
|
||||||
if (symlink (newlock, lockfname) == -1) {
|
symlink_ok = (symlink (newlock, lockfname) != -1);
|
||||||
g_free (lockfname);
|
|
||||||
g_free (newlock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (lockfname);
|
|
||||||
g_free (newlock);
|
g_free (newlock);
|
||||||
return 1;
|
g_free (lockfname);
|
||||||
|
|
||||||
|
return symlink_ok ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lowers file lock if possible
|
/* Lowers file lock if possible
|
||||||
@ -233,26 +246,32 @@ unlock_file (const char *fname)
|
|||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
|
||||||
/* Just to be sure */
|
/* Just to be sure */
|
||||||
if (!fname || !*fname)
|
if (fname == NULL || *fname == '\0')
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fname = tilde_expand (fname);
|
||||||
lockfname = lock_build_symlink_name (fname);
|
lockfname = lock_build_symlink_name (fname);
|
||||||
|
g_free (fname);
|
||||||
|
|
||||||
if (lockfname == NULL)
|
if (lockfname == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Check if lock exists */
|
/* Check if lock exists */
|
||||||
if (lstat (lockfname, &statbuf) == -1) {
|
if (lstat (lockfname, &statbuf) == -1)
|
||||||
g_free (lockfname);
|
{
|
||||||
return 0;
|
g_free (lockfname);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lock = lock_get_info (lockfname);
|
lock = lock_get_info (lockfname);
|
||||||
if (lock) {
|
if (lock != NULL)
|
||||||
/* Don't touch if lock is not ours */
|
{
|
||||||
if (lock_extract_info (lock)->pid != getpid ()) {
|
/* Don't touch if lock is not ours */
|
||||||
g_free (lockfname);
|
if (lock_extract_info (lock)->pid != getpid ())
|
||||||
return 0;
|
{
|
||||||
}
|
g_free (lockfname);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove lock */
|
/* Remove lock */
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
#include "lib/skin.h"
|
#include "lib/skin.h"
|
||||||
#include "lib/strutil.h" /* utf string functions */
|
#include "lib/strutil.h" /* utf string functions */
|
||||||
#include "lib/lock.h"
|
#include "lib/lock.h"
|
||||||
|
#include "lib/util.h" /* tilde_expand() */
|
||||||
#include "lib/vfs/mc-vfs/vfs.h"
|
#include "lib/vfs/mc-vfs/vfs.h"
|
||||||
|
|
||||||
#include "src/history.h"
|
#include "src/history.h"
|
||||||
@ -501,13 +502,15 @@ menu_save_mode_cmd (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
edit_set_filename (WEdit * edit, const char *f)
|
edit_set_filename (WEdit * edit, const char *name)
|
||||||
{
|
{
|
||||||
g_free (edit->filename);
|
g_free (edit->filename);
|
||||||
if (!f)
|
|
||||||
f = "";
|
if (name == NULL)
|
||||||
edit->filename = g_strdup (f);
|
name = "";
|
||||||
if (edit->dir == NULL && !g_path_is_absolute (f))
|
|
||||||
|
edit->filename = tilde_expand (name);
|
||||||
|
if (edit->dir == NULL && !g_path_is_absolute (name))
|
||||||
edit->dir = g_strdup (vfs_get_current_dir ());
|
edit->dir = g_strdup (vfs_get_current_dir ());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,8 +560,12 @@ edit_get_save_file_as (WEdit * edit)
|
|||||||
|
|
||||||
if (quick_dialog (&Quick_options) != B_CANCEL)
|
if (quick_dialog (&Quick_options) != B_CANCEL)
|
||||||
{
|
{
|
||||||
|
char *fname;
|
||||||
|
|
||||||
edit->lb = cur_lb;
|
edit->lb = cur_lb;
|
||||||
return filename;
|
fname = tilde_expand (filename);
|
||||||
|
g_free (filename);
|
||||||
|
return fname;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user