diff --git a/nshlib/Kconfig b/nshlib/Kconfig index 1fc34cb213e..2d1570b8788 100644 --- a/nshlib/Kconfig +++ b/nshlib/Kconfig @@ -341,6 +341,16 @@ config NSH_DISABLE_CD bool "Disable cd" default DEFAULT_SMALL +config NSH_DISABLE_CHMOD + bool "Disable chmod" + default DEFAULT_SMALL + depends on FS_PERMISSION + +config NSH_DISABLE_CHOWN + bool "Disable chown" + default DEFAULT_SMALL + depends on FS_PERMISSION + config NSH_DISABLE_CP bool "Disable cp" default DEFAULT_SMALL diff --git a/nshlib/nsh.h b/nshlib/nsh.h index 2fb3cf867cc..7abb7c38f82 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -963,6 +963,12 @@ int cmd_irqinfo(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); #ifndef CONFIG_NSH_DISABLE_CAT int cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); #endif +#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHMOD) + int cmd_chmod(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); +#endif +#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHOWN) + int cmd_chown(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); +#endif #ifndef CONFIG_NSH_DISABLE_CP int cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv); #endif diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index ec3f8a385f2..23534fbe598 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -168,6 +168,14 @@ static const struct cmdmap_s g_cmdmap[] = CMD_MAP("cd", cmd_cd, 1, 2, "[|-|~|..]"), #endif +#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHMOD) + CMD_MAP("chmod", cmd_chmod, 3, 3, " "), +#endif + +#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHOWN) + CMD_MAP("chown", cmd_chown, 3, 3, "[][:] "), +#endif + #ifndef CONFIG_NSH_DISABLE_CP CMD_MAP("cp", cmd_cp, 3, 4, "[-r] "), #endif diff --git a/nshlib/nsh_fscmds.c b/nshlib/nsh_fscmds.c index a88c1a20d51..13daa8258e0 100644 --- a/nshlib/nsh_fscmds.c +++ b/nshlib/nsh_fscmds.c @@ -843,6 +843,129 @@ int cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) } #endif +/**************************************************************************** + * Name: cmd_chmod + * + * Description: + * chmod + * + * Only numeric (octal) modes are supported. + * + ****************************************************************************/ + +#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHMOD) +int cmd_chmod(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) +{ + FAR char *fullpath; + FAR char *endptr; + long mode; + int ret = ERROR; + + UNUSED(argc); + + mode = strtol(argv[1], &endptr, 8); + if (endptr == argv[1] || *endptr != '\0' || mode < 0 || mode > 0777) + { + nsh_error(vtbl, g_fmtarginvalid, argv[0]); + return ERROR; + } + + fullpath = nsh_getfullpath(vtbl, argv[2]); + if (fullpath != NULL) + { + ret = chmod(fullpath, (mode_t)mode); + if (ret < 0) + { + nsh_error(vtbl, g_fmtcmdfailed, argv[0], "chmod", NSH_ERRNO); + } + + nsh_freefullpath(fullpath); + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: cmd_chown + * + * Description: + * chown [:] + * chown []: + * + * Only numeric uid/gid forms are supported. Empty uid or gid fields + * leave that side unchanged. + * + ****************************************************************************/ + +#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHOWN) +int cmd_chown(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) +{ + FAR const char *spec = argv[1]; + FAR char *endptr; + FAR char *fullpath; + long value; + uid_t uid = (uid_t)-1; + gid_t gid = (gid_t)-1; + int ret = ERROR; + + UNUSED(argc); + + value = strtol(spec, &endptr, 10); + if (endptr != spec) + { + if (value < 0) + { + nsh_error(vtbl, g_fmtarginvalid, argv[0]); + return ERROR; + } + + uid = (uid_t)value; + } + + if (*endptr == ':') + { + FAR const char *gidstr = endptr + 1; + if (*gidstr != '\0') + { + value = strtol(gidstr, &endptr, 10); + if (*endptr != '\0' || value < 0) + { + nsh_error(vtbl, g_fmtarginvalid, argv[0]); + return ERROR; + } + + gid = (gid_t)value; + } + } + else if (*endptr != '\0') + { + nsh_error(vtbl, g_fmtarginvalid, argv[0]); + return ERROR; + } + + if (uid == (uid_t)-1 && gid == (gid_t)-1) + { + nsh_error(vtbl, g_fmtarginvalid, argv[0]); + return ERROR; + } + + fullpath = nsh_getfullpath(vtbl, argv[2]); + if (fullpath != NULL) + { + ret = lchown(fullpath, uid, gid); + if (ret < 0) + { + nsh_error(vtbl, g_fmtcmdfailed, argv[0], "chown", NSH_ERRNO); + } + + nsh_freefullpath(fullpath); + } + + return ret; +} +#endif + /**************************************************************************** * Name: cmd_dmesg ****************************************************************************/