// Copyright (c) 2022 YAC // SPDX-License-Identifier: AGPL-3.0-or-later /* This file is part of YAC coreutils. * * YAC coreutils is free software: you can redistribute it and/or modify it * under the terms of the GNU Affero General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * YAC coreutils is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see https://www.gnu.org/licenses/. */ use std::env; use std::fs::{ File, read_to_string }; use std::os::fd::{ AsRawFd, FromRawFd }; use std::io::{ self, Read, Write }; use std::str; use arg::Args; use sysexits::ExitCode; #[derive(Args, Debug)] struct Arguments { argv0: String, #[arg(short = "u")] u: bool, paths: Vec, } fn main() -> ExitCode { let mut args = Arguments::from_args(env::args() .collect::>() .iter() .map(String::as_str) .collect::>() ).unwrap(); let argv0 = args.argv0; let mut output: Vec = vec![]; let stdin = io::stdin(); if args.paths.is_empty() { args.paths.push("-".to_string()); } if args.u { for path in args.paths { let handle: File; if path == "-" { handle = unsafe { File::from_raw_fd(stdin.as_raw_fd()) } } else { handle = match File::open(&path) { Ok(file) => file, Err(_) => { eprintln!("{}: {}: No such file or directory.", &argv0, &path); return ExitCode::NoInput; }, }; } let mut stdout = io::BufWriter::with_capacity(0, io::stdout()); for byte in handle.bytes() { stdout.write(&[byte.unwrap()]).unwrap(); stdout.flush().unwrap(); } } return ExitCode::Ok; } else { let mut stdout = io::stdout(); for path in args.paths { if path == "-" { let mut bytes: Vec = Vec::new(); stdin.lock().read_to_end(&mut bytes).unwrap(); for byte in &bytes { output.push(byte.to_owned()); } } else { match read_to_string(&path) { Ok(contents) => output.append(&mut contents.as_bytes().to_owned()), Err(_) => { eprintln!("{}: {}: No such file or directory.", &argv0, &path); return ExitCode::NoInput; }, }; } stdout.write(&output[..]); output.clear(); } } ExitCode::Ok }