[cmdline args] Add support for directories

Rather than requiring the user to pass a quoted wildcard to lnav,
we should just support scanning whole directories and reading
them in.  This change adds support for that by detecting the
directory and adding the wildcard to the file list automatically.
Any non-file entries in the given directory are skipped instead
of walking the whole tree, which seems like a reasonable default.
pull/48/head
Timothy Stack 12 years ago
parent b0418957c6
commit abf616e192

@ -2056,12 +2056,17 @@ static void usage(void)
" -r Load older rotated log files as well.\n"
"\n"
"Optional arguments:\n"
" logfile1 The log files to view.\n"
" logfile1 The log files or directories to view. If a\n"
" directory is given, all of the files in the\n"
" directory will be loaded.\n"
"\n"
"Examples:\n"
" To load and follow the syslog file -\n"
" $ lnav -s\n"
"\n"
" To load all of the files in /var/log:\n"
" $ lnav /var/log\n"
"\n"
"Version: " PACKAGE_STRING "\n";
fprintf(stderr, usage_msg, lnav_data.ld_program_name);
@ -2128,6 +2133,18 @@ static void watch_logfile(string filename, int fd, bool required)
else {
rc = stat(filename.c_str(), &st);
}
if (rc == 0) {
if (!S_ISREG(st.st_mode)) {
if (required) {
rc = -1;
errno = EINVAL;
}
else {
return;
}
}
}
if (rc == -1) {
if (required)
throw logfile::error(filename, errno);
@ -2146,6 +2163,25 @@ static void watch_logfile(string filename, int fd, bool required)
}
}
static void expand_filename(string path, bool required)
{
glob_t gl;
memset(&gl, 0, sizeof(gl));
if (glob(path.c_str(), GLOB_NOCHECK, NULL, &gl) == 0) {
int lpc;
if (gl.gl_pathc > 1 ||
strcmp(path.c_str(), gl.gl_pathv[0]) != 0) {
required = false;
}
for (lpc = 0; lpc < (int)gl.gl_pathc; lpc++) {
watch_logfile(gl.gl_pathv[lpc], -1, required);
}
globfree(&gl);
}
}
static void rescan_files(bool required = false)
{
set< pair<string, int> >::iterator iter;
@ -2153,22 +2189,17 @@ static void rescan_files(bool required = false)
for (iter = lnav_data.ld_file_names.begin();
iter != lnav_data.ld_file_names.end();
iter++) {
watch_logfile(iter->first, iter->second, required);
if (iter->second == -1) {
expand_filename(iter->first, required);
if (lnav_data.ld_flags & LNF_ROTATED) {
string path = iter->first + ".*";
if (lnav_data.ld_flags & LNF_ROTATED) {
string path = iter->first + ".*";
glob_t gl;
memset(&gl, 0, sizeof(gl));
if (glob(path.c_str(), 0, NULL, &gl) == 0) {
int lpc;
for (lpc = 0; lpc < (int)gl.gl_pathc; lpc++) {
watch_logfile(gl.gl_pathv[lpc], -1, false);
}
globfree(&gl);
expand_filename(path, false);
}
}
else {
watch_logfile(iter->first, iter->second, required);
}
}
}
@ -3072,7 +3103,23 @@ int main(int argc, char *argv[])
}
for (lpc = 0; lpc < argc; lpc++) {
lnav_data.ld_file_names.insert(make_pair(argv[lpc], -1));
struct stat st;
if (stat(argv[lpc], &st) == -1) {
perror("Cannot stat file");
retval = EXIT_FAILURE;
}
else if (S_ISDIR(st.st_mode)) {
string dir_wild(argv[lpc]);
if (dir_wild[dir_wild.size() - 1] == '/') {
dir_wild.resize(dir_wild.size() - 1);
}
lnav_data.ld_file_names.insert(make_pair(dir_wild + "/*", -1));
}
else {
lnav_data.ld_file_names.insert(make_pair(argv[lpc], -1));
}
}
if (!isatty(STDOUT_FILENO)) {

Loading…
Cancel
Save