netcat: Rewrite the i/o loop

* Stop echoing back the input.
  It isn't the responsibility of this app, IMO.

* Allow non-text data

* Error checks and cleanups
This commit is contained in:
YAMAMOTO Takashi 2021-01-28 09:57:06 +09:00 committed by Xiang Xiao
parent 8093aa7487
commit eb996e5650

View File

@ -24,8 +24,9 @@
****************************************************************************/
#include <nuttx/config.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
@ -45,12 +46,44 @@
* Public Functions
****************************************************************************/
int do_io(int infd, int outfd)
{
size_t capacity = 256;
char buf[capacity];
while (true)
{
ssize_t avail = read(infd, buf, capacity);
if (avail == 0)
{
break;
}
if (avail == -1)
{
perror("do_io: read error");
return 5;
}
ssize_t written = write(outfd, buf, avail);
if (written == -1)
{
perror("do_io: write error");
return 6;
}
}
return EXIT_SUCCESS;
}
int netcat_server(int argc, char * argv[])
{
FILE * fout = stdout;
int id = -1;
int outfd = STDOUT_FILENO;
struct sockaddr_in server;
struct sockaddr_in client;
int port = NETCAT_PORT;
int result = EXIT_SUCCESS;
if ((1 < argc) && (0 == strcmp("-l", argv[1])))
{
@ -61,21 +94,23 @@ int netcat_server(int argc, char * argv[])
if (3 < argc)
{
fout = fopen(argv[3], "w");
if (0 > fout)
outfd = open(argv[3], O_WRONLY | O_CREAT | O_TRUNC, 0777);
if (outfd == -1)
{
perror("error: io: Failed to create file");
return 1;
outfd = STDOUT_FILENO;
result = 1;
goto out;
}
}
}
int id;
id = socket(AF_INET , SOCK_STREAM , 0);
if (0 > id)
{
perror("error: net: Failed to create socket");
return 2;
result = 2;
goto out;
}
server.sin_family = AF_INET;
@ -84,49 +119,57 @@ int netcat_server(int argc, char * argv[])
if (0 > bind(id, (struct sockaddr *)&server , sizeof(server)))
{
perror("error: net: Failed to bind");
return 3;
result = 3;
goto out;
}
fprintf(stderr, "log: net: listening on :%d\n", port);
listen(id , 3);
int capacity = 256;
char buf[capacity];
if (listen(id , 3) == -1)
{
perror("error: net: Failed to listen");
result = 7;
goto out;
}
socklen_t addrlen;
int conn;
while ((conn = accept(id, (struct sockaddr *)&client, &addrlen)))
while ((conn = accept(id, (struct sockaddr *)&client, &addrlen)) != -1)
{
int avail = 1;
while (0 < avail)
result = do_io(conn, outfd);
if (result != 0)
{
avail = recv(conn, buf, capacity, 0);
fwrite(buf, avail, 1, fout);
int status = fflush(fout);
if (0 != status)
{
perror("error: io: Failed to flush");
}
break;
}
}
if (0 > conn)
{
perror("accept failed");
return 4;
result = 4;
goto out;
}
if (stdout != fout)
out:
if (id != -1)
{
fclose(fout);
close(id);
}
return EXIT_SUCCESS;
if (outfd != STDOUT_FILENO)
{
close(outfd);
}
return result;
}
int netcat_client(int argc, char * argv[])
{
FILE *fin = stdin;
int id = -1;
int infd = STDIN_FILENO;
char *host = "127.0.0.1";
int port = NETCAT_PORT;
int result = EXIT_SUCCESS;
if (argc > 1)
{
@ -140,20 +183,22 @@ int netcat_client(int argc, char * argv[])
if (argc > 3)
{
fin = fopen(argv[3], "r");
if (0 > fin)
infd = open(argv[3], O_RDONLY);
if (infd == -1)
{
perror("error: io: Failed to create file");
return 1;
perror("error: io: Failed to open file");
infd = STDIN_FILENO;
result = 1;
goto out;
}
}
int id;
id = socket(AF_INET , SOCK_STREAM , 0);
if (0 > id)
{
perror("error: net: Failed to create socket");
return 2;
result = 2;
goto out;
}
struct sockaddr_in server;
@ -162,47 +207,31 @@ int netcat_client(int argc, char * argv[])
if (1 != inet_pton(AF_INET, host, &server.sin_addr))
{
perror("error: net: Invalid host");
return 3;
result = 3;
goto out;
}
if (connect(id, (struct sockaddr *) &server, sizeof(server)) < 0)
{
perror("error: net: Failed to connect");
return 4;
result = 4;
goto out;
}
int capacity = 256;
char buf[capacity];
int avail;
while (true)
result = do_io(infd, id);
out:
if (id != -1)
{
avail = -1;
if (fgets(buf, capacity, fin))
{
avail = strnlen(buf, capacity);
}
if (avail < 0)
{
exit(EXIT_SUCCESS);
}
buf[avail] = 0;
avail = write(id, buf, avail);
printf("%s", buf);
if (avail < 0)
{
perror("error: net: writing to socket");
exit(1);
}
close(id);
}
if (stdout != fin)
if (infd != STDIN_FILENO)
{
fclose(fin);
close(infd);
}
return EXIT_SUCCESS;
return result;
}
/****************************************************************************