Add libgeminiclient.3
This commit is contained in:
parent
df1d8b0518
commit
3f17926bce
12
Makefile
12
Makefile
|
@ -17,7 +17,7 @@ magic-libgeminiclient.a:
|
|||
magic-gemini-cat:
|
||||
@${MAGIC}; ${MAKE} ${MAKEFLAGS} gemini-cat
|
||||
libgeminiclient.a: libgeminiclient.o
|
||||
${AR} -cr $@ libgeminiclient.o
|
||||
${AR} ${ARFLAGS} $@ libgeminiclient.o
|
||||
libgeminiclient.o: libgeminiclient.c libgeminiclient.h
|
||||
${CC} -c ${CFLAGS} -o $@ libgeminiclient.c
|
||||
gemini-cat: gemini-cat.c libgeminiclient.a
|
||||
|
@ -28,6 +28,16 @@ install: libgeminiclient.a
|
|||
"$$DESTDIR/$${PREFIX:-/usr/local}/lib/"
|
||||
install -m444 libgeminiclient.h \
|
||||
"$$DESTDIR/$${PREFIX:-/usr/local}/include/"
|
||||
install -m444 libgeminiclient.3 \
|
||||
"$$DESTDIR/$${PREFIX:-/usr/local}/$${MANDIR:-share/man}/man3/
|
||||
@M="$$DESTDIR/$${PREFIX:-/usr/local}/$${MANDIR:-share/man}/"; \
|
||||
link "$$M/man3/libgeminiclient.3" "$$M/man3/gemini_create.3"; \
|
||||
link "$$M/man3/libgeminiclient.3" "$$M/man3/gemini_init.3"; \
|
||||
link "$$M/man3/libgeminiclient.3" "$$M/man3/gemini_open.3"; \
|
||||
link "$$M/man3/libgeminiclient.3" "$$M/man3/gemini_reset.3"; \
|
||||
link "$$M/man3/libgeminiclient.3" "$$M/man3/gemini_close.3"; \
|
||||
link "$$M/man3/libgeminiclient.3" "$$M/man3/gemini_destroy.3";
|
||||
install-all: install install-gemini-cat
|
||||
install-gemini-cat: gemini-cat
|
||||
install -m755 gemini-cat "$$DESTDIR/$${PREFIX:-/usr/local}/bin/"
|
||||
install -m444 gemini-cat.1 \
|
||||
|
|
|
@ -0,0 +1,276 @@
|
|||
.Dd Apr 30, 2020
|
||||
.Dt LIBGEMINICLIENT 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm gemini_create , gemini_init , gemini_open , gemini_read ,
|
||||
.Nm gemini_reset , gemini_close , gemini_destroy
|
||||
.Sh SYNOPSIS
|
||||
.In libgeminiclient.h
|
||||
.Ft struct gemini *
|
||||
.Fn gemini_create void
|
||||
.Ft void
|
||||
.Fn gemini_init "struct gemini *ctx"
|
||||
.Ft int
|
||||
.Fn gemini_open "struct gemini *ctx" "const char *url"
|
||||
.Ft ssize_t
|
||||
.Fn gemini_read "struct gemini *ctx" "void *buffer" "size_t size"
|
||||
.Ft void
|
||||
.Fn gemini_reset "struct gemini *ctx"
|
||||
.Ft void
|
||||
.Fn gemini_close "struct gemini *ctx"
|
||||
.Ft void
|
||||
.Fn gemini_destroy "struct gemini *ctx"
|
||||
.Sh DESCRIPTION
|
||||
.Fn gemini_create
|
||||
allocates a
|
||||
.Vt gemini
|
||||
structure and calls
|
||||
.Fn gemini_init on it.
|
||||
.Pp
|
||||
.Fn gemini_init
|
||||
Initialized the provided
|
||||
.Vt gemini
|
||||
structure.
|
||||
.Pp
|
||||
.Fn gemini_open
|
||||
opens a connection to the provided
|
||||
.Fa url ,
|
||||
and sets up the
|
||||
.Vt gemini
|
||||
structure for reading.
|
||||
.Pp
|
||||
.Fn gemini_read
|
||||
attempts to read using the
|
||||
.Vt gemini
|
||||
structure previously set up by
|
||||
.Fn gemini_open ,
|
||||
sending the request and parsing the response as needed.
|
||||
After a successful return the
|
||||
.Fa meta ,
|
||||
.Fa metalen ,
|
||||
and
|
||||
.Fa status
|
||||
are set to that received by the response.
|
||||
.Fa meta
|
||||
will always be NUL terminated, but it may contain NUL characters itself.
|
||||
.Pp
|
||||
Categories of
|
||||
.Fa status
|
||||
values are as follows:
|
||||
.Bl -tag -width Ds -compact
|
||||
.It Li 1X
|
||||
Request for user-input.
|
||||
META contains the prompt.
|
||||
.It Li 2X
|
||||
Success.
|
||||
META contains the MIME-type.
|
||||
.It Li 3X
|
||||
Redirect.
|
||||
META contains the new URL.
|
||||
.It Li 4X
|
||||
Temporary failure.
|
||||
META contains the error string.
|
||||
.It Li 5X
|
||||
Permanent failure.
|
||||
META contains the error string.
|
||||
.It Li 6X
|
||||
Certificate required.
|
||||
META contains additional information.
|
||||
.El
|
||||
.Pp
|
||||
.Fn gemini_reset
|
||||
prepares the provided
|
||||
.Vt gemini
|
||||
structure to be reused for
|
||||
.Pp
|
||||
.Fn gemini_open
|
||||
while keeping reusable data.
|
||||
This prevents user-configurable information from being reset,
|
||||
and prevents
|
||||
.Fa certfile ,
|
||||
.Fa keyfile ,
|
||||
and
|
||||
.Fa tofufile
|
||||
from being reopened.
|
||||
.Pp
|
||||
.Fn gemini_close
|
||||
Closes and reinitializes the provided
|
||||
.Vt gemini
|
||||
structure.
|
||||
.Pp
|
||||
.Fn gemini_destroy
|
||||
calls
|
||||
.Fn gemini_close
|
||||
on the provided
|
||||
.Vt gemini
|
||||
structure and frees it.
|
||||
.Pp
|
||||
The useful members of the
|
||||
.Vt gemini
|
||||
structure are as follows:
|
||||
.Bd -literal -offset indent -compact
|
||||
struct gemini {
|
||||
char meta[GEMINI_META_MAX + 1];
|
||||
const char *certfile; /* Certificate file */
|
||||
const char *keyfile; /* Key file */
|
||||
const char *tofufile; /* Known-hosts file */
|
||||
size_t metalen; /* Length of `meta' */
|
||||
int flags; /* Configuration flags */
|
||||
int maxredirects; /* Default 5 */
|
||||
short status; /* Response STATUS */
|
||||
short port; /* Default port */
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
Possible
|
||||
.Fa flags
|
||||
are as follows:
|
||||
.Bl -tag -width Ds -compact
|
||||
.It Dv GEMINI_PROMPT
|
||||
Prompt the user for input on status
|
||||
.Li 10 .
|
||||
.It Dv GEMINI_SECURE_PROMPT
|
||||
Prompt the user for input on status
|
||||
.Li 10 ,
|
||||
without echoing the input.
|
||||
.It Dv GEMINI_TOFU_WRITE
|
||||
Write any new certificate information to
|
||||
.Fa tofufile
|
||||
on
|
||||
.Dn gemini_close .
|
||||
.El
|
||||
.Pp
|
||||
All knows
|
||||
.Fa status
|
||||
values are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Li 10
|
||||
The server requested user-input.
|
||||
META contains the suggested prompt to show the user.
|
||||
.It Li 20
|
||||
The request was successful, and the requested data will follow the
|
||||
response.
|
||||
META contains the MIME-type of the data.
|
||||
.It Li 21
|
||||
The request was successful, the requested data will follow the
|
||||
response, and the user-defined certificate can retired.
|
||||
META contains the MIME-type of the data.
|
||||
.It Li 30
|
||||
The requested resource currently exists at a different location.
|
||||
META contains the new URL.
|
||||
.It Li 31
|
||||
The requested resource can be assumed to exist at a different location.
|
||||
META contains the new URL.
|
||||
.It Li 40
|
||||
The request failed in a temporary manner.
|
||||
META may contain additional information.
|
||||
.It Li 41
|
||||
The server is currently unavailable.
|
||||
META may contain additional information.
|
||||
.It Li 42
|
||||
There was a CGI error.
|
||||
META may contain additional information.
|
||||
.It Li 43
|
||||
The requested host does not match the server, and the proxied request
|
||||
failed.
|
||||
the request.
|
||||
META may contain additional information.
|
||||
.It Li 44
|
||||
The request was rejected due to rate-limiting.
|
||||
META contains an estimated amount of seconds before a retry may be
|
||||
successful.
|
||||
.It Li 50
|
||||
The request failed in a permanent manner.
|
||||
META may contain additional information.
|
||||
.It Li 51
|
||||
The requested resource was not found by the server.
|
||||
META may contain additional information.
|
||||
.It Li 52
|
||||
The requested resource no longer exists at that URL.
|
||||
META may contain additional information.
|
||||
.It Li 53
|
||||
The requested host does not match the server, and it refused to proxy
|
||||
the request.
|
||||
META may contain additional information.
|
||||
.It Li 59
|
||||
The server says that the client's request was invalid.
|
||||
META may contain additional information.
|
||||
.It Li 60
|
||||
An user-defined certificate is required.
|
||||
META may contain additional information.
|
||||
.It Li 61
|
||||
A transient user-defined certificate is required.
|
||||
META may contain additional information.
|
||||
.It Li 62
|
||||
An authorized user-defined certificate is required.
|
||||
META may contain additional information.
|
||||
.It Li 63
|
||||
The user-defined certificate was rejected because was not considered
|
||||
valid by the server.
|
||||
META may contain additional information.
|
||||
.It Li 64
|
||||
The user-defined certificate was rejected because it is not yet valid.
|
||||
META may contain additional information.
|
||||
.It Li 65
|
||||
The user-defined certificate was rejected because it is expired.
|
||||
META may contain additional information.
|
||||
.El
|
||||
.Sh RETURN VALUES
|
||||
.Fn gemini_create
|
||||
returns a pointer to a newly initialized
|
||||
.Vt gemini
|
||||
structure, or a NULL on a failure.
|
||||
.Pp
|
||||
.Fn gemini_open
|
||||
returns a 0 on success and a -1 on an error.
|
||||
.Pp
|
||||
.Fn gemini_read
|
||||
returns a -1 on an error, otherwise it returns the amount of data
|
||||
read into the buffer, with 0 only being returned when there is nothing
|
||||
left to read.
|
||||
.Sh EXAMPLES
|
||||
The following example shows how you initialize various values:
|
||||
.Bd -literal -offset indent -compact
|
||||
gemini = gemini_create();
|
||||
gemini->keyfile = keyfile;
|
||||
gemini->certfile = certfile;
|
||||
gemini->tofufile = tofufile;
|
||||
gemini->flags |= GEMINI_TOFU_WRITE;
|
||||
gemini->port = port;
|
||||
while ((url = get_url()) != NULL)
|
||||
if (gemini_open(gemini) != 0)
|
||||
continue;
|
||||
...
|
||||
gemini_reset(gemini);
|
||||
}
|
||||
gemini_destroy(gemini);
|
||||
.Ed
|
||||
.Pp
|
||||
The following example shows how to handle redirects and other status
|
||||
codes yourself:
|
||||
.Bd -literal -offset indent -compact
|
||||
gemini->maxredirects = 0;
|
||||
while ((url = get_url()) != NULL) {
|
||||
if (gemini_open(gemini, url) != 0) {
|
||||
warn("Could not open: %s", url);
|
||||
continue;
|
||||
}
|
||||
while ((r = gemini_read(gemini, buf, bufsize)) > 0) {
|
||||
...
|
||||
}
|
||||
switch (gemini->status / 10) {
|
||||
...
|
||||
case 3:
|
||||
if (yesno("Redirected to \"%s\" [Y/n]?", gemini->meta))
|
||||
prepend_url(gemini->meta);
|
||||
break;
|
||||
...
|
||||
default:
|
||||
warn("Bad status %02hd: %s", gemini->status, g->meta);
|
||||
break;
|
||||
}
|
||||
gemini_reset(gemini);
|
||||
}
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr tls_read 3
|
Loading…
Reference in New Issue