Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Anders Blomdell
rust-hashtoc
Commits
8f1e4e6c
Commit
8f1e4e6c
authored
Dec 06, 2018
by
Anders Blomdell
Browse files
Add option to generate toc for files read from stdin
parent
dd0a9539
Changes
3
Hide whitespace changes
Inline
Side-by-side
Cargo.toml
View file @
8f1e4e6c
[package]
name
=
"hashtoc"
version
=
"0.1.
3
"
version
=
"0.1.
4
"
authors
=
[
"Anders Blomdell <anders.blomdell@control.lth.se>"
]
build
=
"build.rs"
links
=
"libhash.a,libssl"
...
...
src/main.rs
View file @
8f1e4e6c
...
...
@@ -39,7 +39,7 @@ use std::cell::RefCell;
use
libc
::{
c_int
,
time_t
};
use
std
::
result
::
Result
;
use
std
::
io
::
Error
as
IOError
;
use
std
::
io
::{
self
,
Write
};
use
std
::
io
::{
self
,
Write
,
BufRead
};
use
bytes
::
BytesMut
;
use
std
::
ops
::
Deref
;
...
...
@@ -554,7 +554,7 @@ fn dispatcher(options: clap::ArgMatches,
zprintln!
();
}
fn
main
()
{
fn
main
()
->
std
::
io
::
Result
<
()
>
{
let
matches
=
App
::
new
(
"hashtoc"
)
.version
(
"1.0"
)
.author
(
"Anders Blomdell <anders.blomdell@control.lth.se>"
)
...
...
@@ -608,7 +608,11 @@ fn main() {
.arg
(
Arg
::
with_name
(
"zero-terminated"
)
.short
(
"z"
)
.long
(
"zero-terminated"
)
.help
(
"End lines with NULL character"
))
.help
(
"Line endings are the NULL character"
))
.arg
(
Arg
::
with_name
(
"stdin"
)
.long
(
"stdin"
)
.required
(
true
)
.help
(
"Read paths from stdin"
))
.arg
(
Arg
::
with_name
(
"max_age"
)
.short
(
"m"
)
.long
(
"max-age"
)
...
...
@@ -616,7 +620,8 @@ fn main() {
.help
(
"max age of HASH extended attribute(s)"
))
.arg
(
Arg
::
with_name
(
"PATH"
)
.help
(
"path(s) to traverse"
)
.required
(
true
)
.required
(
false
)
.conflicts_with
(
"stdin"
)
.multiple
(
true
)
.index
(
1
))
.get_matches
();
...
...
@@ -628,18 +633,47 @@ fn main() {
let
worker
=
thread
::
spawn
(
move
||
{
dispatcher
(
args
,
rx
);
});
(
worker
,
tx
)
};
let
callback
=
|
p
:
&
Path
,
m
:
&
Metadata
|
{
tx
.send
(
WalkerMessage
::
Inode
(
Inode
{
path
:
p
.to_owned
(),
metadata
:
Some
(
m
.clone
())}))
.unwrap
();
};
let
paths
:
Vec
<
_
>
=
matches
.values_of_os
(
"PATH"
)
.unwrap
()
.collect
();
// let mut paths : Vec<_> = matches.values_of_os("PATH").unwrap().collect();
// paths.sort();
for
p
in
paths
{
let
path
=
std
::
path
::
Path
::
new
(
p
);
let
_
=
tx
.send
(
WalkerMessage
::
Start
(
path
.to_owned
()));
walk
::
visit
(
std
::
path
::
Path
::
new
(
p
),
&
callback
)
.unwrap
();
match
matches
.values_of_os
(
"PATH"
)
{
Some
(
_
)
=>
{
let
callback
=
|
p
:
&
Path
,
m
:
&
Metadata
|
{
tx
.send
(
WalkerMessage
::
Inode
(
Inode
{
path
:
p
.to_owned
(),
metadata
:
Some
(
m
.clone
())}))
.unwrap
();
};
let
paths
:
Vec
<
_
>
=
matches
.values_of_os
(
"PATH"
)
.unwrap
()
.collect
();
for
p
in
paths
{
let
path
=
std
::
path
::
Path
::
new
(
p
);
let
_
=
tx
.send
(
WalkerMessage
::
Start
(
path
.to_owned
()));
walk
::
visit
(
std
::
path
::
Path
::
new
(
p
),
&
callback
)
.unwrap
();
}
},
None
=>
{
let
terminator
=
if
matches
.is_present
(
"zero-terminated"
)
{
0
}
else
{
10
};
let
stdin
=
std
::
io
::
stdin
();
let
mut
handle
=
stdin
.lock
();
let
get_metadata
=
walk
::
metadata_getter
();
loop
{
let
mut
buf
=
vec!
[];
let
len
=
handle
.read_until
(
terminator
,
&
mut
buf
)
.unwrap
();
if
len
==
0
{
break
;
}
let
path
=
Path
::
new
(
OsStr
::
from_bytes
(
&
buf
[
..
len
-
1
]));
let
metadata
=
get_metadata
(
&
path
);
match
metadata
{
Ok
(
metadata
)
=>
tx
.send
(
WalkerMessage
::
Inode
(
Inode
{
path
:
path
.to_owned
(),
metadata
:
Some
(
metadata
)
}))
.unwrap
(),
Err
(
e
)
=>
{
println!
(
"{} {:?}"
,
e
,
path
)
}
};
}
}
}
tx
.send
(
WalkerMessage
::
Done
)
.unwrap
();
worker
.join
()
.unwrap
();
Ok
(())
}
src/walk.rs
View file @
8f1e4e6c
...
...
@@ -26,6 +26,7 @@ use std::fs::{read_dir, symlink_metadata, Metadata};
use
std
::
os
::
unix
::
fs
::
MetadataExt
;
use
libc
::{
AT_FDCWD
,
R_OK
,
X_OK
,
AT_SYMLINK_NOFOLLOW
};
use
libc
;
use
std
::
io
::{
Error
,
ErrorKind
};
macro_rules!
reportln
{
()
=>
(
writeln!
(
io
::
stderr
())
.unwrap_or
(()));
...
...
@@ -165,5 +166,30 @@ pub fn visit(path: &Path, cb: &Fn(&Path, &Metadata)) -> io::Result<()>
Ok
(())
}
pub
fn
metadata_getter
()
->
impl
Fn
(
&
Path
)
->
io
::
Result
<
Metadata
>
{
let
do_access_check
=
need_access_check
();
move
|
path
:
&
Path
|
{
let
metadata
=
symlink_metadata
(
path
);
let
access
=
match
metadata
{
Ok
(
ref
m
)
=>
{
if
!
do_access_check
{
true
}
else
{
if
m
.file_type
()
.is_dir
()
{
check_full_path
(
&
path
,
R_OK
|
X_OK
)
}
else
{
check_full_path
(
&
path
,
R_OK
)
}
}
},
_
=>
false
};
if
!
access
{
Err
(
Error
::
new
(
ErrorKind
::
PermissionDenied
,
"Access denied"
))
}
else
{
metadata
}
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment