summaryrefslogtreecommitdiff
path: root/src/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils.c')
-rw-r--r--src/utils.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/utils.c b/src/utils.c
index 87292e3..5cdef6b 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -143,6 +143,55 @@ write_string(const char *string, FILE *to)
xfwrite(string, strlen(string) + 1, to);
}
+/* Check if a character being put into a URL must be encoded */
+static int
+char_url_mustencode(int c)
+{
+ return (c >= 0 && c <= 0x20)
+ || c == '%'
+ || c == '\x7F';
+}
+
+/* Writes a single character to a file, URL-encoding if necessary */
+void
+write_char_url(int c, FILE *to)
+{
+ int ok;
+
+ if (c < -127 || c > 255)
+ ok = 0;
+ else if (char_url_mustencode(c))
+ ok = fprintf(to, "%%%.2X", (unsigned char) c) == 3;
+ else
+ ok = fputc(c, to) != EOF;
+
+ if (!ok) {
+ msg(MSG_CRITICAL, "Failed to write to file: %s\n",
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+}
+
+/* Writes binary data to a file, URL-encoding any bytes if necessary */
+void
+write_binary_url(const char *string, size_t len, FILE *to)
+{
+ size_t i;
+
+ for (i = 0; i < len; ++i)
+ write_char_url(string[i], to);
+}
+
+/* Writes a normal C string to a file, URL-encoding any chars if necessary */
+void
+write_string_url(const char *string, FILE *to)
+{
+ int c;
+
+ while ((c = *string++) != '\0')
+ write_char_url(c, to);
+}
+
/* Reads an int from a file, using len bytes, in little-endian order */
uint64_t
read_int(const char **from, size_t len, const char *max)