Get rid of unsafe system(3) calls

This commit is contained in:
Arun Prakash Jana 2017-05-15 18:22:00 +05:30
parent 463c270caf
commit ba49beac79
No known key found for this signature in database
GPG Key ID: A75979F35C080412
2 changed files with 67 additions and 53 deletions

View File

@ -52,7 +52,7 @@ Have fun with it! PRs are welcome. Check out [#1](https://github.com/jarun/nnn/i
<p align="center"> <p align="center">
<a href="https://saythanks.io/to/jarun"><img src="https://img.shields.io/badge/say-thanks!-ff69b4.svg" /></a> <a href="https://saythanks.io/to/jarun"><img src="https://img.shields.io/badge/say-thanks!-ff69b4.svg" /></a>
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=RMLTQ76JSXJ4Q"><img src="https://img.shields.io/badge/PayPal-donate-5DADE2.svg" alt="Donate via PayPal!" /></a> <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=RMLTQ76JSXJ4Q"><img src="https://img.shields.io/badge/PayPal-donate-FC746D.svg" alt="Donate via PayPal!" /></a>
</p> </p>
### Features ### Features

118
nnn.c
View File

@ -1027,11 +1027,16 @@ get_lsperms(mode_t mode, char *desc)
return(bits); return(bits);
} }
/* Gets only a single line, that's what we need for now */ /*
* Gets only a single line (that's what we need
* for now) or shows full command output in pager.
*
* If pager is valid, returns NULL
*/
static char * static char *
get_output(char *buf, size_t bytes, char *file, char *arg1, char *arg2) get_output(char *buf, size_t bytes, char *file, char *arg1, char *arg2, int pager)
{ {
pid_t pid = 0; pid_t pid;
int pipefd[2]; int pipefd[2];
FILE* pf; FILE* pf;
int status; int status;
@ -1041,7 +1046,6 @@ get_output(char *buf, size_t bytes, char *file, char *arg1, char *arg2)
printerr(1, "pipe(2)"); printerr(1, "pipe(2)");
pid = fork(); pid = fork();
if (pid == 0) { if (pid == 0) {
/* In child */ /* In child */
close(pipefd[0]); close(pipefd[0]);
@ -1052,15 +1056,30 @@ get_output(char *buf, size_t bytes, char *file, char *arg1, char *arg2)
} }
/* In parent */ /* In parent */
waitpid(pid, &status, 0);
close(pipefd[1]); close(pipefd[1]);
if ((pf = fdopen(pipefd[0], "r"))) { if (!pager) {
ret = fgets(buf, bytes, pf); if ((pf = fdopen(pipefd[0], "r"))) {
close(pipefd[0]); ret = fgets(buf, bytes, pf);
close(pipefd[0]);
}
return ret;
} }
pid = fork();
if (pid == 0) {
/* Show in pager in child */
dup2(pipefd[0], STDIN_FILENO);
execlp("less", "less", NULL);
close(pipefd[0]);
_exit(1);
}
/* In parent */
waitpid(pid, &status, 0); waitpid(pid, &status, 0);
return ret; return NULL;
} }
/* /*
@ -1135,7 +1154,7 @@ show_stats(char* fpath, char* fname, struct stat *sb)
if (S_ISREG(sb->st_mode)) { if (S_ISREG(sb->st_mode)) {
/* Show file(1) output */ /* Show file(1) output */
p = get_output(g_buf, MAX_CMD_LEN, "file", "-b", fpath); p = get_output(g_buf, MAX_CMD_LEN, "file", "-b", fpath, 0);
if (p) { if (p) {
dprintf(fd, "\n\n "); dprintf(fd, "\n\n ");
while (*p) { while (*p) {
@ -1149,32 +1168,29 @@ show_stats(char* fpath, char* fname, struct stat *sb)
} }
dprintf(fd, " %s", begin); dprintf(fd, " %s", begin);
} }
}
dprintf(fd, "\n\n"); dprintf(fd, "\n\n");
} else
dprintf(fd, "\n\n\n");
close(fd); close(fd);
sprintf(g_buf, "cat %s | less", tmp); get_output(NULL, 0, "cat", tmp, NULL, 1);
fd = system(g_buf);
unlink(tmp); unlink(tmp);
return fd; return 0;
} }
static int static int
show_mediainfo(const char* fpath, int full) show_mediainfo(char* fpath, char *arg)
{ {
strcpy(g_buf, "which mediainfo"); if (get_output(g_buf, MAX_CMD_LEN, "which", "mediainfo", NULL, 0) == NULL)
if (get_output(g_buf, MAX_CMD_LEN, "which", "mediainfo", NULL) == NULL)
return -1; return -1;
sprintf(g_buf, "mediainfo \'%s\' ", fpath); exitcurses();
if (full) get_output(NULL, 0, "mediainfo", fpath, arg, 1);
strcat(g_buf, "-f 2>&1 | less"); initcurses();
else
strcat(g_buf, "2>&1 | less");
return system(g_buf); return 0;
} }
static int static int
@ -1612,7 +1628,8 @@ nochange:
/* If nlay doesn't handle it, open plain text /* If nlay doesn't handle it, open plain text
files with vi, then try NNN_FALLBACK_OPENER */ files with vi, then try NNN_FALLBACK_OPENER */
if (get_output(g_buf, MAX_CMD_LEN, "file", "-bi", newpath) == NULL) if (get_output(g_buf, MAX_CMD_LEN, "file", "-bi",
newpath, 0) == NULL)
continue; continue;
if (strstr(g_buf, "text/") == g_buf) { if (strstr(g_buf, "text/") == g_buf) {
@ -1881,48 +1898,45 @@ nochange:
{ {
struct stat sb; struct stat sb;
if (ndents > 0) if (ndents > 0) {
mkpath(path, dents[cur].name, oldpath, PATH_MAX); mkpath(path, dents[cur].name, oldpath, PATH_MAX);
r = lstat(oldpath, &sb); r = lstat(oldpath, &sb);
if (r == -1) { if (r == -1) {
if (dents) if (dents)
dentfree(dents); dentfree(dents);
printerr(1, "lstat"); printerr(1, "lstat");
} else { } else {
exitcurses(); exitcurses();
r = show_stats(oldpath, dents[cur].name, &sb); r = show_stats(oldpath, dents[cur].name, &sb);
initcurses(); initcurses();
if (r < 0) { if (r < 0) {
printmsg(strerror(errno)); printmsg(strerror(errno));
goto nochange; goto nochange;
}
} }
} }
break; break;
} }
case SEL_MEDIA: case SEL_MEDIA:
if (ndents > 0) if (ndents > 0) {
mkpath(path, dents[cur].name, oldpath, PATH_MAX); mkpath(path, dents[cur].name, oldpath, PATH_MAX);
exitcurses(); if(show_mediainfo(oldpath, NULL) == -1) {
r = show_mediainfo(oldpath, FALSE); printmsg("mediainfo missing");
initcurses(); goto nochange;
if (r < 0) { }
printmsg("mediainfo missing");
goto nochange;
} }
break; break;
case SEL_FMEDIA: case SEL_FMEDIA:
if (ndents > 0) if (ndents > 0) {
mkpath(path, dents[cur].name, oldpath, PATH_MAX); mkpath(path, dents[cur].name, oldpath, PATH_MAX);
exitcurses(); if(show_mediainfo(oldpath, "-f") == -1) {
r = show_mediainfo(oldpath, TRUE); printmsg("mediainfo missing");
initcurses(); goto nochange;
if (r < 0) { }
printmsg("mediainfo missing");
goto nochange;
} }
break; break;
case SEL_DFB: case SEL_DFB: