106 lines
3.4 KiB
Rust
106 lines
3.4 KiB
Rust
use structopt::StructOpt;
|
|
use std::time::Duration;
|
|
|
|
use tn3270s::tn3270;
|
|
use tn3270s::tn3270::stream::WriteOrder::SetBufferAddress;
|
|
|
|
#[derive(StructOpt)]
|
|
pub struct Cli {
|
|
#[structopt(short="h", long = "host", default_value="::1")]
|
|
host: String,
|
|
#[structopt(short="p", long = "port", default_value="2101")]
|
|
port: u16,
|
|
|
|
}
|
|
|
|
// _~^~^~_
|
|
// \) / o o \ (/
|
|
// '_ ¬ _'
|
|
// / '-----' \
|
|
// 1234567890123456
|
|
|
|
static rust_logo: [&'static str; 4] = [
|
|
r#" _~^~^~_ "#,
|
|
r#" \) / o o \ (/ "#,
|
|
r#" '_ ¬ _' "#,
|
|
r#" / '-----' \ "#,
|
|
];
|
|
|
|
fn run(mut session: tn3270::Session) -> anyhow::Result<()> {
|
|
use tn3270::stream::*;
|
|
let bufsz = BufferAddressCalculator { width: 80, height: 24 };
|
|
let mut record = WriteCommand {
|
|
command: WriteCommandCode::Write,
|
|
wcc: WCC::RESET | WCC::KBD_RESTORE | WCC::RESET_MDT,
|
|
orders: vec![
|
|
WriteOrder::SetBufferAddress(0),
|
|
WriteOrder::EraseUnprotectedToAddress(bufsz.last_address()),
|
|
WriteOrder::SetBufferAddress(bufsz.encode_address(1, 31)),
|
|
WriteOrder::StartFieldExtended(FieldAttribute::PROTECTED, vec![
|
|
// ExtendedFieldAttribute::ForegroundColor(Color::Red),
|
|
]),
|
|
WriteOrder::SendText("Hello from Rust!".into()),
|
|
WriteOrder::SetBufferAddress(bufsz.encode_address(8, 21)),
|
|
WriteOrder::StartFieldExtended(FieldAttribute::INTENSE_SELECTOR_PEN_DETECTABLE, vec![]),
|
|
WriteOrder::SendText(" ".into()),
|
|
WriteOrder::StartField(FieldAttribute::PROTECTED),
|
|
WriteOrder::SetBufferAddress(bufsz.encode_address(8, 10)),
|
|
WriteOrder::StartFieldExtended(FieldAttribute::PROTECTED, vec![
|
|
ExtendedFieldAttribute::ForegroundColor(Color::Turquoise),
|
|
]),
|
|
WriteOrder::SendText("Name:".into()),
|
|
],
|
|
};
|
|
|
|
for (i, line) in rust_logo.iter().enumerate() {
|
|
record.orders.push(WriteOrder::SetBufferAddress(bufsz.encode_address(3+i as u16, 31)));
|
|
record.orders.push(WriteOrder::StartFieldExtended(FieldAttribute::PROTECTED, vec![
|
|
ExtendedFieldAttribute::ForegroundColor(Color::Red),
|
|
]));
|
|
record.orders.push(WriteOrder::SendText((*line).into()));
|
|
}
|
|
session.send_record(&record)?;
|
|
session.send_record(&WriteCommand{
|
|
command: WriteCommandCode::Write,
|
|
wcc: WCC::RESET_MDT | WCC::KBD_RESTORE,
|
|
orders: vec![],
|
|
})?;
|
|
|
|
let record = session.receive_record(None)?;
|
|
if let Some(record) = record {
|
|
eprintln!("Incoming record: {:?}", hex::encode(record));
|
|
} else {
|
|
eprintln!("No record");
|
|
}
|
|
|
|
|
|
std::thread::sleep(Duration::from_secs(5));
|
|
Ok(())
|
|
}
|
|
|
|
fn main() -> anyhow::Result<()> {
|
|
let options: Cli = Cli::from_args();
|
|
let server = std::net::TcpListener::bind((options.host.as_str(), options.port))?;
|
|
|
|
for client in server.incoming() {
|
|
let client = client?;
|
|
std::thread::spawn(move || {
|
|
let session = match tn3270::Session::new(client) {
|
|
Ok(session) => session,
|
|
Err(err) => {
|
|
eprintln!("Error accepting session: {}", err);
|
|
return;
|
|
}
|
|
};
|
|
|
|
if let Err(err) = run(session) {
|
|
eprintln!("Error in session: {}", err);
|
|
}
|
|
|
|
});
|
|
}
|
|
println!("Hello, world!");
|
|
|
|
Ok(())
|
|
}
|