def _check_path(pathname):
try:
info = os.stat(pathname)
except os.error, e:
return None, ["stat error: %s" % e]
kind = None
errors = []
mode = info[stat.ST_MODE]
isdir = stat.S_ISDIR(mode)
isreg = stat.S_ISREG(mode)
if isreg or isdir:
#
# Quick version of access() where we use existing stat() data.
#
# This might not be perfect -- the OS may return slightly different
# results for some bizarre reason. However, we make a good show of
# "can I read this file/dir?" by checking the various perm bits.
#
# NOTE: if the UID matches, then we must match the user bits -- we
# cannot defer to group or other bits. Similarly, if the GID matches,
# then we must have read access in the group bits.
#
# If the UID or GID don't match, we need to check the
# results of an os.access() call, in case the web server process
# is in the group that owns the directory.
#
if isdir:
mask = stat.S_IROTH | stat.S_IXOTH
else:
mask = stat.S_IROTH
if info[stat.ST_UID] == _uid:
if ((mode >> 6) & mask) != mask:
errors.append("error: path is not accessible to user %i" % _uid)
elif info[stat.ST_GID] == _gid:
if ((mode >> 3) & mask) != mask:
errors.append("error: path is not accessible to group %i" % _gid)
# If the process running the web server is a member of
# the group stat.ST_GID access may be granted.
# so the fall back to os.access is needed to figure this out.
elif (mode & mask) != mask:
if not os.access(pathname, isdir and (os.R_OK | os.X_OK) or os.R_OK):
errors.append("error: path is not accessible")
if isdir:
kind = vclib.DIR
else:
kind = vclib.FILE
else:
errors.append("error: path is not a file or directory")
return kind, errors
评论列表
文章目录