1
0
mirror of https://git.sr.ht/~sircmpwn/gmni synced 2024-11-22 20:32:03 +01:00

Re-add public headers

This commit is contained in:
Eyal Sawady 2020-10-24 13:55:33 -04:00 committed by Drew DeVault
parent 122fb0a9fd
commit f6643cf1b5
4 changed files with 317 additions and 1 deletions

2
.gitignore vendored

@ -1,6 +1,6 @@
.build
build
gmni
/gmni
gmnlm
*.1
*.o

164
include/gmni/gmni.h Normal file

@ -0,0 +1,164 @@
#ifndef GEMINI_CLIENT_H
#define GEMINI_CLIENT_H
#include <netdb.h>
#include <openssl/ssl.h>
#include <stdbool.h>
#include <sys/socket.h>
enum gemini_result {
GEMINI_OK,
GEMINI_ERR_OOM,
GEMINI_ERR_INVALID_URL,
GEMINI_ERR_NOT_GEMINI,
GEMINI_ERR_RESOLVE,
GEMINI_ERR_CONNECT,
GEMINI_ERR_SSL,
GEMINI_ERR_SSL_VERIFY,
GEMINI_ERR_IO,
GEMINI_ERR_PROTOCOL,
};
enum gemini_status {
GEMINI_STATUS_INPUT = 10,
GEMINI_STATUS_SENSITIVE_INPUT = 11,
GEMINI_STATUS_SUCCESS = 20,
GEMINI_STATUS_REDIRECT_TEMPORARY = 30,
GEMINI_STATUS_REDIRECT_PERMANENT = 31,
GEMINI_STATUS_TEMPORARY_FAILURE = 40,
GEMINI_STATUS_SERVER_UNAVAILABLE = 41,
GEMINI_STATUS_CGI_ERROR = 42,
GEMINI_STATUS_PROXY_ERROR = 43,
GEMINI_STATUS_SLOW_DOWN = 44,
GEMINI_STATUS_PERMANENT_FAILURE = 50,
GEMINI_STATUS_NOT_FOUND = 51,
GEMINI_STATUS_GONE = 52,
GEMINI_STATUS_PROXY_REQUEST_REFUSED = 53,
GEMINI_STATUS_BAD_REQUEST = 59,
GEMINI_STATUS_CLIENT_CERTIFICATE_REQUIRED = 60,
GEMINI_STATUS_CERTIFICATE_NOT_AUTHORIZED = 61,
GEMINI_STATUS_CERTIFICATE_NOT_VALID = 62,
};
enum gemini_status_class {
GEMINI_STATUS_CLASS_INPUT = 10,
GEMINI_STATUS_CLASS_SUCCESS = 20,
GEMINI_STATUS_CLASS_REDIRECT = 30,
GEMINI_STATUS_CLASS_TEMPORARY_FAILURE = 40,
GEMINI_STATUS_CLASS_PERMANENT_FAILURE = 50,
GEMINI_STATUS_CLASS_CLIENT_CERTIFICATE_REQUIRED = 60,
};
struct gemini_response {
enum gemini_status status;
char *meta;
// Response body may be read from here if appropriate:
BIO *bio;
// Connection state
SSL_CTX *ssl_ctx;
SSL *ssl;
int fd;
};
struct gemini_options {
// If NULL, an SSL context will be created. If unset, the ssl field
// must also be NULL.
SSL_CTX *ssl_ctx;
// If ai_family != AF_UNSPEC (the default value on most systems), the
// client will connect to this address and skip name resolution.
struct addrinfo *addr;
// If non-NULL, these hints are provided to getaddrinfo. Useful, for
// example, to force IPv4/IPv6.
struct addrinfo *hints;
};
// Requests the specified URL via the gemini protocol. If options is non-NULL,
// it may specify some additional configuration to adjust client behavior.
//
// Returns a value indicating the success of the request.
//
// Caller must call gemini_response_finish afterwards to clean up resources
// before exiting or re-using it for another request.
enum gemini_result gemini_request(const char *url,
struct gemini_options *options,
struct gemini_response *resp);
// Must be called after gemini_request in order to free up the resources
// allocated during the request.
void gemini_response_finish(struct gemini_response *resp);
// Returns a user-friendly string describing an error.
const char *gemini_strerr(enum gemini_result r, struct gemini_response *resp);
// Returns the given URL with the input response set to the specified value.
// The caller must free the string.
char *gemini_input_url(const char *url, const char *input);
// Returns the general response class (i.e. with the second digit set to zero)
// of the given Gemini status code.
enum gemini_status_class gemini_response_class(enum gemini_status status);
enum gemini_tok {
GEMINI_TEXT,
GEMINI_LINK,
GEMINI_PREFORMATTED_BEGIN,
GEMINI_PREFORMATTED_END,
GEMINI_PREFORMATTED_TEXT,
GEMINI_HEADING,
GEMINI_LIST_ITEM,
GEMINI_QUOTE,
};
struct gemini_token {
enum gemini_tok token;
// The token field determines which of the union members is valid.
union {
char *text;
struct {
char *text;
char *url; // May be NULL
} link;
char *preformatted;
struct {
char *title;
int level; // 1, 2, or 3
} heading;
char *list_item;
char *quote_text;
};
};
struct gemini_parser {
BIO *f;
char *buf;
size_t bufsz;
size_t bufln;
bool preformatted;
};
// Initializes a text/gemini parser which reads from the specified BIO.
void gemini_parser_init(struct gemini_parser *p, BIO *f);
// Finishes this text/gemini parser and frees up its resources.
void gemini_parser_finish(struct gemini_parser *p);
// Reads the next token from a text/gemini file.
//
// Returns 0 on success, 1 on EOF, and -1 on failure.
//
// Caller must call gemini_token_finish before exiting or re-using the token
// parameter.
int gemini_parser_next(struct gemini_parser *p, struct gemini_token *token);
// Must be called after gemini_next to free up resources for the next token.
void gemini_token_finish(struct gemini_token *token);
#endif

49
include/gmni/tofu.h Normal file

@ -0,0 +1,49 @@
#ifndef GEMINI_TOFU_H
#define GEMINI_TOFU_H
#include <limits.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <time.h>
enum tofu_error {
TOFU_VALID,
// Expired, wrong CN, etc.
TOFU_INVALID_CERT,
// Cert is valid but we haven't seen it before
TOFU_UNTRUSTED_CERT,
// Cert is valid but we already trust another cert for this host
TOFU_FINGERPRINT_MISMATCH,
};
enum tofu_action {
TOFU_ASK,
TOFU_FAIL,
TOFU_TRUST_ONCE,
TOFU_TRUST_ALWAYS,
};
struct known_host {
char *host, *fingerprint;
time_t expires;
int lineno;
struct known_host *next;
};
// Called when the user needs to be prompted to agree to trust an unknown
// certificate. Return true to trust this certificate.
typedef enum tofu_action (tofu_callback_t)(enum tofu_error error,
const char *fingerprint, struct known_host *host, void *data);
struct gemini_tofu {
char known_hosts_path[PATH_MAX+1];
struct known_host *known_hosts;
int lineno;
tofu_callback_t *callback;
void *cb_data;
};
void gemini_tofu_init(struct gemini_tofu *tofu,
SSL_CTX *ssl_ctx, tofu_callback_t *cb, void *data);
void gemini_tofu_finish(struct gemini_tofu *tofu);
#endif

103
include/gmni/url.h Normal file

@ -0,0 +1,103 @@
#ifndef URLAPI_H
#define URLAPI_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/* the error codes for the URL API */
typedef enum {
CURLUE_OK,
CURLUE_BAD_HANDLE, /* 1 */
CURLUE_BAD_PARTPOINTER, /* 2 */
CURLUE_MALFORMED_INPUT, /* 3 */
CURLUE_BAD_PORT_NUMBER, /* 4 */
CURLUE_UNSUPPORTED_SCHEME, /* 5 */
CURLUE_URLDECODE, /* 6 */
CURLUE_OUT_OF_MEMORY, /* 7 */
CURLUE_USER_NOT_ALLOWED, /* 8 */
CURLUE_UNKNOWN_PART, /* 9 */
CURLUE_NO_SCHEME, /* 10 */
CURLUE_NO_USER, /* 11 */
CURLUE_NO_PASSWORD, /* 12 */
CURLUE_NO_OPTIONS, /* 13 */
CURLUE_NO_HOST, /* 14 */
CURLUE_NO_PORT, /* 15 */
CURLUE_NO_QUERY, /* 16 */
CURLUE_NO_FRAGMENT /* 17 */
} CURLUcode;
typedef enum {
CURLUPART_URL,
CURLUPART_SCHEME,
CURLUPART_USER,
CURLUPART_PASSWORD,
CURLUPART_OPTIONS,
CURLUPART_HOST,
CURLUPART_PORT,
CURLUPART_PATH,
CURLUPART_QUERY,
CURLUPART_FRAGMENT
} CURLUPart;
#define CURLU_PATH_AS_IS (1<<4) /* leave dot sequences */
#define CURLU_DISALLOW_USER (1<<5) /* no user+password allowed */
#define CURLU_URLDECODE (1<<6) /* URL decode on get */
#define CURLU_URLENCODE (1<<7) /* URL encode on set */
#define CURLU_APPENDQUERY (1<<8) /* append a form style part */
typedef struct Curl_URL CURLU;
/*
* curl_url() creates a new CURLU handle and returns a pointer to it.
* Must be freed with curl_url_cleanup().
*/
struct Curl_URL *curl_url(void);
/*
* curl_url_cleanup() frees the CURLU handle and related resources used for
* the URL parsing. It will not free strings previously returned with the URL
* API.
*/
void curl_url_cleanup(struct Curl_URL *handle);
/*
* curl_url_dup() duplicates a CURLU handle and returns a new copy. The new
* handle must also be freed with curl_url_cleanup().
*/
struct Curl_URL *curl_url_dup(struct Curl_URL *in);
/*
* curl_url_get() extracts a specific part of the URL from a CURLU
* handle. Returns error code. The returned pointer MUST be freed with
* free() afterwards.
*/
CURLUcode curl_url_get(struct Curl_URL *handle, CURLUPart what,
char **part, unsigned int flags);
/*
* curl_url_set() sets a specific part of the URL in a CURLU handle. Returns
* error code. The passed in string will be copied. Passing a NULL instead of
* a part string, clears that part.
*/
CURLUcode curl_url_set(struct Curl_URL *handle, CURLUPart what,
const char *part, unsigned int flags);
#endif