Integrate mtpd to Android platform.
1. Adapt logging to liblog.
2. Use control socket to get arguments.
3. Add Android.mk.
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..78c5763
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,30 @@
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := mtpd.c l2tp.c
+LOCAL_SHARED_LIBRARIES := libcutils
+LOCAL_CFLAGS := -DANDROID_CHANGES
+
+LOCAL_MODULE := mtpd
+
+include $(BUILD_EXECUTABLE)
+
+endif
diff --git a/mtpd.c b/mtpd.c
index 996bced..5a2492b 100644
--- a/mtpd.c
+++ b/mtpd.c
@@ -29,6 +29,11 @@
#include <fcntl.h>
#include <time.h>
+#ifdef ANDROID_CHANGES
+#include <android/log.h>
+#include <cutils/sockets.h>
+#endif
+
#include "mtpd.h"
int the_socket = -1;
@@ -95,11 +100,67 @@
}
}
+#ifdef ANDROID_CHANGES
+
+static int get_control_and_arguments(int *argc, char ***argv)
+{
+ static char *args[256];
+ int control;
+ int i;
+
+ log_print(DEBUG, "Waiting for control socket");
+ i = android_get_control_socket("mtpd");
+ if (i == -1 || listen(i, 1) == -1 || (control = accept(i, NULL, 0)) == -1) {
+ log_print(FATAL, "Cannot get control socket");
+ exit(SYSTEM_ERROR);
+ }
+ close(i);
+ fcntl(control, F_SETFD, FD_CLOEXEC);
+
+ args[0] = (*argv)[0];
+ for (i = 1; i < 256; ++i) {
+ unsigned char length;
+ if (recv(control, &length, 1, 0) != 1) {
+ log_print(FATAL, "Cannot get argument length");
+ exit(SYSTEM_ERROR);
+ }
+ if (length == 0xFF) {
+ break;
+ } else {
+ int offset = 0;
+ args[i] = malloc(length + 1);
+ while (offset < length) {
+ int n = recv(control, &args[i][offset], length - offset, 0);
+ if (n > 0) {
+ offset += n;
+ } else {
+ log_print(FATAL, "Cannot get argument value");
+ exit(SYSTEM_ERROR);
+ }
+ }
+ args[i][length] = 0;
+ }
+ }
+ log_print(DEBUG, "Received %d arguments", i - 1);
+
+ *argc = i;
+ *argv = args;
+ return control;
+}
+
+#endif
+
int main(int argc, char **argv)
{
struct pollfd pollfds[2];
int timeout;
- int error = 0;
+ int status;
+#ifdef ANDROID_CHANGES
+ unsigned char code;
+ int control = get_control_and_arguments(&argc, &argv);
+ code = argc - 1;
+ send(control, &code, 1, 0);
+#endif
srandom(time(NULL));
@@ -134,39 +195,54 @@
}
if (timeout < 0) {
- error = -timeout;
+ status = -timeout;
} else {
int signal;
read(signals[0], &signal, sizeof(int));
log_print(INFO, "Received signal %d", signal);
- if (signal == SIGCHLD && waitpid(pppd_pid, &error, WNOHANG) == pppd_pid
- && WIFEXITED(error)) {
- error = WEXITSTATUS(error);
- log_print(INFO, "Pppd is terminated (status = %d)", error);
- error += PPPD_EXITED;
+ if (signal == SIGCHLD && waitpid(pppd_pid, &status, WNOHANG) == pppd_pid
+ && WIFEXITED(status)) {
+ status = WEXITSTATUS(status);
+ log_print(INFO, "Pppd is terminated (status = %d)", status);
+ status += PPPD_EXITED;
pppd_pid = 0;
} else {
- error = USER_REQUESTED;
+ status = USER_REQUESTED;
}
}
stop_pppd();
the_protocol->shutdown();
- log_print(INFO, "Mtpd is terminated (status = %d)", error);
- return error;
+#ifdef ANDROID_CHANGES
+ code = status;
+ send(control, &code, 1, 0);
+#endif
+ log_print(INFO, "Mtpd is terminated (status = %d)", status);
+ return status;
}
void log_print(int level, char *format, ...)
{
if (level >= 0 && level <= LOG_MAX) {
- char *levels = "DIWEF";
+#ifdef ANDROID_CHANGES
+ static int levels[5] = {
+ ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN,
+ ANDROID_LOG_ERROR, ANDROID_LOG_FATAL
+ };
+ va_list ap;
+ va_start(ap, format);
+ __android_log_vprint(levels[level], "mtpd", format, ap);
+ va_end(ap);
+#else
+ static char *levels = "DIWEF";
va_list ap;
fprintf(stderr, "%c: ", levels[level]);
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
fputc('\n', stderr);
+#endif
}
}
@@ -226,14 +302,16 @@
}
if (!pppd_pid) {
- char number[16];
- char *args[1024] = {"", "nodetach", "pppox", number};
- int i;
+ char *args[pppd_argc + 5];
+ char number[12];
sprintf(number, "%d", pppox);
- for (i = 0; i < pppd_argc; ++i) {
- args[4 + i] = pppd_argv[i];
- }
+ args[0] = "pppd";
+ args[1] = "nodetach";
+ args[2] = "pppox";
+ args[3] = number;
+ memcpy(&args[4], pppd_argv, sizeof(char *) * pppd_argc);
+ args[4 + pppd_argc] = NULL;
execvp("pppd", args);
log_print(FATAL, "Exec() %s", strerror(errno));