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 <syspopup_caller.h>
31 #include "ss_device_handler.h"
36 #define FS_TYPE_CHECKER "/sbin/fs-type-checker"
37 #define TEMP_FILE "/tmp/mountd.tmp"
38 #define MTAB_FILE "/etc/mtab"
39 #define MOUNT_POINT "/opt/storage/usb"
41 static int added_noti_value = 0;
42 static int removed_noti_value = 0;
43 static int tempfs_mounted = 0;
45 static int __ss_mount_device(char *dev)
47 if (access(dev, F_OK) != 0) {
48 PRT_TRACE_ERR("Failed to find device: DEVICE(%s)", dev);
55 char buf_mnt_point[BUF_MAX];
57 rel_mnt_point = strrchr(dev, '/');
58 if (rel_mnt_point == NULL) {
59 PRT_TRACE_ERR("Get Relative Mount Path Failed");
63 snprintf(buf_mnt_point, BUF_MAX, "%s%s", MOUNT_POINT, rel_mnt_point);
65 /* Make directory to mount */
66 r = mkdir(buf_mnt_point, 0755);
68 if (errno == EEXIST) {
69 PRT_TRACE("Directory is already exsited: PATH(%s)", buf_mnt_point);
71 PRT_TRACE_ERR("Make Directory Failed: PATH(%s)", buf_mnt_point);
76 /* Mount block device on mount point */
77 r = mount(dev, buf_mnt_point, "vfat", 0, "uid=0,gid=0,dmask=0000,fmask=0111,iocharset=iso8859-1,utf8,shortname=mixed,smackfsroot=*,smackfsdef=*");
79 r = rmdir(buf_mnt_point);
80 PRT_TRACE_ERR("Mount failed: MOUNT PATH(%s", buf_mnt_point);
83 PRT_TRACE("Mount Complete: MOUNT PATH(%s)", buf_mnt_point);
88 static int __ss_unmount_device(char *mnt_point)
90 if (access(mnt_point, F_OK) != 0) {
91 PRT_TRACE_ERR("Failed to find path: MOUNT PATH(%s)", mnt_point);
97 /* Umount block device */
98 ret = umount2(mnt_point, MNT_DETACH);
100 PRT_TRACE_ERR("Unmounting is unabled: MOUNT PATH(%s)", mnt_point);
101 ret = rmdir(mnt_point);
103 PRT_TRACE_ERR("Removing Directory is unabled: PATH(%s)", mnt_point);
110 bundle_add(b, "_SYSPOPUP_CONTENT_", "otg_remove");
111 ret = syspopup_launch("usbotg-syspopup", b);
113 PRT_TRACE_EM("popup lauch failed\n");
117 /* Clean up unmounted directory */
118 ret = rmdir(mnt_point);
120 PRT_TRACE_ERR("Removing Directory is unabled: PATH(%s)", mnt_point);
122 PRT_TRACE("Unmount/Remove Complete: MOUNT PATH(%s)", mnt_point);
127 static int __ss_usb_storage_added(int argc, char *argv[])
129 if (argc != 1 || argv[0] == NULL) {
130 PRT_TRACE_ERR("Get Vconf Value Failed: KEY(%s)", VCONFKEY_SYSMAN_ADDED_USB_STORAGE);
138 char *buf_dev = argv[0];
139 char buf_part_dev[BUF_MAX];
144 char buf_mnt_point[BUF_MAX];
146 /* Check whether mount point directory is exist */
147 if (access(MOUNT_POINT, F_OK) < 0) {
148 if (mkdir(MOUNT_POINT, 0755) < 0) {
149 PRT_TRACE_ERR("Make Mount Directory Failed: DIRECTORY(%s)", MOUNT_POINT);
154 /* Mount tmpfs for protecting user data */
155 if (tempfs_mounted != 1) {
156 if (mount("tmpfs", MOUNT_POINT, "tmpfs", 0, "") < 0) {
157 if (errno != EBUSY) {
158 PRT_TRACE_ERR("Failed to mount USB Storage Mount Directory: DIRECTORY(%s)", MOUNT_POINT);
162 /* Change permission to avoid to write user data on tmpfs */
163 if (chmod(MOUNT_POINT, 0755) < 0) {
164 PRT_TRACE_ERR("Failed to change mode: DIRCTORY(%s)", MOUNT_POINT);
165 umount2(MOUNT_POINT, MNT_DETACH);
172 rel_mnt_point = strrchr(buf_dev, '/');
173 if (rel_mnt_point == NULL) {
174 PRT_TRACE_ERR("Get Relative Mount Path Failed");
177 snprintf(buf_mnt_point, BUF_MAX, "%s%s", MOUNT_POINT, rel_mnt_point);
179 if (__ss_mount_device(buf_dev) < 0) {
180 PRT_TRACE_ERR("Failed to mount %d", buf_dev);
183 FILE *file = setmntent(MTAB_FILE, "r");
184 struct mntent *mnt_entry;
186 /* Check whether block deivce is mounted */
187 while (mnt_entry = getmntent(file)) {
188 mounted_check = strstr(mnt_entry->mnt_fsname, buf_dev);
189 if (mounted_check != NULL) {
190 if (added_noti_value < INT_MAX) {
193 added_noti_value = 1;
195 /* Broadcast mounting notification */
196 if (vconf_set_int(VCONFKEY_SYSMAN_ADDED_USB_STORAGE, added_noti_value) < 0) {
197 PRT_TRACE_ERR("Setting vconf value is failed: KEY(%s)", VCONFKEY_SYSMAN_ADDED_USB_STORAGE);
198 vconf_set_int(VCONFKEY_SYSMAN_ADDED_USB_STORAGE, -1);
201 PRT_TRACE("Setting vconf value: KEY(%s) DEVICE(%s)", VCONFKEY_SYSMAN_ADDED_USB_STORAGE, buf_dev);
206 bundle_add(b, "_SYSPOPUP_CONTENT_", "otg_add");
207 bundle_add(b, "path", buf_mnt_point);
208 ret = syspopup_launch("usbotg-syspopup", b);
210 PRT_TRACE_EM("popup lauch failed\n");
218 /* Failed to mount storage device */
219 PRT_TRACE_ERR("Nothing to be mounted: DEVICE(%s)", buf_dev);
224 static int __ss_usb_storage_removed(int argc, char *argv[])
226 if (argc != 1 || argv[0] == NULL) {
227 PRT_TRACE_ERR("Get Vonf Value Failed: KEY(%s)", VCONFKEY_SYSMAN_REMOVED_USB_STORAGE);
234 char *buf_dev_name = argv[0];
235 char buf_mnt_point[BUF_MAX];
238 snprintf(buf_mnt_point, BUF_MAX, "%s/%s", MOUNT_POINT, buf_dev_name);
240 if (__ss_unmount_device(buf_mnt_point) == 0) {
241 if(umount2(MOUNT_POINT, MNT_DETACH) == 0)
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 PRT_TRACE("Usb storage removed fail");
262 int _ss_usb_storage_init()
264 ss_action_entry_add_internal(PREDEF_USB_STORAGE_ADD, __ss_usb_storage_added, NULL, NULL);
265 ss_action_entry_add_internal(PREDEF_USB_STORAGE_REMOVE, __ss_usb_storage_removed, NULL, NULL);