Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
vnotepad
Exa
提交
6770ac54
E
Exa
项目概览
vnotepad
/
Exa
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
Exa
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
6770ac54
编写于
12月 12, 2014
作者:
B
Ben S
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Replare Unix module with users crate
Feels good turning all that code into a dependency!
上级
61340965
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
57 addition
and
174 deletion
+57
-174
Cargo.lock
Cargo.lock
+6
-0
Cargo.toml
Cargo.toml
+3
-3
src/exa.rs
src/exa.rs
+15
-14
src/file.rs
src/file.rs
+33
-16
src/unix.rs
src/unix.rs
+0
-141
未找到文件。
Cargo.lock
浏览文件 @
6770ac54
...
...
@@ -3,6 +3,7 @@ name = "exa"
version = "0.1.0"
dependencies = [
"ansi_term 0.3.0 (git+https://github.com/ogham/rust-ansi-term.git)",
"users 0.1.0 (git+https://github.com/ogham/rust-users)",
]
[[package]]
...
...
@@ -10,3 +11,8 @@ name = "ansi_term"
version = "0.3.0"
source = "git+https://github.com/ogham/rust-ansi-term.git#4b9ea6cf266053e1a771e75b935b4e54c586c139"
[[package]]
name = "users"
version = "0.1.0"
source = "git+https://github.com/ogham/rust-users#221a1463d3e25acac41615186a1c7fdcf0ad36d7"
Cargo.toml
浏览文件 @
6770ac54
[package]
name
=
"exa"
version
=
"0.1.0"
authors
=
[
"ogham@bsago.me"
]
[[bin]]
name
=
"exa"
[dependencies.
ansi_term
]
git
=
"https://github.com/ogham/rust-ansi-term.git"
[dependencies.
users
]
git
=
"https://github.com/ogham/rust-users.git"
\ No newline at end of file
src/exa.rs
浏览文件 @
6770ac54
...
...
@@ -2,30 +2,31 @@
extern
crate
regex
;
#[phase(plugin)]
extern
crate
regex_macros
;
extern
crate
ansi_term
;
extern
crate
users
;
extern
crate
unicode
;
use
std
::
os
;
use
std
::
io
::
fs
;
use
std
::
io
::
FileType
;
use
std
::
io
::
fs
;
use
std
::
iter
::
AdditiveIterator
;
use
std
::
os
;
use
std
::
str
::
StrVector
;
use
file
::
File
;
use
dir
::
Dir
;
use
column
::
Column
;
use
column
::
Alignment
::
Left
;
use
column
::
Column
;
use
dir
::
Dir
;
use
file
::
File
;
use
options
::{
Options
,
View
};
use
unix
::
Unix
;
use
ansi_term
::
Style
::
Plain
;
use
ansi_term
::
strip_formatting
;
use
users
::
OSUsers
;
pub
mod
column
;
pub
mod
dir
;
pub
mod
format
;
pub
mod
file
;
pub
mod
filetype
;
pub
mod
unix
;
pub
mod
options
;
pub
mod
sort
;
pub
mod
term
;
...
...
@@ -175,7 +176,7 @@ fn details_view(options: &Options, columns: &Vec<Column>, files: Vec<File>) {
// width of each column based on the length of the results and
// padding the fields during output.
let
mut
cache
=
Unix
::
empty_cache
();
let
mut
cache
=
OSUsers
::
empty_cache
();
let
mut
table
:
Vec
<
Vec
<
String
>>
=
files
.iter
()
.map
(|
f
|
columns
.iter
()
.map
(|
c
|
f
.display
(
c
,
&
mut
cache
))
.collect
())
...
...
src/file.rs
浏览文件 @
6770ac54
...
...
@@ -5,10 +5,11 @@ use ansi_term::{ANSIString, Colour, Style};
use
ansi_term
::
Style
::
Plain
;
use
ansi_term
::
Colour
::{
Red
,
Green
,
Yellow
,
Blue
,
Purple
,
Cyan
,
Fixed
};
use
users
::{
Users
,
OSUsers
};
use
column
::
Column
;
use
column
::
Column
::
*
;
use
format
::{
format_metric_bytes
,
format_IEC_bytes
};
use
unix
::
Unix
;
use
sort
::
SortPart
;
use
dir
::
Dir
;
use
filetype
::
HasType
;
...
...
@@ -103,7 +104,7 @@ impl<'a> File<'a> {
}
}
pub
fn
display
(
&
self
,
column
:
&
Column
,
u
nix
:
&
mut
Unix
)
->
String
{
pub
fn
display
(
&
self
,
column
:
&
Column
,
u
sers_cache
:
&
mut
OSUsers
)
->
String
{
match
*
column
{
Permissions
=>
{
self
.permissions_string
()
...
...
@@ -141,18 +142,34 @@ impl<'a> File<'a> {
// Display the ID if the user/group doesn't exist, which
// usually means it was deleted but its files weren't.
User
=>
{
let
uid
=
self
.stat.unstable.uid
as
u32
;
unix
.load_user
(
uid
);
let
user_name
=
unix
.get_user_name
(
uid
)
.unwrap_or
(
uid
.to_string
());
let
style
=
if
unix
.uid
==
uid
{
Yellow
.bold
()
}
else
{
Plain
};
let
uid
=
self
.stat.unstable.uid
as
i32
;
let
user_name
=
match
users_cache
.get_user_by_uid
(
uid
)
{
Some
(
user
)
=>
user
.name
,
None
=>
uid
.to_string
(),
};
let
style
=
if
users_cache
.get_current_uid
()
==
uid
{
Yellow
.bold
()
}
else
{
Plain
};
style
.paint
(
user_name
.as_slice
())
.to_string
()
},
Group
=>
{
let
gid
=
self
.stat.unstable.gid
as
u32
;
unix
.load_group
(
gid
);
let
group_name
=
unix
.get_group_name
(
gid
)
.unwrap_or
(
gid
.to_string
());
let
style
=
if
unix
.is_group_member
(
gid
)
{
Yellow
.normal
()
}
else
{
Plain
};
let
mut
style
=
Plain
;
let
group_name
=
match
users_cache
.get_group_by_gid
(
gid
)
{
Some
(
group
)
=>
{
let
current_uid
=
users_cache
.get_current_uid
();
if
let
Some
(
current_user
)
=
users_cache
.get_user_by_uid
(
current_uid
)
{
if
current_user
.primary_group
==
group
.gid
||
group
.members
.contains
(
&
current_user
.name
)
{
style
=
Yellow
.bold
();
}
}
group
.name
},
None
=>
gid
.to_string
(),
};
style
.paint
(
group_name
.as_slice
())
.to_string
()
},
}
...
...
src/unix.rs
已删除
100644 → 0
浏览文件 @
61340965
use
std
::
ptr
::
read
;
use
std
::
ptr
;
use
std
::
collections
::
HashMap
;
mod
c
{
#![allow(non_camel_case_types)]
extern
crate
libc
;
pub
use
self
::
libc
::{
c_char
,
c_int
,
uid_t
,
gid_t
,
time_t
};
#[repr(C)]
pub
struct
c_passwd
{
pub
pw_name
:
*
const
c_char
,
// login name
pub
pw_passwd
:
*
const
c_char
,
pub
pw_uid
:
c_int
,
// user ID
pub
pw_gid
:
c_int
,
// group ID
pub
pw_change
:
time_t
,
pub
pw_class
:
*
const
c_char
,
pub
pw_gecos
:
*
const
c_char
,
// full name
pub
pw_dir
:
*
const
c_char
,
// login dir
pub
pw_shell
:
*
const
c_char
,
// login shell
pub
pw_expire
:
time_t
,
// password expiry time
}
#[repr(C)]
pub
struct
c_group
{
pub
gr_name
:
*
const
c_char
,
// group name
pub
gr_passwd
:
*
const
c_char
,
// password
pub
gr_gid
:
gid_t
,
// group id
pub
gr_mem
:
*
const
*
const
c_char
,
// names of users in the group
}
extern
{
pub
fn
getpwuid
(
uid
:
c_int
)
->
*
const
c_passwd
;
pub
fn
getgrgid
(
gid
:
uid_t
)
->
*
const
c_group
;
pub
fn
getuid
()
->
libc
::
c_int
;
}
}
pub
struct
Unix
{
user_names
:
HashMap
<
u32
,
Option
<
String
>>
,
// mapping of user IDs to user names
group_names
:
HashMap
<
u32
,
Option
<
String
>>
,
// mapping of groups IDs to group names
groups
:
HashMap
<
u32
,
bool
>
,
// mapping of group IDs to whether the current user is a member
pub
uid
:
u32
,
// current user's ID
pub
username
:
String
,
// current user's name
}
impl
Unix
{
pub
fn
empty_cache
()
->
Unix
{
let
uid
=
unsafe
{
c
::
getuid
()
};
let
infoptr
=
unsafe
{
c
::
getpwuid
(
uid
as
i32
)
};
let
info
=
unsafe
{
infoptr
.as_ref
()
.unwrap
()
};
// the user has to have a name
let
username
=
unsafe
{
String
::
from_raw_buf
(
info
.pw_name
as
*
const
u8
)
};
let
mut
user_names
=
HashMap
::
new
();
user_names
.insert
(
uid
as
u32
,
Some
(
username
.clone
()));
// Unix groups work like this: every group has a list of
// users, referred to by their names. But, every user also has
// a primary group, which isn't in this list. So handle this
// case immediately after we look up the user's details.
let
mut
groups
=
HashMap
::
new
();
groups
.insert
(
info
.pw_gid
as
u32
,
true
);
Unix
{
user_names
:
user_names
,
group_names
:
HashMap
::
new
(),
uid
:
uid
as
u32
,
username
:
username
,
groups
:
groups
,
}
}
pub
fn
get_user_name
(
&
self
,
uid
:
u32
)
->
Option
<
String
>
{
self
.user_names
[
uid
]
.clone
()
}
pub
fn
get_group_name
(
&
self
,
gid
:
u32
)
->
Option
<
String
>
{
self
.group_names
[
gid
]
.clone
()
}
pub
fn
is_group_member
(
&
self
,
gid
:
u32
)
->
bool
{
self
.groups
[
gid
]
}
pub
fn
load_user
(
&
mut
self
,
uid
:
u32
)
{
let
pw
=
unsafe
{
c
::
getpwuid
(
uid
as
i32
)
};
if
pw
.is_not_null
()
{
let
username
=
unsafe
{
Some
(
String
::
from_raw_buf
(
read
(
pw
)
.pw_name
as
*
const
u8
))
};
self
.user_names
.insert
(
uid
,
username
);
}
else
{
self
.user_names
.insert
(
uid
,
None
);
}
}
fn
group_membership
(
group
:
*
const
*
const
c
::
c_char
,
uname
:
&
String
)
->
bool
{
let
mut
i
=
0
;
// The list of members is a pointer to a pointer of
// characters, terminated by a null pointer.
loop
{
match
unsafe
{
group
.offset
(
i
)
.as_ref
()
}
{
Some
(
&
username
)
=>
{
if
username
==
ptr
::
null
()
{
return
false
;
// username was null, weird
}
else
if
unsafe
{
String
::
from_raw_buf
(
username
as
*
const
u8
)
}
==
*
uname
{
return
true
;
// group found!
}
else
{
i
+=
1
;
// try again with the next group
}
},
None
=>
return
false
,
// no more groups to check, and none found
}
}
}
pub
fn
load_group
(
&
mut
self
,
gid
:
u32
)
{
match
unsafe
{
c
::
getgrgid
(
gid
)
.as_ref
()
}
{
None
=>
{
self
.group_names
.insert
(
gid
,
None
);
self
.groups
.insert
(
gid
,
false
);
},
Some
(
r
)
=>
{
let
group_name
=
unsafe
{
Some
(
String
::
from_raw_buf
(
r
.gr_name
as
*
const
u8
))
};
if
!
self
.groups
.contains_key
(
&
gid
)
{
self
.groups
.insert
(
gid
,
Unix
::
group_membership
(
r
.gr_mem
,
&
self
.username
));
}
self
.group_names
.insert
(
gid
,
group_name
);
}
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录