13ff40c12SJohn Marino /*
23ff40c12SJohn Marino  * Minimal command line editing
33ff40c12SJohn Marino  * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
43ff40c12SJohn Marino  *
53ff40c12SJohn Marino  * This software may be distributed under the terms of the BSD license.
63ff40c12SJohn Marino  * See README for more details.
73ff40c12SJohn Marino  */
83ff40c12SJohn Marino 
93ff40c12SJohn Marino #include "includes.h"
103ff40c12SJohn Marino 
113ff40c12SJohn Marino #include "common.h"
123ff40c12SJohn Marino #include "eloop.h"
133ff40c12SJohn Marino #include "edit.h"
143ff40c12SJohn Marino 
153ff40c12SJohn Marino 
16*a1157835SDaniel Fojt #define CMD_BUF_LEN 4096
173ff40c12SJohn Marino static char cmdbuf[CMD_BUF_LEN];
183ff40c12SJohn Marino static int cmdbuf_pos = 0;
193ff40c12SJohn Marino static const char *ps2 = NULL;
203ff40c12SJohn Marino 
213ff40c12SJohn Marino static void *edit_cb_ctx;
223ff40c12SJohn Marino static void (*edit_cmd_cb)(void *ctx, char *cmd);
233ff40c12SJohn Marino static void (*edit_eof_cb)(void *ctx);
243ff40c12SJohn Marino 
253ff40c12SJohn Marino 
edit_read_char(int sock,void * eloop_ctx,void * sock_ctx)263ff40c12SJohn Marino static void edit_read_char(int sock, void *eloop_ctx, void *sock_ctx)
273ff40c12SJohn Marino {
283ff40c12SJohn Marino 	int c;
293ff40c12SJohn Marino 	unsigned char buf[1];
303ff40c12SJohn Marino 	int res;
313ff40c12SJohn Marino 
323ff40c12SJohn Marino 	res = read(sock, buf, 1);
333ff40c12SJohn Marino 	if (res < 0)
343ff40c12SJohn Marino 		perror("read");
353ff40c12SJohn Marino 	if (res <= 0) {
363ff40c12SJohn Marino 		edit_eof_cb(edit_cb_ctx);
373ff40c12SJohn Marino 		return;
383ff40c12SJohn Marino 	}
393ff40c12SJohn Marino 	c = buf[0];
403ff40c12SJohn Marino 
413ff40c12SJohn Marino 	if (c == '\r' || c == '\n') {
423ff40c12SJohn Marino 		cmdbuf[cmdbuf_pos] = '\0';
433ff40c12SJohn Marino 		cmdbuf_pos = 0;
443ff40c12SJohn Marino 		edit_cmd_cb(edit_cb_ctx, cmdbuf);
453ff40c12SJohn Marino 		printf("%s> ", ps2 ? ps2 : "");
463ff40c12SJohn Marino 		fflush(stdout);
473ff40c12SJohn Marino 		return;
483ff40c12SJohn Marino 	}
493ff40c12SJohn Marino 
50*a1157835SDaniel Fojt 	if (c == '\b') {
51*a1157835SDaniel Fojt 		if (cmdbuf_pos > 0)
52*a1157835SDaniel Fojt 			cmdbuf_pos--;
53*a1157835SDaniel Fojt 		return;
54*a1157835SDaniel Fojt 	}
55*a1157835SDaniel Fojt 
563ff40c12SJohn Marino 	if (c >= 32 && c <= 255) {
573ff40c12SJohn Marino 		if (cmdbuf_pos < (int) sizeof(cmdbuf) - 1) {
583ff40c12SJohn Marino 			cmdbuf[cmdbuf_pos++] = c;
593ff40c12SJohn Marino 		}
603ff40c12SJohn Marino 	}
613ff40c12SJohn Marino }
623ff40c12SJohn Marino 
633ff40c12SJohn Marino 
edit_init(void (* cmd_cb)(void * ctx,char * cmd),void (* eof_cb)(void * ctx),char ** (* completion_cb)(void * ctx,const char * cmd,int pos),void * ctx,const char * history_file,const char * ps)643ff40c12SJohn Marino int edit_init(void (*cmd_cb)(void *ctx, char *cmd),
653ff40c12SJohn Marino 	      void (*eof_cb)(void *ctx),
663ff40c12SJohn Marino 	      char ** (*completion_cb)(void *ctx, const char *cmd, int pos),
673ff40c12SJohn Marino 	      void *ctx, const char *history_file, const char *ps)
683ff40c12SJohn Marino {
693ff40c12SJohn Marino 	edit_cb_ctx = ctx;
703ff40c12SJohn Marino 	edit_cmd_cb = cmd_cb;
713ff40c12SJohn Marino 	edit_eof_cb = eof_cb;
723ff40c12SJohn Marino 	eloop_register_read_sock(STDIN_FILENO, edit_read_char, NULL, NULL);
733ff40c12SJohn Marino 	ps2 = ps;
743ff40c12SJohn Marino 
753ff40c12SJohn Marino 	printf("%s> ", ps2 ? ps2 : "");
763ff40c12SJohn Marino 	fflush(stdout);
773ff40c12SJohn Marino 
783ff40c12SJohn Marino 	return 0;
793ff40c12SJohn Marino }
803ff40c12SJohn Marino 
813ff40c12SJohn Marino 
edit_deinit(const char * history_file,int (* filter_cb)(void * ctx,const char * cmd))823ff40c12SJohn Marino void edit_deinit(const char *history_file,
833ff40c12SJohn Marino 		 int (*filter_cb)(void *ctx, const char *cmd))
843ff40c12SJohn Marino {
853ff40c12SJohn Marino 	eloop_unregister_read_sock(STDIN_FILENO);
863ff40c12SJohn Marino }
873ff40c12SJohn Marino 
883ff40c12SJohn Marino 
edit_clear_line(void)893ff40c12SJohn Marino void edit_clear_line(void)
903ff40c12SJohn Marino {
913ff40c12SJohn Marino }
923ff40c12SJohn Marino 
933ff40c12SJohn Marino 
edit_redraw(void)943ff40c12SJohn Marino void edit_redraw(void)
953ff40c12SJohn Marino {
963ff40c12SJohn Marino 	cmdbuf[cmdbuf_pos] = '\0';
973ff40c12SJohn Marino 	printf("\r> %s", cmdbuf);
983ff40c12SJohn Marino }
99