Home | History | Annotate | Download | only in utils
      1 /*
      2  * Minimal command line editing
      3  * Copyright (c) 2010, Jouni Malinen <j (at) w1.fi>
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "includes.h"
     10 
     11 #include "common.h"
     12 #include "eloop.h"
     13 #include "edit.h"
     14 
     15 
     16 #define CMD_BUF_LEN 4096
     17 static char cmdbuf[CMD_BUF_LEN];
     18 static int cmdbuf_pos = 0;
     19 static const char *ps2 = NULL;
     20 
     21 static void *edit_cb_ctx;
     22 static void (*edit_cmd_cb)(void *ctx, char *cmd);
     23 static void (*edit_eof_cb)(void *ctx);
     24 
     25 
     26 static void edit_read_char(int sock, void *eloop_ctx, void *sock_ctx)
     27 {
     28 	int c;
     29 	unsigned char buf[1];
     30 	int res;
     31 
     32 	res = read(sock, buf, 1);
     33 	if (res < 0)
     34 		perror("read");
     35 	if (res <= 0) {
     36 		edit_eof_cb(edit_cb_ctx);
     37 		return;
     38 	}
     39 	c = buf[0];
     40 
     41 	if (c == '\r' || c == '\n') {
     42 		cmdbuf[cmdbuf_pos] = '\0';
     43 		cmdbuf_pos = 0;
     44 		edit_cmd_cb(edit_cb_ctx, cmdbuf);
     45 		printf("%s> ", ps2 ? ps2 : "");
     46 		fflush(stdout);
     47 		return;
     48 	}
     49 
     50 	if (c == '\b') {
     51 		if (cmdbuf_pos > 0)
     52 			cmdbuf_pos--;
     53 		return;
     54 	}
     55 
     56 	if (c >= 32 && c <= 255) {
     57 		if (cmdbuf_pos < (int) sizeof(cmdbuf) - 1) {
     58 			cmdbuf[cmdbuf_pos++] = c;
     59 		}
     60 	}
     61 }
     62 
     63 
     64 int edit_init(void (*cmd_cb)(void *ctx, char *cmd),
     65 	      void (*eof_cb)(void *ctx),
     66 	      char ** (*completion_cb)(void *ctx, const char *cmd, int pos),
     67 	      void *ctx, const char *history_file, const char *ps)
     68 {
     69 	edit_cb_ctx = ctx;
     70 	edit_cmd_cb = cmd_cb;
     71 	edit_eof_cb = eof_cb;
     72 	eloop_register_read_sock(STDIN_FILENO, edit_read_char, NULL, NULL);
     73 	ps2 = ps;
     74 
     75 	printf("%s> ", ps2 ? ps2 : "");
     76 	fflush(stdout);
     77 
     78 	return 0;
     79 }
     80 
     81 
     82 void edit_deinit(const char *history_file,
     83 		 int (*filter_cb)(void *ctx, const char *cmd))
     84 {
     85 	eloop_unregister_read_sock(STDIN_FILENO);
     86 }
     87 
     88 
     89 void edit_clear_line(void)
     90 {
     91 }
     92 
     93 
     94 void edit_redraw(void)
     95 {
     96 	cmdbuf[cmdbuf_pos] = '\0';
     97 	printf("\r> %s", cmdbuf);
     98 }
     99