main.cpp revision 5ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13
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> 195c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat#include <signal.h> 20d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <errno.h> 21d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <string.h> 22d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <sys/stat.h> 23d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <sys/types.h> 245c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat#include <sys/wait.h> 25d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 26d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <fcntl.h> 27d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <dirent.h> 28d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 29d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#define LOG_TAG "Netd" 30d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 31d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include "cutils/log.h" 32d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 33d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include "CommandListener.h" 34d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include "NetlinkManager.h" 35007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#include "DnsProxyListener.h" 36d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 37d18304287dbabc7835be771400b85d4ae8b63de6San Mehatstatic void coldboot(const char *path); 385c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehatstatic void sigchld_handler(int sig); 39d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 40d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint main() { 41d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 42d18304287dbabc7835be771400b85d4ae8b63de6San Mehat CommandListener *cl; 43d18304287dbabc7835be771400b85d4ae8b63de6San Mehat NetlinkManager *nm; 44007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick DnsProxyListener *dpl; 45d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 4608b58b60fd70e81317a9df19cc431f0759bc9e71Steve Block ALOGI("Netd 1.0 starting"); 47d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 48f1c368a83b738658d27720898b433bbc010123baSan Mehat// signal(SIGCHLD, sigchld_handler); 495c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat 50d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (!(nm = NetlinkManager::Instance())) { 515ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Unable to create NetlinkManager"); 52d18304287dbabc7835be771400b85d4ae8b63de6San Mehat exit(1); 53d18304287dbabc7835be771400b85d4ae8b63de6San Mehat }; 54d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 55d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 56d18304287dbabc7835be771400b85d4ae8b63de6San Mehat cl = new CommandListener(); 57d18304287dbabc7835be771400b85d4ae8b63de6San Mehat nm->setBroadcaster((SocketListener *) cl); 58d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 59d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (nm->start()) { 605ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Unable to start NetlinkManager (%s)", strerror(errno)); 61d18304287dbabc7835be771400b85d4ae8b63de6San Mehat exit(1); 62d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 63d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 64007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick // Set local DNS mode, to prevent bionic from proxying 65007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick // back to this service, recursively. 66007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick setenv("ANDROID_DNS_MODE", "local", 1); 67007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick dpl = new DnsProxyListener(); 68007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (dpl->startListener()) { 695ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Unable to start DnsProxyListener (%s)", strerror(errno)); 70007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick exit(1); 71007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 72007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 73d18304287dbabc7835be771400b85d4ae8b63de6San Mehat /* 74d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * Now that we're up, we can respond to commands 75d18304287dbabc7835be771400b85d4ae8b63de6San Mehat */ 76d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (cl->startListener()) { 775ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Unable to start CommandListener (%s)", strerror(errno)); 78d18304287dbabc7835be771400b85d4ae8b63de6San Mehat exit(1); 79d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 80d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 81d18304287dbabc7835be771400b85d4ae8b63de6San Mehat // Eventually we'll become the monitoring thread 82d18304287dbabc7835be771400b85d4ae8b63de6San Mehat while(1) { 83d18304287dbabc7835be771400b85d4ae8b63de6San Mehat sleep(1000); 84d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 85d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 8608b58b60fd70e81317a9df19cc431f0759bc9e71Steve Block ALOGI("Netd exiting"); 87d18304287dbabc7835be771400b85d4ae8b63de6San Mehat exit(0); 88d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 89d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 90d18304287dbabc7835be771400b85d4ae8b63de6San Mehatstatic void do_coldboot(DIR *d, int lvl) 91d18304287dbabc7835be771400b85d4ae8b63de6San Mehat{ 92d18304287dbabc7835be771400b85d4ae8b63de6San Mehat struct dirent *de; 93d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int dfd, fd; 94d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 95d18304287dbabc7835be771400b85d4ae8b63de6San Mehat dfd = dirfd(d); 96d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 97d18304287dbabc7835be771400b85d4ae8b63de6San Mehat fd = openat(dfd, "uevent", O_WRONLY); 98d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if(fd >= 0) { 99d18304287dbabc7835be771400b85d4ae8b63de6San Mehat write(fd, "add\n", 4); 100d18304287dbabc7835be771400b85d4ae8b63de6San Mehat close(fd); 101d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 102d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 103d18304287dbabc7835be771400b85d4ae8b63de6San Mehat while((de = readdir(d))) { 104d18304287dbabc7835be771400b85d4ae8b63de6San Mehat DIR *d2; 105d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 106d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (de->d_name[0] == '.') 107d18304287dbabc7835be771400b85d4ae8b63de6San Mehat continue; 108d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 109d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (de->d_type != DT_DIR && lvl > 0) 110d18304287dbabc7835be771400b85d4ae8b63de6San Mehat continue; 111d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 112d18304287dbabc7835be771400b85d4ae8b63de6San Mehat fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY); 113d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if(fd < 0) 114d18304287dbabc7835be771400b85d4ae8b63de6San Mehat continue; 115d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 116d18304287dbabc7835be771400b85d4ae8b63de6San Mehat d2 = fdopendir(fd); 117d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if(d2 == 0) 118d18304287dbabc7835be771400b85d4ae8b63de6San Mehat close(fd); 119d18304287dbabc7835be771400b85d4ae8b63de6San Mehat else { 120d18304287dbabc7835be771400b85d4ae8b63de6San Mehat do_coldboot(d2, lvl + 1); 121d18304287dbabc7835be771400b85d4ae8b63de6San Mehat closedir(d2); 122d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 123d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 124d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 125d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 126d18304287dbabc7835be771400b85d4ae8b63de6San Mehatstatic void coldboot(const char *path) 127d18304287dbabc7835be771400b85d4ae8b63de6San Mehat{ 128d18304287dbabc7835be771400b85d4ae8b63de6San Mehat DIR *d = opendir(path); 129d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if(d) { 130d18304287dbabc7835be771400b85d4ae8b63de6San Mehat do_coldboot(d, 0); 131d18304287dbabc7835be771400b85d4ae8b63de6San Mehat closedir(d); 132d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 133d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 1345c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat 1355c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehatstatic void sigchld_handler(int sig) { 1365c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat pid_t pid = wait(NULL); 1377b984e3f7e724f8a3547a707210319f3d479f261Steve Block ALOGD("Child process %d exited", pid); 1385c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat} 139