ndc.c revision 745e09fc5694e73920aaad18a626275597bdddb1
1d18304287dbabc7835be771400b85d4ae8b63de6San Mehat/* 2d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * Copyright (C) 2008 The Android Open Source Project 3d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * 4d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 5d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * you may not use this file except in compliance with the License. 6d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * You may obtain a copy of the License at 7d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * 8d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * http://www.apache.org/licenses/LICENSE-2.0 9d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * 10d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * Unless required by applicable law or agreed to in writing, software 11d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * distributed under the License is distributed on an "AS IS" BASIS, 12d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * See the License for the specific language governing permissions and 14d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * limitations under the License. 15d18304287dbabc7835be771400b85d4ae8b63de6San Mehat */ 16d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 17d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <stdio.h> 18d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <stdlib.h> 19d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <unistd.h> 20d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <string.h> 21d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <signal.h> 22d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <errno.h> 23d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <fcntl.h> 24d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 25d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <sys/socket.h> 26d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <sys/select.h> 27d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <sys/time.h> 28d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <sys/types.h> 29d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <sys/un.h> 30d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 31d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <cutils/sockets.h> 32d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <private/android_filesystem_config.h> 33d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 34d18304287dbabc7835be771400b85d4ae8b63de6San Mehatstatic void usage(char *progname); 35d18304287dbabc7835be771400b85d4ae8b63de6San Mehatstatic int do_monitor(int sock, int stop_after_cmd); 36d18304287dbabc7835be771400b85d4ae8b63de6San Mehatstatic int do_cmd(int sock, int argc, char **argv); 37d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 38d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint main(int argc, char **argv) { 39d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int sock; 40745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt int cmdOffset = 0; 41d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 42d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (argc < 2) 43d18304287dbabc7835be771400b85d4ae8b63de6San Mehat usage(argv[0]); 44d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 45745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt // try interpreting the first arg as the socket name - if it fails go back to netd 46745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 47745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt if ((sock = socket_local_client(argv[1], 48d18304287dbabc7835be771400b85d4ae8b63de6San Mehat ANDROID_SOCKET_NAMESPACE_RESERVED, 49d18304287dbabc7835be771400b85d4ae8b63de6San Mehat SOCK_STREAM)) < 0) { 50745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt if ((sock = socket_local_client("netd", 51745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt ANDROID_SOCKET_NAMESPACE_RESERVED, 52745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt SOCK_STREAM)) < 0) { 53745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt fprintf(stderr, "Error connecting (%s)\n", strerror(errno)); 54745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt exit(4); 55745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt } 56745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt } else { 57745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt if (argc < 3) usage(argv[0]); 58745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt printf("Using alt socket %s\n", argv[1]); 59745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt cmdOffset = 1; 60d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 61d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 62745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt if (!strcmp(argv[1+cmdOffset], "monitor")) 63d18304287dbabc7835be771400b85d4ae8b63de6San Mehat exit(do_monitor(sock, 0)); 64745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt exit(do_cmd(sock, argc-cmdOffset, &(argv[cmdOffset]))); 65d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 66d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 67d18304287dbabc7835be771400b85d4ae8b63de6San Mehatstatic int do_cmd(int sock, int argc, char **argv) { 6844ec9035d3821f17d185032ed64446cabae266bfDmitry Shmidt char final_cmd[255] = { '0', ' ', '\0' }; 69d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int i; 70d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 71d18304287dbabc7835be771400b85d4ae8b63de6San Mehat for (i = 1; i < argc; i++) { 72d18304287dbabc7835be771400b85d4ae8b63de6San Mehat char *cmp; 73d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 74d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (!index(argv[i], ' ')) 75d18304287dbabc7835be771400b85d4ae8b63de6San Mehat asprintf(&cmp, "%s%s", argv[i], (i == (argc -1)) ? "" : " "); 76d18304287dbabc7835be771400b85d4ae8b63de6San Mehat else 77d18304287dbabc7835be771400b85d4ae8b63de6San Mehat asprintf(&cmp, "\"%s\"%s", argv[i], (i == (argc -1)) ? "" : " "); 78d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 79d18304287dbabc7835be771400b85d4ae8b63de6San Mehat strcat(final_cmd, cmp); 80d18304287dbabc7835be771400b85d4ae8b63de6San Mehat free(cmp); 81d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 82d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 83d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (write(sock, final_cmd, strlen(final_cmd) + 1) < 0) { 84d18304287dbabc7835be771400b85d4ae8b63de6San Mehat perror("write"); 85d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return errno; 86d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 87d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 88d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return do_monitor(sock, 1); 89d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 90d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 91d18304287dbabc7835be771400b85d4ae8b63de6San Mehatstatic int do_monitor(int sock, int stop_after_cmd) { 92d18304287dbabc7835be771400b85d4ae8b63de6San Mehat char *buffer = malloc(4096); 93d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 94d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (!stop_after_cmd) 95d18304287dbabc7835be771400b85d4ae8b63de6San Mehat printf("[Connected to Netd]\n"); 96d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 97d18304287dbabc7835be771400b85d4ae8b63de6San Mehat while(1) { 98d18304287dbabc7835be771400b85d4ae8b63de6San Mehat fd_set read_fds; 99d18304287dbabc7835be771400b85d4ae8b63de6San Mehat struct timeval to; 100d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int rc = 0; 101d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 102d18304287dbabc7835be771400b85d4ae8b63de6San Mehat to.tv_sec = 10; 103d18304287dbabc7835be771400b85d4ae8b63de6San Mehat to.tv_usec = 0; 104d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 105d18304287dbabc7835be771400b85d4ae8b63de6San Mehat FD_ZERO(&read_fds); 106d18304287dbabc7835be771400b85d4ae8b63de6San Mehat FD_SET(sock, &read_fds); 107d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 108d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if ((rc = select(sock +1, &read_fds, NULL, NULL, &to)) < 0) { 109d18304287dbabc7835be771400b85d4ae8b63de6San Mehat fprintf(stderr, "Error in select (%s)\n", strerror(errno)); 110d18304287dbabc7835be771400b85d4ae8b63de6San Mehat free(buffer); 111d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return errno; 112d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } else if (!rc) { 113d18304287dbabc7835be771400b85d4ae8b63de6San Mehat continue; 114d18304287dbabc7835be771400b85d4ae8b63de6San Mehat fprintf(stderr, "[TIMEOUT]\n"); 115d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return ETIMEDOUT; 116d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } else if (FD_ISSET(sock, &read_fds)) { 117d18304287dbabc7835be771400b85d4ae8b63de6San Mehat memset(buffer, 0, 4096); 118d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if ((rc = read(sock, buffer, 4096)) <= 0) { 119d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (rc == 0) 1209d10b341a0ba46f108cb96e46691197d778cbc06San Mehat fprintf(stderr, "Lost connection to Netd - did it crash?\n"); 121d18304287dbabc7835be771400b85d4ae8b63de6San Mehat else 122d18304287dbabc7835be771400b85d4ae8b63de6San Mehat fprintf(stderr, "Error reading data (%s)\n", strerror(errno)); 123d18304287dbabc7835be771400b85d4ae8b63de6San Mehat free(buffer); 124d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (rc == 0) 125d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return ECONNRESET; 126d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return errno; 127d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 12844ec9035d3821f17d185032ed64446cabae266bfDmitry Shmidt 129d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int offset = 0; 130d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int i = 0; 131d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 132d18304287dbabc7835be771400b85d4ae8b63de6San Mehat for (i = 0; i < rc; i++) { 133d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (buffer[i] == '\0') { 134d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int code; 135d18304287dbabc7835be771400b85d4ae8b63de6San Mehat char tmp[4]; 136d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 137d18304287dbabc7835be771400b85d4ae8b63de6San Mehat strncpy(tmp, buffer + offset, 3); 138d18304287dbabc7835be771400b85d4ae8b63de6San Mehat tmp[3] = '\0'; 139d18304287dbabc7835be771400b85d4ae8b63de6San Mehat code = atoi(tmp); 140d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 141d18304287dbabc7835be771400b85d4ae8b63de6San Mehat printf("%s\n", buffer + offset); 142d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (stop_after_cmd) { 143d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (code >= 200 && code < 600) 144d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return 0; 145d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 146d18304287dbabc7835be771400b85d4ae8b63de6San Mehat offset = i + 1; 147d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 148d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 149d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 150d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 151d18304287dbabc7835be771400b85d4ae8b63de6San Mehat free(buffer); 152d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return 0; 153d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 154d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 155d18304287dbabc7835be771400b85d4ae8b63de6San Mehatstatic void usage(char *progname) { 156745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt fprintf(stderr, "Usage: %s [sockname] <monitor>|<cmd> [arg1] [arg2...]\n", progname); 157d18304287dbabc7835be771400b85d4ae8b63de6San Mehat exit(1); 158d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 159