commit - 932b001a3f330546d8719424f505b8ba671a3896
commit + 2c3a40faf850ad608abf87f928a11fb4fba3057b
blob - ff9a741aaf640a2824015674a4ad446d6476cccb
blob + d54dc62f3b6ccded34abc27df946988df324e38c
--- ChangeLog
+++ ChangeLog
+2020-11-06 Omar Polo <op@venera>
+
+ * gmid.1: added option to log to a file
+
2020-11-05 Omar Polo <op@omarpolo.com>
* gmid.c (filetypes): add MIME type for xml files
blob - c8f89acd284867d00f540bb283159814431b7dc8
blob + fc2381fab34076f690fa3eacbef46081fdf20f66
--- README.md
+++ README.md
\[**-c** *cert.pem*]
\[**-d** *docs*]
\[**-k** *key.pem*]
+\[**-l** *access.log*]
# DESCRIPTION
> The key for the certificate, by default is
> *key.pem*.
+**-l** *access.log*
+
+> log to the given file instead of the standard error.
+
# EXAMPLES
To quickly getting started
blob - 5d86d0db9b347b5e262e0ff9e7f26e221cecef17
blob + a70e81714c7d397bfef19b484e31f03436ebbbe4
--- gmid.1
+++ gmid.1
.Op Fl c Ar cert.pem
.Op Fl d Ar docs
.Op Fl k Ar key.pem
+.Op Fl l Ar access.log
.Ek
.Sh DESCRIPTION
.Nm
.It Fl k Ar key.pem
The key for the certificate, by default is
.Pa key.pem .
+.It Fl l Ar access.log
+log to the given file instead of the standard error.
.El
.Sh EXAMPLES
To quickly getting started
blob - 422fc84d119abb098680b96c64a8c6d7a05fb538
blob + 4e03fc371fbc02c3b7c72efd0482d799cd527656
--- gmid.c
+++ gmid.c
#include <sys/socket.h>
#include <sys/stat.h>
+#include <arpa/inet.h>
#include <netinet/in.h>
#include <assert.h>
int fd;
void *buf, *i;
ssize_t len, off;
+ int af;
+ struct in_addr addr;
};
struct etm { /* file extension to mime */
{NULL, NULL}
};
-int dirfd;
+#define LOG(c, fmt, ...) \
+ do { \
+ char buf[INET_ADDRSTRLEN]; \
+ if (inet_ntop((c)->af, &(c)->addr, buf, sizeof(buf)) == NULL) \
+ err(1, "inet_ntop"); \
+ dprintf(logfd, "[%s] " fmt "\n", buf, __VA_ARGS__); \
+ } while (0)
+int dirfd, logfd;
+
char *url_after_proto(char*);
char *url_start_of_request(char*);
-int url_trim(char*);
+int url_trim(struct client*, char*);
void adjust_path(char*);
int path_isdir(char*);
ssize_t filesize(int);
}
int
-url_trim(char *url)
+url_trim(struct client *c, char *url)
{
const char *e = "\r\n";
char *s;
s[1] = '\0';
if (s[2] != '\0') {
- fprintf(stderr, "the request was longer than 1024 bytes\n");
+ LOG(c, "%s", "request longer than 1024 bytes\n");
return 0;
}
strlcat(fpath, path, PATHBUF);
if ((c->fd = openat(dirfd, fpath, O_RDONLY | O_NOFOLLOW)) == -1) {
- warn("open: %s", fpath);
+ LOG(c, "open failed: %s", fpath);
if (!start_reply(fds, c, NOT_FOUND, "not found"))
return 0;
goodbye(fds, c);
}
if (isdir(c->fd)) {
- warnx("%s is a directory, trying %s/index.gmi", fpath, fpath);
+ LOG(c, "%s is a directory, trying %s/index.gmi", fpath, fpath);
close(c->fd);
c->fd = -1;
send_dir(fpath, fds, c);
}
if ((c->len = filesize(c->fd)) == -1) {
- warn("filesize: %s", fpath);
+ LOG(c, "failed to get file size for %s", fpath);
goodbye(fds, c);
return 0;
}
while (len > 0) {
switch (ret = tls_write(c->ctx, c->i, len)) {
case -1:
- warnx("tls_write: %s", tls_error(c->ctx));
+ LOG(c, "tls_write: %s", tls_error(c->ctx));
goodbye(fds, c);
return;
bzero(buf, GEMINI_URL_LEN);
switch (tls_read(client->ctx, buf, sizeof(buf)-1)) {
case -1:
- warnx("tls_read: %s", tls_error(client->ctx));
+ LOG(client, "tls_read: %s", tls_error(client->ctx));
goodbye(fds, client);
return;
return;
}
- if (!url_trim(buf)) {
+ if (!url_trim(client, buf)) {
if (!start_reply(fds, client, BAD_REQUEST, "bad request"))
return;
goodbye(fds, client);
}
adjust_path(path);
- fprintf(stderr, "requested path: %s\n", path);
+ LOG(client, "get %s", path);
if (path_isdir(path))
send_dir(path, fds, client);
clients[i].state = S_OPEN;
clients[i].fd = -1;
clients[i].buf = MAP_FAILED;
+ clients[i].af = AF_INET;
+ clients[i].addr = addr.sin_addr;
return;
}
signal(SIGPIPE, SIG_IGN);
- while ((ch = getopt(argc, argv, "c:d:hk:")) != -1) {
+ logfd = 2; /* stderr */
+
+ while ((ch = getopt(argc, argv, "c:d:hk:l:")) != -1) {
switch (ch) {
case 'c':
cert = optarg;
key = optarg;
break;
+ case 'l':
+ /* open log file or create it with 644 */
+ if ((logfd = open(optarg, O_WRONLY | O_CREAT,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWOTH)) == -1)
+ err(1, "%s", optarg);
+ break;
+
default:
usage(*argv);
return 1;