diff options
Diffstat (limited to 'src/mime.c')
-rw-r--r-- | src/mime.c | 48 |
1 files changed, 48 insertions, 0 deletions
@@ -28,7 +28,9 @@ static int mime_global_qp(lua_State *L); | |||
28 | static int mime_global_unqp(lua_State *L); | 28 | static int mime_global_unqp(lua_State *L); |
29 | static int mime_global_qpwrp(lua_State *L); | 29 | static int mime_global_qpwrp(lua_State *L); |
30 | static int mime_global_eol(lua_State *L); | 30 | static int mime_global_eol(lua_State *L); |
31 | static int mime_global_dot(lua_State *L); | ||
31 | 32 | ||
33 | static size_t dot(int c, size_t state, luaL_Buffer *buffer); | ||
32 | static void b64setup(UC *b64unbase); | 34 | static void b64setup(UC *b64unbase); |
33 | static size_t b64encode(UC c, UC *input, size_t size, luaL_Buffer *buffer); | 35 | static size_t b64encode(UC c, UC *input, size_t size, luaL_Buffer *buffer); |
34 | static size_t b64pad(const UC *input, size_t size, luaL_Buffer *buffer); | 36 | static size_t b64pad(const UC *input, size_t size, luaL_Buffer *buffer); |
@@ -43,6 +45,7 @@ static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer); | |||
43 | 45 | ||
44 | /* code support functions */ | 46 | /* code support functions */ |
45 | static luaL_reg func[] = { | 47 | static luaL_reg func[] = { |
48 | { "dot", mime_global_dot }, | ||
46 | { "b64", mime_global_b64 }, | 49 | { "b64", mime_global_b64 }, |
47 | { "eol", mime_global_eol }, | 50 | { "eol", mime_global_eol }, |
48 | { "qp", mime_global_qp }, | 51 | { "qp", mime_global_qp }, |
@@ -659,3 +662,48 @@ static int mime_global_eol(lua_State *L) | |||
659 | lua_pushnumber(L, ctx); | 662 | lua_pushnumber(L, ctx); |
660 | return 2; | 663 | return 2; |
661 | } | 664 | } |
665 | |||
666 | /*-------------------------------------------------------------------------*\ | ||
667 | * Takes one byte and stuff it if needed. | ||
668 | \*-------------------------------------------------------------------------*/ | ||
669 | static size_t dot(int c, size_t state, luaL_Buffer *buffer) | ||
670 | { | ||
671 | luaL_putchar(buffer, c); | ||
672 | switch (c) { | ||
673 | case '\r': | ||
674 | return 1; | ||
675 | case '\n': | ||
676 | return (state == 1)? 2: 0; | ||
677 | case '.': | ||
678 | if (state == 2) | ||
679 | luaL_putchar(buffer, '.'); | ||
680 | default: | ||
681 | return 0; | ||
682 | } | ||
683 | } | ||
684 | |||
685 | /*-------------------------------------------------------------------------*\ | ||
686 | * Incrementally applies smtp stuffing to a string | ||
687 | * A, n = dot(l, D) | ||
688 | \*-------------------------------------------------------------------------*/ | ||
689 | static int mime_global_dot(lua_State *L) | ||
690 | { | ||
691 | size_t isize = 0, state = (size_t) luaL_checknumber(L, 1); | ||
692 | const char *input = luaL_optlstring(L, 2, NULL, &isize); | ||
693 | const char *last = input + isize; | ||
694 | luaL_Buffer buffer; | ||
695 | /* end-of-input blackhole */ | ||
696 | if (!input) { | ||
697 | lua_pushnil(L); | ||
698 | lua_pushnumber(L, 2); | ||
699 | return 2; | ||
700 | } | ||
701 | /* process all input */ | ||
702 | luaL_buffinit(L, &buffer); | ||
703 | while (input < last) | ||
704 | state = dot(*input++, state, &buffer); | ||
705 | luaL_pushresult(&buffer); | ||
706 | lua_pushnumber(L, state); | ||
707 | return 2; | ||
708 | } | ||
709 | |||