FrameworkListener.cpp revision 7e8529a8b528fd30586aa037f15a31b29582c537
1/* 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> 17#include <string.h> 18 19#define LOG_TAG "FrameworkListener" 20 21#include <cutils/log.h> 22 23#include <sysutils/FrameworkListener.h> 24#include <sysutils/FrameworkCommand.h> 25#include <sysutils/SocketClient.h> 26 27FrameworkListener::FrameworkListener(const char *socketName) : 28 SocketListener(socketName, true) { 29 mCommands = new FrameworkCommandCollection(); 30} 31 32bool FrameworkListener::onDataAvailable(SocketClient *c) { 33 char buffer[255]; 34 int len; 35 36 if ((len = read(c->getSocket(), buffer, sizeof(buffer) -1)) < 0) { 37 SLOGE("read() failed (%s)", strerror(errno)); 38 return errno; 39 } else if (!len) 40 return false; 41 42 int offset = 0; 43 int i; 44 45 for (i = 0; i < len; i++) { 46 if (buffer[i] == '\0') { 47 dispatchCommand(c, buffer + offset); 48 offset = i + 1; 49 } 50 } 51 return true; 52} 53 54void FrameworkListener::registerCmd(FrameworkCommand *cmd) { 55 mCommands->push_back(cmd); 56} 57 58void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) { 59 FrameworkCommandCollection::iterator i; 60 int argc = 0; 61 char *argv[FrameworkListener::CMD_ARGS_MAX]; 62 char tmp[255]; 63 char *p = data; 64 char *q = tmp; 65 bool esc = false; 66 bool quote = false; 67 int k; 68 69 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 } 93 94 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++; 112 } 113 114 argv[argc++] = strdup(tmp); 115#if 0 116 for (k = 0; k < argc; k++) { 117 SLOGD("arg[%d] = '%s'", k, argv[k]); 118 } 119#endif 120 121 if (quote) { 122 cli->sendMsg(500, "Unclosed quotes error", false); 123 goto out; 124 } 125 126 for (i = mCommands->begin(); i != mCommands->end(); ++i) { 127 FrameworkCommand *c = *i; 128 129 if (!strcmp(argv[0], c->getCommand())) { 130 if (c->runCommand(cli, argc, argv)) { 131 SLOGW("Handler '%s' error (%s)", c->getCommand(), strerror(errno)); 132 } 133 goto out; 134 } 135 } 136 137 cli->sendMsg(500, "Command not recognized", false); 138out: 139 int j; 140 for (j = 0; j < argc; j++) 141 free(argv[j]); 142 return; 143} 144