Initial Contribution
diff --git a/mountd/Server.c b/mountd/Server.c
new file mode 100644
index 0000000..14b3830
--- /dev/null
+++ b/mountd/Server.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/*
+**	mountd server support
+*/
+
+#include "mountd.h"
+
+#include <cutils/properties.h>
+#include <cutils/sockets.h>
+
+#include <pthread.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/socket.h>
+
+#include <private/android_filesystem_config.h>
+
+
+// current client file descriptor
+static int sFD = -1;
+
+// to synchronize writing to client
+static pthread_mutex_t sWriteMutex = PTHREAD_MUTEX_INITIALIZER;
+
+// path for media that failed to mount before the runtime is connected
+static char* sDeferredUnmountableMediaPath = NULL;
+
+static int Write(const char* message)
+{
+    int result = -1;
+
+    pthread_mutex_lock(&sWriteMutex);
+    
+    LOG_SERVER("Write: %s\n", message);
+    if (sFD >= 0)
+        result = write(sFD, message, strlen(message) + 1);
+
+    pthread_mutex_unlock(&sWriteMutex); 
+    
+    return result;
+}
+
+static int Write2(const char* message, const char* data)
+{
+    int result = -1;
+
+    char* buffer = (char *)alloca(strlen(message) + strlen(data) + 1);
+    if (!buffer)
+    {
+        LOG_ERROR("alloca failed in Write2\n");
+        return -1;
+    }
+
+    strcpy(buffer, message);
+    strcat(buffer, data);
+    return Write(buffer);
+}
+
+static void SendStatus()
+{
+    Write(IsMassStorageConnected() ? MOUNTD_UMS_CONNECTED : MOUNTD_UMS_DISCONNECTED);
+    Write(IsMassStorageEnabled() ? MOUNTD_UMS_ENABLED : MOUNTD_UMS_DISABLED);
+}
+
+static void DoCommand(const char* command)
+{
+    LOG_SERVER("DoCommand %s\n", command);
+    
+    if (strcmp(command, MOUNTD_ENABLE_UMS) == 0)
+    {
+        EnableMassStorage(true);
+        Write(MOUNTD_UMS_ENABLED);
+     }
+    else if (strcmp(command, MOUNTD_DISABLE_UMS) == 0) 
+    {
+        EnableMassStorage(false);
+        Write(MOUNTD_UMS_DISABLED);
+    }
+    else if (strcmp(command, MOUNTD_SEND_STATUS) == 0)
+    {
+        SendStatus();
+    }
+    else if (strncmp(command, MOUNTD_MOUNT_MEDIA, strlen(MOUNTD_MOUNT_MEDIA)) == 0)
+    {
+        const char* path = command + strlen(MOUNTD_MOUNT_MEDIA);
+        MountMedia(path);
+    }
+    else if (strncmp(command, MOUNTD_EJECT_MEDIA, strlen(MOUNTD_EJECT_MEDIA)) == 0)
+    {
+        const char* path = command + strlen(MOUNTD_EJECT_MEDIA);
+        UnmountMedia(path);
+    }
+    else
+        LOGE("unknown command %s\n", command);
+}
+
+int RunServer()
+{
+    int socket = android_get_control_socket(MOUNTD_SOCKET);
+    if (socket < 0) {
+        LOGE("Obtaining file descriptor for socket '%s' failed: %s",
+             MOUNTD_SOCKET, strerror(errno));
+        return -1;
+    }
+
+    if (listen(socket, 4) < 0) {
+        LOGE("Unable to listen on file descriptor '%d' for socket '%s': %s",
+             socket, MOUNTD_SOCKET, strerror(errno));
+        return -1;
+    }
+
+    while (1)
+    {
+        struct sockaddr addr;
+        socklen_t alen;
+        struct ucred cred;
+        socklen_t size;
+        
+        alen = sizeof(addr);
+        sFD = accept(socket, &addr, &alen);
+        if (sFD < 0)
+            continue;
+            
+        if (sDeferredUnmountableMediaPath) {
+            NotifyMediaState(sDeferredUnmountableMediaPath, MEDIA_UNMOUNTABLE, false);
+            free(sDeferredUnmountableMediaPath);
+            sDeferredUnmountableMediaPath = NULL;
+        }
+
+        while (1)
+        {    
+            char    buffer[101];
+            int result = read(sFD, buffer, sizeof(buffer) - 1);
+            if (result > 0)
+            {
+                int start = 0;
+                int i;
+                // command should be zero terminated, but just in case
+                buffer[result] = 0;
+                for (i = 0; i < result; i++) 
+                {
+                    if (buffer[i] == 0) 
+                    {
+                        DoCommand(buffer + start);
+                        start = i + 1;
+                    }                   
+                }
+            }
+            else
+            {
+                close(sFD);
+                sFD = -1;
+                break;
+            }
+        }
+    }  
+
+    // should never get here
+    return 0;
+}
+
+void SendMassStorageConnected(boolean connected)
+{
+    Write(connected ? MOUNTD_UMS_CONNECTED : MOUNTD_UMS_DISCONNECTED);
+}
+
+void SendUnmountRequest(const char* path)
+{
+    Write2(MOUNTD_REQUEST_EJECT, path);
+}
+
+void NotifyMediaState(const char* path, MediaState state, boolean readOnly)
+{
+    const char* event = NULL;
+    const char* propertyValue = NULL;
+    
+    switch (state) {
+        case MEDIA_REMOVED:
+            event = MOUNTD_MEDIA_REMOVED;
+            propertyValue = EXTERNAL_STORAGE_REMOVED;
+            break;
+        case MEDIA_UNMOUNTED:
+            event = MOUNTD_MEDIA_UNMOUNTED;
+            propertyValue = EXTERNAL_STORAGE_UNMOUNTED;
+            break;
+        case MEDIA_MOUNTED:
+            event = (readOnly ? MOUNTD_MEDIA_MOUNTED_READ_ONLY : MOUNTD_MEDIA_MOUNTED);
+             propertyValue = (readOnly ? EXTERNAL_STORAGE_MOUNTED_READ_ONLY : EXTERNAL_STORAGE_MOUNTED);
+           break;
+        case MEDIA_SHARED:
+            event = MOUNTD_MEDIA_SHARED;
+            propertyValue = EXTERNAL_STORAGE_SHARED;
+            break;
+        case MEDIA_BAD_REMOVAL:
+            event = MOUNTD_MEDIA_BAD_REMOVAL;
+            propertyValue = EXTERNAL_STORAGE_BAD_REMOVAL;
+            break;
+        case MEDIA_UNMOUNTABLE:
+            event = MOUNTD_MEDIA_UNMOUNTABLE;
+            propertyValue = EXTERNAL_STORAGE_UNMOUNTABLE;
+            break;
+        default:
+            LOG_ERROR("unknown MediaState %d in NotifyMediaState\n", state);
+            return;
+    }
+    
+    property_set(EXTERNAL_STORAGE_STATE, propertyValue);
+    int result = Write2(event, path);
+    if (result < 0 && state == MEDIA_UNMOUNTABLE) {
+    
+        // if we cannot communicate with the runtime, defer this message until the runtime is available
+        sDeferredUnmountableMediaPath = strdup(path);
+    }
+}