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:
parent
8093aa7487
commit
eb996e5650
@ -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;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
Loading…
Reference in New Issue
Block a user