#include "defs.h"
-#if !defined(NO_SSI)
-
#define CMDBUFSIZ 512 /* SSI command buffer size */
#define NEST_MAX 6 /* Maximum nesting level */
}
void
-free_ssi_funcs(struct shttpd_ctx *ctx)
+ssi_func_destructor(struct llhead *lp)
{
- struct llhead *lp, *tmp;
- struct ssi_func *e;
+ struct ssi_func *e = LL_ENTRY(lp, struct ssi_func, link);
- LL_FOREACH_SAFE(&ctx->ssi_funcs, lp, tmp) {
- e = LL_ENTRY(lp, struct ssi_func, link);
- free(e->name);
- free(e);
- }
+ free(e->name);
+ free(e);
}
static const struct ssi_func *
(void) memset(arg, 0, sizeof(*arg));
+ /*
+ * SSI function may be called with parameters. These parameters
+ * are passed as arg->in.buf, arg->in.len vector.
+ */
+ arg->in.buf = strchr(name, ' ');
+ if (arg->in.buf != NULL) {
+ *arg->in.buf++ = '\0';
+ arg->in.len = strlen(arg->in.buf);
+ }
+
if ((ssi_func = find_ssi_func(ssi, name)) != NULL) {
arg->priv = ssi->conn;
arg->user_data = ssi_func->user_data;
{NULL, 0},
};
struct vec *vec;
- const char *p;
+ const char *p, *root = conn->ctx->options[OPT_ROOT];
int len;
for (vec = accepted; vec->len > 0; vec++)
break;
if (vec->len == 6) {
len = my_snprintf(dst, dst_len, "%s%c%s",
- conn->ctx->document_root, DIRSEP, conn->uri);
+ root, DIRSEP, conn->uri);
while (len > 0 && dst[len] != '/')
len--;
dst += len;
dst_len -= len;
} else if (vec->len == 9) {
len = my_snprintf(dst, dst_len, "%s%c",
- conn->ctx->document_root, DIRSEP);
+ root, DIRSEP);
dst += len;
dst_len -= len;
}
static char *
trim_spaces(struct ssi_inc *inc)
{
- unsigned char *p = inc->buf + inc->nbuf - 2;
+ char *p = inc->buf + inc->nbuf - 2;
/* Trim spaces from the right */
*p-- = '\0';
- while (isspace(*p))
+ while (isspace(* (unsigned char *) p))
*p-- = '\0';
/* Shift pointer to the start of attributes */
- for (p = inc->buf; !isspace(*p); p++);
- while (*p && isspace(*p)) p++;
+ for (p = inc->buf; !isspace(* (unsigned char *) p); p++);
+ while (*p && isspace(* (unsigned char *) p)) p++;
return (p);
}
do_if(struct ssi *ssi)
{
struct ssi_inc *inc = ssi->incs + ssi->nest;
- unsigned char *name = trim_spaces(inc);
+ char *name = trim_spaces(inc);
inc->cond = evaluate(ssi, name) ? SSI_GO : SSI_STOP;
}
+
static void
do_elif(struct ssi *ssi)
{
struct ssi_inc *inc = ssi->incs + ssi->nest;
- unsigned char *name = trim_spaces(inc);
+ char *name = trim_spaces(inc);
if (inc->cond == SSI_STOP && evaluate(ssi, name))
inc->cond = SSI_GO;
static void
do_call(struct ssi *ssi, char *buf, int len, int *n)
{
- struct ssi_inc *inc = ssi->incs + ssi->nest;
- unsigned char *name = trim_spaces(inc);
+ struct ssi_inc *inc = ssi->incs + ssi->nest;
+ char *name = trim_spaces(inc);
if (inc->cond == SSI_GO) {
(void) memmove(inc->buf, name, strlen(name) + 1);
do_exec(struct ssi *ssi, char *buf, int len, int *n)
{
struct ssi_inc *inc = ssi->incs + ssi->nest;
- unsigned char *e, *p;
- char cmd[sizeof(inc->buf)];
+ char cmd[sizeof(inc->buf)], *e, *p;
p = trim_spaces(inc);
char *buf = vbuf;
int ch = EOF, n = 0;
-
again:
if (inc->state == SSI_CALL)
}
break;
+ /*
+ * We are buffering whole SSI command, until closing "-->".
+ * That means that when do_command() is called, we can rely
+ * on that full command with arguments is buffered in and
+ * there is no need for streaming.
+ * Restrictions:
+ * 1. The command must fit in CMDBUFSIZ
+ * 2. HTML comments inside the command ? Not sure about this.
+ */
case SSI_BUF:
if (inc->nbuf >= sizeof(inc->buf) - 1) {
pass(inc, buf + n, &n);
}
break;
+ case SSI_EXEC:
+ case SSI_CALL:
+ break;
+
default:
+ /* Never happens */
abort();
break;
}
NULL,
close_ssi
};
-
-#endif /* NO_SSI */