Compare commits
7 Commits
bb30c7d86e
...
1a76b2032e
| Author | SHA1 | Date | |
|---|---|---|---|
|
1a76b2032e
|
|||
|
722ef65c1f
|
|||
|
317dfcb6e2
|
|||
|
bca7167d03
|
|||
|
3e4e4e5103
|
|||
|
9494e8e2af
|
|||
|
8ffe20c0e8
|
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2014 - 2018, Přemysl Janouch <p@janouch.name>
|
||||
Copyright (c) 2014 - 2018, Přemysl Eric Janouch <p@janouch.name>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* liberty-proto.c: the ultimate C unlibrary: protocols
|
||||
*
|
||||
* Copyright (c) 2014 - 2016, Přemysl Janouch <p@janouch.name>
|
||||
* Copyright (c) 2014 - 2016, Přemysl Eric Janouch <p@janouch.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted.
|
||||
@@ -213,6 +213,7 @@ irc_fnmatch (const char *pattern, const char *string)
|
||||
char x_pattern[pattern_size], x_string[string_size];
|
||||
irc_strxfrm (x_pattern, pattern, pattern_size);
|
||||
irc_strxfrm (x_string, string, string_size);
|
||||
// FIXME: this supports [], which is not mentioned in RFC 2812
|
||||
return fnmatch (x_pattern, x_string, 0);
|
||||
}
|
||||
|
||||
@@ -663,10 +664,11 @@ scgi_parser_push (struct scgi_parser *self,
|
||||
if (digit == ':')
|
||||
{
|
||||
self->state = SCGI_READING_NAME;
|
||||
str_remove_slice (&self->input, 0, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (digit < '0' || digit >= '9')
|
||||
if (digit < '0' || digit > '9')
|
||||
return error_set (e, "invalid header netstring");
|
||||
|
||||
size_t new_len = self->headers_len * 10 + (digit - '0');
|
||||
@@ -699,6 +701,7 @@ scgi_parser_push (struct scgi_parser *self,
|
||||
self->state = SCGI_READING_VALUE;
|
||||
|
||||
str_remove_slice (&self->input, 0, 1);
|
||||
self->headers_len--;
|
||||
break;
|
||||
}
|
||||
case SCGI_READING_VALUE:
|
||||
@@ -727,6 +730,7 @@ scgi_parser_push (struct scgi_parser *self,
|
||||
}
|
||||
|
||||
str_remove_slice (&self->input, 0, 1);
|
||||
self->headers_len--;
|
||||
break;
|
||||
}
|
||||
case SCGI_READING_CONTENT:
|
||||
@@ -791,7 +795,8 @@ enum fcgi_protocol_status
|
||||
|
||||
struct fcgi_parser;
|
||||
|
||||
typedef void (*fcgi_message_fn)
|
||||
/// Message handler, returns false if further processing should be stopped
|
||||
typedef bool (*fcgi_message_fn)
|
||||
(const struct fcgi_parser *parser, void *user_data);
|
||||
|
||||
enum fcgi_parser_state
|
||||
@@ -853,7 +858,7 @@ fcgi_parser_unpack_header (struct fcgi_parser *self)
|
||||
str_remove_slice (&self->input, 0, unpacker.offset);
|
||||
}
|
||||
|
||||
static void
|
||||
static bool
|
||||
fcgi_parser_push (struct fcgi_parser *self, const void *data, size_t len)
|
||||
{
|
||||
// This could be made considerably faster for high-throughput applications
|
||||
@@ -865,14 +870,14 @@ fcgi_parser_push (struct fcgi_parser *self, const void *data, size_t len)
|
||||
{
|
||||
case FCGI_READING_HEADER:
|
||||
if (self->input.len < FCGI_HEADER_LEN)
|
||||
return;
|
||||
return true;
|
||||
|
||||
fcgi_parser_unpack_header (self);
|
||||
self->state = FCGI_READING_CONTENT;
|
||||
break;
|
||||
case FCGI_READING_CONTENT:
|
||||
if (self->input.len < self->content_length)
|
||||
return;
|
||||
return true;
|
||||
|
||||
// Move an appropriate part of the input buffer to the content buffer
|
||||
str_reset (&self->content);
|
||||
@@ -882,10 +887,11 @@ fcgi_parser_push (struct fcgi_parser *self, const void *data, size_t len)
|
||||
break;
|
||||
case FCGI_READING_PADDING:
|
||||
if (self->input.len < self->padding_length)
|
||||
return;
|
||||
return true;
|
||||
|
||||
// Call the callback to further process the message
|
||||
self->on_message (self, self->user_data);
|
||||
if (!self->on_message (self, self->user_data))
|
||||
return false;
|
||||
|
||||
// Remove the padding from the input buffer
|
||||
str_remove_slice (&self->input, 0, self->padding_length);
|
||||
@@ -1188,8 +1194,10 @@ ws_parser_unmask (char *payload, uint64_t len, uint32_t mask)
|
||||
{
|
||||
case 3:
|
||||
payload[end + 2] ^= (mask >> 8) & 0xFF;
|
||||
// Fall-through
|
||||
case 2:
|
||||
payload[end + 1] ^= (mask >> 16) & 0xFF;
|
||||
// Fall-through
|
||||
case 1:
|
||||
payload[end ] ^= (mask >> 24) & 0xFF;
|
||||
}
|
||||
@@ -1738,6 +1746,8 @@ mpd_client_send_command (struct mpd_client *self, const char *command, ...)
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
/// "On success for all commands, OK is returned. If a command fails, no more
|
||||
/// commands are executed and the appropriate ACK error is returned"
|
||||
static void
|
||||
mpd_client_list_begin (struct mpd_client *self)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* liberty-tui.c: the ultimate C unlibrary: TUI
|
||||
*
|
||||
* Copyright (c) 2016 - 2017, Přemysl Janouch <p@janouch.name>
|
||||
* Copyright (c) 2016 - 2017, Přemysl Eric Janouch <p@janouch.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted.
|
||||
|
||||
20
liberty.c
20
liberty.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* liberty.c: the ultimate C unlibrary
|
||||
*
|
||||
* Copyright (c) 2014 - 2018, Přemysl Janouch <p@janouch.name>
|
||||
* Copyright (c) 2014 - 2018, Přemysl Eric Janouch <p@janouch.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted.
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/uio.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <signal.h>
|
||||
@@ -116,6 +117,9 @@ extern char **environ;
|
||||
#define CONTAINER_OF(pointer, type, member) \
|
||||
((type *) ((char *) pointer - offsetof (type, member)))
|
||||
|
||||
char *liberty = "They who can give up essential liberty to obtain a little "
|
||||
"temporary safety deserve neither liberty nor safety.";
|
||||
|
||||
// --- Logging -----------------------------------------------------------------
|
||||
|
||||
static void
|
||||
@@ -1092,7 +1096,7 @@ struct async
|
||||
LIST_HEADER (struct async)
|
||||
struct async_manager *manager; ///< Our manager object
|
||||
|
||||
// "cancelled" may not be accesed or modified by the worker thread
|
||||
// "cancelled" may not be accessed or modified by the worker thread
|
||||
|
||||
pthread_t worker; ///< Worker thread ID
|
||||
bool started; ///< Worker thread ID is valid
|
||||
@@ -5253,7 +5257,9 @@ static struct config_item *
|
||||
config_item_parse (const char *script, size_t len,
|
||||
bool single_value_only, struct error **e)
|
||||
{
|
||||
struct config_parser parser = config_parser_make (script, len);
|
||||
volatile struct config_parser parser = config_parser_make (script, len);
|
||||
struct config_parser *volatile self = (struct config_parser *) &parser;
|
||||
|
||||
struct config_item *volatile object = NULL;
|
||||
jmp_buf err;
|
||||
|
||||
@@ -5275,13 +5281,13 @@ config_item_parse (const char *script, size_t len,
|
||||
// This is really only intended for in-program configuration
|
||||
// and telling the line number would look awkward
|
||||
parser.tokenizer.report_line = false;
|
||||
object = config_parser_parse_value (&parser, err);
|
||||
object = config_parser_parse_value (self, err);
|
||||
}
|
||||
else
|
||||
object = config_parser_parse_object (&parser, err);
|
||||
config_parser_expect (&parser, CONFIG_T_ABORT, err);
|
||||
object = config_parser_parse_object (self, err);
|
||||
config_parser_expect (self, CONFIG_T_ABORT, err);
|
||||
end:
|
||||
config_parser_free (&parser);
|
||||
config_parser_free (self);
|
||||
return object;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* tests/liberty.c
|
||||
*
|
||||
* Copyright (c) 2015 - 2016, Přemysl Janouch <p@janouch.name>
|
||||
* Copyright (c) 2015 - 2016, Přemysl Eric Janouch <p@janouch.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* tests/proto.c
|
||||
*
|
||||
* Copyright (c) 2015, Přemysl Janouch <p@janouch.name>
|
||||
* Copyright (c) 2015, Přemysl Eric Janouch <p@janouch.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted.
|
||||
@@ -105,10 +105,20 @@ test_http_parser (void)
|
||||
http_protocol_destroy (iter);
|
||||
}
|
||||
|
||||
struct scgi_fixture
|
||||
{
|
||||
struct scgi_parser parser;
|
||||
bool seen_headers;
|
||||
bool seen_content;
|
||||
};
|
||||
|
||||
static bool
|
||||
test_scgi_parser_on_headers_read (void *user_data)
|
||||
{
|
||||
struct scgi_parser *parser = user_data;
|
||||
struct scgi_fixture *fixture = user_data;
|
||||
struct scgi_parser *parser = &fixture->parser;
|
||||
fixture->seen_headers = true;
|
||||
|
||||
soft_assert (parser->headers.len == 4);
|
||||
soft_assert (!strcmp (str_map_find (&parser->headers,
|
||||
"CONTENT_LENGTH"), "27"));
|
||||
@@ -124,7 +134,9 @@ test_scgi_parser_on_headers_read (void *user_data)
|
||||
static bool
|
||||
test_scgi_parser_on_content (void *user_data, const void *data, size_t len)
|
||||
{
|
||||
(void) user_data;
|
||||
struct scgi_fixture *fixture = user_data;
|
||||
fixture->seen_content = true;
|
||||
|
||||
soft_assert (!strncmp (data, "What is the answer to life?", len));
|
||||
return true;
|
||||
}
|
||||
@@ -132,10 +144,12 @@ test_scgi_parser_on_content (void *user_data, const void *data, size_t len)
|
||||
static void
|
||||
test_scgi_parser (void)
|
||||
{
|
||||
struct scgi_parser parser = scgi_parser_make ();
|
||||
parser.on_headers_read = test_scgi_parser_on_headers_read;
|
||||
parser.on_content = test_scgi_parser_on_content;
|
||||
parser.user_data = &parser;
|
||||
struct scgi_fixture fixture = { scgi_parser_make(), false, false };
|
||||
struct scgi_parser *parser = &fixture.parser;
|
||||
|
||||
parser->on_headers_read = test_scgi_parser_on_headers_read;
|
||||
parser->on_content = test_scgi_parser_on_content;
|
||||
parser->user_data = &fixture;
|
||||
|
||||
// This is an example straight from the specification
|
||||
const char example[] =
|
||||
@@ -147,8 +161,9 @@ test_scgi_parser (void)
|
||||
","
|
||||
"What is the answer to life?";
|
||||
|
||||
soft_assert (scgi_parser_push (&parser, example, sizeof example, NULL));
|
||||
scgi_parser_free (&parser);
|
||||
soft_assert (scgi_parser_push (parser, example, sizeof example, NULL));
|
||||
soft_assert (fixture.seen_headers && fixture.seen_content);
|
||||
scgi_parser_free (parser);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
||||
Reference in New Issue
Block a user