18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Minimal command line editing
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h"
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h"
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h"
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "edit.h"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CMD_BUF_LEN 256
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic char cmdbuf[CMD_BUF_LEN];
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cmdbuf_pos = 0;
1961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic const char *ps2 = NULL;
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void *edit_cb_ctx;
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void (*edit_cmd_cb)(void *ctx, char *cmd);
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void (*edit_eof_cb)(void *ctx);
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void edit_read_char(int sock, void *eloop_ctx, void *sock_ctx)
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int c;
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned char buf[1];
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int res;
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	res = read(sock, buf, 1);
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res < 0)
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		perror("read");
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res <= 0) {
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		edit_eof_cb(edit_cb_ctx);
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	c = buf[0];
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (c == '\r' || c == '\n') {
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cmdbuf[cmdbuf_pos] = '\0';
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cmdbuf_pos = 0;
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		edit_cmd_cb(edit_cb_ctx, cmdbuf);
4561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		printf("%s> ", ps2 ? ps2 : "");
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		fflush(stdout);
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (c >= 32 && c <= 255) {
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (cmdbuf_pos < (int) sizeof(cmdbuf) - 1) {
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			cmdbuf[cmdbuf_pos++] = c;
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint edit_init(void (*cmd_cb)(void *ctx, char *cmd),
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	      void (*eof_cb)(void *ctx),
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	      char ** (*completion_cb)(void *ctx, const char *cmd, int pos),
6161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	      void *ctx, const char *history_file, const char *ps)
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_cb_ctx = ctx;
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_cmd_cb = cmd_cb;
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_eof_cb = eof_cb;
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_register_read_sock(STDIN_FILENO, edit_read_char, NULL, NULL);
6761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ps2 = ps;
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	printf("%s> ", ps2 ? ps2 : "");
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	fflush(stdout);
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid edit_deinit(const char *history_file,
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 int (*filter_cb)(void *ctx, const char *cmd))
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_unregister_read_sock(STDIN_FILENO);
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid edit_clear_line(void)
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid edit_redraw(void)
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf[cmdbuf_pos] = '\0';
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("\r> %s", cmdbuf);
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
93