Пример #1
0
 private void SetPermission(IFile file, bool setSubFiles = false, bool setParentFiles = false)
 {
     if (setParentFiles)
     {
         file.ClearPermission();
         SetPermission(file);
     }
     if (_group.Rules.ContainsKey(file.VirtualPath))
     {
         file.Permission = _group.Rules[file.VirtualPath];
     }
     else
     {
         file.Permission = file.ParentDirectory.Permission;
     }
     if (setSubFiles)
     {
         VDirectory f = file as VDirectory;
         if (f == null)
         {
             return;
         }
         foreach (var s in f.SubFiles)
         {
             if (_group.Rules.ContainsKey(s.VirtualPath))
             {
                 s.Permission = _group.Rules[s.VirtualPath];
             }
             else
             {
                 s.Permission = f.Permission;
             }
         }
     }
 }
Пример #2
0
        /// <summary>
        /// 获取文件夹
        /// </summary>
        /// <param name="vdir">虚拟路径</param>
        /// <returns>文件夹信息,如不存在则为null</returns>
        public DirectoryInfo GetDirectory(string vdir)
        {
            string     pre = VPath.NormalizeFilename(vdir);
            VDirectory dir = Get(pre, true) as VDirectory;

            return(dir == null ? null : dir.RealDirectory);
        }
Пример #3
0
        public VirtualFileSystem(FtpConfig config, FtpUserGroup group, string rootpath = null)
        {
            _config = config;
            _group  = group;
            if (!string.IsNullOrEmpty(rootpath))
            {
                _rootPath = rootpath;
            }
            else if (!string.IsNullOrEmpty(group.HomeDir))
            {
                _rootPath = group.HomeDir;
            }
            else
            {
                _rootPath = config.HomeDir;
            }
            _rootDirectory = new VDirectory(null, new FilePermission("r-xr-xr-x"), _rootPath, "");



            _currentDirectory = _rootDirectory;
            _currentDirectory.Refresh();
            AddGroupLinks();    //FIXED:应在刷新后加入链接
            _currentDirectory.Refresh();
            SetPermission(_currentDirectory, true);
        }
Пример #4
0
        /// <summary>
        /// 获取一个虚拟文件实体
        /// </summary>
        /// <param name="vdir">虚拟路径</param>
        /// <param name="onlyFindDir">只寻找文件夹</param>
        /// <returns>虚拟文件,如不存在则为null</returns>
        private IFile Get(string vdir, bool onlyFindDir = false)
        {
            IFile currentPosition = _rootDirectory;

            if (!vdir.Trim().StartsWith("/"))
            {
                currentPosition = _currentDirectory;
            }
            if (vdir == "")
            {
                return(currentPosition);
            }
            string pre;

            string[] dirs = vdir.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < dirs.Length; i++)
            {
                pre = dirs[i].Trim();
                if (pre == "..")
                {
                    currentPosition = currentPosition.ParentDirectory;
                }
                else
                {
                    if (currentPosition.IsDirectory)
                    {
                        VDirectory temp = currentPosition as VDirectory;
                        if (temp == null || !temp.Enumerate().Contains(pre))
                        {
                            return(null);
                        }
                        if (i >= dirs.Length - 1)   //找到了最后一层,寻找文件
                        {
                            if (onlyFindDir)
                            {
                                currentPosition = temp.SubFiles.Find((t) => (t.Name == pre) && (t.IsDirectory));
                                return(currentPosition ?? _rootDirectory);
                            }
                            //Find:如果找到与指定谓词定义的条件匹配的第一个元素,则为该元素;否则为类型 T 的默认值。
                            currentPosition = temp.SubFiles.Find((t) => (t.Name == pre) && (!t.IsDirectory)) ??
                                              temp.SubFiles.Find((t) => (t.Name == pre) && (t.IsDirectory));
                        }
                        else //不是最后一层,找子目录
                        {
                            currentPosition = temp.SubFiles.Find((t) => (t.Name == pre) && (t.IsDirectory));
                        }
                        if (currentPosition == null)
                        {
                            return(null);
                        }
                    }
                }
                SetPermission(currentPosition);
                currentPosition.Refresh();
            }
            SetPermission(currentPosition, true, true);
            return(!currentPosition.Permission.CanRead ? null : currentPosition);
        }
Пример #5
0
        /// <summary>
        /// 切换当前目录
        /// </summary>
        /// <param name="vPath">虚拟路径</param>
        /// <param name="createDirIfNotExists">目录不存在时,是否创建目录</param> //MARK: WARNING: may cause Security Issue!
        /// <returns></returns>
        public bool ChangeCurrentDirectory(string vPath, bool createDirIfNotExists = false)
        {
            string pre = VPath.NormalizeFilename(vPath, true);

            if (pre == "..")
            {
                _currentDirectory = _currentDirectory.ParentDirectory;
            }
            else if (pre == "/") //FIXED:
            {
                _currentDirectory = _rootDirectory;
            }
            else
            {
                VDirectory v;
                if (pre.StartsWith("/", StringComparison.OrdinalIgnoreCase))    //绝对虚拟路径
                {
                    v = Get(pre, true) as VDirectory;
                }
                else    //相对虚拟路径
                {
                    v = _currentDirectory.SubFiles.Find((t) => t.IsDirectory && t.Name == pre) as VDirectory;
                }
                if (v == null)
                {
                    if (!createDirIfNotExists)
                    {
                        return(false);
                    }
                    //ADDED:
                    FileError fileError = CreateDirectory(pre);
                    if (fileError == FileError.None)
                    {
                        var dir = Get(pre, true) as VDirectory;
                        if (dir != null)
                        {
                            v = dir;
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
                _currentDirectory = v;
            }
            _currentDirectory.Refresh();
            SetPermission(_currentDirectory, true);
            return(true);
        }
Пример #6
0
 public VFile(VDirectory parent, FilePermission permission, string realPath, string name)
 {
     ParentDirectory = parent;
     _permission     = permission ?? ParentDirectory.Permission;
     try
     {
         Name     = name ?? Path.GetFileName(realPath);
         RealFile = new FileInfo(realPath);
     }
     catch (Exception e)
     {
         //throw e;
         RealFile = null;
     }
 }
Пример #7
0
        /// <summary>
        /// 虚拟文件夹
        /// </summary>
        /// <param name="permission">权限</param>
        /// <param name="parent">父目录</param>
        /// <param name="name">文件夹名</param>
        /// <param name="realPath">真实路径</param>
        public VDirectory(VDirectory parent, FilePermission permission, string realPath, string name = null)
        {
            ParentDirectory = parent;

            _permission = permission ?? ParentDirectory.Permission;
            try
            {
                Name = name ?? VPath.GetFileName(realPath);
                if (ParentDirectory == null || ParentDirectory == this)
                {
                    VirtualPath = "/";
                }
                else
                {
                    VirtualPath = VPath.Combine(ParentDirectory.VirtualPath, Name);
                }
                RealDirectory = new DirectoryInfo(realPath);
            }
            catch (Exception e)
            {
                //throw e;
                RealDirectory = null;
            }
        }
Пример #8
0
        private List <string> GenerateList(IEnumerable <IFile> list)
        {
            List <string> fileList = new List <string>();

            DateTime now = DateTime.Now;

            foreach (var f in list)
            {
                if (!f.Permission.CanRead)
                {
                    continue;
                }
                //参考格式
                //drwxrwxrwx   1 user     group           0 Nov 27 00:13 上传

                StringBuilder sb = new StringBuilder();
                DateTime      editDate;
                if (f.IsDirectory)
                {
                    VDirectory vf = (VDirectory)f;
                    editDate = vf.RealDirectory.LastWriteTime;

                    sb.Append('d').Append(f.Permission.ToString());                                 //文件权限10位
                    sb.Append("   1 ");                                                             //1空格  子文件个数2位 1空格
                    sb.Append(string.Format("{0,-8}", _config.Owner.PadRight(8))).Append(' ');      //文件所有者8位 1空格
                    sb.Append(string.Format("{0,-8}", _config.OwnerGroup.PadRight(8))).Append(' '); //文件所有者8位 1空格
                    //sb.Append(_config.Owner.Substring(0, 8).PadRight(8)).Append(' ');       //文件所有者8位 1空格
                    //sb.Append(_config.OwnerGroup.Substring(0, 8).PadRight(8)).Append(' ');  //文件所有组8位 1空格
                    sb.Append("       0 ");                                   //文件大小>=8位,文件夹通常为0或4096  1空格

                    sb.Append(editDate < now.Subtract(TimeSpan.FromDays(180)) //文件修改日期5位,1空格,时间5位,1空格
                        ? editDate.ToString("MMM dd  yyyy", CultureInfo.InvariantCulture)
                        : editDate.ToString("MMM dd HH:mm", CultureInfo.InvariantCulture))
                    .Append(' ');
                    sb.Append(f.Name);
                }
                else
                {
                    VFile vf = (VFile)f;
                    editDate = vf.RealFile.LastWriteTime;

                    //string.Format("{0,-50}", theObj);//格式化成50个字符,原字符左对齐,不足则补空格
                    //string.Format("{0,50}", theObj);//格式化成50个字符,原字符右对齐,不足则补空格
                    sb.Append('-').Append(f.Permission.ToString());                                 //文件权限10位
                    sb.Append("   1 ");                                                             //1空格  子文件个数2位 1空格
                    sb.Append(string.Format("{0,-8}", _config.Owner.PadRight(8))).Append(' ');      //文件所有者8位 1空格
                    sb.Append(string.Format("{0,-8}", _config.OwnerGroup.PadRight(8))).Append(' '); //文件所有者8位 1空格
                    //sb.Append(_config.OwnerGroup.Substring(0, 8).PadRight(8)).Append(' ');  //文件所有组8位 1空格
                    string length = vf.RealFile.Length.ToString(CultureInfo.InvariantCulture);
                    if (length.Length < 8)
                    {
                        length = length.PadLeft(8);
                    }
                    sb.Append(length).Append(' ');                            //文件大小>=8位  1空格
                    sb.Append(editDate < now.Subtract(TimeSpan.FromDays(180)) //文件修改日期5位,1空格,时间5位,1空格
                        ? editDate.ToString("MMM dd  yyyy", CultureInfo.InvariantCulture)
                        : editDate.ToString("MMM dd HH:mm", CultureInfo.InvariantCulture))
                    .Append(' ');
                    sb.Append(f.Name);
                }
                fileList.Add(sb.ToString());
            }
            return(fileList);
        }
Пример #9
0
        /*  perm权限设置
         *  perm="a" / "c" / "d" / "e" / "f" / "l" / "m" / "p" / "r" / "w"
         *  a:文件,APPE追加许可
         *  c:文件夹,STOR STOU APPE存储许可(不能已存在)
         *  d:全部,RMD DELE删除许可
         *  e:文件夹,CWD PWD CDUP目录切换许可
         *  f:全部,RNFR重命名许可
         *  l:文件夹,LIST NLST MLSD列目录许可
         *  m:文件夹,MKD建目录许可
         *  p:文件夹,DELE文件夹内容删除许可
         *  r:文件,RTER取得许可
         *  w:文件,STOR存储许可
         */

        /// <summary>
        /// 取得格式化的文件列表
        /// <para>MLSD in RFC 3659</para>
        /// </summary>
        /// <param name="vPath"></param>
        /// <returns></returns>
        public List <string> MachineListFiles(string vPath = null)
        {
            VDirectory dir;

            if (string.IsNullOrEmpty(vPath))
            {
                dir = _currentDirectory;
                SetPermission(dir, true);
            }
            else
            {
                dir = Get(VPath.NormalizeFilename(vPath), true) as VDirectory ?? _currentDirectory;
            }

            dir.Refresh();  //FIXED:目录及时更新

            List <string> fileList = new List <string>();

            DateTime now = DateTime.Now;

            foreach (var f in dir.SubFiles)
            {
                if (!f.Permission.CanRead)
                {
                    continue;
                }
                //参考格式
                //type=dir;modify=20141218151753;perm=el; 新建文件夹
                DateTime      editDate;
                StringBuilder sb = new StringBuilder();

                if (f.IsDirectory)
                {
                    VDirectory vf = (VDirectory)f;
                    editDate = vf.RealDirectory.LastWriteTime.ToUniversalTime();

                    sb.Append("Type=dir;");                                                       //type类型
                    sb.Append("modify=").Append(editDate.ToString("yyyyMMddHHmmss")).Append(';'); //modify修改时间
                    //sb.Append("size=").Append("0");   //文件夹没有size
                    //-RFC 3659- -7.5.5- Its value is always an unordered sequence of alphabetic characters. 意味着权限字母不用排序
                    sb.Append("perm=el");   //perm权限,具体见上
                    if (vf.Permission.CanWrite)
                    {
                        sb.Append("cm");
                    }
                    if (vf.Permission.GroupCanWrite)
                    {
                        sb.Append("dfp");
                    }
                    sb.Append("; ");
                    sb.Append(f.Name);
                }
                else
                {
                    VFile vf = (VFile)f;
                    editDate = vf.RealFile.LastWriteTime.ToUniversalTime();

                    //参考格式
                    //type=file;modify=20140628041312;size=761344; Server.exe

                    sb.Append("type=file;");                                                      //type类型
                    sb.Append("modify=").Append(editDate.ToString("yyyyMMddHHmmss")).Append(';'); //modify修改时间
                    sb.Append("size=").Append(vf.RealFile.Length).Append(';');                    //size大小
                    //-RFC 3659- -7.5.5- Its value is always an unordered sequence of alphabetic characters. 意味着权限字母不用排序
                    sb.Append("perm=r");                                                          //perm权限,具体见上
                    if (vf.Permission.CanWrite)
                    {
                        //sb.Append("cm");
                    }
                    if (vf.Permission.GroupCanWrite)
                    {
                        sb.Append("adfw");
                    }
                    sb.Append("; ");
                    sb.Append(f.Name);
                }
                fileList.Add(sb.ToString());
            }
            return(fileList);
        }