2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.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
8 * http://www.tizenopensource.org/license
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.
21 #include <sys/types.h>
23 #include <sys/mount.h>
30 #include "ss_device_handler.h"
35 #define FS_TYPE_CHECKER "/sbin/fs-type-checker"
36 #define TEMP_FILE "/tmp/mountd.tmp"
37 #define MTAB_FILE "/etc/mtab"
38 #define MOUNT_POINT "/opt/storage/usb"
40 static int added_noti_value = 0;
41 static int removed_noti_value = 0;
43 static int __ss_mount_device(char *dev)
45 if (access(dev, F_OK) != 0) {
46 PRT_TRACE_ERR("Failed to find device: DEVICE(%s)", dev);
53 char buf_mnt_point[BUF_MAX];
55 rel_mnt_point = strrchr(dev, '/');
56 if (rel_mnt_point == NULL) {
57 PRT_TRACE_ERR("Get Relative Mount Path Failed");
61 snprintf(buf_mnt_point, BUF_MAX, "%s%s", MOUNT_POINT, rel_mnt_point);
63 /* Make directory to mount */
64 r = mkdir(buf_mnt_point, 0755);
66 if (errno == EEXIST) {
67 PRT_TRACE("Directory is already exsited: PATH(%s)", buf_mnt_point);
69 PRT_TRACE_ERR("Make Directory Failed: PATH(%s)", buf_mnt_point);
74 /* Mount block device on mount point */
75 r = mount(dev, buf_mnt_point, "vfat", 0, "uid=0,gid=0,dmask=0000,fmask=0111,iocharset=iso8859-1,utf8,shortname=mixed");
77 r = rmdir(buf_mnt_point);
78 PRT_TRACE_ERR("Mount failed: MOUNT PATH(%s", buf_mnt_point);
81 PRT_TRACE("Mount Complete: MOUNT PATH(%s)", buf_mnt_point);
86 static int __ss_unmount_device(char *mnt_point)
88 if (access(mnt_point, F_OK) != 0) {
89 PRT_TRACE_ERR("Failed to find path: MOUNT PATH(%s)", mnt_point);
95 /* Umount block device */
96 r = umount2(mnt_point, MNT_DETACH);
98 PRT_TRACE_ERR("Unmounting is unabled: MOUNT PATH(%s)", mnt_point);
101 PRT_TRACE_ERR("Removing Directory is unabled: PATH(%s)", mnt_point);
106 /* Clean up unmounted directory */
107 r = rmdir(mnt_point);
109 PRT_TRACE_ERR("Removing Directory is unabled: PATH(%s)", mnt_point);
111 PRT_TRACE("Unmount/Remove Complete: MOUNT PATH(%s)", mnt_point);
116 static int __ss_usb_storage_added(int argc, char *argv[])
118 if (argc != 1 || argv[0] == NULL) {
119 PRT_TRACE_ERR("Get Vconf Value Failed: KEY(%s)", VCONFKEY_SYSMAN_ADDED_USB_STORAGE);
126 char *buf_dev = argv[0];
127 char buf_part_dev[BUF_MAX];
131 /* Check whether mount point directory is exist */
132 if (access(MOUNT_POINT, F_OK) < 0) {
133 if (mkdir(MOUNT_POINT, 0755) < 0) {
134 PRT_TRACE_ERR("Make Mount Directory Failed: DIRECTORY(%s)", MOUNT_POINT);
139 /* Mount tmpfs for protecting user data */
140 if (mount("tmpfs", MOUNT_POINT, "tmpfs", 0, "") < 0) {
141 if (errno != EBUSY) {
142 PRT_TRACE_ERR("Failed to mount USB Storage Mount Directory: DIRECTORY(%s)", MOUNT_POINT);
147 /* Change permission to avoid to write user data on tmpfs */
148 if (chmod(MOUNT_POINT, 0755) < 0) {
149 PRT_TRACE_ERR("Failed to change mode: DIRCTORY(%s)", MOUNT_POINT);
153 /* Mount a single partition storage device */
154 if (__ss_mount_device(buf_dev) < 0) {
155 /* Mount a multi partition storage device */
156 for (part_num = 1; part_num < 10; part_num++) {
157 snprintf(buf_part_dev, BUF_MAX, "%s%d", buf_dev, part_num);
158 if (__ss_mount_device(buf_part_dev) < 0) {
159 PRT_TRACE("Mounting partition is unabled: PARTITION(%s)", buf_part_dev);
165 FILE *file = setmntent(MTAB_FILE, "r");
166 struct mntent *mnt_entry;
168 /* Check whether block deivce is mounted */
169 while (mnt_entry = getmntent(file)) {
170 mounted_check = strstr(mnt_entry->mnt_fsname, buf_dev);
171 if (mounted_check != NULL) {
172 if (added_noti_value < INT_MAX) {
175 added_noti_value = 1;
177 /* Broadcast mounting notification */
178 if (vconf_set_int(VCONFKEY_SYSMAN_ADDED_USB_STORAGE, added_noti_value) < 0) {
179 PRT_TRACE_ERR("Setting vconf value is failed: KEY(%s)", VCONFKEY_SYSMAN_ADDED_USB_STORAGE);
180 vconf_set_int(VCONFKEY_SYSMAN_ADDED_USB_STORAGE, -1);
183 PRT_TRACE("Setting vconf value: KEY(%s) DEVICE(%s)", VCONFKEY_SYSMAN_ADDED_USB_STORAGE, buf_dev);
189 /* Failed to mount storage device */
190 PRT_TRACE_ERR("Nothing to be mounted: DEVICE(%s)", buf_dev);
195 static int __ss_usb_storage_removed(int argc, char *argv[])
197 if (argc != 1 || argv[0] == NULL) {
198 PRT_TRACE_ERR("Get Vonf Value Failed: KEY(%s)", VCONFKEY_SYSMAN_REMOVED_USB_STORAGE);
205 char *buf_dev_name = argv[0];
206 char buf_mnt_point[BUF_MAX];
209 snprintf(buf_mnt_point, BUF_MAX, "%s/%s", MOUNT_POINT, buf_dev_name);
211 if (__ss_unmount_device(buf_mnt_point) == 0) {
212 umount2(MOUNT_POINT, MNT_DETACH);
214 if (removed_noti_value < INT_MAX) {
215 ++removed_noti_value;
217 removed_noti_value = 1;
219 if (vconf_set_int(VCONFKEY_SYSMAN_REMOVED_USB_STORAGE, removed_noti_value) < 0) {
220 PRT_TRACE_ERR("Setting vconf value is failed: KEY(%s)", VCONFKEY_SYSMAN_REMOVED_USB_STORAGE);
221 vconf_set_int(VCONFKEY_SYSMAN_ADDED_USB_STORAGE, -1);
224 PRT_TRACE("Setting vconf value: KEY(%s) DEVICE(%s)", VCONFKEY_SYSMAN_REMOVED_USB_STORAGE, buf_dev_name);
228 FILE *file = setmntent(MTAB_FILE, "r");
229 struct mntent *mnt_entry;
231 while (mnt_entry = getmntent(file)) {
232 mounted_check = strstr(mnt_entry->mnt_dir, buf_mnt_point);
233 if (mounted_check != NULL) {
234 if (__ss_unmount_device(mnt_entry->mnt_dir) < 0) {
235 PRT_TRACE_ERR("Unmount Failed: MOUNT PATH(%s)", mnt_entry->mnt_dir);
237 PRT_TRACE("Unmount Success: MOUNT PATH(%s)", mnt_entry->mnt_dir);
242 umount2(MOUNT_POINT, MNT_DETACH);
244 if (removed_noti_value < INT_MAX) {
245 ++removed_noti_value;
247 removed_noti_value = 1;
249 if (vconf_set_int(VCONFKEY_SYSMAN_REMOVED_USB_STORAGE, removed_noti_value) < 0) {
250 PRT_TRACE_ERR("Setting vconf value is failed: KEY(%s)", VCONFKEY_SYSMAN_REMOVED_USB_STORAGE);
251 vconf_set_int(VCONFKEY_SYSMAN_ADDED_USB_STORAGE, -1);
254 PRT_TRACE("Setting vconf value: KEY(%s) DEVICE(%s)", VCONFKEY_SYSMAN_REMOVED_USB_STORAGE, buf_dev_name);
258 int _ss_usb_storage_init()
260 ss_action_entry_add_internal(PREDEF_USB_STORAGE_ADD, __ss_usb_storage_added, NULL, NULL);
261 ss_action_entry_add_internal(PREDEF_USB_STORAGE_REMOVE, __ss_usb_storage_removed, NULL, NULL);