ndc.c revision 745e09fc5694e73920aaad18a626275597bdddb1
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 17#include <stdio.h> 18#include <stdlib.h> 19#include <unistd.h> 20#include <string.h> 21#include <signal.h> 22#include <errno.h> 23#include <fcntl.h> 24 25#include <sys/socket.h> 26#include <sys/select.h> 27#include <sys/time.h> 28#include <sys/types.h> 29#include <sys/un.h> 30 31#include <cutils/sockets.h> 32#include <private/android_filesystem_config.h> 33 34static void usage(char *progname); 35static int do_monitor(int sock, int stop_after_cmd); 36static int do_cmd(int sock, int argc, char **argv); 37 38int main(int argc, char **argv) { 39 int sock; 40 int cmdOffset = 0; 41 42 if (argc < 2) 43 usage(argv[0]); 44 45 // try interpreting the first arg as the socket name - if it fails go back to netd 46 47 if ((sock = socket_local_client(argv[1], 48 ANDROID_SOCKET_NAMESPACE_RESERVED, 49 SOCK_STREAM)) < 0) { 50 if ((sock = socket_local_client("netd", 51 ANDROID_SOCKET_NAMESPACE_RESERVED, 52 SOCK_STREAM)) < 0) { 53 fprintf(stderr, "Error connecting (%s)\n", strerror(errno)); 54 exit(4); 55 } 56 } else { 57 if (argc < 3) usage(argv[0]); 58 printf("Using alt socket %s\n", argv[1]); 59 cmdOffset = 1; 60 } 61 62 if (!strcmp(argv[1+cmdOffset], "monitor")) 63 exit(do_monitor(sock, 0)); 64 exit(do_cmd(sock, argc-cmdOffset, &(argv[cmdOffset]))); 65} 66 67static int do_cmd(int sock, int argc, char **argv) { 68 char final_cmd[255] = { '0', ' ', '\0' }; 69 int i; 70 71 for (i = 1; i < argc; i++) { 72 char *cmp; 73 74 if (!index(argv[i], ' ')) 75 asprintf(&cmp, "%s%s", argv[i], (i == (argc -1)) ? "" : " "); 76 else 77 asprintf(&cmp, "\"%s\"%s", argv[i], (i == (argc -1)) ? "" : " "); 78 79 strcat(final_cmd, cmp); 80 free(cmp); 81 } 82 83 if (write(sock, final_cmd, strlen(final_cmd) + 1) < 0) { 84 perror("write"); 85 return errno; 86 } 87 88 return do_monitor(sock, 1); 89} 90 91static int do_monitor(int sock, int stop_after_cmd) { 92 char *buffer = malloc(4096); 93 94 if (!stop_after_cmd) 95 printf("[Connected to Netd]\n"); 96 97 while(1) { 98 fd_set read_fds; 99 struct timeval to; 100 int rc = 0; 101 102 to.tv_sec = 10; 103 to.tv_usec = 0; 104 105 FD_ZERO(&read_fds); 106 FD_SET(sock, &read_fds); 107 108 if ((rc = select(sock +1, &read_fds, NULL, NULL, &to)) < 0) { 109 fprintf(stderr, "Error in select (%s)\n", strerror(errno)); 110 free(buffer); 111 return errno; 112 } else if (!rc) { 113 continue; 114 fprintf(stderr, "[TIMEOUT]\n"); 115 return ETIMEDOUT; 116 } else if (FD_ISSET(sock, &read_fds)) { 117 memset(buffer, 0, 4096); 118 if ((rc = read(sock, buffer, 4096)) <= 0) { 119 if (rc == 0) 120 fprintf(stderr, "Lost connection to Netd - did it crash?\n"); 121 else 122 fprintf(stderr, "Error reading data (%s)\n", strerror(errno)); 123 free(buffer); 124 if (rc == 0) 125 return ECONNRESET; 126 return errno; 127 } 128 129 int offset = 0; 130 int i = 0; 131 132 for (i = 0; i < rc; i++) { 133 if (buffer[i] == '\0') { 134 int code; 135 char tmp[4]; 136 137 strncpy(tmp, buffer + offset, 3); 138 tmp[3] = '\0'; 139 code = atoi(tmp); 140 141 printf("%s\n", buffer + offset); 142 if (stop_after_cmd) { 143 if (code >= 200 && code < 600) 144 return 0; 145 } 146 offset = i + 1; 147 } 148 } 149 } 150 } 151 free(buffer); 152 return 0; 153} 154 155static void usage(char *progname) { 156 fprintf(stderr, "Usage: %s [sockname] <monitor>|<cmd> [arg1] [arg2...]\n", progname); 157 exit(1); 158} 159