2010-07-18 07:41:18 +08:00
|
|
|
/* Custom CLI command completion.
|
|
|
|
*
|
|
|
|
* Copyright (c) 1992, 1993 Simmule Turner and Rich Salz. All rights reserved.
|
|
|
|
*
|
|
|
|
* This software is not subject to any license of the American Telephone
|
|
|
|
* and Telegraph Company or of the Regents of the University of California.
|
|
|
|
*
|
|
|
|
* Permission is granted to anyone to use this software for any purpose on
|
|
|
|
* any computer system, and to alter it and redistribute it freely, subject
|
|
|
|
* to the following restrictions:
|
|
|
|
* 1. The authors are not responsible for the consequences of use of this
|
|
|
|
* software, no matter how awful, even if they arise from flaws in it.
|
|
|
|
* 2. The origin of this software must not be misrepresented, either by
|
|
|
|
* explicit claim or by omission. Since few users ever read sources,
|
|
|
|
* credits must appear in the documentation.
|
|
|
|
* 3. Altered versions must be plainly marked as such, and must not be
|
|
|
|
* misrepresented as being the original software. Since few users
|
|
|
|
* ever read sources, credits must appear in the documentation.
|
|
|
|
* 4. This notice may not be removed or altered.
|
|
|
|
*/
|
|
|
|
|
2008-10-02 07:52:40 +08:00
|
|
|
#include "editline.h"
|
|
|
|
#include <string.h>
|
|
|
|
|
2010-08-04 08:23:05 +08:00
|
|
|
#define HISTORY "/tmp/.cli-history"
|
|
|
|
|
2010-07-18 04:18:17 +08:00
|
|
|
static char *list[] = {
|
2017-11-29 23:40:10 +08:00
|
|
|
"foo ", "bar ", "bsd ", "cli ", "ls ", "cd ", "malloc ", "tee ", NULL
|
2008-10-02 07:52:40 +08:00
|
|
|
};
|
|
|
|
|
2010-07-18 07:41:18 +08:00
|
|
|
/* Attempt to complete the pathname, returning an allocated copy.
|
|
|
|
* Fill in *unique if we completed it, or set it to 0 if ambiguous. */
|
2010-07-18 04:18:17 +08:00
|
|
|
static char *my_rl_complete(char *token, int *match)
|
2008-10-02 07:52:40 +08:00
|
|
|
{
|
2017-11-29 23:40:10 +08:00
|
|
|
int i;
|
|
|
|
int index = -1;
|
|
|
|
int matchlen = 0;
|
|
|
|
int count = 0;
|
|
|
|
|
|
|
|
for (i = 0; list[i]; i++) {
|
2020-01-05 15:21:36 +08:00
|
|
|
int partlen = strlen(token); /* Part of token */
|
2017-11-29 23:40:10 +08:00
|
|
|
|
2020-01-05 15:21:36 +08:00
|
|
|
if (!strncmp(list[i], token, partlen)) {
|
2017-11-29 23:40:10 +08:00
|
|
|
index = i;
|
|
|
|
matchlen = partlen;
|
|
|
|
count ++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (count == 1) {
|
|
|
|
*match = 1;
|
2020-01-05 15:21:36 +08:00
|
|
|
return strdup(list[index] + matchlen);
|
2017-11-29 23:40:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
2008-10-02 07:52:40 +08:00
|
|
|
}
|
|
|
|
|
2010-07-18 07:41:18 +08:00
|
|
|
/* Return all possible completions. */
|
2010-07-18 04:18:17 +08:00
|
|
|
static int my_rl_list_possib(char *token, char ***av)
|
2008-10-02 07:52:40 +08:00
|
|
|
{
|
2017-11-29 23:40:10 +08:00
|
|
|
int i, num, total = 0;
|
|
|
|
char **copy;
|
2018-11-17 18:50:26 +08:00
|
|
|
|
2017-11-29 23:40:10 +08:00
|
|
|
for (num = 0; list[num]; num++)
|
|
|
|
;
|
|
|
|
|
2020-01-05 15:21:36 +08:00
|
|
|
if (!num)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
copy = malloc(num * sizeof(char *));
|
2017-11-29 23:40:10 +08:00
|
|
|
for (i = 0; i < num; i++) {
|
2020-01-05 15:21:36 +08:00
|
|
|
if (!strncmp(list[i], token, strlen (token))) {
|
|
|
|
copy[total] = strdup(list[i]);
|
|
|
|
total++;
|
2017-11-29 23:40:10 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
*av = copy;
|
|
|
|
|
|
|
|
return total;
|
2008-10-02 07:52:40 +08:00
|
|
|
}
|
|
|
|
|
2010-08-05 18:48:51 +08:00
|
|
|
el_status_t list_possible(void)
|
|
|
|
{
|
|
|
|
char **av;
|
|
|
|
char *word;
|
|
|
|
int ac;
|
|
|
|
|
|
|
|
word = el_find_word();
|
|
|
|
ac = rl_list_possib(word, &av);
|
|
|
|
if (word)
|
|
|
|
free(word);
|
|
|
|
if (ac) {
|
|
|
|
el_print_columns(ac, av);
|
|
|
|
while (--ac >= 0)
|
|
|
|
free(av[ac]);
|
|
|
|
free(av);
|
|
|
|
|
|
|
|
return CSmove;
|
|
|
|
}
|
|
|
|
|
|
|
|
return el_ring_bell();
|
|
|
|
}
|
|
|
|
|
2015-04-06 20:45:07 +08:00
|
|
|
el_status_t do_suspend(void)
|
|
|
|
{
|
2017-11-29 23:40:10 +08:00
|
|
|
puts("Abort!");
|
|
|
|
return CSstay;
|
2015-04-06 20:45:07 +08:00
|
|
|
}
|
|
|
|
|
2019-05-06 06:52:13 +08:00
|
|
|
static void breakit(int signo)
|
|
|
|
{
|
2020-01-05 15:21:36 +08:00
|
|
|
(void)signo;
|
2019-05-08 23:03:49 +08:00
|
|
|
puts("Got SIGINT");
|
2019-05-06 06:52:13 +08:00
|
|
|
}
|
|
|
|
|
2020-01-05 15:21:36 +08:00
|
|
|
/* Use el_no_echo when reading passwords and similar */
|
|
|
|
static int unlock(const char *passwd)
|
|
|
|
{
|
|
|
|
char *prompt = "Enter password: ";
|
|
|
|
char *line;
|
|
|
|
int rc = 1;
|
|
|
|
|
|
|
|
el_no_echo = 1;
|
|
|
|
|
|
|
|
while ((line = readline(prompt))) {
|
|
|
|
rc = strncmp(line, passwd, strlen(passwd));
|
|
|
|
free(line);
|
|
|
|
|
|
|
|
if (rc) {
|
|
|
|
printf("\nWrong password, please try again, it's secret.\n");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("\nAchievement unlocked!\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
el_no_echo = 0;
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2017-11-29 23:40:10 +08:00
|
|
|
int main(void)
|
2008-10-02 07:52:40 +08:00
|
|
|
{
|
2017-11-29 23:40:10 +08:00
|
|
|
char *line;
|
2018-11-17 18:50:26 +08:00
|
|
|
char *prompt = "cli> ";
|
2017-11-29 23:40:10 +08:00
|
|
|
|
2019-05-06 06:52:13 +08:00
|
|
|
signal(SIGINT, breakit);
|
|
|
|
|
2017-11-29 23:40:10 +08:00
|
|
|
/* Setup callbacks */
|
|
|
|
rl_set_complete_func(&my_rl_complete);
|
|
|
|
rl_set_list_possib_func(&my_rl_list_possib);
|
2018-11-17 18:50:26 +08:00
|
|
|
|
2017-11-29 23:40:10 +08:00
|
|
|
el_bind_key('?', list_possible);
|
|
|
|
el_bind_key(CTL('Z'), do_suspend);
|
|
|
|
read_history(HISTORY);
|
|
|
|
|
2018-11-17 18:50:26 +08:00
|
|
|
while ((line = readline(prompt))) {
|
2020-01-05 15:21:36 +08:00
|
|
|
if (!strncmp(line, "unlock", 6) && unlock("secret")) {
|
|
|
|
free(line);
|
|
|
|
fprintf(stderr, "\nSecurity breach, user logged out!\n");
|
|
|
|
break;
|
2018-11-17 18:50:26 +08:00
|
|
|
}
|
|
|
|
|
2010-08-07 06:08:31 +08:00
|
|
|
if (*line != '\0')
|
|
|
|
printf("\t\t\t|%s|\n", line);
|
2018-11-17 18:50:26 +08:00
|
|
|
free(line);
|
2017-11-29 23:40:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
write_history(HISTORY);
|
|
|
|
|
|
|
|
return 0;
|
2008-10-02 07:52:40 +08:00
|
|
|
}
|
2017-11-29 23:40:10 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Local Variables:
|
|
|
|
* c-file-style: "k&r"
|
|
|
|
* c-basic-offset: 4
|
|
|
|
* End:
|
|
|
|
*/
|