当前位置: 技术问答>linux和unix
请教chown的实现和原理
来源: 互联网 发布时间:2016-12-09
本文导语: 现在在做一个路由器上访问USB的功能,碰到用户权限问题。 路由器里面只有chmod命令,chown命令都不全。 现在想参考下chown的实现,自己搞一个函数。 google和百度了一下,没有找到合适的源码,就下载了busybox源码下...
现在在做一个路由器上访问USB的功能,碰到用户权限问题。
路由器里面只有chmod命令,chown命令都不全。
现在想参考下chown的实现,自己搞一个函数。
google和百度了一下,没有找到合适的源码,就下载了busybox源码下来看chown.c结果看不懂。
没有具体的问题,请各位尽量多告知点信息。
下面是busybox里面的源码:
static int FAST_FUNC fileAction(const char *fileName, struct stat *statbuf,
void *vparam, int depth UNUSED_PARAM)
{
#define param (*(struct param_t*)vparam)
#define opt option_mask32
uid_t u = (param.ugid.uid == (uid_t)-1L) ? statbuf->st_uid : param.ugid.uid;
gid_t g = (param.ugid.gid == (gid_t)-1L) ? statbuf->st_gid : param.ugid.gid;
if (param.chown_func(fileName, u, g) == 0) {
if (OPT_VERBOSE
|| (OPT_CHANGED && (statbuf->st_uid != u || statbuf->st_gid != g))
) {
printf("changed ownership of '%s' to %u:%un",
fileName, (unsigned)u, (unsigned)g);
}
return TRUE;
}
if (!OPT_QUIET)
bb_simple_perror_msg(fileName);
return FALSE;
#undef opt
#undef param
}
int chown_main(int argc UNUSED_PARAM, char **argv)
{
int retval = EXIT_SUCCESS;
int opt, flags;
struct param_t param;
/* Just -1 might not work: uid_t may be unsigned long */
param.ugid.uid = -1L;
param.ugid.gid = -1L;
#if ENABLE_FEATURE_CHOWN_LONG_OPTIONS
applet_long_options = chown_longopts;
#endif
opt_complementary = "-2";
opt = getopt32(argv, OPT_STR);
argv += optind;
/* This matches coreutils behavior (almost - see below) */
param.chown_func = chown;
if (OPT_NODEREF
/* || (OPT_RECURSE && !OPT_TRAVERSE_TOP): */
IF_DESKTOP( || (opt & (BIT_RECURSE|BIT_TRAVERSE_TOP)) == BIT_RECURSE)
) {
param.chown_func = lchown;
}
flags = ACTION_DEPTHFIRST; /* match coreutils order */
if (OPT_RECURSE)
flags |= ACTION_RECURSE;
if (OPT_TRAVERSE_TOP)
flags |= ACTION_FOLLOWLINKS_L0; /* -H/-L: follow links on depth 0 */
if (OPT_TRAVERSE)
flags |= ACTION_FOLLOWLINKS; /* follow links if -L */
parse_chown_usergroup_or_die(¶m.ugid, argv[0]);
/* Ok, ready to do the deed now */
while (*++argv) {
if (!recursive_action(*argv,
flags, /* flags */
fileAction, /* file action */
fileAction, /* dir action */
¶m, /* user data */
0) /* depth */
) {
retval = EXIT_FAILURE;
}
}
return retval;
}
路由器里面只有chmod命令,chown命令都不全。
现在想参考下chown的实现,自己搞一个函数。
google和百度了一下,没有找到合适的源码,就下载了busybox源码下来看chown.c结果看不懂。
没有具体的问题,请各位尽量多告知点信息。
下面是busybox里面的源码:
static int FAST_FUNC fileAction(const char *fileName, struct stat *statbuf,
void *vparam, int depth UNUSED_PARAM)
{
#define param (*(struct param_t*)vparam)
#define opt option_mask32
uid_t u = (param.ugid.uid == (uid_t)-1L) ? statbuf->st_uid : param.ugid.uid;
gid_t g = (param.ugid.gid == (gid_t)-1L) ? statbuf->st_gid : param.ugid.gid;
if (param.chown_func(fileName, u, g) == 0) {
if (OPT_VERBOSE
|| (OPT_CHANGED && (statbuf->st_uid != u || statbuf->st_gid != g))
) {
printf("changed ownership of '%s' to %u:%un",
fileName, (unsigned)u, (unsigned)g);
}
return TRUE;
}
if (!OPT_QUIET)
bb_simple_perror_msg(fileName);
return FALSE;
#undef opt
#undef param
}
int chown_main(int argc UNUSED_PARAM, char **argv)
{
int retval = EXIT_SUCCESS;
int opt, flags;
struct param_t param;
/* Just -1 might not work: uid_t may be unsigned long */
param.ugid.uid = -1L;
param.ugid.gid = -1L;
#if ENABLE_FEATURE_CHOWN_LONG_OPTIONS
applet_long_options = chown_longopts;
#endif
opt_complementary = "-2";
opt = getopt32(argv, OPT_STR);
argv += optind;
/* This matches coreutils behavior (almost - see below) */
param.chown_func = chown;
if (OPT_NODEREF
/* || (OPT_RECURSE && !OPT_TRAVERSE_TOP): */
IF_DESKTOP( || (opt & (BIT_RECURSE|BIT_TRAVERSE_TOP)) == BIT_RECURSE)
) {
param.chown_func = lchown;
}
flags = ACTION_DEPTHFIRST; /* match coreutils order */
if (OPT_RECURSE)
flags |= ACTION_RECURSE;
if (OPT_TRAVERSE_TOP)
flags |= ACTION_FOLLOWLINKS_L0; /* -H/-L: follow links on depth 0 */
if (OPT_TRAVERSE)
flags |= ACTION_FOLLOWLINKS; /* follow links if -L */
parse_chown_usergroup_or_die(¶m.ugid, argv[0]);
/* Ok, ready to do the deed now */
while (*++argv) {
if (!recursive_action(*argv,
flags, /* flags */
fileAction, /* file action */
fileAction, /* dir action */
¶m, /* user data */
0) /* depth */
) {
retval = EXIT_FAILURE;
}
}
return retval;
}
|
學習了,看來是更簡便的解決方法。
樓主慷慨,大家來接分啊~
|
呵呵
smb.conf中加入veto files 过滤文件。
[public]
veto files =
smb.conf中加入veto files 过滤文件。
[public]
veto files =