nc: Port to LibMain

This commit is contained in:
Kenneth Myhra 2022-01-15 18:09:27 +01:00 committed by Linus Groh
parent ae71d2b70e
commit 294cbb7108
Notes: sideshowbarker 2024-07-17 20:49:36 +09:00
2 changed files with 37 additions and 74 deletions

View File

@ -127,6 +127,7 @@ target_link_libraries(markdown-check LibMarkdown)
target_link_libraries(matroska LibVideo)
target_link_libraries(md LibMarkdown)
target_link_libraries(mkdir LibMain)
target_link_libraries(nc LibMain)
target_link_libraries(netstat LibMain)
target_link_libraries(notify LibGUI)
target_link_libraries(nproc LibMain)

View File

@ -7,7 +7,9 @@
#include <AK/ByteBuffer.h>
#include <LibCore/ArgsParser.h>
#include <LibCore/EventLoop.h>
#include <LibCore/System.h>
#include <LibCore/UDPSocket.h>
#include <LibMain/Main.h>
#include <arpa/inet.h>
#include <errno.h>
#include <netdb.h>
@ -26,7 +28,7 @@
//
// nc -l someport > out.file
int main(int argc, char** argv)
ErrorOr<int> serenity_main(Main::Arguments arguments)
{
bool should_listen = false;
bool verbose = false;
@ -43,7 +45,7 @@ int main(int argc, char** argv)
args_parser.add_option(should_close, "Close connection after reading stdin to the end", nullptr, 'N');
args_parser.add_positional_argument(target, "Address to listen on, or the address or hostname to connect to", "target");
args_parser.add_positional_argument(port, "Port to connect to or listen on", "port");
args_parser.parse(argc, argv);
args_parser.parse(arguments);
if (udp_mode) {
if (should_listen) {
@ -52,34 +54,29 @@ int main(int argc, char** argv)
}
Core::EventLoop loop;
auto socket = Core::UDPSocket::construct();
auto socket = TRY(Core::UDPSocket::try_create());
socket->on_connected = [&]() {
if (verbose)
warnln("connected to {}:{}", target, port);
};
socket->connect(target, port);
Array<u8, 1024> buffer;
for (;;) {
char buf[1024];
int nread = read(STDIN_FILENO, buf, sizeof(buf));
if (nread < 0) {
perror("read");
return 1;
}
Bytes buffer_span = buffer.span();
auto nread = TRY(Core::System::read(STDIN_FILENO, buffer_span));
buffer_span = buffer_span.trim(nread);
socket->send({ buf, static_cast<size_t>(nread) });
socket->send({ buffer_span.data(), static_cast<size_t>(nread) });
}
}
int fd;
if (should_listen) {
int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd < 0) {
perror("socket");
return 1;
}
int listen_fd = TRY(Core::System::socket(AF_INET, SOCK_STREAM, 0));
sockaddr_in sa {};
sa.sin_family = AF_INET;
@ -92,61 +89,34 @@ int main(int argc, char** argv)
}
}
if (bind(listen_fd, (struct sockaddr*)&sa, sizeof(sa)) == -1) {
perror("bind");
return 1;
}
if (listen(listen_fd, 1) == -1) {
perror("listen");
return 1;
}
TRY(Core::System::bind(listen_fd, (struct sockaddr*)&sa, sizeof(sa)));
TRY(Core::System::listen(listen_fd, 1));
char addr_str[INET_ADDRSTRLEN];
sockaddr_in sin;
socklen_t len;
len = sizeof(sin);
if (getsockname(listen_fd, (struct sockaddr*)&sin, &len) == -1) {
perror("getsockname");
return 1;
}
TRY(Core::System::getsockname(listen_fd, (struct sockaddr*)&sin, &len));
if (verbose)
warnln("waiting for a connection on {}:{}", inet_ntop(sin.sin_family, &sin.sin_addr, addr_str, sizeof(addr_str) - 1), ntohs(sin.sin_port));
len = sizeof(sin);
fd = accept(listen_fd, (struct sockaddr*)&sin, &len);
if (fd == -1) {
perror("accept");
return 1;
}
TRY(Core::System::accept(listen_fd, (struct sockaddr*)&sin, &len));
if (verbose)
warnln("got connection from {}:{}", inet_ntop(sin.sin_family, &sin.sin_addr, addr_str, sizeof(addr_str) - 1), ntohs(sin.sin_port));
if (close(listen_fd) == -1) {
perror("close");
return 1;
};
TRY(Core::System::close(listen_fd));
} else {
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
perror("socket");
return 1;
}
fd = TRY(Core::System::socket(AF_INET, SOCK_STREAM, 0));
struct timeval timeout {
3, 0
};
if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) {
perror("setsockopt");
return 1;
}
if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0) {
perror("setsockopt");
return 1;
}
TRY(Core::System::setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)));
TRY(Core::System::setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)));
auto* hostent = gethostbyname(target);
if (!hostent) {
@ -163,10 +133,8 @@ int main(int argc, char** argv)
char addr_str[INET_ADDRSTRLEN];
warnln("connecting to {}:{}", inet_ntop(dst_addr.sin_family, &dst_addr.sin_addr, addr_str, sizeof(addr_str) - 1), ntohs(dst_addr.sin_port));
}
if (connect(fd, (struct sockaddr*)&dst_addr, sizeof(dst_addr)) < 0) {
perror("connect");
return 1;
}
TRY(Core::System::connect(fd, (struct sockaddr*)&dst_addr, sizeof(dst_addr)));
if (verbose)
warnln("connected!");
}
@ -204,12 +172,10 @@ int main(int argc, char** argv)
}
if (!stdin_closed && FD_ISSET(STDIN_FILENO, &readfds)) {
char buf[1024];
int nread = read(STDIN_FILENO, buf, sizeof(buf));
if (nread < 0) {
perror("read(STDIN_FILENO)");
return 1;
}
Array<u8, 1024> buffer;
Bytes buffer_span = buffer.span();
auto nread = TRY(Core::System::read(STDIN_FILENO, buffer_span));
buffer_span = buffer_span.trim(nread);
// stdin closed
if (nread == 0) {
@ -217,22 +183,19 @@ int main(int argc, char** argv)
if (verbose)
warnln("stdin closed");
if (should_close) {
close(fd);
TRY(Core::System::close(fd));
fd_closed = true;
}
} else if (write(fd, buf, nread) < 0) {
perror("write(fd)");
return 1;
} else {
TRY(Core::System::write(fd, buffer_span));
}
}
if (!fd_closed && FD_ISSET(fd, &readfds)) {
char buf[1024];
int nread = read(fd, buf, sizeof(buf));
if (nread < 0) {
perror("read(fd)");
return 1;
}
Array<u8, 1024> buffer;
Bytes buffer_span = buffer.span();
auto nread = TRY(Core::System::read(fd, buffer_span));
buffer_span = buffer_span.trim(nread);
// remote end closed
if (nread == 0) {
@ -241,9 +204,8 @@ int main(int argc, char** argv)
fd_closed = true;
if (verbose)
warnln("remote closed");
} else if (write(STDOUT_FILENO, buf, nread) < 0) {
perror("write(STDOUT_FILENO)");
return 1;
} else {
TRY(Core::System::write(STDOUT_FILENO, buffer_span));
}
}
}