Derive session and mount paths, shorten paths

This commit is contained in:
Arun Prakash Jana 2020-06-08 09:44:53 +05:30
parent b62adec72c
commit d19d8d5f02
No known key found for this signature in database
GPG key ID: A75979F35C080412

150
src/nnn.c
View file

@ -363,13 +363,11 @@ static char *pager;
static char *shell; static char *shell;
static char *home; static char *home;
static char *initpath; static char *initpath;
static char *cfgdir; static char *cfgpath;
static char *selpath; static char *selpath;
static char *listpath; static char *listpath;
static char *prefixpath; static char *listroot;
static char *plugindir; static char *plgpath;
static char *sessiondir;
static char *mountdir;
static char *pnamebuf, *pselbuf; static char *pnamebuf, *pselbuf;
static char *mark; static char *mark;
#ifndef NOFIFO #ifndef NOFIFO
@ -630,6 +628,17 @@ static char cp[] = "cp -iRp";
static char mv[] = "mv -i"; static char mv[] = "mv -i";
#endif #endif
/* Tokens used for path creation */
#define TOK_PLG 0
#define TOK_SSN 1
#define TOK_MNT 2
static const char * const toks[] = {
"plugins",
"sessions",
"mounts",
};
/* Patterns */ /* Patterns */
#define P_CPMVFMT 0 #define P_CPMVFMT 0
#define P_CPMVRNM 1 #define P_CPMVRNM 1
@ -1186,7 +1195,7 @@ static size_t seltofile(int fd, uint *pcount)
lastpos = selbufpos - 1; lastpos = selbufpos - 1;
if (listpath) { if (listpath) {
prefixlen = (ssize_t)xstrlen(prefixpath); prefixlen = (ssize_t)xstrlen(listroot);
initlen = (ssize_t)xstrlen(listpath); initlen = (ssize_t)xstrlen(listpath);
} }
@ -1198,7 +1207,7 @@ static size_t seltofile(int fd, uint *pcount)
if (write(fd, pbuf, len) != len) if (write(fd, pbuf, len) != len)
return pos; return pos;
} else { } else {
if (write(fd, prefixpath, prefixlen) != prefixlen) if (write(fd, listroot, prefixlen) != prefixlen)
return pos; return pos;
if (write(fd, pbuf + initlen, len - initlen) != (len - initlen)) if (write(fd, pbuf + initlen, len - initlen) != (len - initlen))
return pos; return pos;
@ -1299,7 +1308,7 @@ static void endselection(void)
return; return;
} }
snprintf(buf, sizeof(buf), patterns[P_REPLACE], listpath, prefixpath, g_tmpfpath); snprintf(buf, sizeof(buf), patterns[P_REPLACE], listpath, listroot, g_tmpfpath);
spawn(utils[UTIL_SH_EXEC], buf, NULL, F_CLI); spawn(utils[UTIL_SH_EXEC], buf, NULL, F_CLI);
fd = open(g_tmpfpath, O_RDONLY); fd = open(g_tmpfpath, O_RDONLY);
@ -2029,12 +2038,12 @@ static void archive_selection(const char *cmd, const char *archive, const char *
static bool write_lastdir(const char *curpath) static bool write_lastdir(const char *curpath)
{ {
bool ret = TRUE; bool ret = TRUE;
size_t len = xstrlen(cfgdir); size_t len = xstrlen(cfgpath);
xstrsncpy(cfgdir + len, "/.lastd", 8); xstrsncpy(cfgpath + len, "/.lastd", 8);
DPRINTF_S(cfgdir); DPRINTF_S(cfgpath);
FILE *fp = fopen(cfgdir, "w"); FILE *fp = fopen(cfgpath, "w");
if (fp) { if (fp) {
if (fprintf(fp, "cd \"%s\"", curpath) < 0) if (fprintf(fp, "cd \"%s\"", curpath) < 0)
@ -3435,12 +3444,13 @@ static void savecurctx(settings *curcfg, char *path, char *curname, int r /* nex
static void save_session(bool last_session, int *presel) static void save_session(bool last_session, int *presel)
{ {
char spath[PATH_MAX];
int i; int i;
session_header_t header; session_header_t header;
FILE *fsession; FILE *fsession;
char *sname; char *sname;
bool status = FALSE; bool status = FALSE;
char ssnpath[PATH_MAX];
char spath[PATH_MAX];
memset(&header, 0, sizeof(session_header_t)); memset(&header, 0, sizeof(session_header_t));
@ -3461,7 +3471,9 @@ static void save_session(bool last_session, int *presel)
sname = !last_session ? xreadline(NULL, messages[MSG_SSN_NAME]) : "@"; sname = !last_session ? xreadline(NULL, messages[MSG_SSN_NAME]) : "@";
if (!sname[0]) if (!sname[0])
return; return;
mkpath(sessiondir, sname, spath);
mkpath(cfgpath, toks[TOK_SSN], ssnpath);
mkpath(ssnpath, sname, spath);
fsession = fopen(spath, "wb"); fsession = fopen(spath, "wb");
if (!fsession) { if (!fsession) {
@ -3497,21 +3509,24 @@ END:
static bool load_session(const char *sname, char **path, char **lastdir, char **lastname, bool restore) static bool load_session(const char *sname, char **path, char **lastdir, char **lastname, bool restore)
{ {
char spath[PATH_MAX];
int i = 0; int i = 0;
session_header_t header; session_header_t header;
FILE *fsession; FILE *fsession;
bool has_loaded_dynamically = !(sname || restore); bool has_loaded_dynamically = !(sname || restore);
bool status = FALSE; bool status = FALSE;
char ssnpath[PATH_MAX];
char spath[PATH_MAX];
mkpath(cfgpath, toks[TOK_SSN], ssnpath);
if (!restore) { if (!restore) {
sname = sname ? sname : xreadline(NULL, messages[MSG_SSN_NAME]); sname = sname ? sname : xreadline(NULL, messages[MSG_SSN_NAME]);
if (!sname[0]) if (!sname[0])
return FALSE; return FALSE;
mkpath(sessiondir, sname, spath); mkpath(ssnpath, sname, spath);
} else } else
mkpath(sessiondir, "@", spath); mkpath(ssnpath, "@", spath);
if (has_loaded_dynamically) if (has_loaded_dynamically)
save_session(TRUE, NULL); save_session(TRUE, NULL);
@ -3884,6 +3899,7 @@ static bool archive_mount(char *newpath)
char *dir, *cmd = utils[UTIL_ARCHIVEMOUNT]; char *dir, *cmd = utils[UTIL_ARCHIVEMOUNT];
char *name = dents[cur].name; char *name = dents[cur].name;
size_t len = dents[cur].nlen; size_t len = dents[cur].nlen;
char mntpath[PATH_MAX];
if (!getutil(cmd)) { if (!getutil(cmd)) {
printmsg(messages[MSG_UTIL_MISSING]); printmsg(messages[MSG_UTIL_MISSING]);
@ -3905,7 +3921,8 @@ static bool archive_mount(char *newpath)
DPRINTF_S(dir); DPRINTF_S(dir);
/* Create the mount point */ /* Create the mount point */
mkpath(mountdir, dir, newpath); mkpath(cfgpath, toks[TOK_MNT], mntpath);
mkpath(mntpath, dir, newpath);
free(dir); free(dir);
if (!xmktree(newpath, TRUE)) { if (!xmktree(newpath, TRUE)) {
@ -3930,6 +3947,7 @@ static bool remote_mount(char *newpath)
int opt; int opt;
char *tmp, *env; char *tmp, *env;
bool r = getutil(utils[UTIL_RCLONE]), s = getutil(utils[UTIL_SSHFS]); bool r = getutil(utils[UTIL_RCLONE]), s = getutil(utils[UTIL_SSHFS]);
char mntpath[PATH_MAX];
if (!(r || s)) { if (!(r || s)) {
printmsg(messages[MSG_UTIL_MISSING]); printmsg(messages[MSG_UTIL_MISSING]);
@ -3958,7 +3976,8 @@ static bool remote_mount(char *newpath)
} }
/* Create the mount point */ /* Create the mount point */
mkpath(mountdir, tmp, newpath); mkpath(cfgpath, toks[TOK_MNT], mntpath);
mkpath(mntpath, tmp, newpath);
if (!xmktree(newpath, TRUE)) { if (!xmktree(newpath, TRUE)) {
printwarn(NULL); printwarn(NULL);
return FALSE; return FALSE;
@ -4005,6 +4024,7 @@ static bool unmount(char *name, char *newpath, int *presel, char *currentpath)
bool child = FALSE; bool child = FALSE;
bool parent = FALSE; bool parent = FALSE;
bool hovered = TRUE; bool hovered = TRUE;
char mntpath[PATH_MAX];
#ifndef __APPLE__ #ifndef __APPLE__
/* On Ubuntu it's fusermount */ /* On Ubuntu it's fusermount */
@ -4014,8 +4034,10 @@ static bool unmount(char *name, char *newpath, int *presel, char *currentpath)
} }
#endif #endif
if (tmp && strcmp(mountdir, currentpath) == 0) { mkpath(cfgpath, toks[TOK_MNT], mntpath);
mkpath(mountdir, tmp, newpath);
if (tmp && strcmp(mntpath, currentpath) == 0) {
mkpath(mntpath, tmp, newpath);
child = lstat(newpath, &sb) != -1; child = lstat(newpath, &sb) != -1;
parent = lstat(xdirname(newpath), &psb) != -1; parent = lstat(xdirname(newpath), &psb) != -1;
if (!child && !parent) { if (!child && !parent) {
@ -4032,7 +4054,7 @@ static bool unmount(char *name, char *newpath, int *presel, char *currentpath)
} }
/* Create the mount point */ /* Create the mount point */
mkpath(mountdir, tmp, newpath); mkpath(mntpath, tmp, newpath);
if (!xdiraccess(newpath)) { if (!xdiraccess(newpath)) {
*presel = MSGWAIT; *presel = MSGWAIT;
return FALSE; return FALSE;
@ -4369,7 +4391,7 @@ static bool run_selected_plugin(char **path, const char *file, char *runfile, ch
if (!cmd_as_plugin) { if (!cmd_as_plugin) {
/* Generate absolute path to plugin */ /* Generate absolute path to plugin */
mkpath(plugindir, file, g_buf); mkpath(plgpath, file, g_buf);
if (runfile && runfile[0]) { if (runfile && runfile[0]) {
xstrsncpy(*lastname, runfile, NAME_MAX); xstrsncpy(*lastname, runfile, NAME_MAX);
@ -4397,7 +4419,7 @@ static bool run_selected_plugin(char **path, const char *file, char *runfile, ch
static bool plugscript(const char *plugin, uchar flags) static bool plugscript(const char *plugin, uchar flags)
{ {
mkpath(plugindir, plugin, g_buf); mkpath(plgpath, plugin, g_buf);
if (!access(g_buf, X_OK)) { if (!access(g_buf, X_OK)) {
spawn(g_buf, NULL, NULL, flags); spawn(g_buf, NULL, NULL, flags);
return TRUE; return TRUE;
@ -4411,7 +4433,7 @@ static void launch_app(char *newpath)
int r = F_NORMAL; int r = F_NORMAL;
char *tmp = newpath; char *tmp = newpath;
mkpath(plugindir, utils[UTIL_LAUNCH], newpath); mkpath(plgpath, utils[UTIL_LAUNCH], newpath);
if (!getutil(utils[UTIL_FZF]) || access(newpath, X_OK) < 0) { if (!getutil(utils[UTIL_FZF]) || access(newpath, X_OK) < 0) {
tmp = xreadline(NULL, messages[MSG_APP_NAME]); tmp = xreadline(NULL, messages[MSG_APP_NAME]);
@ -5590,7 +5612,7 @@ nochange:
if (cfg.runplugin) { if (cfg.runplugin) {
cfg.runplugin = 0; cfg.runplugin = 0;
/* Must be in plugin dir and same context to select plugin */ /* Must be in plugin dir and same context to select plugin */
if ((cfg.runctx == cfg.curctx) && !strcmp(path, plugindir)) { if ((cfg.runctx == cfg.curctx) && !strcmp(path, plgpath)) {
endselection(); endselection();
/* Copy path so we can return back to earlier dir */ /* Copy path so we can return back to earlier dir */
xstrsncpy(path, rundir, PATH_MAX); xstrsncpy(path, rundir, PATH_MAX);
@ -5861,7 +5883,7 @@ nochange:
case SEL_STATS: // fallthrough case SEL_STATS: // fallthrough
case SEL_CHMODX: case SEL_CHMODX:
if (ndents) { if (ndents) {
tmp = (listpath && xstrcmp(path, listpath) == 0) ? prefixpath : path; tmp = (listpath && xstrcmp(path, listpath) == 0) ? listroot : path;
mkpath(tmp, dents[cur].name, newpath); mkpath(tmp, dents[cur].name, newpath);
if (lstat(newpath, &sb) == -1 if (lstat(newpath, &sb) == -1
@ -6067,7 +6089,7 @@ nochange:
if (r == 'c') { if (r == 'c') {
tmp = (listpath && xstrcmp(path, listpath) == 0) tmp = (listpath && xstrcmp(path, listpath) == 0)
? prefixpath : path; ? listroot : path;
mkpath(tmp, dents[cur].name, newpath); mkpath(tmp, dents[cur].name, newpath);
if (!xrm(newpath)) if (!xrm(newpath))
continue; continue;
@ -6298,7 +6320,7 @@ nochange:
} }
case SEL_PLUGIN: case SEL_PLUGIN:
/* Check if directory is accessible */ /* Check if directory is accessible */
if (!xdiraccess(plugindir)) { if (!xdiraccess(plgpath)) {
printwarn(&presel); printwarn(&presel);
goto nochange; goto nochange;
} }
@ -6347,7 +6369,7 @@ nochange:
* If toggled, and still in the plugin dir, * If toggled, and still in the plugin dir,
* switch to original directory * switch to original directory
*/ */
if (strcmp(path, plugindir) == 0) { if (strcmp(path, plgpath) == 0) {
xstrsncpy(path, rundir, PATH_MAX); xstrsncpy(path, rundir, PATH_MAX);
xstrsncpy(lastname, runfile, NAME_MAX); xstrsncpy(lastname, runfile, NAME_MAX);
rundir[0] = runfile[0] = '\0'; rundir[0] = runfile[0] = '\0';
@ -6360,7 +6382,7 @@ nochange:
} }
xstrsncpy(rundir, path, PATH_MAX); xstrsncpy(rundir, path, PATH_MAX);
xstrsncpy(path, plugindir, PATH_MAX); xstrsncpy(path, plgpath, PATH_MAX);
if (ndents) if (ndents)
xstrsncpy(runfile, dents[cur].name, NAME_MAX); xstrsncpy(runfile, dents[cur].name, NAME_MAX);
cfg.runctx = cfg.curctx; cfg.runctx = cfg.curctx;
@ -6692,10 +6714,10 @@ static char *load_input(int fd, const char *path)
for (i = 0; i < entries; ++i) for (i = 0; i < entries; ++i)
paths[i] = input + offsets[i]; paths[i] = input + offsets[i];
prefixpath = malloc(sizeof(char) * PATH_MAX); listroot = malloc(sizeof(char) * PATH_MAX);
if (!prefixpath) if (!listroot)
goto malloc_1; goto malloc_1;
prefixpath[0] = '\0'; listroot[0] = '\0';
DPRINTF_S(paths[0]); DPRINTF_S(paths[0]);
@ -6714,18 +6736,18 @@ static char *load_input(int fd, const char *path)
DPRINTF_S(paths[i]); DPRINTF_S(paths[i]);
xstrsncpy(g_buf, paths[i], PATH_MAX); xstrsncpy(g_buf, paths[i], PATH_MAX);
if (!common_prefix(xdirname(g_buf), prefixpath)) { if (!common_prefix(xdirname(g_buf), listroot)) {
entries = i + 1; // free from the current entry entries = i + 1; // free from the current entry
goto malloc_2; goto malloc_2;
} }
DPRINTF_S(prefixpath); DPRINTF_S(listroot);
} }
DPRINTF_S(prefixpath); DPRINTF_S(listroot);
if (prefixpath[0]) if (listroot[0])
tmpdir = make_tmp_tree(paths, entries, prefixpath); tmpdir = make_tmp_tree(paths, entries, listroot);
malloc_2: malloc_2:
for (i = entries - 1; i >= 0; --i) for (i = entries - 1; i >= 0; --i)
@ -6828,48 +6850,50 @@ static bool setup_config(void)
if (!xdg) if (!xdg)
len = xstrlen(home) + 1 + 21; /* add length of "/.config/nnn/sessions" */ len = xstrlen(home) + 1 + 21; /* add length of "/.config/nnn/sessions" */
cfgdir = (char *)malloc(len); cfgpath = (char *)malloc(len);
plugindir = (char *)malloc(len); plgpath = (char *)malloc(len);
sessiondir = (char *)malloc(len); if (!cfgpath || !plgpath) {
mountdir = (char *)malloc(len);
if (!cfgdir || !plugindir || !sessiondir) {
xerror(); xerror();
return FALSE; return FALSE;
} }
if (xdg) { if (xdg) {
xstrsncpy(cfgdir, xdgcfg, len); xstrsncpy(cfgpath, xdgcfg, len);
r = len - 13; /* subtract length of "/nnn/sessions" */ r = len - 13; /* subtract length of "/nnn/sessions" */
} else { } else {
r = xstrsncpy(cfgdir, home, len); r = xstrsncpy(cfgpath, home, len);
/* Create ~/.config */ /* Create ~/.config */
xstrsncpy(cfgdir + r - 1, "/.config", len - r); xstrsncpy(cfgpath + r - 1, "/.config", len - r);
DPRINTF_S(cfgdir); DPRINTF_S(cfgpath);
r += 8; /* length of "/.config" */ r += 8; /* length of "/.config" */
} }
/* Create ~/.config/nnn */ /* Create ~/.config/nnn */
xstrsncpy(cfgdir + r - 1, "/nnn", len - r); xstrsncpy(cfgpath + r - 1, "/nnn", len - r);
DPRINTF_S(cfgdir); DPRINTF_S(cfgpath);
/* Create ~/.config/nnn/plugins */ /* Create ~/.config/nnn/plugins */
mkpath(cfgdir, "plugins", plugindir); mkpath(cfgpath, toks[TOK_PLG], plgpath);
if (!xmktree(plugindir, TRUE)) { if (!xmktree(plgpath, TRUE)) {
xerror(); xerror();
return FALSE; return FALSE;
} }
/* Create ~/.config/nnn/sessions */ /* Create ~/.config/nnn/sessions */
mkpath(cfgdir, "sessions", sessiondir); char ssnpath[len];
if (!xmktree(sessiondir, TRUE)) {
mkpath(cfgpath, toks[TOK_SSN], ssnpath);
if (!xmktree(ssnpath, TRUE)) {
xerror(); xerror();
return FALSE; return FALSE;
} }
/* Create ~/.config/nnn/mounts */ /* Create ~/.config/nnn/mounts */
mkpath(cfgdir, "mounts", mountdir); char mntpath[len];
if (!xmktree(mountdir, TRUE)) {
mkpath(cfgpath, toks[TOK_MNT], mntpath);
if (!xmktree(mntpath, TRUE)) {
xerror(); xerror();
return FALSE; return FALSE;
} }
@ -6889,7 +6913,7 @@ static bool setup_config(void)
} }
if (!env_sel) { if (!env_sel) {
r = xstrsncpy(selpath, cfgdir, len + 3); r = xstrsncpy(selpath, cfgpath, len + 3);
xstrsncpy(selpath + r - 1, "/.selection", 12); xstrsncpy(selpath + r - 1, "/.selection", 12);
DPRINTF_S(selpath); DPRINTF_S(selpath);
} }
@ -6915,14 +6939,12 @@ static bool set_tmp_path(void)
static void cleanup(void) static void cleanup(void)
{ {
free(selpath); free(selpath);
free(plugindir); free(plgpath);
free(sessiondir); free(cfgpath);
free(mountdir);
free(cfgdir);
free(initpath); free(initpath);
free(bmstr); free(bmstr);
free(pluginstr); free(pluginstr);
free(prefixpath); free(listroot);
free(ihashbmp); free(ihashbmp);
free(bookmark); free(bookmark);
free(plug); free(plug);
@ -7296,7 +7318,7 @@ int main(int argc, char *argv[])
rl_bind_key('\t', rl_complete); rl_bind_key('\t', rl_complete);
#endif #endif
if (rlhist) { if (rlhist) {
mkpath(cfgdir, ".history", g_buf); mkpath(cfgpath, ".history", g_buf);
read_history(g_buf); read_history(g_buf);
} }
#endif #endif
@ -7321,7 +7343,7 @@ int main(int argc, char *argv[])
#ifndef NORL #ifndef NORL
if (rlhist) { if (rlhist) {
mkpath(cfgdir, ".history", g_buf); mkpath(cfgpath, ".history", g_buf);
write_history(g_buf); write_history(g_buf);
} }
#endif #endif