int cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) { FAR const char *source; FAR char *fullsource; FAR const char *target; FAR char *fulltarget; FAR const char *filesystem = NULL; bool badarg = false; int option; int ret; /* The mount command behaves differently if no parameters are provided */ #ifndef CONFIG_NUTTX_KERNEL if (argc < 2) { return mount_show(vtbl, argv[0]); } #endif /* Get the mount options. NOTE: getopt() is not thread safe nor re-entrant. * To keep its state proper for the next usage, it is necessary to parse to * the end of the line even if an error occurs. If an error occurs, this * logic just sets 'badarg' and continues. */ while ((option = getopt(argc, argv, ":t:")) != ERROR) { switch (option) { case 't': filesystem = optarg; break; case ':': nsh_output(vtbl, g_fmtargrequired, argv[0]); badarg = true; break; case '?': default: nsh_output(vtbl, g_fmtarginvalid, argv[0]); badarg = true; break; } } /* If a bad argument was encountered, then return without processing the * command. */ if (badarg) { return ERROR; } /* There may be one or two required arguments after the options: the source * and target paths. Some file systems do not require the source parameter * so if there is only one parameter left, it must be the target. */ if (optind >= argc) { nsh_output(vtbl, g_fmtargrequired, argv[0]); return ERROR; } source = NULL; target = argv[optind]; optind++; if (optind < argc) { source = target; target = argv[optind]; optind++; if (optind < argc) { nsh_output(vtbl, g_fmttoomanyargs, argv[0]); return ERROR; } } /* While the above parsing for the -t argument looks nice, the -t argument * not really optional. */ if (!filesystem) { nsh_output(vtbl, g_fmtargrequired, argv[0]); return ERROR; } /* The source and target paths might be relative to the current * working directory. */ fullsource = NULL; fulltarget = NULL; if (source) { fullsource = nsh_getfullpath(vtbl, source); if (!fullsource) { return ERROR; } } fulltarget = nsh_getfullpath(vtbl, target); if (!fulltarget) { ret = ERROR; goto errout; } /* Perform the mount */ ret = mount(fullsource, fulltarget, filesystem, 0, NULL); if (ret < 0) { nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mount", NSH_ERRNO); } errout: if (fullsource) { nsh_freefullpath(fullsource); } if (fulltarget) { nsh_freefullpath(fulltarget); } return ret; }
/**************************************************************************** * Name: tash_mount * * Description: * Mount specific file system. * * Usage: * mount -t <filesystem name> <source directory> <target directory> ****************************************************************************/ static int tash_mount(int argc, char **args) { int option; int ret; const char *fs = NULL; const char *source; char *fullsource; const char *target; char *fulltarget; bool badarg = false; if (argc < 2) { return mount_show(mount_handler, args[1]); } optind = -1; while ((option = getopt(argc, args, ":t:")) != ERROR) { switch (option) { case 't': fs = optarg; break; case ':': FSCMD_OUTPUT(MISSING_ARGS, args[0]); badarg = true; break; case '?': default: FSCMD_OUTPUT(INVALID_ARGS, args[0]); badarg = true; break; } } if (badarg) { FSCMD_OUTPUT(INVALID_ARGS " : [-t] <fs_type> <source> <target>\n", args[0]); return 0; } if (!fs || optind >= argc) { FSCMD_OUTPUT(MISSING_ARGS, args[0]); return ERROR; } source = NULL; target = args[optind]; optind++; if (optind < argc) { source = target; target = args[optind]; optind++; if (optind < argc) { FSCMD_OUTPUT(TOO_MANY_ARGS, args[0]); return ERROR; } } fullsource = NULL; fulltarget = NULL; if (source) { fullsource = get_fullpath(source); if (!fullsource) { return ERROR; } } fulltarget = get_fullpath(target); if (!fulltarget) { ret = ERROR; goto errout; } /* Perform the mount */ ret = mount(fullsource, fulltarget, fs, 0, NULL); if (ret < 0) { FSCMD_OUTPUT(CMD_FAILED, args[0], fs); } errout: fscmd_free(fulltarget); fscmd_free(fullsource); return ret; }