#![no_std] #![no_main] use lancer_user::fs::{self, FsRights}; use lancer_user::net; use lancer_user::println; use lancer_user::syscall; #[unsafe(no_mangle)] pub extern "C" fn lancer_main() -> ! { let (rx, _tx) = match net::init() { Some(pair) => pair, None => { lancer_user::show!(net, error, "netsock init failed"); syscall::exit(); } }; let mut args_buf = [0u8; 512]; let args_len = net::recv_args(&rx, &mut args_buf); let args = &args_buf[..args_len]; let (_cmd, rest) = net::next_token(args); let (src_tok, rest2) = net::next_token(rest); let (dst_tok, _) = net::next_token(rest2); if src_tok.is_empty() || dst_tok.is_empty() { println!("usage: cp "); syscall::exit(); } let mut client = unsafe { fs::init() }; let src_handle = match fs::open_path_with_rights(&mut client, 0, src_tok, fs::FsRights::READ) { Ok(h) => h, Err(e) => { println!("cp: src: {}", e.name()); syscall::exit(); } }; let (dst_parent, dst_name) = match fs::open_parent(&mut client, 0, dst_tok) { Ok(pair) => pair, Err(e) => { println!("cp: dst: {}", e.name()); let _ = client.close(src_handle); syscall::exit(); } }; let dst_mode = FsRights::from_raw(FsRights::WRITE.raw() | FsRights::CREATE.raw()); let dst_handle = match client.open(dst_parent, dst_name, dst_mode) { Ok(h) => h, Err(e) => { println!("cp: dst open: {}", e.name()); let _ = client.close(dst_parent); let _ = client.close(src_handle); syscall::exit(); } }; match client.truncate(dst_handle, 0) { Ok(()) => {} Err(e) => { println!("cp: truncate: {}", e.name()); let _ = client.close(dst_handle); let _ = client.close(dst_parent); let _ = client.close(src_handle); syscall::exit(); } } let mut buf = [0u8; 4096]; fn copy_chunks(client: &mut fs::FsClient, src: u8, dst: u8, buf: &mut [u8], offset: u64) { match client.read(src, offset, buf) { Ok(0) => {} Ok(n) => match client.write(dst, offset, &buf[..n]) { Ok(_) => copy_chunks(client, src, dst, buf, offset + n as u64), Err(e) => println!("cp: write: {}", e.name()), }, Err(e) => println!("cp: read: {}", e.name()), } } copy_chunks(&mut client, src_handle, dst_handle, &mut buf, 0); let _ = client.close(dst_handle); let _ = client.close(dst_parent); let _ = client.close(src_handle); syscall::exit() }