diff options
| author | Jonas Suhr Christensen <jsc@umbraculum.org> | 2012-05-22 12:09:08 +0200 | 
|---|---|---|
| committer | Jonas Suhr Christensen <jsc@umbraculum.org> | 2012-05-22 12:09:08 +0200 | 
| commit | ae4b5a79e5863ee6440b2070361f3229285a9380 (patch) | |
| tree | 7461391600f0ac80b47690c614940e019e237fef /src | |
| parent | c5effddd6d8edac976b40133f0f3b3d589bfe9b2 (diff) | |
Working cli client.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.am | 1 | ||||
| -rw-r--r-- | src/messageparser.cc | 80 | ||||
| -rw-r--r-- | src/messageparser.h | 1 | ||||
| -rw-r--r-- | src/muniacli.cc | 257 | 
4 files changed, 302 insertions, 37 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 0e59695..c256f54 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,6 +28,7 @@ muniacli_LDADD = $(LIBWEBSOCKETS_LIBS)  muniacli_CXXFLAGS = $(LIBWEBSOCKETS_CFLAGS)  muniacli_SOURCES = \ +	messageparser.cc \  	muniacli.cc  EXTRA_DIST = \ diff --git a/src/messageparser.cc b/src/messageparser.cc index 62923be..bfaa033 100644 --- a/src/messageparser.cc +++ b/src/messageparser.cc @@ -98,75 +98,95 @@ inline static void parse_into_msg_tokens(std::string& data,  }  inline static void create_msg_list(MsgTokensList& msgTokensList, -                                   MessageList& msgList) { +                                   MessageList& msgList, +                                   bool clientmode) { +  int origin = 0; +  if(clientmode) { +    origin = 1; +  } +    MsgTokensList::iterator it_msg;    for(it_msg = msgTokensList.begin(); it_msg != msgTokensList.end(); it_msg++) {      TokenVector t = *it_msg;      //malformed msg -    if(t.size() < 1) continue; +    if(t.size() < origin+1) continue;      message_t m; -    if(t[0] == "observe") m.cmd = cmd::observe; -    else if(t[0] == "unobserve") m.cmd = cmd::unobserve; -    else if(t[0] == "create") m.cmd = cmd::create; -    else if(t[0] == "remove") m.cmd = cmd::remove; -    else if(t[0] == "move") m.cmd = cmd::move; -    else if(t[0] == "update") m.cmd = cmd::update; +//  printf("t[%d] : %s, running in clientmode: %d\n", origin, t[origin].c_str(), clientmode); + +//  printf("%d\n", t.size()); + +    if(t[origin] == "observe") m.cmd = cmd::observe; +    else if(t[origin] == "unobserve") m.cmd = cmd::unobserve; +    else if(t[origin] == "create") m.cmd = cmd::create; +    else if(t[origin] == "remove") m.cmd = cmd::remove; +    else if(t[origin] == "move") m.cmd = cmd::move; +    else if(t[origin] == "update") m.cmd = cmd::update;      else m.cmd = cmd::error;  //    printf("Number of tokens %d\n", t.size());      switch(m.cmd) {        case cmd::observe: { -        if(t.size() != 1+1) {  -          printf("Wrong number of parameters\n"); +        if(t.size() != origin+1+1) {  +          printf("W1: rong number of parameters\n");            continue;          } -        m.observe.id = atoi(t[1].c_str()); +        m.observe.id = atoi(t[origin+1].c_str());          break;        }        case cmd::unobserve: { -        if(t.size() != 1+1) {  +        if(t.size() != origin+1+1) {             printf("Wrong number of parameters\n");            continue;          } -        m.unobserve.id = atoi(t[1].c_str()); +        m.unobserve.id = atoi(t[origin+1].c_str());          break;        }        case cmd::create: { -        if(t.size() != 1+1) {  +        if(!clientmode && t.size() != origin+1+1) {             printf("Wrong number of parameters\n");            continue;          } -        m.create.parentid = atoi(t[1].c_str()); +        if(clientmode && t.size() != origin+1+2) {  +          printf("Wrong number of parameters\n"); +          continue; +        } +        if(clientmode) { +          m.create.id = atoi(t[origin+1].c_str()); +          m.create.parentid = atoi(t[origin+2].c_str()); +        } +        else { +          m.create.parentid = atoi(t[origin+1].c_str()); +        }          break;        }        case cmd::remove: { -        if(t.size() != 1+1) {  +        if(t.size() != origin+1+1) {             printf("Wrong number of parameters\n");            continue;          } -        m.remove.id = atoi(t[1].c_str()); +        m.remove.id = atoi(t[origin+1].c_str());          break;        }        case cmd::move: { -        if(t.size() != 2+1) {  +        if(t.size() != origin+2+1) {             printf("Wrong number of parameters\n");            continue;          } -        m.move.id = atoi(t[1].c_str()); -        m.move.parentid = atoi(t[2].c_str()); +        m.move.id = atoi(t[origin+1].c_str()); +        m.move.parentid = atoi(t[origin+2].c_str());          break;        }        case cmd::update: { -        if(t.size() != 2+1) { +        if(t.size() != origin+2+1) {            printf("Wrong number of parameters\n");            continue;           } -        m.update.id = atoi(t[1].c_str()); -        sprintf(m.update.title, "%s", t[2].c_str()); +        m.update.id = atoi(t[origin+1].c_str()); +        sprintf(m.update.title, "%s", t[origin+2].c_str());          break;        }        default: @@ -177,13 +197,23 @@ inline static void create_msg_list(MsgTokensList& msgTokensList,  }  MessageList parse_msg(std::string data) { -  printf("Parsing: %s\n", data.c_str());  +//  printf("Parsing: %s\n", data.c_str());  + +  MsgTokensList msgTokensList; +  parse_into_msg_tokens(data, msgTokensList); +   +  MessageList msgList; +  create_msg_list(msgTokensList, msgList, false); +   +  return msgList; +} +MessageList parse_msg_client(std::string data) {    MsgTokensList msgTokensList;    parse_into_msg_tokens(data, msgTokensList);    MessageList msgList; -  create_msg_list(msgTokensList, msgList); +  create_msg_list(msgTokensList, msgList, true);    return msgList;  } diff --git a/src/messageparser.h b/src/messageparser.h index 11b11cb..95208f2 100644 --- a/src/messageparser.h +++ b/src/messageparser.h @@ -31,6 +31,7 @@  #include "message.h"  MessageList parse_msg(std::string msg); +MessageList parse_msg_client(std::string msg);  //message_t create_msg(cmd::cmd_t type, task_t task);  std::string msg_tostring(message_t msg); diff --git a/src/muniacli.cc b/src/muniacli.cc index a84de65..30e0ecf 100644 --- a/src/muniacli.cc +++ b/src/muniacli.cc @@ -30,13 +30,94 @@  #include <unistd.h>  #include <getopt.h>  #include <string.h> +#include <string> +#include <list> +#include <map> + +#include "message.h" +#include "messageparser.h"  #include <libwebsockets.h> +  enum demo_protocols {  	PROTOCOL_TASK  }; +enum cmd_t { +  DEFAULT, +  CREATE, +  LIST, +  REMOVE, +  UPDATE +}; + +static bool run; +static bool interactive; +static std::string msgs; +static int taskid; + +static std::map<int, std::list<int> > structuremap; +static std::map<int, std::string> titlemap; + +static std::string indent; + + +static void rec_pretty_print(int node) { +  //  printf("pretty printing %d\n", node); +  //  for(std::map<int, std::list<int>>::iterator it = structuremap.begin(); +  //        it != structuremap.end(); it++) { +  //    std::list<int> childlist = *it; +   +  printf("%s%d - %s\n", indent.c_str(), node, titlemap[node].c_str()); +  std::list<int> childlist = structuremap[node];  +  if(!childlist.empty()) { +    for(std::list<int>::iterator it = childlist.begin(); +        it != childlist.end(); it++) { +      int child = *it; +      indent += "  "; +      rec_pretty_print(child); +    } +  } +   +  indent = indent.substr(0, indent.length()-2); +} +   +static void pretty_print(std::string msgs) { +  //  printf("%s\n", msgs.c_str()); +  MessageList list = parse_msg_client(msgs); + +  std::string indent; +  int prevtask = -1; + +  std::list<int> childlist; + +  for(MessageList::iterator it = list.begin(); +      it != list.end(); it++) { +    message_t msg = *it; +     +    switch(msg.cmd) { +    case cmd::create: +      //      printf("Parent %d, id %d\n", msg.create.parentid, msg.create.id); +      childlist = structuremap[msg.create.parentid]; +      childlist.push_back(msg.create.id); +      structuremap[msg.create.parentid] = childlist; +      //      printf("Childlist size of %d = %d\n", msg.create.parentid, childlist.size()); +      break; +    case cmd::update: +      //      char buf[256]; +      //      sprintf(buf, "%s", msg.update.title); +      titlemap[msg.update.id] = msg.update.title; +      //      printf("%s\n", buf); +      break; +    default: +      break; +    } +  } + +  rec_pretty_print(taskid); +} +  static int callback_task(struct libwebsocket_context *me,                           struct libwebsocket *wsi,                           enum libwebsocket_callback_reasons reason, @@ -46,6 +127,7 @@ static int callback_task(struct libwebsocket_context *me,  						  LWS_SEND_BUFFER_POST_PADDING];  	int l;    char msg[4096]; +  std::string r;  	switch (reason) { @@ -59,21 +141,34 @@ static int callback_task(struct libwebsocket_context *me,  		break;  	case LWS_CALLBACK_CLIENT_RECEIVE: -    fprintf(stderr, "rx %d '", (int)len); -    fwrite(in, len, 1, stderr); -    fprintf(stderr, "'\n"); +    //    fprintf(stderr, "rx %d '", (int)len); +    //    fwrite(in, len, 1, stderr); +    //    fprintf(stderr, "\n"); +    pretty_print((char*)in);      libwebsocket_callback_on_writable(me, wsi); + +    if(!interactive) run = false;  		break;  	case LWS_CALLBACK_CLIENT_WRITEABLE: -    fgets(msg, sizeof(msg), stdin); -    printf("send...\n"); -		l = sprintf((char *)&buf[LWS_SEND_BUFFER_PRE_PADDING], "%s", msg); +     +    if(interactive) { +      fgets(msg, sizeof(msg), stdin); +      msgs += msg; +      printf("send...\n"); +    } -		libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], -                       l, LWS_WRITE_TEXT); +    if(!msgs.empty()) { +      //      printf("Sending %s\n", msgs.c_str()); +      l = sprintf((char *)&buf[LWS_SEND_BUFFER_PRE_PADDING], "%s", msgs.c_str()); +     +      libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], +                         l, LWS_WRITE_TEXT); +     +      msgs.clear(); +    }  		break; - +      	default:  		break;  	} @@ -92,6 +187,7 @@ int client(const char *address, int port)  	struct libwebsocket *wsi_task = NULL;  	int ietf_version = -1; // latest +  	context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, NULL,                                          protocols,                                          libwebsocket_internal_extensions, @@ -108,6 +204,7 @@ int client(const char *address, int port)  	 */    int n = 1;  	while(n >= 0) { +  		n = libwebsocket_service(context, 1000);  		if (wsi_task == NULL) { @@ -129,17 +226,153 @@ int client(const char *address, int port)  					wsi_mirror, LWS_CLOSE_STATUS_GOINGAWAY);        */  		} + +    if(!run) break;  	} -	fprintf(stderr, "Exiting\n"); +  //	fprintf(stderr, "Exiting\n");  	libwebsocket_context_destroy(context);  	return 0;  } -int main() +static struct option options[] = { +  { "create", no_argument, NULL, 'C'}, +  { "help", no_argument,    NULL, 'h' }, +  { "host", required_argument, NULL, 'H'}, +  { "interactive", no_argument, NULL, 'i'}, +  { "id", required_argument, NULL, 'I'}, +  { "list", no_argument, NULL, 'L'}, +  { "name", required_argument, NULL, 'n'}, +  { "port", required_argument,  NULL, 'p' }, +  { "remove", no_argument, NULL, 'R'}, +  { "update", required_argument, NULL, 'U'}, +  { NULL, 0, 0, 0 } +}; + +static char* USAGE= +  "Usage: muniacli [OPTION]... TASK COMMAND\n" +  "Commandline client to munia." +  "Options:\n" +  "  -p, --port          Port on host\n" +  "  -H, --host          Host\n" +  "  -i, --interactive   Run in interactive/shell mode\n" +  "Task:\n" +  "  -N, --name          Select task by name\n" +  "  -I, --id            Select task by id\n" +  "Commands:\n" +  "  -C, --create        Create new subtask in TASK\n" +  "  -L, --list          List subtasks in TASK\n" +  "  -R, --remove        Remove subtask from TASK\n" +  "  -U, --update        Update data in TASK"; + + +int main(int argc, char** argv)  { -  client("localhost", 10001); +  int port = 7681; +  struct libwebsocket_context *context; +  int opts = 0; +  std::string host = "localhost"; +  int optionscount = 0; +  std::string taskbyid; +  std::string taskbyname; +  cmd_t cmd = DEFAULT; +  std::string cmd_opts; + +  interactive = false; +  run = true; + +  int n = 0; +  while(n >= 0) { +    n = getopt_long(argc, argv, "p:iN:I:CLR:U:hH:", options, NULL); +    if(n < 0) continue; +    switch(n) { +    case 'i': +      interactive = true; +      break; +    case 'p': +      port = atoi(optarg); +      break; +    case 'H': +      host = optarg; +      break; +    case 'h': +      fprintf(stderr, "%s\n", USAGE); +      exit(1); +    case 'N': +      taskbyname = optarg; +      break; +    case 'I': +      taskbyid = optarg; +      break; +    case 'C': +      cmd = CREATE; +      break; +    case 'L': +      cmd = LIST; +      break; +    case 'R': +      cmd = REMOVE; +      break; +    case 'U': +      cmd = UPDATE; +      cmd_opts = optarg; +      break; +    } +  } + +  if(cmd == DEFAULT) { +    fprintf(stderr, "%s\n", USAGE); +    exit(1); +  } + +  if(!taskbyname.empty()) { +    taskbyid = -1; +    fprintf(stderr, "Option '-N, --name' is not yet supported\n"); +    fprintf(stderr, "%s\n", USAGE); +    exit(1); +  } + +  if(taskbyid.empty()) { +    fprintf(stderr, "%s\n", USAGE); +    exit(1); +  } + +  taskid = atoi(taskbyid.c_str()); + +  switch(cmd) { +  case CREATE: +    msgs = "create " + taskbyid + ";"; +    break; +  case LIST: +    msgs = "observe " + taskbyid; //+  +      //    "; unobserve " + task + ";"; +    break; +  case REMOVE: +    msgs = "remove " + taskbyid + ";"; +    break; +  case UPDATE: +    msgs = "update " + taskbyid + " " + cmd_opts; +    break; +  } + +  /* +  if(!interactive && argc - optionscount < 3) { +    fprintf(stderr, "%s", USAGE); +    exit(1); +  } +  else if (interactive && argc - optionscount < 2){ +    fprintf(stderr, "%s", USAGE); +    exit(1); +  } + +    if(!interactive) { +    //    printf("cmd: %s\n", argv[3]); +      msgs = argv[3]; +    } +  */ + +  client("localhost", port);    return 0;  }  | 
