blob: 27ec8de90a3456cde8dea9e9515a5d969c28fff5 [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18** mountd main program
19*/
20
21#include "mountd.h"
22
23#include <cutils/config_utils.h>
24#include <cutils/cpu_info.h>
25#include <cutils/properties.h>
26
27#include <sys/mount.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <unistd.h>
32
33#include <linux/capability.h>
34#include <linux/prctl.h>
35
36#include <private/android_filesystem_config.h>
37
38#ifdef MOUNTD_LOG
39FILE* logFile;
40#endif
41
42struct asec_cfg {
43 const char *name;
44 const char *backing_file;
45 const char *size;
46 const char *mount_point;
47 const char *crypt;
48};
49
50static int ProcessAsecData(cnode *node, struct asec_cfg *stores, int idx)
51{
52 cnode *child = node->first_child;
53 const char *name = NULL;
54 const char *file = NULL;
55 const char *size = NULL;
56 const char *mp = NULL;
57 const char *crypt = NULL;
58
59 LOG_ASEC("ProcessAsecData(%s, %p, %d)\n", node->name, stores, idx);
60
61 while (child) {
62 if (!strcmp(child->name, "name"))
63 name = child->value;
64 else if (!strcmp(child->name, "backing_file"))
65 file = child->value;
66 else if (!strcmp(child->name, "size"))
67 size = child->value;
68 else if (!strcmp(child->name, "mount_point"))
69 mp = child->value;
70 else if (!strcmp(child->name, "crypt"))
71 crypt = child->value;
72 child = child->next;
73 }
74
75 if (!name || !file || !size || !mp || !crypt) {
76 LOG_ERROR("Missing required token from config. Skipping ASEC volume\n");
77 return -1;
78 } else if (idx == ASEC_STORES_MAX) {
79 LOG_ERROR("Maximum # of ASEC stores already defined\n");
80 return -1;
81 }
82
83 stores[idx].name = name;
84 stores[idx].backing_file = file;
85 stores[idx].size = size;
86 stores[idx].mount_point = mp;
87 stores[idx].crypt = crypt;
88 return ++idx;
89}
90
91static void ReadConfigFile(const char* path)
92{
93 cnode* root = config_node("", "");
94 cnode* node;
95
96 config_load_file(root, path);
97 node = root->first_child;
98
99 while (node)
100 {
101 if (strcmp(node->name, "mount") == 0)
102 {
103 const char* block_device = NULL;
104 const char* mount_point = NULL;
105 const char* driver_store_path = NULL;
106 boolean enable_ums = false;
107 cnode* child = node->first_child;
108 struct asec_cfg asec_stores[ASEC_STORES_MAX];
109 int asec_idx = 0;
110
111 memset(asec_stores, 0, sizeof(asec_stores));
112
113 while (child)
114 {
115 const char* name = child->name;
116 const char* value = child->value;
117
118 if (!strncmp(name, "asec_", 5)) {
119 int rc = ProcessAsecData(child, asec_stores, asec_idx);
120 if (rc < 0) {
121 LOG_ERROR("Error processing ASEC cfg data\n");
122 } else
123 asec_idx = rc;
124 } else if (strcmp(name, "block_device") == 0)
125 block_device = value;
126 else if (strcmp(name, "mount_point") == 0)
127 mount_point = value;
128 else if (strcmp(name, "driver_store_path") == 0)
129 driver_store_path = value;
130 else if (strcmp(name, "enable_ums") == 0 &&
131 strcmp(value, "true") == 0)
132 enable_ums = true;
133
134 child = child->next;
135 }
136
137 // mount point and removable fields are optional
138 if (block_device && mount_point)
139 {
140 void *mp = AddMountPoint(block_device, mount_point, driver_store_path, enable_ums);
141 int i;
142
143 for (i = 0; i < asec_idx; i++) {
144 AddAsecToMountPoint(mp, asec_stores[i].name, asec_stores[i].backing_file,
145 asec_stores[i].size, asec_stores[i].mount_point,
146 asec_stores[i].crypt);
147 }
148 }
149 }
150
151 node = node->next;
152 }
153}
154
155int main(int argc, char* argv[])
156{
157 const char* configPath = "/system/etc/mountd.conf";
158 int i;
159
160 for (i = 1; i < argc; i++)
161 {
162 const char* arg = argv[i];
163
164 if (strcmp(arg, "-f") == 0)
165 {
166 if (i < argc - 1)
167 configPath = argv[++i];
168 }
169 }
170
171 ReadConfigFile(configPath);
172 StartAutoMounter();
173 return RunServer();
174}