diff --git a/include/client.h b/include/gmni.h
rename from include/client.h
rename to include/gmni.h
index 671de12e7ee53fbbfc03407760723d2a66458c2d..42cfdac95530c9d6a5f4e6e6c3b85635908cc1e6 100644
--- a/include/client.h
+++ b/include/gmni.h
@@ -4,8 +4,49 @@ #include <netdb.h>
#include <openssl/ssl.h>
#include <sys/socket.h>
+enum gemini_result {
+ GEMINI_OK,
+ GEMINI_ERR_OOM,
+ GEMINI_ERR_INVALID_URL,
+ GEMINI_ERR_RESOLVE,
+ GEMINI_ERR_CONNECT,
+ GEMINI_ERR_SSL,
+ 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 {
- int status;
+ enum gemini_status status;
char *meta;
// Response body may be read from here if appropriate:
@@ -35,17 +76,6 @@ // example, to force IPv4/IPv6.
struct addrinfo *hints;
};
-enum gemini_result {
- GEMINI_OK,
- GEMINI_ERR_OOM,
- GEMINI_ERR_INVALID_URL,
- GEMINI_ERR_RESOLVE,
- GEMINI_ERR_CONNECT,
- GEMINI_ERR_SSL,
- GEMINI_ERR_IO,
- GEMINI_ERR_PROTOCOL,
-};
-
// Requests the specified URL via the gemini protocol. If options is non-NULL,
// it may specify some additional configuration to adjust client behavior.
//
@@ -67,5 +97,9 @@
// 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);
#endif
diff --git a/src/client.c b/src/client.c
index 59fa1381ab66496900acb4321f22c6ec3675db5e..86152d6183462636cca4eecbd47824569a688cb1 100644
--- a/src/client.c
+++ b/src/client.c
@@ -9,7 +9,7 @@ #include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
-#include "client.h"
+#include "gmni.h"
#include "url.h"
static enum gemini_result
@@ -264,3 +264,9 @@ cleanup:
curl_url_cleanup(uri);
return new_url;
}
+
+enum gemini_status_class
+gemini_response_class(enum gemini_status status)
+{
+ return status / 10;
+}
diff --git a/src/gmni.c b/src/gmni.c
index bdaa9baaca75e5f167add9a0ebed73cc60eaa647..b4efdc0235dac0279ce284f2c6b19f680a191647 100644
--- a/src/gmni.c
+++ b/src/gmni.c
@@ -11,7 +11,7 @@ #include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
-#include "client.h"
+#include "gmni.h"
static void
usage(char *argv_0)
@@ -120,8 +120,8 @@ goto next;
}
char *new_url, *input = NULL;
- switch (resp.status / 10) {
- case 1: // INPUT
+ switch (gemini_response_class(resp.status)) {
+ case GEMINI_STATUS_CLASS_INPUT:
if (input_mode == INPUT_SUPPRESS) {
exit = true;
break;
@@ -149,7 +149,7 @@ free(url);
url = new_url;
assert(url);
goto next;
- case 3: // REDIRECT
+ case GEMINI_STATUS_CLASS_REDIRECT:
free(url);
url = strdup(resp.meta);
if (!follow_redirects) {
@@ -160,10 +160,10 @@ }
exit = true;
}
goto next;
- case 6: // CLIENT CERTIFICATE REQUIRED
+ case GEMINI_STATUS_CLASS_CLIENT_CERTIFICATE_REQUIRED:
assert(0); // TODO
- case 4: // TEMPORARY FAILURE
- case 5: // PERMANENT FAILURE
+ case GEMINI_STATUS_CLASS_TEMPORARY_FAILURE:
+ case GEMINI_STATUS_CLASS_PERMANENT_FAILURE:
if (header_mode == OMIT_HEADERS) {
fprintf(stderr, "%s: %d %s\n",
resp.status / 10 == 4 ?
@@ -172,7 +172,7 @@ resp.status, resp.meta);
}
exit = true;
break;
- case 2: // SUCCESS
+ case GEMINI_STATUS_CLASS_SUCCESS:
exit = true;
break;
}