Add address and port command line parameters
This commit is contained in:
parent
e7dc81cfad
commit
726acba679
@ -3,5 +3,3 @@
|
|||||||
A small gopher server for POSIX systems, written in C99.
|
A small gopher server for POSIX systems, written in C99.
|
||||||
|
|
||||||
To build: `make`
|
To build: `make`
|
||||||
|
|
||||||
At the moment it only serves on `::1` at port 7070.
|
|
||||||
|
78
main.c
78
main.c
@ -18,12 +18,14 @@
|
|||||||
|
|
||||||
#define _POSIX_SOURCE
|
#define _POSIX_SOURCE
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -36,8 +38,8 @@ int pledge(const char *, const char *);
|
|||||||
int unveil(const char *, const char *);
|
int unveil(const char *, const char *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define HOST "::1"
|
#define DEFAULT_ADDRSTR "::1"
|
||||||
#define PORT 7070
|
#define DEFAULT_PORT 70
|
||||||
|
|
||||||
#define RESP_TERM ".\r\n"
|
#define RESP_TERM ".\r\n"
|
||||||
#define RESP_TERM_LEN 3 /* strlen(".\r\n") */
|
#define RESP_TERM_LEN 3 /* strlen(".\r\n") */
|
||||||
@ -83,6 +85,12 @@ static int append_selector_part(const char *part, size_t partlen, char *buf,
|
|||||||
return partlen + 1;
|
return partlen + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void usage(const char *name)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: %s [-a ipv6addr] [-p portnum] srvroot\n", name);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
(void)argc;
|
(void)argc;
|
||||||
@ -100,24 +108,68 @@ int main(int argc, char *argv[])
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get srvroot path from arguments and copy into pbuf.
|
* Extract arguments.
|
||||||
|
*/
|
||||||
|
const char *srvroot = NULL, *addrstr = NULL, *portstr = NULL;
|
||||||
|
if (argc < 2)
|
||||||
|
usage(argv[0]);
|
||||||
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
if (argv[i][0] == '-') {
|
||||||
|
if (i + 1 >= argc || strlen(argv[i]) != 2)
|
||||||
|
usage(argv[0]);
|
||||||
|
switch (argv[i][1]) {
|
||||||
|
case 'a':
|
||||||
|
addrstr = argv[++i];
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
portstr = argv[++i];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage(argv[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
srvroot = argv[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!srvroot)
|
||||||
|
usage(argv[0]);
|
||||||
|
if (!addrstr)
|
||||||
|
addrstr = DEFAULT_ADDRSTR;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse address and port.
|
||||||
|
*/
|
||||||
|
struct in6_addr addr;
|
||||||
|
if (inet_pton(AF_INET6, addrstr, &addr) != 1)
|
||||||
|
usage(argv[0]);
|
||||||
|
if (portstr[0] == '-')
|
||||||
|
usage(argv[0]);
|
||||||
|
uint16_t port;
|
||||||
|
{
|
||||||
|
char *end;
|
||||||
|
unsigned long res = strtoul(portstr, &end, 10);
|
||||||
|
if (*end != '\0' || res > UINT16_MAX)
|
||||||
|
usage(argv[0]);
|
||||||
|
else
|
||||||
|
port = res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy srvroot into pbuf.
|
||||||
*
|
*
|
||||||
* The srvroot being at the start of pbuf should be maintained
|
* The srvroot being at the start of pbuf should be maintained
|
||||||
* through the whole application. Any trailing '/' is removed if
|
* through the whole application. Any trailing '/' is removed if
|
||||||
* present.
|
* present.
|
||||||
*/
|
*/
|
||||||
if (argc < 2) {
|
size_t srvroot_len = strlen(srvroot);
|
||||||
fprintf(stderr, "Usage: %s srvroot\n", argv[0]);
|
if (srvroot[srvroot_len - 1] == '/')
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
size_t srvroot_len = strlen(argv[1]);
|
|
||||||
if (argv[1][srvroot_len - 1] == '/')
|
|
||||||
--srvroot_len;
|
--srvroot_len;
|
||||||
if (srvroot_len > PBUF_SIZE) {
|
if (srvroot_len > PBUF_SIZE) {
|
||||||
fprintf(stderr, "srvroot path is too long\n");
|
fprintf(stderr, "srvroot path is too long\n");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
memcpy(pbuf, argv[1], srvroot_len);
|
memcpy(pbuf, srvroot, srvroot_len);
|
||||||
|
|
||||||
#ifdef __OpenBSD__
|
#ifdef __OpenBSD__
|
||||||
/*
|
/*
|
||||||
@ -169,8 +221,8 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
const struct sockaddr_in6 haddr = {
|
const struct sockaddr_in6 haddr = {
|
||||||
.sin6_family = AF_INET6,
|
.sin6_family = AF_INET6,
|
||||||
.sin6_port = htons(PORT),
|
.sin6_port = htons(port),
|
||||||
.sin6_addr = in6addr_loopback,
|
.sin6_addr = addr,
|
||||||
};
|
};
|
||||||
if (bind(sfd, (const struct sockaddr *)&haddr, sizeof(haddr)) == -1) {
|
if (bind(sfd, (const struct sockaddr *)&haddr, sizeof(haddr)) == -1) {
|
||||||
fprintf(stderr, "Error binding socket to address\n");
|
fprintf(stderr, "Error binding socket to address\n");
|
||||||
@ -407,7 +459,7 @@ int main(int argc, char *argv[])
|
|||||||
*/
|
*/
|
||||||
n = snprintf(&rbuf[rlen], RBUF_SIZE - rlen,
|
n = snprintf(&rbuf[rlen], RBUF_SIZE - rlen,
|
||||||
"%1u%s\t%s\t%s\t%u\r\n", type, ent->d_name,
|
"%1u%s\t%s\t%s\t%u\r\n", type, ent->d_name,
|
||||||
&pbuf[srvroot_len], HOST, PORT);
|
&pbuf[srvroot_len], addrstr, port);
|
||||||
if (n >= RBUF_SIZE - rlen) {
|
if (n >= RBUF_SIZE - rlen) {
|
||||||
fprintf(stderr, "Response buffer was too small\n");
|
fprintf(stderr, "Response buffer was too small\n");
|
||||||
goto send_response;
|
goto send_response;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user