int mount_main(int argc, char **argv) { char *cmdopts = bb_xstrdup(""), *fstabname, *fstype=0, *storage_path=0; FILE *fstab; int i, opt, all = FALSE, rc = 0; struct mntent mtpair[2], *mtcur = mtpair; int resolved_spec = 0; /* parse long options, like --bind and --move. Note that -o option * and --option are synonymous. Yes, this means --remount,rw works. */ for (i = opt = 0; i < argc; i++) { if (argv[i][0] == '-' && argv[i][1] == '-') { append_mount_options(&cmdopts,argv[i]+2); } else argv[opt++] = argv[i]; } argc = opt; // Parse remaining options while ((opt = getopt(argc, argv, "o:t:rwavnfi")) > 0) { switch (opt) { case 'o': append_mount_options(&cmdopts, optarg); break; case 't': fstype = optarg; break; case 'r': append_mount_options(&cmdopts, "ro"); break; case 'w': append_mount_options(&cmdopts, "rw"); break; case 'a': all = TRUE; break; case 'n': USE_FEATURE_MTAB_SUPPORT(useMtab = FALSE;) break; case 'f': USE_FEATURE_MTAB_SUPPORT(fakeIt = FALSE;) break; case 'i': case 'v': break; // ignore default: bb_show_usage(); }
static int mount_it_now(struct mntent *mp, int vfsflags, char *filteropts) { int rc; if (fakeIt) { return 0; } // Mount, with fallback to read-only if necessary. for(;;) { rc = mount(mp->mnt_fsname, mp->mnt_dir, mp->mnt_type, vfsflags, filteropts); if(!rc || (vfsflags&MS_RDONLY) || (errno!=EACCES && errno!=EROFS)) break; bb_error_msg("%s is write-protected, mounting read-only", mp->mnt_fsname); vfsflags |= MS_RDONLY; } // Abort entirely if permission denied. if (rc && errno == EPERM) bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); /* If the mount was successful, and we're maintaining an old-style * mtab file by hand, add the new entry to it now. */ if(ENABLE_FEATURE_MTAB_SUPPORT && useMtab && !rc) { FILE *mountTable = setmntent(bb_path_mtab_file, "a+"); int i; if(!mountTable) bb_error_msg("No %s\n",bb_path_mtab_file); // Add vfs string flags for(i=0; mount_options[i].flags != MS_REMOUNT; i++) if (mount_options[i].flags > 0) append_mount_options(&(mp->mnt_opts), // Shut up about the darn const. It's not important. I don't care. (char *)mount_options[i].name); // Remove trailing / (if any) from directory we mounted on i = strlen(mp->mnt_dir); if(i>1 && mp->mnt_dir[i-1] == '/') mp->mnt_dir[i-1] = 0; // Write and close. if(!mp->mnt_type || !*mp->mnt_type) mp->mnt_type="--bind"; addmntent(mountTable, mp); endmntent(mountTable); if (ENABLE_FEATURE_CLEAN_UP) if(strcmp(mp->mnt_type,"--bind")) mp->mnt_type = 0; } return rc; }
// Perform actual mount of specific filesystem at specific location. // NB: mp->xxx fields may be trashed on exit static int mount_it_now(struct mntent *mp, int vfsflags, char *filteropts) { int rc = 0; if (fakeIt) goto mtab; // Mount, with fallback to read-only if necessary. for (;;) { rc = mount(mp->mnt_fsname, mp->mnt_dir, mp->mnt_type, vfsflags, filteropts); if (!rc || (vfsflags&MS_RDONLY) || (errno!=EACCES && errno!=EROFS)) break; bb_error_msg("%s is write-protected, mounting read-only", mp->mnt_fsname); vfsflags |= MS_RDONLY; } // Abort entirely if permission denied. if (rc && errno == EPERM) bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); /* If the mount was successful, and we're maintaining an old-style * mtab file by hand, add the new entry to it now. */ mtab: if (ENABLE_FEATURE_MTAB_SUPPORT && useMtab && !rc && !(vfsflags & MS_REMOUNT)) { char *fsname; FILE *mountTable = setmntent(bb_path_mtab_file, "a+"); int i; if (!mountTable) { bb_error_msg("no %s",bb_path_mtab_file); goto ret; } // Add vfs string flags for (i=0; mount_options[i].flags != MS_REMOUNT; i++) if (mount_options[i].flags > 0 && (mount_options[i].flags & vfsflags)) append_mount_options(&(mp->mnt_opts), mount_options[i].name); // Remove trailing / (if any) from directory we mounted on i = strlen(mp->mnt_dir) - 1; if (i > 0 && mp->mnt_dir[i] == '/') mp->mnt_dir[i] = 0; // Convert to canonical pathnames as needed mp->mnt_dir = bb_simplify_path(mp->mnt_dir); fsname = 0; if (!mp->mnt_type || !*mp->mnt_type) { /* bind mount */ mp->mnt_fsname = fsname = bb_simplify_path(mp->mnt_fsname); mp->mnt_type = (char*)"bind"; } mp->mnt_freq = mp->mnt_passno = 0; // Write and close. addmntent(mountTable, mp); endmntent(mountTable); if (ENABLE_FEATURE_CLEAN_UP) { free(mp->mnt_dir); free(fsname); } } ret: return rc; }