diff --git a/utils/.gitignore b/utils/.gitignore
index ffd29a92..414487cd 100644
--- a/utils/.gitignore
+++ b/utils/.gitignore
@@ -6,6 +6,7 @@ chvideomode
clear
colormake
column
+command-not-found
cp
date
du
diff --git a/utils/Makefile b/utils/Makefile
index 4771f322..515d443c 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -22,6 +22,7 @@ chvideomode \
clear \
colormake \
column \
+command-not-found \
cp \
date \
du \
diff --git a/utils/command-not-found.cpp b/utils/command-not-found.cpp
new file mode 100644
index 00000000..4620b136
--- /dev/null
+++ b/utils/command-not-found.cpp
@@ -0,0 +1,54 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the Free
+ Software Foundation, either version 3 of the License, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program. If not, see .
+
+ command-not-found.cpp
+ Prints a notice that the attempted command wasn't found and possibly
+ suggests how to install the command or suggests the proper spelling in case
+ of a typo.
+
+*******************************************************************************/
+
+#include
+#include
+
+void suggest_editor(const char* filename)
+{
+ fprintf(stderr, "No command '%s' found, did you mean:\n", filename);
+ fprintf(stderr, " Command 'editor' from package 'utils'\n");
+}
+
+void suggest_pager(const char* filename)
+{
+ fprintf(stderr, "No command '%s' found, did you mean:\n", filename);
+ fprintf(stderr, " Command 'pager' from package 'utils'\n");
+}
+
+int main(int argc, char* argv[])
+{
+ const char* filename = 2 <= argc ? argv[1] : argv[0];
+ if ( !strcmp(filename, "ed") ||
+ !strcmp(filename, "emacs") ||
+ !strcmp(filename, "nano") ||
+ !strcmp(filename, "vi") ||
+ !strcmp(filename, "vim") )
+ suggest_editor(filename);
+ else if ( !strcmp(filename, "less") ||
+ !strcmp(filename, "more") )
+ suggest_pager(filename);
+ fprintf(stderr, "%s: command not found\n", filename);
+ return 127;
+}
diff --git a/utils/mxsh.cpp b/utils/mxsh.cpp
index beee7452..7a197eb5 100644
--- a/utils/mxsh.cpp
+++ b/utils/mxsh.cpp
@@ -68,7 +68,7 @@ void updateenv()
}
}
-int runcommandline(const char** tokens, bool* exitexec)
+int runcommandline(const char** tokens, bool* exitexec, bool interactive)
{
int result = 127;
size_t cmdnext = 0;
@@ -273,6 +273,12 @@ readcmd:
}
execvp(argv[0], argv);
+ if ( interactive )
+ {
+ int errno_saved = errno;
+ execlp("command-not-found", "command-not-found", argv[0], NULL);
+ errno = errno_saved;
+ }
error(127, errno, "%s", argv[0]);
return 127;
@@ -454,7 +460,7 @@ int get_and_run_command(FILE* fp, const char* fpname, bool interactive,
return status;
argv[argc] = NULL;
- status = runcommandline(argv, exitexec);
+ status = runcommandline(argv, exitexec, interactive);
if ( status && exit_on_error )
*exitexec = true;
return status;