mtpd.c revision 84e3195dffa22e8d1568ef9d70aea4bcbba71a72
179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh/* 279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * Copyright (C) 2009 The Android Open Source Project 379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * 479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * Licensed under the Apache License, Version 2.0 (the "License"); 579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * you may not use this file except in compliance with the License. 679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * You may obtain a copy of the License at 779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * 879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * http://www.apache.org/licenses/LICENSE-2.0 979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * 1079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * Unless required by applicable law or agreed to in writing, software 1179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * distributed under the License is distributed on an "AS IS" BASIS, 1279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * See the License for the specific language governing permissions and 1479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * limitations under the License. 1579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh */ 1679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 1779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <stdio.h> 1879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <stdlib.h> 1979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <stdarg.h> 2079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <string.h> 2179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <errno.h> 2279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <sys/types.h> 2379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <sys/socket.h> 2479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <sys/poll.h> 2579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <sys/wait.h> 2679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <netdb.h> 2779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <signal.h> 2879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <unistd.h> 2979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <fcntl.h> 3079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <time.h> 3179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 3284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#ifdef ANDROID_CHANGES 3384e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#include <android/log.h> 3484e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#include <cutils/sockets.h> 3584e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#endif 3684e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh 3779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include "mtpd.h" 3879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 3979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehint the_socket = -1; 4079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 4179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehextern struct protocol l2tp; 4279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehstatic struct protocol *protocols[] = {&l2tp, NULL}; 4379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehstatic struct protocol *the_protocol; 4479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 4579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehstatic int pppd_argc; 4679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehstatic char **pppd_argv; 4779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehstatic pid_t pppd_pid; 4879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 4979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh/* We redirect signals to a pipe in order to prevent race conditions. */ 5079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehstatic int signals[2]; 5179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 5279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehstatic void interrupt(int signal) 5379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh{ 5479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh write(signals[1], &signal, sizeof(int)); 5579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh} 5679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 5779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehstatic int initialize(int argc, char **argv) 5879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh{ 5979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh int timeout = 0; 6079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh int i; 6179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 6279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh for (i = 2; i < argc; ++i) { 6379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (!argv[i][0]) { 6479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh pppd_argc = argc - i - 1; 6579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh pppd_argv = &argv[i + 1]; 6679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh argc = i; 6779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh break; 6879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 6979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 7079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 7179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (argc >= 2) { 7279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh for (i = 0; protocols[i]; ++i) { 7379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (!strcmp(argv[1], protocols[i]->name)) { 7479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(INFO, "Using protocol %s", protocols[i]->name); 7579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh the_protocol = protocols[i]; 7679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh timeout = the_protocol->connect(argc - 2, &argv[2]); 7779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh break; 7879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 7979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 8079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 8179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 8279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (!the_protocol || timeout == -USAGE_ERROR) { 8379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh printf("Usage: %s <protocol-args> '' <pppd-args>, " 8479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh "where protocol-args are one of:\n", argv[0]); 8579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh for (i = 0; protocols[i]; ++i) { 8679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh printf(" %s %s\n", protocols[i]->name, protocols[i]->usage); 8779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 8879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh exit(USAGE_ERROR); 8979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 9079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh return timeout; 9179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh} 9279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 9379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehstatic void stop_pppd() 9479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh{ 9579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (pppd_pid) { 9679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(INFO, "Sending signal to pppd (pid = %d)", pppd_pid); 9779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh kill(pppd_pid, SIGTERM); 9879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh sleep(5); 9979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh pppd_pid = 0; 10079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 10179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh} 10279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 10384e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#ifdef ANDROID_CHANGES 10484e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh 10584e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yehstatic int get_control_and_arguments(int *argc, char ***argv) 10684e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh{ 10784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh static char *args[256]; 10884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh int control; 10984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh int i; 11084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh 11184e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh log_print(DEBUG, "Waiting for control socket"); 11284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh i = android_get_control_socket("mtpd"); 11384e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh if (i == -1 || listen(i, 1) == -1 || (control = accept(i, NULL, 0)) == -1) { 11484e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh log_print(FATAL, "Cannot get control socket"); 11584e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh exit(SYSTEM_ERROR); 11684e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh } 11784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh close(i); 11884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh fcntl(control, F_SETFD, FD_CLOEXEC); 11984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh 12084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh args[0] = (*argv)[0]; 12184e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh for (i = 1; i < 256; ++i) { 12284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh unsigned char length; 12384e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh if (recv(control, &length, 1, 0) != 1) { 12484e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh log_print(FATAL, "Cannot get argument length"); 12584e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh exit(SYSTEM_ERROR); 12684e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh } 12784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh if (length == 0xFF) { 12884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh break; 12984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh } else { 13084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh int offset = 0; 13184e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh args[i] = malloc(length + 1); 13284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh while (offset < length) { 13384e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh int n = recv(control, &args[i][offset], length - offset, 0); 13484e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh if (n > 0) { 13584e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh offset += n; 13684e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh } else { 13784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh log_print(FATAL, "Cannot get argument value"); 13884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh exit(SYSTEM_ERROR); 13984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh } 14084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh } 14184e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh args[i][length] = 0; 14284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh } 14384e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh } 14484e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh log_print(DEBUG, "Received %d arguments", i - 1); 14584e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh 14684e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh *argc = i; 14784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh *argv = args; 14884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh return control; 14984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh} 15084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh 15184e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#endif 15284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh 15379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehint main(int argc, char **argv) 15479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh{ 15579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh struct pollfd pollfds[2]; 15679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh int timeout; 15784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh int status; 15884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#ifdef ANDROID_CHANGES 15984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh unsigned char code; 16084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh int control = get_control_and_arguments(&argc, &argv); 16184e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh code = argc - 1; 16284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh send(control, &code, 1, 0); 16384e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#endif 16479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 16579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh srandom(time(NULL)); 16679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 16779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (pipe(signals) == -1) { 16879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(FATAL, "Pipe() %s", strerror(errno)); 16979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh exit(SYSTEM_ERROR); 17079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 17179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 17279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh signal(SIGHUP, interrupt); 17379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh signal(SIGINT, interrupt); 17479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh signal(SIGTERM, interrupt); 17579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh signal(SIGCHLD, interrupt); 17679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh signal(SIGPIPE, SIG_IGN); 17779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh atexit(stop_pppd); 17879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 17979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh timeout = initialize(argc, argv); 18079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh pollfds[0].fd = signals[0]; 18179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh pollfds[0].events = POLLIN; 18279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh pollfds[1].fd = the_socket; 18379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh pollfds[1].events = POLLIN; 18479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 18579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh while (timeout >= 0) { 18679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (poll(pollfds, 2, timeout ? timeout : -1) == -1 && errno != EINTR) { 18779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(FATAL, "Poll() %s", strerror(errno)); 18879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh exit(SYSTEM_ERROR); 18979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 19079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (pollfds[0].revents) { 19179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh break; 19279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 19379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh timeout = pollfds[1].revents ? 19479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh the_protocol->process() : the_protocol->timeout(); 19579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 19679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 19779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (timeout < 0) { 19884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh status = -timeout; 19979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } else { 20079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh int signal; 20179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh read(signals[0], &signal, sizeof(int)); 20279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(INFO, "Received signal %d", signal); 20384e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh if (signal == SIGCHLD && waitpid(pppd_pid, &status, WNOHANG) == pppd_pid 20484e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh && WIFEXITED(status)) { 20584e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh status = WEXITSTATUS(status); 20684e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh log_print(INFO, "Pppd is terminated (status = %d)", status); 20784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh status += PPPD_EXITED; 20879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh pppd_pid = 0; 20979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } else { 21084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh status = USER_REQUESTED; 21179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 21279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 21379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 21479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh stop_pppd(); 21579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh the_protocol->shutdown(); 21679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 21784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#ifdef ANDROID_CHANGES 21884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh code = status; 21984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh send(control, &code, 1, 0); 22084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#endif 22184e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh log_print(INFO, "Mtpd is terminated (status = %d)", status); 22284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh return status; 22379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh} 22479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 22579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehvoid log_print(int level, char *format, ...) 22679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh{ 22779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (level >= 0 && level <= LOG_MAX) { 22884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#ifdef ANDROID_CHANGES 22984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh static int levels[5] = { 23084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, 23184e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh ANDROID_LOG_ERROR, ANDROID_LOG_FATAL 23284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh }; 23384e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh va_list ap; 23484e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh va_start(ap, format); 23584e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh __android_log_vprint(levels[level], "mtpd", format, ap); 23684e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh va_end(ap); 23784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#else 23884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh static char *levels = "DIWEF"; 23979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh va_list ap; 24079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh fprintf(stderr, "%c: ", levels[level]); 24179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh va_start(ap, format); 24279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh vfprintf(stderr, format, ap); 24379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh va_end(ap); 24479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh fputc('\n', stderr); 24584e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#endif 24679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 24779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh} 24879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 24979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehvoid create_socket(int family, int type, char *server, char *port) 25079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh{ 25179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh struct addrinfo hints = { 25279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh .ai_flags = AI_NUMERICSERV, 25379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh .ai_family = family, 25479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh .ai_socktype = type, 25579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh }; 25679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh struct addrinfo *records; 25779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh struct addrinfo *r; 25879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh int error; 25979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 26079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(INFO, "Connecting to %s port %s", server, port); 26179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 26279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh error = getaddrinfo(server, port, &hints, &records); 26379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (error) { 26479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(FATAL, "Getaddrinfo() %s", (error == EAI_SYSTEM) ? 26579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh strerror(errno) : gai_strerror(error)); 26679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh exit(NETWORK_ERROR); 26779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 26879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 26979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh for (r = records; r; r = r->ai_next) { 27079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh the_socket = socket(r->ai_family, r->ai_socktype, r->ai_protocol); 27179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (the_socket != -1 27279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh && connect(the_socket, r->ai_addr, r->ai_addrlen) == 0) { 27379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh break; 27479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 27579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 27679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 27779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh freeaddrinfo(records); 27879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 27979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (the_socket == -1) { 28079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(FATAL, "Connect() %s", strerror(errno)); 28179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh exit(NETWORK_ERROR); 28279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 28379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 28479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh fcntl(the_socket, F_SETFD, FD_CLOEXEC); 28579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(INFO, "Connection established (socket = %d)", the_socket); 28679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh} 28779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 28879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehvoid start_pppd(int pppox) 28979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh{ 29079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (pppd_pid) { 29179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(WARNING, "Pppd is already started (pid = %d)", pppd_pid); 29279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh close(pppox); 29379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh return; 29479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 29579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 29679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(INFO, "Starting pppd (pppox = %d)", pppox); 29779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 29879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh pppd_pid = fork(); 29979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (pppd_pid < 0) { 30079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(FATAL, "Fork() %s", strerror(errno)); 30179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh exit(SYSTEM_ERROR); 30279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 30379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 30479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (!pppd_pid) { 30584e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh char *args[pppd_argc + 5]; 30684e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh char number[12]; 30779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 30879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh sprintf(number, "%d", pppox); 30984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh args[0] = "pppd"; 31084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh args[1] = "nodetach"; 31184e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh args[2] = "pppox"; 31284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh args[3] = number; 31384e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh memcpy(&args[4], pppd_argv, sizeof(char *) * pppd_argc); 31484e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh args[4 + pppd_argc] = NULL; 31579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 31679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh execvp("pppd", args); 31779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(FATAL, "Exec() %s", strerror(errno)); 31879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh exit(1); /* Pretending a fatal error in pppd. */ 31979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 32079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 32179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(INFO, "Pppd started (pid = %d)", pppd_pid); 32279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh close(pppox); 32379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh} 324