blob: 640b6df25b4a253a8af83ebdd465b664c77c65e5 [file] [log] [blame]
San Mehat168415b2009-05-06 11:14:21 -07001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include <errno.h>
San Mehat3d407292009-05-07 08:49:30 -070017#include <string.h>
San Mehat168415b2009-05-06 11:14:21 -070018
19#define LOG_TAG "FrameworkListener"
20
21#include <cutils/log.h>
22
23#include <sysutils/FrameworkListener.h>
24#include <sysutils/FrameworkCommand.h>
San Mehatfa644ff2009-05-08 11:15:53 -070025#include <sysutils/SocketClient.h>
San Mehat168415b2009-05-06 11:14:21 -070026
27FrameworkListener::FrameworkListener(const char *socketName) :
28 SocketListener(socketName, true) {
29 mCommands = new FrameworkCommandCollection();
30}
31
San Mehatfa644ff2009-05-08 11:15:53 -070032bool FrameworkListener::onDataAvailable(SocketClient *c) {
San Mehatd7680662009-05-12 11:16:59 -070033 char buffer[255];
San Mehat168415b2009-05-06 11:14:21 -070034 int len;
35
San Mehatfa644ff2009-05-08 11:15:53 -070036 if ((len = read(c->getSocket(), buffer, sizeof(buffer) -1)) < 0) {
San Mehat7e8529a2010-03-25 09:31:42 -070037 SLOGE("read() failed (%s)", strerror(errno));
Kenny Rootf31d2ed2010-09-14 09:55:22 -070038 return false;
San Mehatc73a3a52009-06-15 14:06:03 -070039 } else if (!len)
San Mehat168415b2009-05-06 11:14:21 -070040 return false;
San Mehat168415b2009-05-06 11:14:21 -070041
San Mehatd7680662009-05-12 11:16:59 -070042 int offset = 0;
San Mehat168415b2009-05-06 11:14:21 -070043 int i;
44
San Mehat168415b2009-05-06 11:14:21 -070045 for (i = 0; i < len; i++) {
San Mehatc73a3a52009-06-15 14:06:03 -070046 if (buffer[i] == '\0') {
San Mehatd7680662009-05-12 11:16:59 -070047 dispatchCommand(c, buffer + offset);
48 offset = i + 1;
San Mehat168415b2009-05-06 11:14:21 -070049 }
50 }
51 return true;
52}
53
54void FrameworkListener::registerCmd(FrameworkCommand *cmd) {
55 mCommands->push_back(cmd);
56}
57
San Mehatc73a3a52009-06-15 14:06:03 -070058void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) {
San Mehatc4a895b2009-06-23 21:10:57 -070059 FrameworkCommandCollection::iterator i;
60 int argc = 0;
San Mehatc73a3a52009-06-15 14:06:03 -070061 char *argv[FrameworkListener::CMD_ARGS_MAX];
San Mehatc4a895b2009-06-23 21:10:57 -070062 char tmp[255];
63 char *p = data;
64 char *q = tmp;
65 bool esc = false;
66 bool quote = false;
67 int k;
San Mehatfa644ff2009-05-08 11:15:53 -070068
San Mehatc4a895b2009-06-23 21:10:57 -070069 memset(argv, 0, sizeof(argv));
70 memset(tmp, 0, sizeof(tmp));
71 while(*p) {
72 if (*p == '\\') {
73 if (esc) {
74 *q++ = '\\';
75 esc = false;
76 } else
77 esc = true;
78 p++;
79 continue;
80 } else if (esc) {
81 if (*p == '"')
82 *q++ = '"';
83 else if (*p == '\\')
84 *q++ = '\\';
85 else {
86 cli->sendMsg(500, "Unsupported escape sequence", false);
87 goto out;
88 }
89 p++;
90 esc = false;
91 continue;
92 }
San Mehatc73a3a52009-06-15 14:06:03 -070093
San Mehatc4a895b2009-06-23 21:10:57 -070094 if (*p == '"') {
95 if (quote)
96 quote = false;
97 else
98 quote = true;
99 p++;
100 continue;
101 }
102
103 *q = *p++;
104 if (!quote && *q == ' ') {
105 *q = '\0';
106 argv[argc++] = strdup(tmp);
107 memset(tmp, 0, sizeof(tmp));
108 q = tmp;
109 continue;
110 }
111 q++;
San Mehatfa644ff2009-05-08 11:15:53 -0700112 }
113
San Mehatc4a895b2009-06-23 21:10:57 -0700114 argv[argc++] = strdup(tmp);
115#if 0
116 for (k = 0; k < argc; k++) {
San Mehat7e8529a2010-03-25 09:31:42 -0700117 SLOGD("arg[%d] = '%s'", k, argv[k]);
San Mehatc4a895b2009-06-23 21:10:57 -0700118 }
119#endif
San Mehat168415b2009-05-06 11:14:21 -0700120
San Mehatc4a895b2009-06-23 21:10:57 -0700121 if (quote) {
122 cli->sendMsg(500, "Unclosed quotes error", false);
123 goto out;
124 }
125
San Mehat168415b2009-05-06 11:14:21 -0700126 for (i = mCommands->begin(); i != mCommands->end(); ++i) {
127 FrameworkCommand *c = *i;
128
San Mehatc73a3a52009-06-15 14:06:03 -0700129 if (!strcmp(argv[0], c->getCommand())) {
130 if (c->runCommand(cli, argc, argv)) {
San Mehat7e8529a2010-03-25 09:31:42 -0700131 SLOGW("Handler '%s' error (%s)", c->getCommand(), strerror(errno));
San Mehat168415b2009-05-06 11:14:21 -0700132 }
San Mehatc4a895b2009-06-23 21:10:57 -0700133 goto out;
San Mehat168415b2009-05-06 11:14:21 -0700134 }
135 }
136
San Mehatd7680662009-05-12 11:16:59 -0700137 cli->sendMsg(500, "Command not recognized", false);
San Mehatc4a895b2009-06-23 21:10:57 -0700138out:
139 int j;
140 for (j = 0; j < argc; j++)
141 free(argv[j]);
San Mehatfa644ff2009-05-08 11:15:53 -0700142 return;
San Mehat168415b2009-05-06 11:14:21 -0700143}