main.cpp 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> 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" 36745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt#include "MDnsSdListener.h" 37d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 38d18304287dbabc7835be771400b85d4ae8b63de6San Mehatstatic void coldboot(const char *path); 395c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehatstatic void sigchld_handler(int sig); 40c1044d4507a79166f3cfac9cacf669888f049ea9Selim Gurunstatic void blockSigpipe(); 41d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 42d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint main() { 43d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 44d18304287dbabc7835be771400b85d4ae8b63de6San Mehat CommandListener *cl; 45d18304287dbabc7835be771400b85d4ae8b63de6San Mehat NetlinkManager *nm; 46007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick DnsProxyListener *dpl; 47745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt MDnsSdListener *mdnsl; 48d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 4908b58b60fd70e81317a9df19cc431f0759bc9e71Steve Block ALOGI("Netd 1.0 starting"); 50d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 51f1c368a83b738658d27720898b433bbc010123baSan Mehat// signal(SIGCHLD, sigchld_handler); 52c1044d4507a79166f3cfac9cacf669888f049ea9Selim Gurun blockSigpipe(); 535c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat 54d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (!(nm = NetlinkManager::Instance())) { 555ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Unable to create NetlinkManager"); 56d18304287dbabc7835be771400b85d4ae8b63de6San Mehat exit(1); 57d18304287dbabc7835be771400b85d4ae8b63de6San Mehat }; 58d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 59d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 60d18304287dbabc7835be771400b85d4ae8b63de6San Mehat cl = new CommandListener(); 61d18304287dbabc7835be771400b85d4ae8b63de6San Mehat nm->setBroadcaster((SocketListener *) cl); 62d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 63d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (nm->start()) { 645ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Unable to start NetlinkManager (%s)", strerror(errno)); 65d18304287dbabc7835be771400b85d4ae8b63de6San Mehat exit(1); 66d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 67d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 68007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick // Set local DNS mode, to prevent bionic from proxying 69007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick // back to this service, recursively. 70007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick setenv("ANDROID_DNS_MODE", "local", 1); 71007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick dpl = new DnsProxyListener(); 72007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (dpl->startListener()) { 735ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Unable to start DnsProxyListener (%s)", strerror(errno)); 74007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick exit(1); 75007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 76007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 77745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt mdnsl = new MDnsSdListener(); 78745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt if (mdnsl->startListener()) { 79745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt ALOGE("Unable to start MDnsSdListener (%s)", strerror(errno)); 80745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt exit(1); 81745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt } 82d18304287dbabc7835be771400b85d4ae8b63de6San Mehat /* 83d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * Now that we're up, we can respond to commands 84d18304287dbabc7835be771400b85d4ae8b63de6San Mehat */ 85d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (cl->startListener()) { 865ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block ALOGE("Unable to start CommandListener (%s)", strerror(errno)); 87d18304287dbabc7835be771400b85d4ae8b63de6San Mehat exit(1); 88d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 89d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 90d18304287dbabc7835be771400b85d4ae8b63de6San Mehat // Eventually we'll become the monitoring thread 91d18304287dbabc7835be771400b85d4ae8b63de6San Mehat while(1) { 92d18304287dbabc7835be771400b85d4ae8b63de6San Mehat sleep(1000); 93d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 94d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 9508b58b60fd70e81317a9df19cc431f0759bc9e71Steve Block ALOGI("Netd exiting"); 96d18304287dbabc7835be771400b85d4ae8b63de6San Mehat exit(0); 97d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 98d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 99d18304287dbabc7835be771400b85d4ae8b63de6San Mehatstatic void do_coldboot(DIR *d, int lvl) 100d18304287dbabc7835be771400b85d4ae8b63de6San Mehat{ 101d18304287dbabc7835be771400b85d4ae8b63de6San Mehat struct dirent *de; 102d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int dfd, fd; 103d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 104d18304287dbabc7835be771400b85d4ae8b63de6San Mehat dfd = dirfd(d); 105d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 106d18304287dbabc7835be771400b85d4ae8b63de6San Mehat fd = openat(dfd, "uevent", O_WRONLY); 107d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if(fd >= 0) { 108d18304287dbabc7835be771400b85d4ae8b63de6San Mehat write(fd, "add\n", 4); 109d18304287dbabc7835be771400b85d4ae8b63de6San Mehat close(fd); 110d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 111d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 112d18304287dbabc7835be771400b85d4ae8b63de6San Mehat while((de = readdir(d))) { 113d18304287dbabc7835be771400b85d4ae8b63de6San Mehat DIR *d2; 114d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 115d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (de->d_name[0] == '.') 116d18304287dbabc7835be771400b85d4ae8b63de6San Mehat continue; 117d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 118d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (de->d_type != DT_DIR && lvl > 0) 119d18304287dbabc7835be771400b85d4ae8b63de6San Mehat continue; 120d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 121d18304287dbabc7835be771400b85d4ae8b63de6San Mehat fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY); 122d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if(fd < 0) 123d18304287dbabc7835be771400b85d4ae8b63de6San Mehat continue; 124d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 125d18304287dbabc7835be771400b85d4ae8b63de6San Mehat d2 = fdopendir(fd); 126d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if(d2 == 0) 127d18304287dbabc7835be771400b85d4ae8b63de6San Mehat close(fd); 128d18304287dbabc7835be771400b85d4ae8b63de6San Mehat else { 129d18304287dbabc7835be771400b85d4ae8b63de6San Mehat do_coldboot(d2, lvl + 1); 130d18304287dbabc7835be771400b85d4ae8b63de6San Mehat closedir(d2); 131d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 132d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 133d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 134d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 135d18304287dbabc7835be771400b85d4ae8b63de6San Mehatstatic void coldboot(const char *path) 136d18304287dbabc7835be771400b85d4ae8b63de6San Mehat{ 137d18304287dbabc7835be771400b85d4ae8b63de6San Mehat DIR *d = opendir(path); 138d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if(d) { 139d18304287dbabc7835be771400b85d4ae8b63de6San Mehat do_coldboot(d, 0); 140d18304287dbabc7835be771400b85d4ae8b63de6San Mehat closedir(d); 141d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 142d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 1435c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat 1445c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehatstatic void sigchld_handler(int sig) { 1455c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat pid_t pid = wait(NULL); 1467b984e3f7e724f8a3547a707210319f3d479f261Steve Block ALOGD("Child process %d exited", pid); 1475c1b8af16dbbc20c89aaca2f93e725e12b16d055San Mehat} 148c1044d4507a79166f3cfac9cacf669888f049ea9Selim Gurun 149c1044d4507a79166f3cfac9cacf669888f049ea9Selim Gurunstatic void blockSigpipe() 150c1044d4507a79166f3cfac9cacf669888f049ea9Selim Gurun{ 151c1044d4507a79166f3cfac9cacf669888f049ea9Selim Gurun sigset_t mask; 152c1044d4507a79166f3cfac9cacf669888f049ea9Selim Gurun 153c1044d4507a79166f3cfac9cacf669888f049ea9Selim Gurun sigemptyset(&mask); 154c1044d4507a79166f3cfac9cacf669888f049ea9Selim Gurun sigaddset(&mask, SIGPIPE); 155c1044d4507a79166f3cfac9cacf669888f049ea9Selim Gurun if (sigprocmask(SIG_BLOCK, &mask, NULL) != 0) 156c1044d4507a79166f3cfac9cacf669888f049ea9Selim Gurun ALOGW("WARNING: SIGPIPE not blocked\n"); 157c1044d4507a79166f3cfac9cacf669888f049ea9Selim Gurun} 158