luci-0.8: remove obsolete code

This commit is contained in:
Jo-Philipp Wich 2009-05-29 19:27:10 +00:00
parent f698890d2e
commit 5e481381d5
21 changed files with 0 additions and 4314 deletions

View file

@ -1,13 +0,0 @@
include ../../build/module.mk
include ../../build/config.mk
include ../../build/gccconfig.mk
%.o: %.c
$(COMPILE) $(LUA_CFLAGS) $(FPIC) -c -o $@ $<
compile: src/fastindex.o
mkdir -p dist$(LUCI_LIBRARYDIR)
$(LINK) $(SHLIB_FLAGS) -o dist$(LUCI_LIBRARYDIR)/fastindex.so src/fastindex.o $(LUA_SHLIBS)
clean:
rm -f src/*.o

View file

@ -1,379 +0,0 @@
/*
* fastindex - fast lua module indexing plugin
* Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <sys/types.h>
#include <sys/time.h>
#include <sys/cdefs.h>
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE /* XXX: portability hack for timestamp */
#endif
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <glob.h>
#include <lualib.h>
#include <lauxlib.h>
#include "list.h"
#define MODNAME "luci.fastindex"
#define DEFAULT_BUFLEN 1024
//#define DEBUG 1
#ifdef DEBUG
#define DPRINTF(...) fprintf(stderr, __VA_ARGS__)
#else
#define DPRINTF(...) do {} while (0)
#endif
/**
* list_for_each_offset - iterate over a list, start with the provided pointer
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each_offset(pos, head, offset) \
for (pos = (offset)->next; pos != (offset); \
pos = ((pos->next == (head)) && ((offset) != (head)) ? (head)->next : pos->next))
static char *namespace = NULL;
struct fastindex_entry {
struct list_head list;
time_t timestamp;
int checked;
char *name;
};
struct fastindex_pattern {
struct list_head list;
char pattern[];
};
struct fastindex {
lua_State *L;
int checked;
char *func;
struct list_head patterns;
struct list_head *last;
struct list_head entries;
int ofs;
char *buf;
int buflen;
};
static inline struct fastindex *
to_fastindex(struct lua_State *L)
{
struct fastindex *f;
lua_getfield(L, lua_upvalueindex(1), "__data");
f = lua_touserdata(L, -1);
lua_pop(L, 1);
return f;
}
static int
fastindex_module(lua_State *L)
{
const char *s;
s = luaL_checkstring(L, 1);
if (s) {
if (namespace)
free(namespace);
namespace = strdup(s);
}
return 0;
}
static struct fastindex_entry *
find_entry(struct fastindex *f, char *name)
{
struct list_head *p;
if (!f->last)
f->last = &f->entries;
list_for_each_offset(p, &f->entries, f->last) {
struct fastindex_entry *e;
e = container_of(p, struct fastindex_entry, list);
if (!strcmp(e->name, name))
return e;
}
return NULL;
}
static struct fastindex_entry *
new_entry(struct fastindex *f, char *name)
{
struct fastindex_entry *e;
e = malloc(sizeof(struct fastindex_entry));
if (!e)
goto error;
memset(e, 0, sizeof(struct fastindex_entry));
e->name = strdup(name);
if (!e->name) {
free(e);
goto error;
}
INIT_LIST_HEAD(&e->list);
return e;
error:
return NULL;
}
static void free_entry(struct fastindex_entry *e)
{
list_del(&e->list);
free(e->name);
free(e);
}
int bufferwriter(lua_State *L, const void *p, size_t sz, void *ud)
{
struct fastindex *f = ud;
while (f->ofs + sz > f->buflen) {
char *b = f->buf;
f->buflen *= 2;
f->buf = realloc(f->buf, f->buflen);
if (!f->buf) {
free(b);
return 1;
}
}
memcpy(f->buf + f->ofs, p, sz);
f->ofs += sz;
return 0;
}
static void
load_index(struct fastindex *f, struct fastindex_entry *e)
{
lua_State *L;
DPRINTF("Loading module: %s\n", e->name);
if (!f->buf)
f->buf = malloc(f->buflen);
if (!f->buf)
luaL_error(f->L, "Out of memory!\n");
f->ofs = 0;
L = luaL_newstate();
if (!L)
return;
namespace = NULL;
luaL_openlibs(L);
lua_pushcfunction(L, fastindex_module);
lua_setfield(L, LUA_GLOBALSINDEX, "module");
do {
if (luaL_dofile(L, e->name)) {
DPRINTF("Warning: unable to open module '%s'\n", e->name);
break;
}
lua_getglobal(L, f->func);
lua_dump(L, bufferwriter, f);
DPRINTF("Got %d bytes\n", f->ofs);
if (f->ofs == 0)
break;
lua_createtable(f->L, (namespace ? 2 : 1), 0);
luaL_loadbuffer(f->L, f->buf, f->ofs, "tmp");
lua_rawseti(f->L, -2, 1);
if (namespace) {
DPRINTF("Module has namespace '%s'\n", namespace);
lua_pushstring(f->L, namespace);
lua_rawseti(f->L, -2, 2);
free(namespace);
namespace = NULL;
}
lua_setfield(f->L, -2, e->name);
} while (0);
lua_close(L);
}
static int
fastindex_scan(lua_State *L)
{
struct list_head *tmp, *p;
struct fastindex *f;
glob_t gl;
int i;
int gl_flags = GLOB_NOESCAPE | GLOB_NOSORT | GLOB_MARK;
f = to_fastindex(L);
f->checked++;
if (list_empty(&f->patterns))
return 0;
lua_getfield(L, lua_upvalueindex(1), "indexes");
list_for_each(p, &f->patterns) {
struct fastindex_pattern *pt = container_of(p, struct fastindex_pattern, list);
glob(pt->pattern, gl_flags, NULL, &gl);
gl_flags |= GLOB_APPEND;
}
for (i = 0; i < gl.gl_pathc; i++) {
struct fastindex_entry *e;
struct stat st;
if (stat(gl.gl_pathv[i], &st))
continue;
if ((st.st_mode & S_IFMT) != S_IFREG)
continue;
e = find_entry(f, gl.gl_pathv[i]);
if (!e) {
e = new_entry(f, gl.gl_pathv[i]);
list_add_tail(&e->list, &f->entries);
}
e->checked = f->checked;
if ((e->timestamp < st.st_mtime)) {
load_index(f, e);
e->timestamp = st.st_mtime;
}
}
globfree(&gl);
list_for_each_safe(p, tmp, &f->entries) {
struct fastindex_entry *e = container_of(p, struct fastindex_entry, list);
if (e->checked < f->checked) {
lua_pushnil(f->L);
lua_setfield(f->L, -2, e->name);
free_entry(e);
}
}
lua_pop(L, 1);
return 0;
}
static int
fastindex_free(lua_State *L)
{
struct fastindex *f;
struct list_head *p, *tmp;
f = lua_touserdata(L, -1);
list_for_each_safe(p, tmp, &f->patterns) {
struct fastindex_pattern *pt;
pt = container_of(p, struct fastindex_pattern, list);
list_del(p);
free(pt);
}
list_for_each_safe(p, tmp, &f->entries) {
struct fastindex_entry *e;
e = container_of(p, struct fastindex_entry, list);
free_entry(e);
}
return 0;
}
static int
fastindex_add(lua_State *L)
{
struct fastindex_pattern *pt;
struct fastindex *f;
const char *str;
f = to_fastindex(L);
str = luaL_checkstring(L, 1);
if (!str)
luaL_error(L, "Invalid argument");
pt = malloc(sizeof(struct fastindex_pattern) + strlen(str) + 1);
if (!pt)
luaL_error(L, "Out of memory");
INIT_LIST_HEAD(&pt->list);
strcpy(pt->pattern, str);
list_add(&pt->list, &f->patterns);
return 0;
}
static const luaL_Reg fastindex_m[] = {
{ "add", fastindex_add },
{ "scan", fastindex_scan },
{ NULL, NULL }
};
static int
fastindex_new(lua_State *L)
{
struct fastindex *f;
const char *func;
func = luaL_checkstring(L, 1);
f = lua_newuserdata(L, sizeof(struct fastindex));
lua_createtable(L, 0, 2);
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, fastindex_free);
lua_setfield(L, -2, "__gc");
lua_pushvalue(L, -1);
lua_setmetatable(L, -3);
lua_pushvalue(L, -2);
lua_setfield(L, -2, "__data");
lua_createtable(L, 0, 1);
lua_setfield(L, -2, "indexes");
lua_pushvalue(L, -2);
luaI_openlib(L, NULL, fastindex_m, 1);
memset(f, 0, sizeof(struct fastindex));
f->L = L;
f->buflen = DEFAULT_BUFLEN;
INIT_LIST_HEAD(&f->entries);
INIT_LIST_HEAD(&f->patterns);
f->func = strdup(func);
if (!f->func) {
if (f->func)
free(f->func);
luaL_error(L, "Out of memory\n");
}
return 1;
}
static const luaL_Reg fastindex[] = {
{ "new", fastindex_new },
{ NULL, NULL },
};
int
luaopen_luci_fastindex(lua_State *L)
{
luaL_register(L, MODNAME, fastindex);
return 0;
}

View file

@ -1,601 +0,0 @@
#ifndef _LINUX_LIST_H
#define _LINUX_LIST_H
#include <stddef.h>
/**
* container_of - cast a member of a structure out to the containing structure
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
#ifndef container_of
#define container_of(ptr, type, member) ( \
(type *)( (char *)ptr - offsetof(type,member) ))
#endif
/*
* Simple doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty() on entry does not return true after this, the entry is
* in an undefined state.
*/
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = NULL;
entry->prev = NULL;
}
/**
* list_replace - replace old entry by new one
* @old : the element to be replaced
* @new : the new element to insert
*
* If @old was empty, it will be overwritten.
*/
static inline void list_replace(struct list_head *old,
struct list_head *new)
{
new->next = old->next;
new->next->prev = new;
new->prev = old->prev;
new->prev->next = new;
}
static inline void list_replace_init(struct list_head *old,
struct list_head *new)
{
list_replace(old, new);
INIT_LIST_HEAD(old);
}
/**
* list_del_init - deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
*/
static inline void list_del_init(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
/**
* list_move - delete from one list and add as another's head
* @list: the entry to move
* @head: the head that will precede our entry
*/
static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del(list->prev, list->next);
list_add(list, head);
}
/**
* list_move_tail - delete from one list and add as another's tail
* @list: the entry to move
* @head: the head that will follow our entry
*/
static inline void list_move_tail(struct list_head *list,
struct list_head *head)
{
__list_del(list->prev, list->next);
list_add_tail(list, head);
}
/**
* list_is_last - tests whether @list is the last entry in list @head
* @list: the entry to test
* @head: the head of the list
*/
static inline int list_is_last(const struct list_head *list,
const struct list_head *head)
{
return list->next == head;
}
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
/**
* list_empty_careful - tests whether a list is empty and not being modified
* @head: the list to test
*
* Description:
* tests whether a list is empty _and_ checks that no other CPU might be
* in the process of modifying either member (next or prev)
*
* NOTE: using list_empty_careful() without synchronization
* can only be safe if the only activity that can happen
* to the list entry is list_del_init(). Eg. it cannot be used
* if another CPU could re-list_add() it.
*/
static inline int list_empty_careful(const struct list_head *head)
{
struct list_head *next = head->next;
return (next == head) && (next == head->prev);
}
static inline void __list_splice(struct list_head *list,
struct list_head *head)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
struct list_head *at = head->next;
first->prev = head;
head->next = first;
last->next = at;
at->prev = last;
}
/**
* list_splice - join two lists
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice(struct list_head *list, struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head);
}
/**
* list_splice_init - join two lists and reinitialise the emptied list.
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* The list at @list is reinitialised
*/
static inline void list_splice_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head);
INIT_LIST_HEAD(list);
}
}
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
/**
* list_first_entry - get the first element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*
* Note, that list is expected to be not empty.
*/
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); \
pos = pos->next)
/**
* __list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*
* This variant differs from list_for_each() in that it's the
* simplest possible list iteration code, no prefetching is done.
* Use this for code that knows the list to be very short (empty
* or 1 entry) most of the time.
*/
#define __list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
/**
* list_for_each_prev - iterate over a list backwards
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); \
pos = pos->prev)
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop cursor.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/**
* list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
* @pos: the &struct list_head to use as a loop cursor.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_prev_safe(pos, n, head) \
for (pos = (head)->prev, n = pos->prev; \
pos != (head); \
pos = n, n = pos->prev)
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member))
/**
* list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
* @pos: the type * to use as a start point
* @head: the head of the list
* @member: the name of the list_struct within the struct.
*
* Prepares a pos entry for use as a start point in list_for_each_entry_continue().
*/
#define list_prepare_entry(pos, head, member) \
((pos) ? : list_entry(head, typeof(*pos), member))
/**
* list_for_each_entry_continue - continue iteration over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Continue to iterate over list of given type, continuing after
* the current position.
*/
#define list_for_each_entry_continue(pos, head, member) \
for (pos = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_continue_reverse - iterate backwards from the given point
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Start to iterate over list of given type backwards, continuing after
* the current position.
*/
#define list_for_each_entry_continue_reverse(pos, head, member) \
for (pos = list_entry(pos->member.prev, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member))
/**
* list_for_each_entry_from - iterate over list of given type from the current point
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Iterate over list of given type, continuing from current position.
*/
#define list_for_each_entry_from(pos, head, member) \
for (; &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
* list_for_each_entry_safe_continue
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Iterate over list of given type, continuing after current point,
* safe against removal of list entry.
*/
#define list_for_each_entry_safe_continue(pos, n, head, member) \
for (pos = list_entry(pos->member.next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
* list_for_each_entry_safe_from
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Iterate over list of given type from current point, safe against
* removal of list entry.
*/
#define list_for_each_entry_safe_from(pos, n, head, member) \
for (n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
* list_for_each_entry_safe_reverse
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Iterate backwards over list of given type, safe against removal
* of list entry.
*/
#define list_for_each_entry_safe_reverse(pos, n, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member), \
n = list_entry(pos->member.prev, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.prev, typeof(*n), member))
/*
* Double linked lists with a single pointer list head.
* Mostly useful for hash tables where the two pointer list head is
* too wasteful.
* You lose the ability to access the tail in O(1).
*/
struct hlist_head {
struct hlist_node *first;
};
struct hlist_node {
struct hlist_node *next, **pprev;
};
#define HLIST_HEAD_INIT { .first = NULL }
#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
static inline void INIT_HLIST_NODE(struct hlist_node *h)
{
h->next = NULL;
h->pprev = NULL;
}
static inline int hlist_unhashed(const struct hlist_node *h)
{
return !h->pprev;
}
static inline int hlist_empty(const struct hlist_head *h)
{
return !h->first;
}
static inline void __hlist_del(struct hlist_node *n)
{
struct hlist_node *next = n->next;
struct hlist_node **pprev = n->pprev;
*pprev = next;
if (next)
next->pprev = pprev;
}
static inline void hlist_del(struct hlist_node *n)
{
__hlist_del(n);
n->next = NULL;
n->pprev = NULL;
}
static inline void hlist_del_init(struct hlist_node *n)
{
if (!hlist_unhashed(n)) {
__hlist_del(n);
INIT_HLIST_NODE(n);
}
}
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
{
struct hlist_node *first = h->first;
n->next = first;
if (first)
first->pprev = &n->next;
h->first = n;
n->pprev = &h->first;
}
/* next must be != NULL */
static inline void hlist_add_before(struct hlist_node *n,
struct hlist_node *next)
{
n->pprev = next->pprev;
n->next = next;
next->pprev = &n->next;
*(n->pprev) = n;
}
static inline void hlist_add_after(struct hlist_node *n,
struct hlist_node *next)
{
next->next = n->next;
n->next = next;
next->pprev = &n->next;
if(next->next)
next->next->pprev = &next->next;
}
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
#define hlist_for_each(pos, head) \
for (pos = (head)->first; pos; pos = pos->next)
#define hlist_for_each_safe(pos, n, head) \
for (pos = (head)->first; pos; pos = n)
/**
* hlist_for_each_entry - iterate over list of given type
* @tpos: the type * to use as a loop cursor.
* @pos: the &struct hlist_node to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry(tpos, pos, head, member) \
for (pos = (head)->first; pos && \
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
pos = pos->next)
/**
* hlist_for_each_entry_continue - iterate over a hlist continuing after current point
* @tpos: the type * to use as a loop cursor.
* @pos: the &struct hlist_node to use as a loop cursor.
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry_continue(tpos, pos, member) \
for (pos = (pos)->next; pos && \
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
pos = pos->next)
/**
* hlist_for_each_entry_from - iterate over a hlist continuing from current point
* @tpos: the type * to use as a loop cursor.
* @pos: the &struct hlist_node to use as a loop cursor.
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry_from(tpos, pos, member) \
for (; pos && \
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
pos = pos->next)
/**
* hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @tpos: the type * to use as a loop cursor.
* @pos: the &struct hlist_node to use as a loop cursor.
* @n: another &struct hlist_node to use as temporary storage
* @head: the head for your list.
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
for (pos = (head)->first; \
pos && ({ n = pos->next; 1; }) && \
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
pos = n)
#endif

View file

@ -1,2 +0,0 @@
boa-patches/series
boa-*.*

View file

@ -1,52 +0,0 @@
include ../../build/config.mk
include ../../build/gccconfig.mk
include ../../build/module.mk
BOA_VERSION = 0.94.13
BOA_SITE = http://www.boa.org
BOA_DIR = boa-$(BOA_VERSION)
BOA_FILE = $(BOA_DIR).tar.gz
BOA_URL = $(BOA_SITE)/$(BOA_FILE)
BOA_PATCHDIR = boa-patches
$(BOA_FILE):
wget -O $@ $(BOA_URL) || rm -f $@
$(BOA_PATCHDIR)/series:
(cd $(BOA_PATCHDIR); ls *.patch | sort > series)
$(BOA_DIR)/.prepared: $(BOA_FILE)
rm -rf $(BOA_DIR)
tar xvfz $(BOA_FILE)
ln -s ../$(BOA_PATCHDIR) $(BOA_DIR)/patches
touch $@
$(BOA_DIR)/.patched: $(BOA_DIR)/.prepared $(BOA_PATCHDIR)/series
(cd $(BOA_DIR); \
if [ -x "$$(which quilt 2>/dev/null)" ]; then \
[ "$$(quilt top 2>/dev/null)" = "$$(tail -n1 patches/series)" ] || quilt push -a; \
else \
cat patches/*.patch | patch -p1; \
fi; \
)
touch $@
$(BOA_DIR)/.configured: $(BOA_DIR)/.patched
(cd $(BOA_DIR)/src; ./configure --disable-debug)
touch $@
boa-compile: $(BOA_DIR)/.configured
$(MAKE) -C $(BOA_DIR)/src CC=$(CC) CFLAGS="$(CFLAGS) -DINET6 -DACCEPT_ON -DWHEN_DOES_THIS_APPLY"
%.o: %.c
$(COMPILE) $(LUA_CFLAGS) -I$(BOA_DIR)/src $(FPIC) -c -o $@ $<
compile: boa-compile src/luci.o src/cgi.o
mkdir -p dist/usr/bin dist/usr/lib/boa
cp $(BOA_DIR)/src/boa $(BOA_DIR)/src/boa_indexer dist/usr/bin
$(LINK) $(SHLIB_FLAGS) -o dist/usr/lib/boa/luci.so src/luci.o src/cgi.o $(LDFLAGS) $(LUA_LIBS)
clean:
rm -rf $(BOA_DIR) $(BOA_FILE)
rm -f boa-patches/series
rm -f src/*.o

View file

@ -1,22 +0,0 @@
diff -urN boa-0.94.13/src/util.c boa/src/util.c
--- boa-0.94.13/src/util.c 2002-07-08 01:22:18.000000000 +0200
+++ boa/src/util.c 2008-04-25 21:56:20.000000000 +0200
@@ -95,14 +95,9 @@
static char buf[30];
int time_offset;
- if (use_localtime) {
- t = localtime(&current_time);
- time_offset = TIMEZONE_OFFSET(t);
- } else {
- t = gmtime(&current_time);
- time_offset = 0;
- }
-
+ t = gmtime(&current_time);
+ time_offset = 0;
+
p = buf + 29;
*p-- = '\0';
*p-- = ' ';

View file

@ -1,22 +0,0 @@
Index: boa-0.94.13/src/config.c
===================================================================
--- boa-0.94.13.orig/src/config.c 2008-06-29 00:55:19.000000000 +0200
+++ boa-0.94.13/src/config.c 2008-06-29 00:59:08.000000000 +0200
@@ -273,12 +273,12 @@
}
he = gethostbyname(temp_name);
- if (he == NULL) {
- perror("gethostbyname:");
- exit(1);
- }
+ if (he && he->h_name)
+ server_name = he->h_name;
+ else
+ server_name = "OpenWrt";
- server_name = strdup(he->h_name);
+ server_name = strdup(server_name);
if (server_name == NULL) {
perror("strdup:");
exit(1);

View file

@ -1,13 +0,0 @@
Index: boa-0.94.13/src/boa.c
===================================================================
--- boa-0.94.13.orig/src/boa.c 2002-07-23 17:50:29.000000000 +0200
+++ boa-0.94.13/src/boa.c 2008-06-29 01:12:31.000000000 +0200
@@ -222,7 +222,7 @@
/* test for failed-but-return-was-successful setuid
* http://www.securityportal.com/list-archive/bugtraq/2000/Jun/0101.html
*/
- if (setuid(0) != -1) {
+ if ((server_uid != 0) && (setuid(0) != -1)) {
DIE("icky Linux kernel bug!");
}
} else {

File diff suppressed because it is too large Load diff

View file

@ -1,15 +0,0 @@
Index: boa-0.94.13/src/request.c
===================================================================
--- boa-0.94.13.orig/src/request.c 2008-06-29 01:11:52.000000000 +0200
+++ boa-0.94.13/src/request.c 2008-10-07 18:10:59.000000000 +0200
@@ -281,6 +281,10 @@
if (req->script_name)
free(req->script_name);
+#ifdef ACCEPT_ON
+ req->accept[0] = '\0';
+#endif
+
if ((req->keepalive == KA_ACTIVE) &&
(req->response_status < 500) && req->kacount > 0) {
int bytes_to_move;

View file

@ -1,257 +0,0 @@
diff -urN boa-0.94.13.orig/src/boa.c boa-0.94.13/src/boa.c
--- boa-0.94.13.orig/src/boa.c 2008-10-28 16:15:45.000000000 +0100
+++ boa-0.94.13/src/boa.c 2008-10-28 15:56:27.000000000 +0100
@@ -27,6 +27,12 @@
#include <sys/resource.h>
/* globals */
+
+#ifdef INET6
+int server_addr_family;
+socklen_t server_addr_len;
+#endif
+
int backlog = SO_MAXCONN;
time_t start_time;
@@ -164,14 +170,36 @@
return 0;
}
+#ifdef INET6
+sa_family_t *get_addr_family(struct sockaddr *address)
+{
+ if(server_addr_family == AF_INET6) {
+ return &(((struct sockaddr_in6 *) address)->sin6_family);
+ }
+
+ return &(((struct sockaddr_in *) address)->sin_family);
+}
+#endif
+
static int create_server_socket(void)
{
int server_s;
- server_s = socket(SERVER_AF, SOCK_STREAM, IPPROTO_TCP);
+#ifdef INET6
+ server_addr_family = AF_INET6;
+ server_addr_len = sizeof(struct sockaddr_in6);
+ server_s = socket(server_addr_family, SOCK_STREAM, IPPROTO_TCP);
if (server_s == -1) {
- DIE("unable to create socket");
+ server_addr_family = AF_INET;
+ server_addr_len = sizeof(struct sockaddr_in);
+#endif
+ server_s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (server_s == -1) {
+ DIE("unable to create socket");
+ }
+#ifdef INET6
}
+#endif
/* server socket is nonblocking */
if (set_nonblock_fd(server_s) == -1) {
diff -urN boa-0.94.13.orig/src/boa.h boa-0.94.13/src/boa.h
--- boa-0.94.13.orig/src/boa.h 2008-10-28 16:15:58.000000000 +0100
+++ boa-0.94.13/src/boa.h 2008-10-28 14:45:52.000000000 +0100
@@ -199,4 +199,12 @@
int plugin_handle(request * req);
struct httpd_plugin *plugin_lookup(request *req);
+/* IPv6 */
+
+#ifdef INET6
+extern int server_addr_family;
+extern socklen_t server_addr_len;
+sa_family_t *get_addr_family(struct sockaddr *address);
+#endif
+
#endif
diff -urN boa-0.94.13.orig/src/compat.h boa-0.94.13/src/compat.h
--- boa-0.94.13.orig/src/compat.h 2002-06-06 07:02:28.000000000 +0200
+++ boa-0.94.13/src/compat.h 2008-10-28 15:31:16.000000000 +0100
@@ -71,11 +71,13 @@
#ifdef INET6
#define SOCKADDR sockaddr_storage
-#define S_FAMILY __s_family
-#define SERVER_AF AF_INET6
+#define SOCKADDR_LEN server_addr_len
+#define S_FAMILY(address) (*get_addr_family((struct sockaddr *) (address)))
+#define SERVER_AF server_addr_family
#else
#define SOCKADDR sockaddr_in
-#define S_FAMILY sin_family
+#define SOCKADDR_LEN sizeof(struct sockaddr_in)
+#define S_FAMILY(address) ((*address).sin_family)
#define SERVER_AF AF_INET
#endif
diff -urN boa-0.94.13.orig/src/ip.c boa-0.94.13/src/ip.c
--- boa-0.94.13.orig/src/ip.c 2002-01-21 03:19:16.000000000 +0100
+++ boa-0.94.13/src/ip.c 2008-10-28 15:52:05.000000000 +0100
@@ -44,52 +44,64 @@
#include "boa.h"
#include <arpa/inet.h> /* inet_ntoa */
+#include <netinet/in.h>
/* Binds to the existing server_s, based on the configuration string
in server_ip. IPv6 version doesn't pay attention to server_ip yet. */
int bind_server(int server_s, char *server_ip)
{
+ struct sockaddr *server_sockaddr;
+ struct sockaddr_in server_sockaddr4;
+
#ifdef INET6
- struct sockaddr_in6 server_sockaddr;
- server_sockaddr.sin6_family = AF_INET6;
- memcpy(&server_sockaddr.sin6_addr, &in6addr_any, sizeof (in6addr_any));
- server_sockaddr.sin6_port = htons(server_port);
-#else
- struct sockaddr_in server_sockaddr;
- memset(&server_sockaddr, 0, sizeof server_sockaddr);
+ struct sockaddr_in6 server_sockaddr6;
+ if(SERVER_AF == AF_INET6) {
+ server_sockaddr6.sin6_family = AF_INET6;
+ memcpy(&server_sockaddr6.sin6_addr, &in6addr_any, sizeof (in6addr_any));
+ server_sockaddr6.sin6_port = htons(server_port);
+ server_sockaddr = (struct sockaddr *) &server_sockaddr6;
+ } else {
+#endif
+ memset(&server_sockaddr4, 0, SOCKADDR_LEN);
#ifdef HAVE_SIN_LEN /* uncomment for BSDs */
- server_sockaddr.sin_len = sizeof server_sockaddr;
+ server_sockaddr4.sin_len = SOCKADDR_LEN;
#endif
- server_sockaddr.sin_family = AF_INET;
- if (server_ip != NULL) {
- inet_aton(server_ip, &server_sockaddr.sin_addr);
- } else {
- server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ server_sockaddr4.sin_family = AF_INET;
+ if (server_ip != NULL) {
+ inet_aton(server_ip, &server_sockaddr4.sin_addr);
+ } else {
+ server_sockaddr4.sin_addr.s_addr = htonl(INADDR_ANY);
+ }
+ server_sockaddr4.sin_port = htons(server_port);
+ server_sockaddr = (struct sockaddr *) &server_sockaddr4;
+#ifdef INET6
}
- server_sockaddr.sin_port = htons(server_port);
#endif
- return bind(server_s, (struct sockaddr *) &server_sockaddr,
- sizeof (server_sockaddr));
+ return bind(server_s, server_sockaddr, SOCKADDR_LEN);
}
char *ascii_sockaddr(struct SOCKADDR *s, char *dest, int len)
{
#ifdef INET6
- if (getnameinfo((struct sockaddr *) s,
- sizeof(struct SOCKADDR),
- dest, len, NULL, 0, NI_NUMERICHOST)) {
- fprintf(stderr, "[IPv6] getnameinfo failed\n");
- *dest = '\0';
- }
+ if(SERVER_AF == AF_INET6) {
+ if (getnameinfo((struct sockaddr *) s,
+ SOCKADDR_LEN,
+ dest, len, NULL, 0, NI_NUMERICHOST)) {
+ fprintf(stderr, "[IPv6] getnameinfo failed\n");
+ *dest = '\0';
+ }
#ifdef WHEN_DOES_THIS_APPLY
- if ((s->__ss_family == AF_INET6) &&
- IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *) s)->sin6_addr))) {
- memmove(dest, dest+7, NI_MAXHOST);
- }
+ if (((((struct sockaddr_in6 *) s)->sin6_family) == AF_INET6) &&
+ IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *) s)->sin6_addr))) {
+ memmove(dest, dest+7, NI_MAXHOST);
+ }
#endif
-#else
- memmove(dest, inet_ntoa(s->sin_addr), len);
+ } else {
+#endif
+ memmove(dest, inet_ntoa(((struct sockaddr_in *) s)->sin_addr), len);
+#ifdef INET6
+ }
#endif
return dest;
}
@@ -98,17 +110,21 @@
{
int p = -1;
#ifdef INET6
- char serv[NI_MAXSERV];
+ if(SERVER_AF == AF_INET6) {
+ char serv[NI_MAXSERV];
- if (getnameinfo((struct sockaddr *) s,
- sizeof(struct SOCKADDR),
- NULL, 0, serv, sizeof(serv), NI_NUMERICSERV)) {
- fprintf(stderr, "[IPv6] getnameinfo failed\n");
+ if (getnameinfo((struct sockaddr *) s,
+ SOCKADDR_LEN,
+ NULL, 0, serv, sizeof(serv), NI_NUMERICSERV)) {
+ fprintf(stderr, "[IPv6] getnameinfo failed\n");
+ } else {
+ p = atoi(serv);
+ }
} else {
- p = atoi(serv);
+#endif
+ p = ntohs(((struct sockaddr_in *) s)->sin_port);
+#ifdef INET6
}
-#else
- p = ntohs(s->sin_port);
#endif
return p;
}
diff -urN boa-0.94.13.orig/src/mmap_cache.c boa-0.94.13/src/mmap_cache.c
--- boa-0.94.13.orig/src/mmap_cache.c 2002-03-24 23:35:34.000000000 +0100
+++ boa-0.94.13/src/mmap_cache.c 2008-10-28 14:55:16.000000000 +0100
@@ -67,7 +67,7 @@
m = mmap(0, s->st_size, PROT_READ, MAP_OPTIONS, data_fd, 0);
- if ((int) m == -1) {
+ if ((ssize_t) m == -1) {
/* boa_perror(req,"mmap"); */
return NULL;
}
diff -urN boa-0.94.13.orig/src/request.c boa-0.94.13/src/request.c
--- boa-0.94.13.orig/src/request.c 2008-10-28 16:16:03.000000000 +0100
+++ boa-0.94.13/src/request.c 2008-10-28 15:17:20.000000000 +0100
@@ -75,12 +75,12 @@
int fd; /* socket */
struct SOCKADDR remote_addr; /* address */
struct SOCKADDR salocal;
- int remote_addrlen = sizeof (struct SOCKADDR);
+ int remote_addrlen = SOCKADDR_LEN;
request *conn; /* connection */
- size_t len;
+ socklen_t len;
static int system_bufsize = 0; /* Default size of SNDBUF given by system */
- remote_addr.S_FAMILY = 0xdead;
+ S_FAMILY(&remote_addr) = 0xdead;
fd = accept(server_s, (struct sockaddr *) &remote_addr,
&remote_addrlen);
@@ -133,7 +133,7 @@
}
#endif
- len = sizeof(salocal);
+ len = SOCKADDR_LEN;
if (getsockname(fd, (struct sockaddr *) &salocal, &len) != 0) {
WARN("getsockname");

View file

@ -1,20 +0,0 @@
#!/bin/sh
CWD=$1
cat <<EOF
Port 8080
ErrorLog /dev/stderr
AccessLog /dev/stderr
DocumentRoot $CWD/www
DirectoryMaker $CWD/usr/lib/boa/boa_indexer
KeepAliveMax 1000
KeepAliveTimeout 10
MimeTypes $CWD/etc/mime.types
DefaultType text/plain
CGIPath $CWD/bin:$CWD/usr/bin:$CWD/usr/local/bin
AddType application/x-httpd-cgi cgi
AddType application/x-httpd-cgi sh
ScriptAlias /cgi-bin/ $CWD/www/cgi-bin
PluginRoot $CWD/usr/lib/boa
EOF

View file

@ -1,74 +0,0 @@
--[[
LuCI - SGI-Module for Webuci
Description:
Server Gateway Interface for Webuci
FileId:
$Id$
License:
Copyright 2008 Steven Barth <steven@midlink.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
]]--
module("luci.sgi.webuci", package.seeall)
local ltn12 = require("luci.ltn12")
require("luci.http")
require("luci.util")
require("luci.dispatcher")
function run(env, vars)
local r = luci.http.Request(
env,
ltn12.source.empty(),
ltn12.sink.file(io.stderr)
)
r.message.params = vars
local x = coroutine.create(luci.dispatcher.httpdispatch)
local status = ""
local headers = {}
local active = true
while coroutine.status(x) ~= "dead" do
local res, id, data1, data2 = coroutine.resume(x, r)
if not res then
print(env.SERVER_PROTOCOL .. " 500 Internal Server Error")
print("Content-Type: text/plain\n")
print(id)
break;
end
if active then
if id == 1 then
status = env.SERVER_PROTOCOL .. " " .. tostring(data1) .. " " .. data2 .. "\r\n"
elseif id == 2 then
headers[data1] = data2
elseif id == 3 then
io.write(status)
for k, v in pairs(headers) do
io.write(k .. ": " .. v .. "\r\n")
end
io.write("\r\n")
elseif id == 4 then
io.write(data1)
elseif id == 5 then
active = false
end
end
end
end

View file

@ -1,17 +0,0 @@
Port 80
ErrorLog /dev/stderr
AccessLog /dev/stderr
DocumentRoot /www
DirectoryMaker /usr/lib/boa/boa_indexer
KeepAliveMax 1000
KeepAliveTimeout 10
MimeTypes /etc/mime.types
DefaultType text/plain
ServerName localhost
CGIPath /bin:/usr/bin
AddType application/x-httpd-cgi cgi
AddType application/x-httpd-cgi sh
ScriptAlias /cgi-bin/ /www/cgi-bin
PluginRoot /usr/lib/boa

View file

@ -1,57 +0,0 @@
#!/bin/sh /etc/rc.common
#
# Written by Miquel van Smoorenburg <miquels@cistron.nl>.
# Modified for Debian GNU/Linux
# by Ian Murdock <imurdock@gnu.ai.mit.edu>.
# Modified for boa by Bill Allombert <ballombe@debian.org>.
# Modified for OpenWrt by Steven Barth <steven@midlink.org>.
### BEGIN INIT INFO
# Provides: boa
# Required-Start: $local_fs $remote_fs $network
# Required-Stop: $local_fs $remote_fs $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Boa: lightweight and high performance web server
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/boa
NAME=boa
DESC="HTTP server"
START=49
test -x $DAEMON || exit 0
set -e
start() {
echo -n "Starting $DESC: $NAME"
start-stop-daemon -S -q -x $DAEMON
echo "."
}
stop() {
echo -n "Stopping $DESC: $NAME"
start-stop-daemon -K -q -x $DAEMON
echo "."
}
restart() {
echo -n "Restarting $DESC: $NAME... "
start-stop-daemon -K -s HUP -q -x $DAEMON
echo "done."
}
reload() {
#
# If the daemon can reload its config files on the fly
# for example by sending it SIGHUP, do it here.
#
# If the daemon responds to changes in its config file
# directly anyway, make this a do-nothing entry.
#
echo -n "Reloading $DESC configuration... "
start-stop-daemon -K -s 1 -q -x $DAEMON
echo "done."
}

View file

@ -1,748 +0,0 @@
###############################################################################
#
# MIME-TYPES and the extensions that represent them
#
# This file is part of the "mime-support" package. Please send email (not a
# bug report) to mime-support@packages.debian.org if you would like new types
# and/or extensions to be added.
#
# The reason that all types are managed by the mime-support package instead
# allowing individual packages to install types in much the same way as they
# add entries in to the mailcap file is so these types can be referenced by
# other programs (such as a web server) even if the specific support package
# for that type is not installed.
#
# Users can add their own types if they wish by creating a ".mime.types"
# file in their home directory. Definitions included there will take
# precedence over those listed here.
#
# Note: Compression schemes like "gzip", "bzip", and "compress" are not
# actually "mime-types". They are "encodings" and hence must _not_ have
# entries in this file to map their extensions. The "mime-type" of an
# encoded file refers to the type of data that has been encoded, not the
# type of encoding.
#
###############################################################################
application/activemessage
application/andrew-inset ez
application/applefile
application/atom atom
application/atomcat+xml atomcat
application/atomserv+xml atomsrv
application/atomicmail
application/batch-SMTP
application/beep+xml
application/cals-1840
application/cap cap pcap
application/commonground
application/cu-seeme cu
application/cybercash
application/dca-rft
application/dec-dx
application/docbook+xml
application/dsptype tsp
application/dvcs
application/edi-consent
application/edi-x12
application/edifact
application/eshop
application/font-tdpfr
application/futuresplash spl
application/ghostview
application/hta hta
application/http
application/hyperstudio
application/iges
application/index
application/index.cmd
application/index.obj
application/index.response
application/index.vnd
application/iotp
application/ipp
application/isup
application/java-archive jar
application/java-serialized-object ser
application/java-vm class
application/mac-binhex40 hqx
application/mac-compactpro cpt
application/macwriteii
application/marc
application/mathematica nb
application/mathematica-old
application/ms-tnef
application/msaccess mdb
application/msword doc dot
application/news-message-id
application/news-transmission
application/ocsp-request
application/ocsp-response
application/octet-stream bin
application/oda oda
application/ogg ogg
application/parityfec
application/pdf pdf
application/pgp-encrypted
application/pgp-keys key
application/pgp-signature pgp
application/pics-rules prf
application/pkcs10
application/pkcs7-mime
application/pkcs7-signature
application/pkix-cert
application/pkix-crl
application/pkixcmp
application/postscript ps ai eps
application/prs.alvestrand.titrax-sheet
application/prs.cww
application/prs.nprend
application/qsig
application/rar rar
application/rdf+xml rdf
application/remote-printing
application/riscos
application/rss+xml rss
application/rtf rtf
application/sdp
application/set-payment
application/set-payment-initiation
application/set-registration
application/set-registration-initiation
application/sgml
application/sgml-open-catalog
application/sieve
application/slate
application/smil smi smil
application/timestamp-query
application/timestamp-reply
application/vemmi
application/whoispp-query
application/whoispp-response
application/wita
application/wordperfect wpd
application/wordperfect5.1 wp5
application/x400-bp
application/xhtml+xml xhtml xht
application/xml xml xsl
application/xml-dtd
application/xml-external-parsed-entity
application/zip zip
application/vnd.3M.Post-it-Notes
application/vnd.accpac.simply.aso
application/vnd.accpac.simply.imp
application/vnd.acucobol
application/vnd.aether.imp
application/vnd.anser-web-certificate-issue-initiation
application/vnd.anser-web-funds-transfer-initiation
application/vnd.audiograph
application/vnd.bmi
application/vnd.businessobjects
application/vnd.canon-cpdl
application/vnd.canon-lips
application/vnd.cinderella cdy
application/vnd.claymore
application/vnd.commerce-battelle
application/vnd.commonspace
application/vnd.comsocaller
application/vnd.contact.cmsg
application/vnd.cosmocaller
application/vnd.ctc-posml
application/vnd.cups-postscript
application/vnd.cups-raster
application/vnd.cups-raw
application/vnd.cybank
application/vnd.dna
application/vnd.dpgraph
application/vnd.dxr
application/vnd.ecdis-update
application/vnd.ecowin.chart
application/vnd.ecowin.filerequest
application/vnd.ecowin.fileupdate
application/vnd.ecowin.series
application/vnd.ecowin.seriesrequest
application/vnd.ecowin.seriesupdate
application/vnd.enliven
application/vnd.epson.esf
application/vnd.epson.msf
application/vnd.epson.quickanime
application/vnd.epson.salt
application/vnd.epson.ssf
application/vnd.ericsson.quickcall
application/vnd.eudora.data
application/vnd.fdf
application/vnd.ffsns
application/vnd.flographit
application/vnd.framemaker
application/vnd.fsc.weblaunch
application/vnd.fujitsu.oasys
application/vnd.fujitsu.oasys2
application/vnd.fujitsu.oasys3
application/vnd.fujitsu.oasysgp
application/vnd.fujitsu.oasysprs
application/vnd.fujixerox.ddd
application/vnd.fujixerox.docuworks
application/vnd.fujixerox.docuworks.binder
application/vnd.fut-misnet
application/vnd.google-earth.kml+xml kml
application/vnd.google-earth.kmz kmz
application/vnd.grafeq
application/vnd.groove-account
application/vnd.groove-identity-message
application/vnd.groove-injector
application/vnd.groove-tool-message
application/vnd.groove-tool-template
application/vnd.groove-vcard
application/vnd.hhe.lesson-player
application/vnd.hp-HPGL
application/vnd.hp-PCL
application/vnd.hp-PCLXL
application/vnd.hp-hpid
application/vnd.hp-hps
application/vnd.httphone
application/vnd.hzn-3d-crossword
application/vnd.ibm.MiniPay
application/vnd.ibm.afplinedata
application/vnd.ibm.modcap
application/vnd.informix-visionary
application/vnd.intercon.formnet
application/vnd.intertrust.digibox
application/vnd.intertrust.nncp
application/vnd.intu.qbo
application/vnd.intu.qfx
application/vnd.irepository.package+xml
application/vnd.is-xpr
application/vnd.japannet-directory-service
application/vnd.japannet-jpnstore-wakeup
application/vnd.japannet-payment-wakeup
application/vnd.japannet-registration
application/vnd.japannet-registration-wakeup
application/vnd.japannet-setstore-wakeup
application/vnd.japannet-verification
application/vnd.japannet-verification-wakeup
application/vnd.koan
application/vnd.lotus-1-2-3
application/vnd.lotus-approach
application/vnd.lotus-freelance
application/vnd.lotus-notes
application/vnd.lotus-organizer
application/vnd.lotus-screencam
application/vnd.lotus-wordpro
application/vnd.mcd
application/vnd.mediastation.cdkey
application/vnd.meridian-slingshot
application/vnd.mif
application/vnd.minisoft-hp3000-save
application/vnd.mitsubishi.misty-guard.trustweb
application/vnd.mobius.daf
application/vnd.mobius.dis
application/vnd.mobius.msl
application/vnd.mobius.plc
application/vnd.mobius.txf
application/vnd.motorola.flexsuite
application/vnd.motorola.flexsuite.adsi
application/vnd.motorola.flexsuite.fis
application/vnd.motorola.flexsuite.gotap
application/vnd.motorola.flexsuite.kmr
application/vnd.motorola.flexsuite.ttc
application/vnd.motorola.flexsuite.wem
application/vnd.mozilla.xul+xml xul
application/vnd.ms-artgalry
application/vnd.ms-asf
application/vnd.ms-excel xls xlb xlt
application/vnd.ms-lrm
application/vnd.ms-pki.seccat cat
application/vnd.ms-pki.stl stl
application/vnd.ms-powerpoint ppt pps
application/vnd.ms-project
application/vnd.ms-tnef
application/vnd.ms-works
application/vnd.mseq
application/vnd.msign
application/vnd.music-niff
application/vnd.musician
application/vnd.netfpx
application/vnd.noblenet-directory
application/vnd.noblenet-sealer
application/vnd.noblenet-web
application/vnd.novadigm.EDM
application/vnd.novadigm.EDX
application/vnd.novadigm.EXT
application/vnd.oasis.opendocument.chart odc
application/vnd.oasis.opendocument.database odb
application/vnd.oasis.opendocument.formula odf
application/vnd.oasis.opendocument.graphics odg
application/vnd.oasis.opendocument.graphics-template otg
application/vnd.oasis.opendocument.image odi
application/vnd.oasis.opendocument.presentation odp
application/vnd.oasis.opendocument.presentation-template otp
application/vnd.oasis.opendocument.spreadsheet ods
application/vnd.oasis.opendocument.spreadsheet-template ots
application/vnd.oasis.opendocument.text odt
application/vnd.oasis.opendocument.text-master odm
application/vnd.oasis.opendocument.text-template ott
application/vnd.oasis.opendocument.text-web oth
application/vnd.osa.netdeploy
application/vnd.palm
application/vnd.pg.format
application/vnd.pg.osasli
application/vnd.powerbuilder6
application/vnd.powerbuilder6-s
application/vnd.powerbuilder7
application/vnd.powerbuilder7-s
application/vnd.powerbuilder75
application/vnd.powerbuilder75-s
application/vnd.previewsystems.box
application/vnd.publishare-delta-tree
application/vnd.pvi.ptid1
application/vnd.pwg-xhtml-print+xml
application/vnd.rapid
application/vnd.rim.cod cod
application/vnd.s3sms
application/vnd.seemail
application/vnd.shana.informed.formdata
application/vnd.shana.informed.formtemplate
application/vnd.shana.informed.interchange
application/vnd.shana.informed.package
application/vnd.smaf mmf
application/vnd.sss-cod
application/vnd.sss-dtf
application/vnd.sss-ntf
application/vnd.stardivision.calc sdc
application/vnd.stardivision.chart sds
application/vnd.stardivision.draw sda
application/vnd.stardivision.impress sdd
application/vnd.stardivision.math sdf
application/vnd.stardivision.writer sdw
application/vnd.stardivision.writer-global sgl
application/vnd.street-stream
application/vnd.sun.xml.calc sxc
application/vnd.sun.xml.calc.template stc
application/vnd.sun.xml.draw sxd
application/vnd.sun.xml.draw.template std
application/vnd.sun.xml.impress sxi
application/vnd.sun.xml.impress.template sti
application/vnd.sun.xml.math sxm
application/vnd.sun.xml.writer sxw
application/vnd.sun.xml.writer.global sxg
application/vnd.sun.xml.writer.template stw
application/vnd.svd
application/vnd.swiftview-ics
application/vnd.symbian.install sis
application/vnd.triscape.mxs
application/vnd.trueapp
application/vnd.truedoc
application/vnd.tve-trigger
application/vnd.ufdl
application/vnd.uplanet.alert
application/vnd.uplanet.alert-wbxml
application/vnd.uplanet.bearer-choice
application/vnd.uplanet.bearer-choice-wbxml
application/vnd.uplanet.cacheop
application/vnd.uplanet.cacheop-wbxml
application/vnd.uplanet.channel
application/vnd.uplanet.channel-wbxml
application/vnd.uplanet.list
application/vnd.uplanet.list-wbxml
application/vnd.uplanet.listcmd
application/vnd.uplanet.listcmd-wbxml
application/vnd.uplanet.signal
application/vnd.vcx
application/vnd.vectorworks
application/vnd.vidsoft.vidconference
application/vnd.visio vsd
application/vnd.vividence.scriptfile
application/vnd.wap.sic
application/vnd.wap.slc
application/vnd.wap.wbxml wbxml
application/vnd.wap.wmlc wmlc
application/vnd.wap.wmlscriptc wmlsc
application/vnd.webturbo
application/vnd.wrq-hp3000-labelled
application/vnd.wt.stf
application/vnd.xara
application/vnd.xfdl
application/vnd.yellowriver-custom-menu
application/x-123 wk
application/x-7z-compressed 7z
application/x-abiword abw
application/x-apple-diskimage dmg
application/x-bcpio bcpio
application/x-bittorrent torrent
application/x-cab cab
application/x-cbr cbr
application/x-cbz cbz
application/x-cdf cdf
application/x-cdlink vcd
application/x-chess-pgn pgn
application/x-core
application/x-cpio cpio
application/x-csh csh
application/x-debian-package deb udeb
application/x-director dcr dir dxr
application/x-dms dms
application/x-doom wad
application/x-dvi dvi
application/x-httpd-eruby rhtml
application/x-executable
application/x-flac flac
application/x-font pfa pfb gsf pcf pcf.Z
application/x-freemind mm
application/x-futuresplash spl
application/x-gnumeric gnumeric
application/x-go-sgf sgf
application/x-graphing-calculator gcf
application/x-gtar gtar tgz taz
application/x-hdf hdf
application/x-httpd-php phtml pht php
application/x-httpd-php-source phps
application/x-httpd-php3 php3
application/x-httpd-php3-preprocessed php3p
application/x-httpd-php4 php4
application/x-ica ica
application/x-internet-signup ins isp
application/x-iphone iii
application/x-iso9660-image iso
application/x-java-applet
application/x-java-bean
application/x-java-jnlp-file jnlp
application/x-javascript js
application/x-jmol jmz
application/x-kchart chrt
application/x-kdelnk
application/x-killustrator kil
application/x-koan skp skd skt skm
application/x-kpresenter kpr kpt
application/x-kspread ksp
application/x-kword kwd kwt
application/x-latex latex
application/x-lha lha
application/x-lyx lyx
application/x-lzh lzh
application/x-lzx lzx
application/x-maker frm maker frame fm fb book fbdoc
application/x-mif mif
application/x-ms-wmd wmd
application/x-ms-wmz wmz
application/x-msdos-program com exe bat dll
application/x-msi msi
application/x-netcdf nc
application/x-ns-proxy-autoconfig pac
application/x-nwc nwc
application/x-object o
application/x-oz-application oza
application/x-pkcs7-certreqresp p7r
application/x-pkcs7-crl crl
application/x-python-code pyc pyo
application/x-quicktimeplayer qtl
application/x-redhat-package-manager rpm
application/x-rx
application/x-sh sh
application/x-shar shar
application/x-shellscript
application/x-shockwave-flash swf swfl
application/x-stuffit sit sitx
application/x-sv4cpio sv4cpio
application/x-sv4crc sv4crc
application/x-tar tar
application/x-tcl tcl
application/x-tex-gf gf
application/x-tex-pk pk
application/x-texinfo texinfo texi
application/x-trash ~ % bak old sik
application/x-troff t tr roff
application/x-troff-man man
application/x-troff-me me
application/x-troff-ms ms
application/x-ustar ustar
application/x-videolan
application/x-wais-source src
application/x-wingz wz
application/x-x509-ca-cert crt
application/x-xcf xcf
application/x-xfig fig
application/x-xpinstall xpi
audio/32kadpcm
audio/3gpp
audio/basic au snd
audio/g.722.1
audio/l16
audio/midi mid midi kar
audio/mp4a-latm
audio/mpa-robust
audio/mpeg mpga mpega mp2 mp3 m4a
audio/mpegurl m3u
audio/parityfec
audio/prs.sid sid
audio/telephone-event
audio/tone
audio/vnd.cisco.nse
audio/vnd.cns.anp1
audio/vnd.cns.inf1
audio/vnd.digital-winds
audio/vnd.everad.plj
audio/vnd.lucent.voice
audio/vnd.nortel.vbk
audio/vnd.nuera.ecelp4800
audio/vnd.nuera.ecelp7470
audio/vnd.nuera.ecelp9600
audio/vnd.octel.sbc
audio/vnd.qcelp
audio/vnd.rhetorex.32kadpcm
audio/vnd.vmx.cvsd
audio/x-aiff aif aiff aifc
audio/x-gsm gsm
audio/x-mpegurl m3u
audio/x-ms-wma wma
audio/x-ms-wax wax
audio/x-pn-realaudio-plugin
audio/x-pn-realaudio ra rm ram
audio/x-realaudio ra
audio/x-scpls pls
audio/x-sd2 sd2
audio/x-wav wav
chemical/x-alchemy alc
chemical/x-cache cac cache
chemical/x-cache-csf csf
chemical/x-cactvs-binary cbin cascii ctab
chemical/x-cdx cdx
chemical/x-cerius cer
chemical/x-chem3d c3d
chemical/x-chemdraw chm
chemical/x-cif cif
chemical/x-cmdf cmdf
chemical/x-cml cml
chemical/x-compass cpa
chemical/x-crossfire bsd
chemical/x-csml csml csm
chemical/x-ctx ctx
chemical/x-cxf cxf cef
#chemical/x-daylight-smiles smi
chemical/x-embl-dl-nucleotide emb embl
chemical/x-galactic-spc spc
chemical/x-gamess-input inp gam gamin
chemical/x-gaussian-checkpoint fch fchk
chemical/x-gaussian-cube cub
chemical/x-gaussian-input gau gjc gjf
chemical/x-gaussian-log gal
chemical/x-gcg8-sequence gcg
chemical/x-genbank gen
chemical/x-hin hin
chemical/x-isostar istr ist
chemical/x-jcamp-dx jdx dx
chemical/x-kinemage kin
chemical/x-macmolecule mcm
chemical/x-macromodel-input mmd mmod
chemical/x-mdl-molfile mol
chemical/x-mdl-rdfile rd
chemical/x-mdl-rxnfile rxn
chemical/x-mdl-sdfile sd sdf
chemical/x-mdl-tgf tgf
#chemical/x-mif mif
chemical/x-mmcif mcif
chemical/x-mol2 mol2
chemical/x-molconn-Z b
chemical/x-mopac-graph gpt
chemical/x-mopac-input mop mopcrt mpc dat zmt
chemical/x-mopac-out moo
chemical/x-mopac-vib mvb
chemical/x-ncbi-asn1 asn
chemical/x-ncbi-asn1-ascii prt ent
chemical/x-ncbi-asn1-binary val aso
chemical/x-ncbi-asn1-spec asn
chemical/x-pdb pdb ent
chemical/x-rosdal ros
chemical/x-swissprot sw
chemical/x-vamas-iso14976 vms
chemical/x-vmd vmd
chemical/x-xtel xtel
chemical/x-xyz xyz
image/cgm
image/g3fax
image/gif gif
image/ief ief
image/jpeg jpeg jpg jpe
image/naplps
image/pcx pcx
image/png png
image/prs.btif
image/prs.pti
image/svg+xml svg svgz
image/tiff tiff tif
image/vnd.cns.inf2
image/vnd.djvu djvu djv
image/vnd.dwg
image/vnd.dxf
image/vnd.fastbidsheet
image/vnd.fpx
image/vnd.fst
image/vnd.fujixerox.edmics-mmr
image/vnd.fujixerox.edmics-rlc
image/vnd.mix
image/vnd.net-fpx
image/vnd.svf
image/vnd.wap.wbmp wbmp
image/vnd.xiff
image/x-cmu-raster ras
image/x-coreldraw cdr
image/x-coreldrawpattern pat
image/x-coreldrawtemplate cdt
image/x-corelphotopaint cpt
image/x-icon ico
image/x-jg art
image/x-jng jng
image/x-ms-bmp bmp
image/x-photoshop psd
image/x-portable-anymap pnm
image/x-portable-bitmap pbm
image/x-portable-graymap pgm
image/x-portable-pixmap ppm
image/x-rgb rgb
image/x-xbitmap xbm
image/x-xpixmap xpm
image/x-xwindowdump xwd
inode/chardevice
inode/blockdevice
inode/directory-locked
inode/directory
inode/fifo
inode/socket
message/delivery-status
message/disposition-notification
message/external-body
message/http
message/s-http
message/news
message/partial
message/rfc822 eml
model/iges igs iges
model/mesh msh mesh silo
model/vnd.dwf
model/vnd.flatland.3dml
model/vnd.gdl
model/vnd.gs-gdl
model/vnd.gtw
model/vnd.mts
model/vnd.vtu
model/vrml wrl vrml
multipart/alternative
multipart/appledouble
multipart/byteranges
multipart/digest
multipart/encrypted
multipart/form-data
multipart/header-set
multipart/mixed
multipart/parallel
multipart/related
multipart/report
multipart/signed
multipart/voice-message
text/calendar ics icz
text/css css
text/csv csv
text/directory
text/english
text/enriched
text/h323 323
text/html html htm shtml
text/iuls uls
text/mathml mml
text/parityfec
text/plain asc txt text pot
text/prs.lines.tag
text/rfc822-headers
text/richtext rtx
text/rtf
text/scriptlet sct wsc
text/t140
text/texmacs tm ts
text/tab-separated-values tsv
text/uri-list
text/vnd.abc
text/vnd.curl
text/vnd.DMClientScript
text/vnd.flatland.3dml
text/vnd.fly
text/vnd.fmi.flexstor
text/vnd.in3d.3dml
text/vnd.in3d.spot
text/vnd.IPTC.NewsML
text/vnd.IPTC.NITF
text/vnd.latex-z
text/vnd.motorola.reflex
text/vnd.ms-mediapackage
text/vnd.sun.j2me.app-descriptor jad
text/vnd.wap.si
text/vnd.wap.sl
text/vnd.wap.wml wml
text/vnd.wap.wmlscript wmls
text/x-bibtex bib
text/x-boo boo
text/x-c++hdr h++ hpp hxx hh
text/x-c++src c++ cpp cxx cc
text/x-chdr h
text/x-component htc
text/x-crontab
text/x-csh csh
text/x-csrc c
text/x-dsrc d
text/x-diff diff patch
text/x-haskell hs
text/x-java java
text/x-literate-haskell lhs
text/x-makefile
text/x-moc moc
text/x-pascal p pas
text/x-pcs-gcd gcd
text/x-perl pl pm
text/x-python py
text/x-server-parsed-html
text/x-setext etx
text/x-sh sh
text/x-tcl tcl tk
text/x-tex tex ltx sty cls
text/x-vcalendar vcs
text/x-vcard vcf
video/3gpp 3gp
video/dl dl
video/dv dif dv
video/fli fli
video/gl gl
video/mpeg mpeg mpg mpe
video/mp4 mp4
video/quicktime qt mov
video/mp4v-es
video/parityfec
video/pointer
video/vnd.fvt
video/vnd.motorola.video
video/vnd.motorola.videop
video/vnd.mpegurl mxu
video/vnd.mts
video/vnd.nokia.interleaved-multimedia
video/vnd.vivo
video/x-la-asf lsf lsx
video/x-mng mng
video/x-ms-asf asf asx
video/x-ms-wm wm
video/x-ms-wmv wmv
video/x-ms-wmx wmx
video/x-ms-wvx wvx
video/x-msvideo avi
video/x-sgi-movie movie
x-conference/x-cooltalk ice
x-epoc/x-sisx-app sisx
x-world/x-vrml vrm vrml wrl

View file

@ -1,66 +0,0 @@
module("luci-plugin", package.seeall)
function normalize(path)
local newpath
while newpath ~= path do
if (newpath) then
path = newpath
end
newpath = string.gsub(path, "/[^/]+/../", "/")
end
return newpath
end
function init(path)
-- NB: path points to ROOT/usr/lib/boa, change it to /usr/lib/lua
root = normalize(path .. '/../../../')
path = normalize(path .. '/../lua/')
package.cpath = path..'?.so;'..package.cpath
package.path = path..'?.lua;'..package.path
require("luci.dispatcher")
require("luci.sgi.webuci")
require("luci.model.uci")
if (root ~= '/') then
-- Entering dummy mode
luci.model.uci.cursor = function(config, ...)
return uci.cursor(config or root .. "/etc/config", ...)
end
luci.sys.hostname = function() return "" end
luci.sys.loadavg = function() return 0,0,0,0,0 end
luci.sys.reboot = function() return end
luci.sys.sysinfo = function() return "","","" end
luci.sys.syslog = function() return "" end
luci.sys.net.arptable = function() return {} end
luci.sys.net.devices = function() return {} end
luci.sys.net.routes = function() return {} end
luci.sys.wifi.getiwconfig = function() return {} end
luci.sys.wifi.iwscan = function() return {} end
luci.sys.user.checkpasswd = function() return true end
end
end
function prepare_req(uri)
luci.dispatcher.createindex()
env = {}
env.REQUEST_URI = uri
-- TODO: setting luci-plugin.reload = true allows this function to trigger a context reload
end
function handle_req(context)
env.SERVER_PROTOCOL = context.server_proto
env.REMOTE_ADDR = context.remote_addr
env.REQUEST_METHOD = context.request_method
env.PATH_INFO = context.uri
env.REMOTE_PORT = context.remote_port
env.SERVER_ADDR = context.server_addr
env.HTTP_COOKIE = context.cookie
env.HTTP_ACCEPT = context.http_accept
env.SCRIPT_NAME = env.REQUEST_URI:sub(1, #env.REQUEST_URI - #env.PATH_INFO)
luci.sgi.webuci.run(env, vars)
end

View file

@ -1,530 +0,0 @@
/*
* CGI routines for luci
* Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/*
* Based on code from cgilib:
*
* cgi.c - Some simple routines for CGI programming
* Copyright (c) 1996-9,2007,8 Martin Schulze <joey@infodrom.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE 1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <strings.h>
#include <ctype.h>
#include <lauxlib.h>
#define BUFSIZE 128
static char *
cgiGetLine (FILE *stream)
{
static char *line = NULL;
static size_t size = 0;
char buf[BUFSIZE];
char *cp;
if (!line) {
if ((line = (char *)malloc (BUFSIZE)) == NULL)
return NULL;
size = BUFSIZE;
}
line[0] = '\0';
while (!feof (stream)) {
if ((cp = fgets (buf, sizeof (buf), stream)) == NULL)
return NULL;
if (strlen(line)+strlen(buf)+1 > size) {
if ((cp = (char *)realloc (line, size + BUFSIZE)) == NULL)
return line;
size += BUFSIZE;
line = cp;
}
strcat (line, buf);
if (line[strlen(line)-1] == '\n') {
line[strlen(line)-1] = '\0';
if (line[strlen(line)-1] == '\r')
line[strlen(line)-1] = '\0';
return line;
}
}
return NULL;
}
static const char *
luci_getenv(lua_State *L, const char *name)
{
const char *ret;
lua_getfield(L, lua_upvalueindex(2), name);
ret = lua_tostring(L, -1);
lua_pop(L, 1);
return ret;
}
static void
luci_setvar(lua_State *L, const char *name, const char *value, bool append)
{
/* Check if there is an existing value already */
lua_getfield(L, lua_upvalueindex(1), name);
if (lua_isnil(L, -1)) {
/* nope, we're safe - add a new one */
lua_pushstring(L, value);
lua_setfield(L, lua_upvalueindex(1), name);
} else if (lua_istable(L, -1) && append) {
/* it's a table already, but appending is requested
* take the last element and append the new string to it */
int tlast = lua_objlen(L, -1);
lua_rawgeti(L, -1, tlast);
lua_pushstring(L, value);
lua_pushstring(L, "\n");
lua_concat(L, 3);
lua_rawseti(L, -2, tlast);
} else if (lua_istable(L, -1)) {
/* it's a table, which means we already have two
* or more entries, add the next one */
int tnext = lua_objlen(L, -1) + 1; /* next entry */
lua_pushstring(L, value);
luaL_setn(L, -2, tnext);
lua_rawseti(L, -2, tnext);
} else if (lua_isstring(L, -1) && append) {
/* append the new string to the existing variable */
lua_pushstring(L, value);
lua_pushstring(L, "\n");
lua_concat(L, 3);
lua_setfield(L, lua_upvalueindex(1), name);
} else if (lua_isstring(L, -1)) {
/* we're trying to add a variable that already has
* a string value. convert the string value to a
* table and add our new value to the table as well
*/
lua_createtable(L, 2, 0);
lua_pushvalue(L, -2); /* copy of the initial string value */
lua_rawseti(L, -2, 1);
lua_pushstring(L, value);
lua_rawseti(L, -2, 2);
lua_setfield(L, lua_upvalueindex(1), name);
} else {
luaL_error(L, "Invalid table entry type for index '%s'", name);
}
}
char *cgiDecodeString (char *text)
{
char *cp, *xp;
for (cp=text,xp=text; *cp; cp++) {
if (*cp == '%') {
if (strchr("0123456789ABCDEFabcdef", *(cp+1))
&& strchr("0123456789ABCDEFabcdef", *(cp+2))) {
if (islower(*(cp+1)))
*(cp+1) = toupper(*(cp+1));
if (islower(*(cp+2)))
*(cp+2) = toupper(*(cp+2));
*(xp) = (*(cp+1) >= 'A' ? *(cp+1) - 'A' + 10 : *(cp+1) - '0' ) * 16
+ (*(cp+2) >= 'A' ? *(cp+2) - 'A' + 10 : *(cp+2) - '0');
xp++;cp+=2;
}
} else {
*(xp++) = *cp;
}
}
memset(xp, 0, cp-xp);
return text;
}
#if 0
/* cgiReadFile()
*
* Read and save a file fro a multipart request
*/
#include <errno.h>
char *cgiReadFile (FILE *stream, char *boundary)
{
char *crlfboundary, *buf;
size_t boundarylen;
int c;
unsigned int pivot;
char *cp;
char template[]= "/tmp/cgilibXXXXXX";
FILE *tmpfile;
int fd;
boundarylen = strlen(boundary)+3;
if ((crlfboundary = (char *)malloc (boundarylen)) == NULL)
return NULL;
sprintf (crlfboundary, "\r\n%s", boundary);
if ((buf = (char *)malloc (boundarylen)) == NULL) {
free (crlfboundary);
return NULL;
}
memset (buf, 0, boundarylen);
pivot = 0;
if ((fd = mkstemp (template)) == -1) {
free (crlfboundary);
free (buf);
return NULL;
}
if ((tmpfile = fdopen (fd, "w")) == NULL) {
free (crlfboundary);
free (buf);
unlink (template);
return NULL;
}
while (!feof (stream)) {
c = fgetc (stream);
if (c == 0) {
if (strlen (buf)) {
for (cp=buf; *cp; cp++)
putc (*cp, tmpfile);
memset (buf, 0, boundarylen);
pivot = 0;
}
putc (c, tmpfile);
continue;
}
if (strlen (buf)) {
if (crlfboundary[pivot+1] == c) {
buf[++pivot] = c;
if (strlen (buf) == strlen (crlfboundary))
break;
else
continue;
} else {
for (cp=buf; *cp; cp++)
putc (*cp, tmpfile);
memset (buf, 0, boundarylen);
pivot = 0;
}
}
if (crlfboundary[0] == c) {
buf[0] = c;
} else {
fputc (c, tmpfile);
}
}
if (!feof (stream))
fgets (buf, boundarylen, stream);
fclose (tmpfile);
free (crlfboundary);
free (buf);
return strdup (template);
}
#endif
/*
* Decode multipart/form-data
*/
#define MULTIPART_DELTA 5
void luci_parse_multipart (lua_State *L, char *boundary)
{
char *line;
char *cp, *xp;
char *name = NULL, *type = NULL;
char *fname = NULL;
int header = 1;
bool append = false;
while ((line = cgiGetLine (stdin)) != NULL) {
if (!strncmp (line, boundary, strlen(boundary))) {
header = 1;
if (name)
free(name);
if (type)
free(type);
name = NULL;
type = NULL;
append = false;
} else if (header && !name && !strncasecmp (line, "Content-Disposition: form-data; ", 32)) {
if ((cp = strstr (line, "name=\"")) == NULL)
continue;
cp += 6;
if ((xp = strchr (cp, '\"')) == NULL)
continue;
name = malloc(xp-cp + 1);
strncpy(name, cp, xp-cp);
name[xp-cp] = 0;
cgiDecodeString (name);
if ((cp = strstr (line, "filename=\"")) == NULL)
continue;
cp += 10;
if ((xp = strchr (cp, '\"')) == NULL)
continue;
fname = malloc(xp-cp + 1);
strncpy(fname, cp, xp-cp);
fname[xp-cp] = 0;
cgiDecodeString (fname);
} else if (header && !type && !strncasecmp (line, "Content-Type: ", 14)) {
cp = line + 14;
type = strdup (cp);
} else if (header) {
if (!strlen(line)) {
header = 0;
if (fname) {
#if 0
header = 1;
tmpfile = cgiReadFile (stdin, boundary);
if (!tmpfile) {
free (name);
free (fname);
if (type)
free (type);
name = fname = type = NULL;
}
cgiDebugOutput (2, "Wrote %s (%s) to file: %s", name, fname, tmpfile);
if (!strlen (fname)) {
cgiDebugOutput (3, "Found empty filename, removing");
unlink (tmpfile);
free (tmpfile);
free (name);
free (fname);
if (type)
free (type);
name = fname = type = NULL;
} else {
if ((file = (s_file *)malloc (sizeof (s_file))) == NULL) {
cgiDebugOutput (3, "malloc failed, ignoring %s=%s", name, fname);
unlink (tmpfile);
free (tmpfile);
free (name);
free (fname);
if (type)
free (type);
name = fname = type = NULL;
continue;
}
file->name = name;
file->type = type;
file->tmpfile = tmpfile;
if ((cp = rindex (fname, '/')) == NULL)
file->filename = fname;
else {
file->filename = strdup (++cp);
free (fname);
}
name = type = fname = NULL;
if (!files) {
if ((files = (s_file **)malloc(2*sizeof (s_file *))) == NULL) {
cgiDebugOutput (3, "malloc failed, ignoring %s=%s", name, fname);
unlink (tmpfile);
free (tmpfile);
free (name);
name = NULL;
if (type) {
free (type);
type = NULL;
}
free (file->filename);
free (file);
continue;
}
memset (files, 0, 2*sizeof (s_file *));
index = 0;
} else {
for (index=0; files[index]; index++);
if ((tmpf = (s_file **)realloc(files, (index+2)*sizeof (s_file *))) == NULL) {
cgiDebugOutput (3, "realloc failed, ignoring %s=%s", name, fname);
unlink (tmpfile);
free (tmpfile);
free (name);
if (type)
free (type);
free (file->filename);
free (file);
name = type = fname = NULL;
continue;
}
files = tmpf;
memset (files + index, 0, 2*sizeof (s_file *));
}
files[index] = file;
}
#else
free(fname);
fname = NULL;
#endif
}
}
} else {
if (!name)
return;
cgiDecodeString(line);
luci_setvar(L, name, line, append);
if (!append) /* beginning of variable contents */
append = true;
}
}
}
/* parse the request header and store variables
* in the array supplied as function argument 1 on the stack
*/
int luci_parse_header (lua_State *L)
{
int length;
char *line = NULL;
int numargs;
char *cp = NULL, *ip = NULL, *esp = NULL;
const char *ct, *il;
int i;
if (!lua_istable(L, lua_upvalueindex(1)))
luaL_error(L, "Invalid argument");
if (!lua_istable(L, lua_upvalueindex(2)))
luaL_error(L, "Invalid argument");
ct = luci_getenv(L, "content_type");
if (ct) {
ct = cp = strdup(ct);
}
if (cp && strstr(cp, "multipart/form-data") && strstr(cp, "boundary=")) {
cp = strstr(cp, "boundary=") + strlen ("boundary=") - 2;
*cp = *(cp+1) = '-';
luci_parse_multipart(L, cp);
free((char *) ct);
return 0;
}
free((char *) ct);
ct = luci_getenv(L, "request_method");
il = luci_getenv(L, "content_length");
if (!ct) {
fprintf(stderr, "no request method!\n");
return 0;
}
if (!strcmp(ct, "POST")) {
if (il) {
length = atoi(il);
if (length <= 0)
return 0;
line = (char *)malloc (length+2);
if (line)
fgets(line, length+1, stdin);
}
} else if (!strcmp(ct, "GET")) {
ct = luci_getenv(L, "query_string");
if (ct)
esp = strdup(ct);
if (esp && strlen(esp)) {
line = (char *)malloc (strlen(esp)+2);
if (line)
strcpy (line, esp);
}
free(esp);
}
if (!line)
return 0;
/*
* From now on all cgi variables are stored in the variable line
* and look like foo=bar&foobar=barfoo&foofoo=
*/
for (cp=line; *cp; cp++)
if (*cp == '+')
*cp = ' ';
if (strlen(line)) {
for (numargs=1,cp=line; *cp; cp++)
if (*cp == '&' || *cp == ';' ) numargs++;
} else
numargs = 0;
cp = line;
i=0;
while (*cp) {
char *name;
char *value;
if ((ip = (char *)strchr(cp, '&')) != NULL) {
*ip = '\0';
} else if ((ip = (char *)strchr(cp, ';')) != NULL) {
*ip = '\0';
} else
ip = cp + strlen(cp);
if ((esp=(char *)strchr(cp, '=')) == NULL)
goto skip;
if (!strlen(esp))
goto skip;
if (i >= numargs)
goto skip;
esp[0] = 0;
name = cp;
cgiDecodeString (name);
cp = ++esp;
value = cp;
cgiDecodeString (value);
luci_setvar(L, name, value, false);
skip:
cp = ++ip;
}
free(line);
return 0;
}

View file

@ -1,236 +0,0 @@
/*
* luci
* Copyright (C) 2008 John Crispin <blogic@openwrt.org>
* Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <string.h>
#include <stdio.h>
#include <boa-plugin.h>
#include <lauxlib.h>
#include <lualib.h>
#include <stdbool.h>
#include <stdlib.h>
#define LUAMAIN "luci.lua"
static lua_State *L = NULL;
extern int luci_parse_header (lua_State *L);
static lua_State *luci_context_init(struct httpd_plugin *p)
{
char *path = NULL;
lua_State *Lnew;
int ret = 0;
Lnew = luaL_newstate();
if (!Lnew)
goto error;
luaL_openlibs(Lnew);
path = malloc(strlen(p->dir) + sizeof(LUAMAIN) + 2);
strcpy(path, p->dir);
strcat(path, "/" LUAMAIN);
ret = luaL_dofile(Lnew, path);
lua_getfield(Lnew, LUA_GLOBALSINDEX, "luci-plugin");
do {
if (!lua_istable(Lnew, -1)) {
ret = 1;
break;
}
lua_getfield(Lnew, -1, "init");
if (!lua_isfunction(Lnew, -1))
break;
lua_pushstring(Lnew, p->dir);
ret = lua_pcall(Lnew, 1, 0, 0);
} while (0);
free(path);
if (ret != 0)
goto error;
return Lnew;
error:
fprintf(stderr, "Error: ");
if (Lnew) {
const char *s = lua_tostring(Lnew, -1);
if (!s)
s = "unknown error";
fprintf(stderr, "%s\n", s);
lua_close(Lnew);
} else {
fprintf(stderr, "Out of memory!\n");
}
return NULL;
}
static int luci_init(struct httpd_plugin *p)
{
L = luci_context_init(p);
return (L != NULL);
}
static void pushvar(char *name, char *val)
{
if (!val)
return;
lua_pushstring(L, val);
lua_setfield(L, -2, name);
}
static int luci_pcall(lua_State *L, char *func, int narg)
{
int ret;
ret = lua_pcall(L, narg, narg, 0);
if (ret) {
const char *s = lua_tostring(L, -1);
if (s)
fprintf(stderr, "Error running %s: %s\n", func, s);
return ret;
}
if (!narg)
return ret;
ret = lua_isnumber(L, -1);
if (!ret)
goto done;
ret = lua_tonumber(L, -1);
done:
lua_pop(L, 1);
return ret;
}
static int luci_prepare_req(struct httpd_plugin *p, struct http_context *ctx)
{
int ret;
bool reload = false;
lua_getglobal(L, "luci-plugin");
lua_getfield(L, -1, "reload");
if (lua_isboolean(L, -1))
reload = lua_toboolean(L, -1);
lua_pop(L, 1);
if (reload) {
lua_close(L);
L = luci_context_init(p);
lua_getglobal(L, "luci-plugin");
}
lua_getfield(L, -1, "prepare_req");
ret = lua_isfunction(L, -1);
if (!ret)
goto done;
lua_pushstring(L, ctx->uri);
ret = luci_pcall(L, "prepare_req", 1);
done:
lua_pop(L, 1);
return ret;
}
static int luci_handle_req(struct httpd_plugin *p, struct http_context *ctx)
{
int ret;
lua_newtable(L); /* new table for the http context */
/* convert http_context data structure to lua table */
#define PUSH(x) pushvar(#x, ctx->x)
PUSH(cookie);
PUSH(request_method);
PUSH(server_addr);
PUSH(server_proto);
PUSH(query_string);
PUSH(remote_addr);
lua_pushinteger(L, ctx->remote_port);
lua_setfield(L, -2, "remote_port");
PUSH(content_type);
PUSH(content_length);
PUSH(http_accept);
#undef PUSH
if (!strncmp(ctx->uri, p->prefix, strlen(p->prefix)))
pushvar("uri", ctx->uri + strlen(p->prefix));
else
pushvar("uri", ctx->uri);
/* make sure the global 'luci' table is prepared */
lua_getglobal(L, "luci-plugin");
if (!lua_istable(L, -1))
return 0;
lua_getfield(L, -1, "init_req");
if (!lua_isfunction(L, -1)) {
/* ignore error */
lua_pop(L, 1);
} else {
lua_pushvalue(L, -3);
luci_pcall(L, "init_req", 1);
}
/* storage space for cgi variables */
lua_newtable(L);
lua_pushvalue(L, -1); /* copy for setfield */
lua_setfield(L, -3, "vars");
lua_pushvalue(L, -3); /* the http context table */
/*
* make luci_parse_header a closure
* argument 1: the luci.vars table
* argument 2: the http context table
*/
lua_pushcclosure(L, luci_parse_header, 2);
ret = luci_pcall(L, "parse_header", 0);
lua_getfield(L, -1, "handle_req");
ret = lua_isfunction(L, -1);
if (!ret)
goto done;
lua_pushvalue(L, -3);
ret = luci_pcall(L, "handle_req", 1);
/* pop the luci and http context tables */
done:
lua_pop(L, 2);
return ret;
}
static void luci_unload(struct httpd_plugin *p)
{
lua_close(L);
}
HTTPD_PLUGIN {
.prefix = "/luci/",
.init = luci_init,
.done = luci_unload,
.prepare_req = luci_prepare_req,
.handle_req = luci_handle_req,
};

View file

@ -1,2 +0,0 @@
include ../../build/config.mk
include ../../build/module.mk

View file

@ -1,79 +0,0 @@
--[[
LuCI - SGI-Module for WSAPI
Description:
Server Gateway Interface for WSAPI
FileId:
$Id$
License:
Copyright 2008 Steven Barth <steven@midlink.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
]]--
module("luci.sgi.wsapi", package.seeall)
local ltn12 = require("luci.ltn12")
require("luci.http")
require("luci.dispatcher")
require("luci.http.protocol")
function run(wsapi_env)
local r = luci.http.Request(
wsapi_env,
ltn12.source.file(wsapi_env.input),
ltn12.sink.file(wsapi_env.error)
)
local res, id, data1, data2 = true, 0, nil, nil
local headers = {}
local status = 200
local x = coroutine.create(luci.dispatcher.httpdispatch)
local active = true
while id < 3 do
res, id, data1, data2 = coroutine.resume(x, r)
if not res then
status = 500
headers["Content-Type"] = "text/plain"
local err = {id}
return status, headers, function() local x = table.remove(err) return x end
end
if id == 1 then
status = data1
elseif id == 2 then
headers[data1] = data2
end
end
local function iter()
local res, id, data = coroutine.resume(x)
if id == 4 and active then
return data
elseif id == 5 then
active = false
return ""
else
return ""
end
if coroutine.status(x) == "dead" then
return nil
end
end
return status, headers, iter
end