luci-0.8: remove obsolete code
This commit is contained in:
parent
f698890d2e
commit
5e481381d5
21 changed files with 0 additions and 4314 deletions
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
2
libs/sgi-webuci/.gitignore
vendored
2
libs/sgi-webuci/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
boa-patches/series
|
||||
boa-*.*
|
|
@ -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
|
|
@ -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(¤t_time);
|
||||
- time_offset = TIMEZONE_OFFSET(t);
|
||||
- } else {
|
||||
- t = gmtime(¤t_time);
|
||||
- time_offset = 0;
|
||||
- }
|
||||
-
|
||||
+ t = gmtime(¤t_time);
|
||||
+ time_offset = 0;
|
||||
+
|
||||
p = buf + 29;
|
||||
*p-- = '\0';
|
||||
*p-- = ' ';
|
||||
|
|
@ -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);
|
|
@ -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
|
@ -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;
|
|
@ -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");
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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."
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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,
|
||||
};
|
|
@ -1,2 +0,0 @@
|
|||
include ../../build/config.mk
|
||||
include ../../build/module.mk
|
|
@ -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
|
Loading…
Reference in a new issue