mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 06:17:35 +00:00
nc: Port to LibMain
This commit is contained in:
parent
ae71d2b70e
commit
294cbb7108
2 changed files with 37 additions and 74 deletions
|
@ -127,6 +127,7 @@ target_link_libraries(markdown-check LibMarkdown)
|
||||||
target_link_libraries(matroska LibVideo)
|
target_link_libraries(matroska LibVideo)
|
||||||
target_link_libraries(md LibMarkdown)
|
target_link_libraries(md LibMarkdown)
|
||||||
target_link_libraries(mkdir LibMain)
|
target_link_libraries(mkdir LibMain)
|
||||||
|
target_link_libraries(nc LibMain)
|
||||||
target_link_libraries(netstat LibMain)
|
target_link_libraries(netstat LibMain)
|
||||||
target_link_libraries(notify LibGUI)
|
target_link_libraries(notify LibGUI)
|
||||||
target_link_libraries(nproc LibMain)
|
target_link_libraries(nproc LibMain)
|
||||||
|
|
|
@ -7,7 +7,9 @@
|
||||||
#include <AK/ByteBuffer.h>
|
#include <AK/ByteBuffer.h>
|
||||||
#include <LibCore/ArgsParser.h>
|
#include <LibCore/ArgsParser.h>
|
||||||
#include <LibCore/EventLoop.h>
|
#include <LibCore/EventLoop.h>
|
||||||
|
#include <LibCore/System.h>
|
||||||
#include <LibCore/UDPSocket.h>
|
#include <LibCore/UDPSocket.h>
|
||||||
|
#include <LibMain/Main.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
@ -26,7 +28,7 @@
|
||||||
//
|
//
|
||||||
// nc -l someport > out.file
|
// nc -l someport > out.file
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
{
|
{
|
||||||
bool should_listen = false;
|
bool should_listen = false;
|
||||||
bool verbose = 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_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(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.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 (udp_mode) {
|
||||||
if (should_listen) {
|
if (should_listen) {
|
||||||
|
@ -52,34 +54,29 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::EventLoop loop;
|
Core::EventLoop loop;
|
||||||
auto socket = Core::UDPSocket::construct();
|
auto socket = TRY(Core::UDPSocket::try_create());
|
||||||
|
|
||||||
socket->on_connected = [&]() {
|
socket->on_connected = [&]() {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
warnln("connected to {}:{}", target, port);
|
warnln("connected to {}:{}", target, port);
|
||||||
};
|
};
|
||||||
|
|
||||||
socket->connect(target, port);
|
socket->connect(target, port);
|
||||||
|
|
||||||
|
Array<u8, 1024> buffer;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
char buf[1024];
|
Bytes buffer_span = buffer.span();
|
||||||
int nread = read(STDIN_FILENO, buf, sizeof(buf));
|
auto nread = TRY(Core::System::read(STDIN_FILENO, buffer_span));
|
||||||
if (nread < 0) {
|
buffer_span = buffer_span.trim(nread);
|
||||||
perror("read");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
socket->send({ buf, static_cast<size_t>(nread) });
|
socket->send({ buffer_span.data(), static_cast<size_t>(nread) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (should_listen) {
|
if (should_listen) {
|
||||||
int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
|
int listen_fd = TRY(Core::System::socket(AF_INET, SOCK_STREAM, 0));
|
||||||
if (listen_fd < 0) {
|
|
||||||
perror("socket");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sockaddr_in sa {};
|
sockaddr_in sa {};
|
||||||
sa.sin_family = AF_INET;
|
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) {
|
TRY(Core::System::bind(listen_fd, (struct sockaddr*)&sa, sizeof(sa)));
|
||||||
perror("bind");
|
TRY(Core::System::listen(listen_fd, 1));
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listen(listen_fd, 1) == -1) {
|
|
||||||
perror("listen");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char addr_str[INET_ADDRSTRLEN];
|
char addr_str[INET_ADDRSTRLEN];
|
||||||
|
|
||||||
sockaddr_in sin;
|
sockaddr_in sin;
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
|
|
||||||
len = sizeof(sin);
|
len = sizeof(sin);
|
||||||
if (getsockname(listen_fd, (struct sockaddr*)&sin, &len) == -1) {
|
TRY(Core::System::getsockname(listen_fd, (struct sockaddr*)&sin, &len));
|
||||||
perror("getsockname");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (verbose)
|
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));
|
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);
|
len = sizeof(sin);
|
||||||
fd = accept(listen_fd, (struct sockaddr*)&sin, &len);
|
TRY(Core::System::accept(listen_fd, (struct sockaddr*)&sin, &len));
|
||||||
if (fd == -1) {
|
|
||||||
perror("accept");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
warnln("got connection from {}:{}", inet_ntop(sin.sin_family, &sin.sin_addr, addr_str, sizeof(addr_str) - 1), ntohs(sin.sin_port));
|
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) {
|
TRY(Core::System::close(listen_fd));
|
||||||
perror("close");
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
fd = TRY(Core::System::socket(AF_INET, SOCK_STREAM, 0));
|
||||||
if (fd < 0) {
|
|
||||||
perror("socket");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct timeval timeout {
|
struct timeval timeout {
|
||||||
3, 0
|
3, 0
|
||||||
};
|
};
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) {
|
TRY(Core::System::setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)));
|
||||||
perror("setsockopt");
|
TRY(Core::System::setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)));
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0) {
|
|
||||||
perror("setsockopt");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* hostent = gethostbyname(target);
|
auto* hostent = gethostbyname(target);
|
||||||
if (!hostent) {
|
if (!hostent) {
|
||||||
|
@ -163,10 +133,8 @@ int main(int argc, char** argv)
|
||||||
char addr_str[INET_ADDRSTRLEN];
|
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));
|
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");
|
TRY(Core::System::connect(fd, (struct sockaddr*)&dst_addr, sizeof(dst_addr)));
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
warnln("connected!");
|
warnln("connected!");
|
||||||
}
|
}
|
||||||
|
@ -204,12 +172,10 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!stdin_closed && FD_ISSET(STDIN_FILENO, &readfds)) {
|
if (!stdin_closed && FD_ISSET(STDIN_FILENO, &readfds)) {
|
||||||
char buf[1024];
|
Array<u8, 1024> buffer;
|
||||||
int nread = read(STDIN_FILENO, buf, sizeof(buf));
|
Bytes buffer_span = buffer.span();
|
||||||
if (nread < 0) {
|
auto nread = TRY(Core::System::read(STDIN_FILENO, buffer_span));
|
||||||
perror("read(STDIN_FILENO)");
|
buffer_span = buffer_span.trim(nread);
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// stdin closed
|
// stdin closed
|
||||||
if (nread == 0) {
|
if (nread == 0) {
|
||||||
|
@ -217,22 +183,19 @@ int main(int argc, char** argv)
|
||||||
if (verbose)
|
if (verbose)
|
||||||
warnln("stdin closed");
|
warnln("stdin closed");
|
||||||
if (should_close) {
|
if (should_close) {
|
||||||
close(fd);
|
TRY(Core::System::close(fd));
|
||||||
fd_closed = true;
|
fd_closed = true;
|
||||||
}
|
}
|
||||||
} else if (write(fd, buf, nread) < 0) {
|
} else {
|
||||||
perror("write(fd)");
|
TRY(Core::System::write(fd, buffer_span));
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fd_closed && FD_ISSET(fd, &readfds)) {
|
if (!fd_closed && FD_ISSET(fd, &readfds)) {
|
||||||
char buf[1024];
|
Array<u8, 1024> buffer;
|
||||||
int nread = read(fd, buf, sizeof(buf));
|
Bytes buffer_span = buffer.span();
|
||||||
if (nread < 0) {
|
auto nread = TRY(Core::System::read(fd, buffer_span));
|
||||||
perror("read(fd)");
|
buffer_span = buffer_span.trim(nread);
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remote end closed
|
// remote end closed
|
||||||
if (nread == 0) {
|
if (nread == 0) {
|
||||||
|
@ -241,9 +204,8 @@ int main(int argc, char** argv)
|
||||||
fd_closed = true;
|
fd_closed = true;
|
||||||
if (verbose)
|
if (verbose)
|
||||||
warnln("remote closed");
|
warnln("remote closed");
|
||||||
} else if (write(STDOUT_FILENO, buf, nread) < 0) {
|
} else {
|
||||||
perror("write(STDOUT_FILENO)");
|
TRY(Core::System::write(STDOUT_FILENO, buffer_span));
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue