forked from lda/telodendria
Document some new headers.
This commit is contained in:
parent
b70c3f0bed
commit
2d8d5244c4
6 changed files with 422 additions and 71 deletions
12
TODO.txt
12
TODO.txt
|
@ -22,10 +22,10 @@ Milestone: v0.3.0
|
||||||
|
|
||||||
[ ] Documentation
|
[ ] Documentation
|
||||||
[x] Array
|
[x] Array
|
||||||
[ ] Io
|
[x] Io
|
||||||
[ ] Stream
|
[ ] Stream
|
||||||
[ ] Tls
|
[ ] Tls
|
||||||
[ ] HttpClient
|
[x] HttpClient
|
||||||
[ ] Uri
|
[ ] Uri
|
||||||
[ ] td
|
[ ] td
|
||||||
[ ] tt
|
[ ] tt
|
||||||
|
@ -35,15 +35,15 @@ Milestone: v0.3.0
|
||||||
[x] Log
|
[x] Log
|
||||||
[ ] TelodendriaConfig -> Config
|
[ ] TelodendriaConfig -> Config
|
||||||
[x] HashMap
|
[x] HashMap
|
||||||
[ ] HttpRouter
|
[x] HttpRouter
|
||||||
[x] Html
|
[x] Html
|
||||||
[ ] Str
|
[x] Str
|
||||||
[ ] HeaderParser
|
[x] HeaderParser
|
||||||
[ ] hdoc
|
[ ] hdoc
|
||||||
[x] telodendria-admin
|
[x] telodendria-admin
|
||||||
[x] telodendria-setup
|
[x] telodendria-setup
|
||||||
[x] telodendria-config
|
[x] telodendria-config
|
||||||
[~] Refactor dev pages so function description and
|
[x] Refactor dev pages so function description and
|
||||||
return value are in the same location.
|
return value are in the same location.
|
||||||
|
|
||||||
[x] Debug memory leaks with caching
|
[x] Debug memory leaks with caching
|
||||||
|
|
|
@ -24,12 +24,32 @@
|
||||||
#ifndef TELODENDRIA_HEADERPARSER_H
|
#ifndef TELODENDRIA_HEADERPARSER_H
|
||||||
#define TELODENDRIA_HEADERPARSER_H
|
#define TELODENDRIA_HEADERPARSER_H
|
||||||
|
|
||||||
|
/***
|
||||||
|
* @Nm HeaderParser
|
||||||
|
* @Nd Parse simple C header files.
|
||||||
|
* @Dd April 29 2023
|
||||||
|
*
|
||||||
|
* .Nm
|
||||||
|
* is an extremely simple parser that lacks most of the functionality
|
||||||
|
* one would expect from a C code parser. It simply maps a stream
|
||||||
|
* of tokens into a few categories, parsing major ``milestones'' in
|
||||||
|
* a header, without actually understanding any of the details.
|
||||||
|
* .Pp
|
||||||
|
* This exists because it is used to generate man pages from headers.
|
||||||
|
* See
|
||||||
|
* .Xr hdoc 1
|
||||||
|
* for example usage of this parser.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <Stream.h>
|
#include <Stream.h>
|
||||||
#include <Array.h>
|
#include <Array.h>
|
||||||
|
|
||||||
/* Here's a comment */
|
|
||||||
#define HEADER_EXPR_MAX 4096
|
#define HEADER_EXPR_MAX 4096
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Headers are parsed as expressions. These are the expressions that
|
||||||
|
* this parser recognizes.
|
||||||
|
*/
|
||||||
typedef enum HeaderExprType
|
typedef enum HeaderExprType
|
||||||
{
|
{
|
||||||
HP_COMMENT,
|
HP_COMMENT,
|
||||||
|
@ -42,6 +62,9 @@ typedef enum HeaderExprType
|
||||||
HP_EOF
|
HP_EOF
|
||||||
} HeaderExprType;
|
} HeaderExprType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A representation of a function declaration.
|
||||||
|
*/
|
||||||
typedef struct HeaderDeclaration
|
typedef struct HeaderDeclaration
|
||||||
{
|
{
|
||||||
char returnType[64];
|
char returnType[64];
|
||||||
|
@ -49,12 +72,26 @@ typedef struct HeaderDeclaration
|
||||||
Array *args;
|
Array *args;
|
||||||
} HeaderDeclaration;
|
} HeaderDeclaration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A global variable declaration. The type must be of the same size
|
||||||
|
* as the function declaration's return type due to the way parsing
|
||||||
|
* them is implemented.
|
||||||
|
*/
|
||||||
typedef struct HeaderGlobal
|
typedef struct HeaderGlobal
|
||||||
{
|
{
|
||||||
char type[64];
|
char type[64];
|
||||||
char name[HEADER_EXPR_MAX - 64];
|
char name[HEADER_EXPR_MAX - 64];
|
||||||
} HeaderGlobal;
|
} HeaderGlobal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A representation of a single header expression. Note that that state
|
||||||
|
* structure is entirely internally managed, so it should not be
|
||||||
|
* accessed or manipulated by functions outside the functions defined
|
||||||
|
* here.
|
||||||
|
* .Pp
|
||||||
|
* The type field should be used to determine which field in the data
|
||||||
|
* union is valid.
|
||||||
|
*/
|
||||||
typedef struct HeaderExpr
|
typedef struct HeaderExpr
|
||||||
{
|
{
|
||||||
HeaderExprType type;
|
HeaderExprType type;
|
||||||
|
@ -77,7 +114,11 @@ typedef struct HeaderExpr
|
||||||
} state;
|
} state;
|
||||||
} HeaderExpr;
|
} HeaderExpr;
|
||||||
|
|
||||||
extern void
|
/**
|
||||||
HeaderParse(Stream *, HeaderExpr *);
|
* Parse the next expression into the given header expression structure.
|
||||||
|
* To parse an entire C header, this function should be called in a
|
||||||
|
* loop until the type of the expression is HP_EOF.
|
||||||
|
*/
|
||||||
|
extern void HeaderParse(Stream *, HeaderExpr *);
|
||||||
|
|
||||||
#endif /* TELODENDRIA_HEADERPARSER_H */
|
#endif /* TELODENDRIA_HEADERPARSER_H */
|
||||||
|
|
|
@ -24,32 +24,81 @@
|
||||||
#ifndef TELODENDRIA_HTTPCLIENT_H
|
#ifndef TELODENDRIA_HTTPCLIENT_H
|
||||||
#define TELODENDRIA_HTTPCLIENT_H
|
#define TELODENDRIA_HTTPCLIENT_H
|
||||||
|
|
||||||
|
/***
|
||||||
|
* @Nm HttpClient
|
||||||
|
* @Nd Extremely simple HTTP client.
|
||||||
|
* @Dd April 29 2023
|
||||||
|
* @Xr Http HttpServer Tls
|
||||||
|
*
|
||||||
|
* .Nm
|
||||||
|
* HttpClient
|
||||||
|
* builds on the HTTP API to provide a simple yet functional HTTP
|
||||||
|
* client. It aims at being easy to use and minimal, yet also
|
||||||
|
* efficient.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <HashMap.h>
|
#include <HashMap.h>
|
||||||
#include <Http.h>
|
#include <Http.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A server response is represented by a client context. It is
|
||||||
|
* opaque, so the functions defined in this API should be used to
|
||||||
|
* fetch data from and manipulate it.
|
||||||
|
*/
|
||||||
typedef struct HttpClientContext HttpClientContext;
|
typedef struct HttpClientContext HttpClientContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make an HTTP request. This function takes the request method,
|
||||||
|
* any flags defined in the HTTP API, the port, hostname, and path,
|
||||||
|
* all in that order. It returns NULL if there was an error making
|
||||||
|
* the request. Otherwise it returns a client context. Note that this
|
||||||
|
* function does not actually send any data, it simply makes the
|
||||||
|
* connection. Use
|
||||||
|
* .Fn HttpRequestHeader
|
||||||
|
* to add headers to the request. Then, send headers with
|
||||||
|
* .Fn HttpRequestSendHeaders .
|
||||||
|
* Finally, the request body, if any, can be written to the output
|
||||||
|
* stream, and then the request can be fully sent using
|
||||||
|
* .Fn HttpRequestSend .
|
||||||
|
*/
|
||||||
extern HttpClientContext *
|
extern HttpClientContext *
|
||||||
HttpRequest(HttpRequestMethod, int, unsigned short, char *, char *);
|
HttpRequest(HttpRequestMethod, int, unsigned short, char *, char *);
|
||||||
|
|
||||||
extern void
|
/**
|
||||||
HttpRequestHeader(HttpClientContext *, char *, char *);
|
* Set a request header to send to the server when making the
|
||||||
|
* request.
|
||||||
|
*/
|
||||||
|
extern void HttpRequestHeader(HttpClientContext *, char *, char *);
|
||||||
|
|
||||||
extern void
|
/**
|
||||||
HttpRequestSendHeaders(HttpClientContext *);
|
* Send the request headers to the server. This must be called before
|
||||||
|
* the request body can be written or a response body can be read.
|
||||||
|
*/
|
||||||
|
extern void HttpRequestSendHeaders(HttpClientContext *);
|
||||||
|
|
||||||
extern HttpStatus
|
/**
|
||||||
HttpRequestSend(HttpClientContext *);
|
* Flush the request stream to the server. This function should be
|
||||||
|
* called before the response body is read.
|
||||||
|
*/
|
||||||
|
extern HttpStatus HttpRequestSend(HttpClientContext *);
|
||||||
|
|
||||||
extern HashMap *
|
/**
|
||||||
HttpResponseHeaders(HttpClientContext *);
|
* Get the headers returned by the server.
|
||||||
|
*/
|
||||||
|
extern HashMap * HttpResponseHeaders(HttpClientContext *);
|
||||||
|
|
||||||
extern Stream *
|
/**
|
||||||
HttpClientStream(HttpClientContext *);
|
* Get the stream used to write the request body and read the
|
||||||
|
* response body.
|
||||||
|
*/
|
||||||
|
extern Stream * HttpClientStream(HttpClientContext *);
|
||||||
|
|
||||||
extern void
|
/**
|
||||||
HttpClientContextFree(HttpClientContext *);
|
* Free all memory associated with the client context. This closes the
|
||||||
|
* connection, if it was still open.
|
||||||
|
*/
|
||||||
|
extern void HttpClientContextFree(HttpClientContext *);
|
||||||
|
|
||||||
#endif /* TELODENDRIA_HTTPCLIENT_H */
|
#endif /* TELODENDRIA_HTTPCLIENT_H */
|
||||||
|
|
|
@ -24,22 +24,68 @@
|
||||||
#ifndef TELODENDRIA_HTTPROUTER_H
|
#ifndef TELODENDRIA_HTTPROUTER_H
|
||||||
#define TELODENDRIA_HTTPROUTER_H
|
#define TELODENDRIA_HTTPROUTER_H
|
||||||
|
|
||||||
|
/***
|
||||||
|
* @Nm HttpRouter
|
||||||
|
* @Nd Simple HTTP request router with regular expression support.
|
||||||
|
* @Dd April 29 2023
|
||||||
|
* @Xr HttpServer Http
|
||||||
|
*
|
||||||
|
* .Nm
|
||||||
|
* provides a simple mechanism for assigning functions to an HTTP
|
||||||
|
* request path. It is a simple tree data structure that parses the
|
||||||
|
* registered request paths and maps functions onto each part of the
|
||||||
|
* path. Then, requests can be easily routed to their appropriate
|
||||||
|
* handler functions.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <Array.h>
|
#include <Array.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The router structure is opaque and thus managed entirely by the
|
||||||
|
* functions defined in this API.
|
||||||
|
*/
|
||||||
typedef struct HttpRouter HttpRouter;
|
typedef struct HttpRouter HttpRouter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function written to handle an HTTP request takes an array
|
||||||
|
* consisting of the matched path parts in the order they appear in
|
||||||
|
* the path, and a pointer to caller-provided arguments, if any.
|
||||||
|
* It returns a pointer that the caller is assumed to know how to
|
||||||
|
* handle.
|
||||||
|
*/
|
||||||
typedef void *(HttpRouteFunc) (Array *, void *);
|
typedef void *(HttpRouteFunc) (Array *, void *);
|
||||||
|
|
||||||
extern HttpRouter *
|
/**
|
||||||
HttpRouterCreate(void);
|
* Create a new empty routing tree.
|
||||||
|
*/
|
||||||
|
extern HttpRouter * HttpRouterCreate(void);
|
||||||
|
|
||||||
extern void
|
/**
|
||||||
HttpRouterFree(HttpRouter *);
|
* Free all the memory associated with the given routing tree.
|
||||||
|
*/
|
||||||
|
extern void HttpRouterFree(HttpRouter *);
|
||||||
|
|
||||||
extern int
|
/**
|
||||||
HttpRouterAdd(HttpRouter *, char *, HttpRouteFunc *);
|
* Register the specified route function to be executed upon requests
|
||||||
|
* for the specified HTTP path. The path is parsed by splitting at
|
||||||
|
* each path separator. Each part of the path is a regular expression
|
||||||
|
* that matches the entire path part. A regular expression cannot
|
||||||
|
* match more than one path part. This allows for paths like
|
||||||
|
* .Pa /some/path/(.*)/parts
|
||||||
|
* to work as one would expect.
|
||||||
|
*/
|
||||||
|
extern int HttpRouterAdd(HttpRouter *, char *, HttpRouteFunc *);
|
||||||
|
|
||||||
extern int
|
/**
|
||||||
HttpRouterRoute(HttpRouter *, char *, void *, void **);
|
* Route the specified request path using the specified routing
|
||||||
|
* tree. This function will parse the path and match it to the
|
||||||
|
* appropriate route handler function. The return value is a boolean
|
||||||
|
* value that indicates whether or not an appropriate route function
|
||||||
|
* was found. If an appropriate function was found, then the void
|
||||||
|
* pointer is passed to it as arguments that it is expected to know
|
||||||
|
* how to handle, and the pointer to a void pointer is where the
|
||||||
|
* route function's response will be placed.
|
||||||
|
*/
|
||||||
|
extern int HttpRouterRoute(HttpRouter *, char *, void *, void **);
|
||||||
|
|
||||||
#endif /* TELODENDRIA_HTTPROUTER_H */
|
#endif /* TELODENDRIA_HTTPROUTER_H */
|
||||||
|
|
188
src/include/Io.h
188
src/include/Io.h
|
@ -24,6 +24,37 @@
|
||||||
#ifndef TELODENDRIA_IO_H
|
#ifndef TELODENDRIA_IO_H
|
||||||
#define TELODENDRIA_IO_H
|
#define TELODENDRIA_IO_H
|
||||||
|
|
||||||
|
/***
|
||||||
|
* @Nm Io
|
||||||
|
* @Nd Source/sink-agnostic I/O for implementing custom streams.
|
||||||
|
* @Dd April 29 2023
|
||||||
|
* @Xr Stream Tls
|
||||||
|
*
|
||||||
|
* Many systems provide platform-specific means of implementing custom
|
||||||
|
* streams using file pointers. However, POSIX does not define a way
|
||||||
|
* of programmatically creating custom streams.
|
||||||
|
* .Nm
|
||||||
|
* therefore fills this gap in POSIX by mimicking all of the
|
||||||
|
* functionality of these platform-specific functions, but in pure
|
||||||
|
* POSIX C. It defines a number of callback funtions to be executed
|
||||||
|
* in place of the standard POSIX I/O functions, which are used to
|
||||||
|
* implement arbitrary streams that may not be to a file or socket.
|
||||||
|
* Additionally, streams can now be pipelined; the sink of one stream
|
||||||
|
* may be the source of another lower-level stream. Additionally, all
|
||||||
|
* streams, regardless of their source or sink, share the same API, so
|
||||||
|
* streams can be handled in a much more generic manner. This allows
|
||||||
|
* the HTTP client and server libraries to seemlessly support TLS and
|
||||||
|
* plain connections without having to handle each separately.
|
||||||
|
* .Pp
|
||||||
|
* .Nm
|
||||||
|
* was heavily inspired by GNU's
|
||||||
|
* .Fn fopencookie
|
||||||
|
* and BSD's
|
||||||
|
* .Fn funopen .
|
||||||
|
* It aims to combine the best of both of these functions into a single
|
||||||
|
* API that is intuitive and easy to use.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -33,13 +64,61 @@
|
||||||
#define IO_BUFFER 4096
|
#define IO_BUFFER 4096
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An opaque structure analogous to a POSIX file descriptor.
|
||||||
|
*/
|
||||||
typedef struct Io Io;
|
typedef struct Io Io;
|
||||||
|
|
||||||
typedef ssize_t(IoReadFunc) (void *, void *, size_t);
|
/**
|
||||||
typedef ssize_t(IoWriteFunc) (void *, void *, size_t);
|
* Read input from the source of a stream. This function should
|
||||||
typedef off_t(IoSeekFunc) (void *, off_t, int);
|
* attempt to read the specified number of bytes of data from the
|
||||||
|
* given cookie into the given buffer. It should behave identically
|
||||||
|
* to the POSIX
|
||||||
|
* .Xr read 2
|
||||||
|
* system call, except instead of using an integer descriptor as the
|
||||||
|
* first parameter, a pointer to an implementation-defined cookie
|
||||||
|
* stores any information the function needs to read from the source.
|
||||||
|
*/
|
||||||
|
typedef ssize_t (IoReadFunc) (void *, void *, size_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write output to a sink. This function should attempt to write the
|
||||||
|
* specified number of bytes of data from the given buffer into the
|
||||||
|
* stream described by the given cookie. It should behave identically
|
||||||
|
* to the POSIX
|
||||||
|
* .Xr write 2
|
||||||
|
* system call, except instead of using an integer descriptor as the
|
||||||
|
* first parameter, a pointer to an implementation-defined cookie
|
||||||
|
* stores any information the function needs to write to the sink.
|
||||||
|
*/
|
||||||
|
typedef ssize_t (IoWriteFunc) (void *, void *, size_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repositions the offset of the stream described by the specified
|
||||||
|
* cookie. This function should behave identically to the POSIX
|
||||||
|
* .Xr lseek 2
|
||||||
|
* system call, except instead of using an integer descriptor as the
|
||||||
|
* first parameter, a pointer to an implementation-defined cookie
|
||||||
|
* stores any information the function needs to seek the stream.
|
||||||
|
*/
|
||||||
|
typedef off_t (IoSeekFunc) (void *, off_t, int);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the given stream, making future reads or writes result in
|
||||||
|
* undefined behavior. This function should also free all memory
|
||||||
|
* associated with the cookie. It should behave identically to the
|
||||||
|
* .Xr close 2
|
||||||
|
* system call, except instead of using an integer descriptor for the
|
||||||
|
* parameter, a pointer to an implementation-defined cookie stores any
|
||||||
|
* information the function needs to close the stream.
|
||||||
|
*/
|
||||||
typedef int (IoCloseFunc) (void *);
|
typedef int (IoCloseFunc) (void *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple mechanism for grouping together a set of stream functions,
|
||||||
|
* to be passed to
|
||||||
|
* .Fn IoCreate .
|
||||||
|
*/
|
||||||
typedef struct IoFunctions
|
typedef struct IoFunctions
|
||||||
{
|
{
|
||||||
IoReadFunc *read;
|
IoReadFunc *read;
|
||||||
|
@ -48,37 +127,96 @@ typedef struct IoFunctions
|
||||||
IoCloseFunc *close;
|
IoCloseFunc *close;
|
||||||
} IoFunctions;
|
} IoFunctions;
|
||||||
|
|
||||||
extern Io *
|
/**
|
||||||
IoCreate(void *, IoFunctions);
|
* Create a new stream using the specified cookie and the specified
|
||||||
|
* I/O functions.
|
||||||
|
*/
|
||||||
|
extern Io * IoCreate(void *, IoFunctions);
|
||||||
|
|
||||||
extern ssize_t
|
/**
|
||||||
IoRead(Io *, void *, size_t);
|
* Read the specified number of bytes from the specified stream into
|
||||||
|
* the specified buffer. This calls the stream's underlying IoReadFunc,
|
||||||
|
* which should behave identically to the POSIX
|
||||||
|
* .Xr read 2
|
||||||
|
* system call.
|
||||||
|
*/
|
||||||
|
extern ssize_t IoRead(Io *, void *, size_t);
|
||||||
|
|
||||||
extern ssize_t
|
/**
|
||||||
IoWrite(Io *, void *, size_t);
|
* Write the specified number of bytes from the specified stream into
|
||||||
|
* the specified buffer. This calls the stream's underlying
|
||||||
|
* IoWriteFunc, which should behave identically to the POSIX
|
||||||
|
* .Xr write 2
|
||||||
|
* system call.
|
||||||
|
*/
|
||||||
|
extern ssize_t IoWrite(Io *, void *, size_t);
|
||||||
|
|
||||||
extern off_t
|
/**
|
||||||
IoSeek(Io *, off_t, int);
|
* Seek the specified stream using the specified offset and whence
|
||||||
|
* value. This calls the stream's underlying IoSeekFunc, which should
|
||||||
|
* behave identically to the POSIX
|
||||||
|
* .Xr lseek 2
|
||||||
|
* system call.
|
||||||
|
*/
|
||||||
|
extern off_t IoSeek(Io *, off_t, int);
|
||||||
|
|
||||||
extern int
|
/**
|
||||||
IoClose(Io *);
|
* Close the specified stream. This calls the stream's underlying
|
||||||
|
* IoCloseFunc, which should behave identically to the POSIX
|
||||||
|
* .Xr close 2
|
||||||
|
* system call.
|
||||||
|
*/
|
||||||
|
extern int IoClose(Io *);
|
||||||
|
|
||||||
extern int
|
/**
|
||||||
IoVprintf(Io *, const char *, va_list);
|
* Print a formatted string to the given stream. This is a
|
||||||
|
* re-implementation of the standard library function
|
||||||
|
* .Xr vfprintf 3 ,
|
||||||
|
* and behaves identically.
|
||||||
|
*/
|
||||||
|
extern int IoVprintf(Io *, const char *, va_list);
|
||||||
|
|
||||||
extern int
|
/**
|
||||||
IoPrintf(Io *, const char *,...);
|
* Print a formatted string to the given stream. This is a
|
||||||
|
* re-implementation of the standard library function
|
||||||
|
* .Xr fprintf 3 ,
|
||||||
|
* and behaves identically.
|
||||||
|
*/
|
||||||
|
extern int IoPrintf(Io *, const char *,...);
|
||||||
|
|
||||||
extern ssize_t
|
/**
|
||||||
IoCopy(Io *, Io *);
|
* Read all the bytes from the first stream and write them to the
|
||||||
|
* second stream. Neither stream is closed upon the completion of this
|
||||||
|
* function. This can be used for quick and convenient buffered
|
||||||
|
* copying of data from one stream into another.
|
||||||
|
*/
|
||||||
|
extern ssize_t IoCopy(Io *, Io *);
|
||||||
|
|
||||||
extern Io *
|
/**
|
||||||
IoFd(int);
|
* Wrap a POSIX file descriptor to take advantage of this API. The
|
||||||
|
* common use case for this function is when a regular file descriptor
|
||||||
|
* needs to be accessed by an application that uses this API to also
|
||||||
|
* access non-POSIX streams.
|
||||||
|
*/
|
||||||
|
extern Io * IoFd(int);
|
||||||
|
|
||||||
extern Io *
|
/**
|
||||||
IoOpen(const char *, int, mode_t);
|
* Open or create a file for reading or writing. The specified file
|
||||||
|
* name is opened for reading or writing as specified by the given
|
||||||
|
* flags and mode. This function is a simple convenience wrapper around
|
||||||
|
* the POSIX
|
||||||
|
* .Xr open 2
|
||||||
|
* system call that passes the opened file descriptor into
|
||||||
|
* .Fn IoFd .
|
||||||
|
*/
|
||||||
|
extern Io * IoOpen(const char *, int, mode_t);
|
||||||
|
|
||||||
extern Io *
|
/**
|
||||||
IoFile(FILE *);
|
* Wrap a standard C file pointer to take advantage of this API. The
|
||||||
|
* common use case for this function is when a regular C file pointer
|
||||||
|
* needs to be accessed by an application that uses this API to also
|
||||||
|
* access custom streams.
|
||||||
|
*/
|
||||||
|
extern Io * IoFile(FILE *);
|
||||||
|
|
||||||
#endif /* TELODENDRIA_IO_H */
|
#endif /* TELODENDRIA_IO_H */
|
||||||
|
|
|
@ -24,49 +24,126 @@
|
||||||
#ifndef TELODENDRIA_REGTOKEN_H
|
#ifndef TELODENDRIA_REGTOKEN_H
|
||||||
#define TELODENDRIA_REGTOKEN_H
|
#define TELODENDRIA_REGTOKEN_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Nm RegToken
|
||||||
|
* @Nd Manage Matrix client registration tokens.
|
||||||
|
* @Dd April 29 2023
|
||||||
|
* @Xr User
|
||||||
|
*
|
||||||
|
* .Nm
|
||||||
|
* manages registration tokens, which are used to allow specific
|
||||||
|
* trusted people to register accounts on a homeserver without
|
||||||
|
* necessarily allowing entirely open registration. In Telodendria,
|
||||||
|
* registration tokens can also grant privileges to a user upon
|
||||||
|
* registration. This allows the initial server administrator account
|
||||||
|
* to be granted all privileges when it is created.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <Db.h>
|
#include <Db.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This structure describes a registration token that is in the
|
||||||
|
* database.
|
||||||
|
*/
|
||||||
typedef struct RegTokenInfo
|
typedef struct RegTokenInfo
|
||||||
{
|
{
|
||||||
Db *db;
|
Db *db;
|
||||||
DbRef *ref;
|
DbRef *ref;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The token itself.
|
||||||
|
*/
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Who created this token. Note that this can be NULL if the
|
||||||
|
* token was created by Telodendria itself.
|
||||||
|
*/
|
||||||
char *owner;
|
char *owner;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* How many times the token was used.
|
||||||
|
*/
|
||||||
int used;
|
int used;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* How many uses are allowed.
|
||||||
|
*/
|
||||||
int uses;
|
int uses;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timestamp when this token was created.
|
||||||
|
*/
|
||||||
unsigned long created;
|
unsigned long created;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timestamp when this token expires, or 0 if it does not
|
||||||
|
* expire.
|
||||||
|
*/
|
||||||
unsigned long expires;
|
unsigned long expires;
|
||||||
|
|
||||||
int grants; /* privileges */
|
/*
|
||||||
|
* A bit field describing the privileges this token grants. See
|
||||||
|
* the User API documentation for the privileges supported.
|
||||||
|
*/
|
||||||
|
int grants;
|
||||||
|
|
||||||
} RegTokenInfo;
|
} RegTokenInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ``Use'' the specified registration token by increasing the used
|
||||||
|
* count by one and writing the changes to the database. This function
|
||||||
|
* only takes action if the token is allowed to be used. Check
|
||||||
|
* .Fn RegTokenValid
|
||||||
|
* to see if a token actually can be used.
|
||||||
|
*/
|
||||||
|
extern void RegTokenUse(RegTokenInfo *);
|
||||||
|
|
||||||
extern void
|
/**
|
||||||
RegTokenUse(RegTokenInfo *);
|
* Return a boolean value indicating whether or not the specified
|
||||||
|
* token exists in the database.
|
||||||
|
*/
|
||||||
|
extern int RegTokenExists(Db *, char *);
|
||||||
|
|
||||||
extern int
|
/**
|
||||||
RegTokenExists(Db *, char *);
|
* Delete the specified registration token from the database.
|
||||||
|
*/
|
||||||
|
extern int RegTokenDelete(RegTokenInfo *);
|
||||||
|
|
||||||
extern int
|
/**
|
||||||
RegTokenDelete(RegTokenInfo *);
|
* Retrieve information about the specified registration token from
|
||||||
|
* the database.
|
||||||
|
*/
|
||||||
|
extern RegTokenInfo * RegTokenGetInfo(Db *, char *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new registration with the given name, owner, expiration
|
||||||
|
* timestamp, number of uses, and privileges to grant, all specified
|
||||||
|
* in that order. Upon success, a registration token information
|
||||||
|
* structure will be returned. Otherwise, NULL will be returned.
|
||||||
|
*/
|
||||||
extern RegTokenInfo *
|
extern RegTokenInfo *
|
||||||
RegTokenGetInfo(Db *, char *);
|
RegTokenCreate(Db *, char *, char *, unsigned long, int, int);
|
||||||
|
|
||||||
extern RegTokenInfo *
|
/**
|
||||||
RegTokenCreate(Db *, char *, char *, unsigned long, int, int);
|
* Free the memory associated with the registration token. This should
|
||||||
|
* be called after
|
||||||
|
* .Fn RegTokenClose .
|
||||||
|
*/
|
||||||
|
extern void RegTokenFree(RegTokenInfo *);
|
||||||
|
|
||||||
extern void
|
/**
|
||||||
RegTokenFree(RegTokenInfo *);
|
* Return a boolean value indicating whether or not the specified token
|
||||||
|
* is valid. A registration token is only valid if it has not expired
|
||||||
|
* and still has at least one remaining use.
|
||||||
|
*/
|
||||||
|
extern int RegTokenValid(RegTokenInfo *);
|
||||||
|
|
||||||
extern int
|
/**
|
||||||
RegTokenValid(RegTokenInfo *);
|
* Unlock the database reference associated with the given registration
|
||||||
|
* token. This should be called before
|
||||||
extern int
|
* .Fn RegTokenFree .
|
||||||
RegTokenClose(RegTokenInfo *);
|
*/
|
||||||
|
extern int RegTokenClose(RegTokenInfo *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue