summaryrefslogtreecommitdiffhomepage
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/fastindex/Makefile13
-rw-r--r--libs/fastindex/src/fastindex.c379
-rw-r--r--libs/fastindex/src/list.h601
-rw-r--r--libs/lucid-http/Makefile2
-rw-r--r--libs/lucid-http/docs/OVERVIEW17
-rw-r--r--libs/lucid-http/luasrc/lucid/http.lua36
-rw-r--r--libs/lucid-http/luasrc/lucid/http/DirectoryPublisher.lua50
-rw-r--r--libs/lucid-http/luasrc/lucid/http/LuciWebPublisher.lua73
-rw-r--r--libs/lucid-http/luasrc/lucid/http/Redirector.lua33
-rw-r--r--libs/lucid-http/luasrc/lucid/http/handler/catchall.lua87
-rw-r--r--libs/lucid-http/luasrc/lucid/http/handler/file.lua272
-rw-r--r--libs/lucid-http/luasrc/lucid/http/handler/luci.lua113
-rw-r--r--libs/lucid-http/luasrc/lucid/http/server.lua600
-rw-r--r--libs/lucid-rpc/Makefile2
-rw-r--r--libs/lucid-rpc/docs/OVERVIEW19
-rw-r--r--libs/lucid-rpc/luasrc/lucid/rpc.lua51
-rw-r--r--libs/lucid-rpc/luasrc/lucid/rpc/ruci.lua85
-rw-r--r--libs/lucid-rpc/luasrc/lucid/rpc/server.lua338
-rw-r--r--libs/lucid-rpc/luasrc/lucid/rpc/system.lua101
-rw-r--r--libs/lucid/Makefile2
-rw-r--r--libs/lucid/docs/OVERVIEW75
-rw-r--r--libs/lucid/hostfiles/etc/config/lucid75
-rw-r--r--libs/lucid/luasrc/lucid.lua348
-rw-r--r--libs/lucid/luasrc/lucid/tcpserver.lua254
-rw-r--r--libs/lucid/root/etc/config/lucid52
-rwxr-xr-xlibs/lucid/root/etc/init.d/lucid43
26 files changed, 0 insertions, 3721 deletions
diff --git a/libs/fastindex/Makefile b/libs/fastindex/Makefile
deleted file mode 100644
index ee1a40ea8..000000000
--- a/libs/fastindex/Makefile
+++ /dev/null
@@ -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
diff --git a/libs/fastindex/src/fastindex.c b/libs/fastindex/src/fastindex.c
deleted file mode 100644
index c9c64bf75..000000000
--- a/libs/fastindex/src/fastindex.c
+++ /dev/null
@@ -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;
-}
diff --git a/libs/fastindex/src/list.h b/libs/fastindex/src/list.h
deleted file mode 100644
index 2959a061d..000000000
--- a/libs/fastindex/src/list.h
+++ /dev/null
@@ -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
diff --git a/libs/lucid-http/Makefile b/libs/lucid-http/Makefile
deleted file mode 100644
index 2bdfad16e..000000000
--- a/libs/lucid-http/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-include ../../build/module.mk
-include ../../build/config.mk \ No newline at end of file
diff --git a/libs/lucid-http/docs/OVERVIEW b/libs/lucid-http/docs/OVERVIEW
deleted file mode 100644
index 74b499ca9..000000000
--- a/libs/lucid-http/docs/OVERVIEW
+++ /dev/null
@@ -1,17 +0,0 @@
- LuCId HTTP/1.1 Server Slave
-
-*** Abstract ***
-The LuCId HTTP-Server Slave is an HTTP/1.1 implementation for the LuCId
-superserver loosely based on the LuCI HTTP stack. It supports keep-alive,
-pipelining, basic authentication, kernel-mode file transfer (sendfile()
-through nixio), address and hostname based virtual hosts, custom 404 pages,
-E-Tags, conditional headers, directory indexing and partial file transfers.
-
-
-*** Workflow ***
-After receiving an incoming connection from LuCId, the slave parses the request
-and prepares the environment for the acion handler. After that the virtual host
-will be dispatched and the request will be passed on to the respective handler.
-The handler will enforce access restrictions if configured and then returns a
-status code a set of response headers, as well as a content resource that will
-be sent to the user. \ No newline at end of file
diff --git a/libs/lucid-http/luasrc/lucid/http.lua b/libs/lucid-http/luasrc/lucid/http.lua
deleted file mode 100644
index 931967c56..000000000
--- a/libs/lucid-http/luasrc/lucid/http.lua
+++ /dev/null
@@ -1,36 +0,0 @@
---[[
-LuCI - Lua Configuration Interface
-
-Copyright 2009 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
-
-$Id$
-]]--
-
-local require, ipairs, pcall = require, ipairs, pcall
-local srv = require "luci.lucid.http.server"
-
-module "luci.lucid.http"
-
---- Prepare the HTTP-daemon and its associated publishers.
--- @param publisher Table of publishers
--- @return factory callback or nil, error message
-function factory(publisher)
- local server = srv.Server()
- for _, r in ipairs(publisher) do
- local t = r[".type"]
- local s, mod = pcall(require, "luci.lucid.http." .. (r[".type"] or ""))
- if s and mod then
- mod.factory(server, r)
- else
- return nil, mod
- end
- end
-
- return function(...) return server:process(...) end
-end \ No newline at end of file
diff --git a/libs/lucid-http/luasrc/lucid/http/DirectoryPublisher.lua b/libs/lucid-http/luasrc/lucid/http/DirectoryPublisher.lua
deleted file mode 100644
index 09cade49e..000000000
--- a/libs/lucid-http/luasrc/lucid/http/DirectoryPublisher.lua
+++ /dev/null
@@ -1,50 +0,0 @@
---[[
-LuCId HTTP-Slave
-(c) 2009 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
-
-$Id$
-]]--
-
-local ipairs, require, tostring, type = ipairs, require, tostring, type
-local file = require "luci.lucid.http.handler.file"
-local srv = require "luci.lucid.http.server"
-
-module "luci.lucid.http.DirectoryPublisher"
-
-
---- Prepare a directory publisher and assign it to a given Virtual Host.
--- @param server HTTP daemon object
--- @param config publisher configuration
-function factory(server, config)
- config.domain = config.domain or ""
- local vhost = server:get_vhosts()[config.domain]
- if not vhost then
- vhost = srv.VHost()
- server:set_vhost(config.domain, vhost)
- end
-
- local handler = file.Simple(config.name, config.physical, config)
- if config.read then
- for _, r in ipairs(config.read) do
- if r:sub(1,1) == ":" then
- handler:restrict({interface = r:sub(2)})
- else
- handler:restrict({user = r})
- end
- end
- end
-
- if type(config.virtual) == "table" then
- for _, v in ipairs(config.virtual) do
- vhost:set_handler(v, handler)
- end
- else
- vhost:set_handler(config.virtual or "", handler)
- end
-end
diff --git a/libs/lucid-http/luasrc/lucid/http/LuciWebPublisher.lua b/libs/lucid-http/luasrc/lucid/http/LuciWebPublisher.lua
deleted file mode 100644
index 5dc70df84..000000000
--- a/libs/lucid-http/luasrc/lucid/http/LuciWebPublisher.lua
+++ /dev/null
@@ -1,73 +0,0 @@
---[[
-LuCId HTTP-Slave
-(c) 2009 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
-
-$Id$
-]]--
-
-local ipairs, pcall, type = ipairs, pcall, type
-local luci = require "luci.lucid.http.handler.luci"
-local srv = require "luci.lucid.http.server"
-
-
-module "luci.lucid.http.LuciWebPublisher"
-
-
---- Prepare a LuCI web publisher and assign it to a given Virtual Host.
--- @param server HTTP daemon object
--- @param config publisher configuration
-function factory(server, config)
- pcall(function()
- require "luci.dispatcher"
- require "luci.cbi"
- end)
-
- config.domain = config.domain or ""
- local vhost = server:get_vhosts()[config.domain]
- if not vhost then
- vhost = srv.VHost()
- server:set_vhost(config.domain, vhost)
- end
-
- local prefix
- if config.physical and #config.physical > 0 then
- prefix = {}
- for k in config.physical:gmatch("[^/]+") do
- if #k > 0 then
- prefix[#prefix+1] = k
- end
- end
- end
-
- local handler = luci.Luci(config.name, prefix)
- if config.exec then
- for _, r in ipairs(config.exec) do
- if r:sub(1,1) == ":" then
- handler:restrict({interface = r:sub(2)})
- else
- handler:restrict({user = r})
- end
- end
- end
-
- local mypath
- if type(config.virtual) == "table" then
- for _, v in ipairs(config.virtual) do
- mypath = mypath or v
- vhost:set_handler(v, handler)
- end
- else
- mypath = config.virtual
- vhost:set_handler(config.virtual or "", handler)
- end
-
- if config.home then
- vhost.default = mypath
- end
-end
diff --git a/libs/lucid-http/luasrc/lucid/http/Redirector.lua b/libs/lucid-http/luasrc/lucid/http/Redirector.lua
deleted file mode 100644
index 66a86a7ff..000000000
--- a/libs/lucid-http/luasrc/lucid/http/Redirector.lua
+++ /dev/null
@@ -1,33 +0,0 @@
---[[
-LuCId HTTP-Slave
-(c) 2009 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
-
-$Id$
-]]--
-
-local ipairs = ipairs
-local catchall = require "luci.lucid.http.handler.catchall"
-local srv = require "luci.lucid.http.server"
-
-module "luci.lucid.http.Redirector"
-
---- Prepare a redirector publisher and assign it to a given Virtual Host.
--- @param server HTTP daemon object
--- @param config publisher configuration
-function factory(server, config)
- config.domain = config.domain or ""
- local vhost = server:get_vhosts()[config.domain]
- if not vhost then
- vhost = srv.VHost()
- server:set_vhost(config.domain, vhost)
- end
-
- local handler = catchall.Redirect(config.name, config.physical)
- vhost:set_handler(config.virtual or "", handler)
-end
diff --git a/libs/lucid-http/luasrc/lucid/http/handler/catchall.lua b/libs/lucid-http/luasrc/lucid/http/handler/catchall.lua
deleted file mode 100644
index 13272d91e..000000000
--- a/libs/lucid-http/luasrc/lucid/http/handler/catchall.lua
+++ /dev/null
@@ -1,87 +0,0 @@
---[[
-LuCId HTTP-Slave
-(c) 2009 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
-
-$Id$
-]]--
-
-local srv = require "luci.lucid.http.server"
-local proto = require "luci.http.protocol"
-local util = require "luci.util"
-local ip = require "luci.ip"
-local ipairs = ipairs
-
---- Catchall Handler
--- @cstyle instance
-module "luci.lucid.http.handler.catchall"
-
---- Create a Redirect handler.
--- @param name Name
--- @param target Redirect Target
--- @class function
--- @return Redirect handler object
-Redirect = util.class(srv.Handler)
-
-function Redirect.__init__(self, name, target)
- srv.Handler.__init__(self, name)
- self.target = target
-end
-
---- Handle a GET request.
--- @param request Request object
--- @return status code, header table, response source
-function Redirect.handle_GET(self, request)
- local target = self.target
- local protocol = request.env.HTTPS and "https://" or "http://"
- local server = request.env.SERVER_ADDR
-
- if request.env.REMOTE_ADDR and not request.env.REMOTE_ADDR:find(":") then
- local compare = ip.IPv4(request.env.REMOTE_ADDR)
- for _, iface in ipairs(request.server.interfaces) do
- if iface.family == "inet" and iface.addr and iface.netmask then
- if ip.IPv4(iface.addr, iface.netmask):contains(compare) then
- server = iface.addr
- break
- end
- end
- end
- end
-
- if server:find(":") then
- server = "[" .. server .. "]"
- end
-
- if self.target:sub(1,1) == ":" then
- target = protocol .. server .. target
- end
-
- local s, e = target:find("%TARGET%", 1, true)
- if s then
- local req = protocol .. (request.env.HTTP_HOST or server)
- .. request.env.REQUEST_URI
- target = target:sub(1, s-1) .. req .. target:sub(e+1)
- end
-
- return 302, { Location = target }
-end
-
---- Handle a POST request.
--- @class function
--- @param request Request object
--- @return status code, header table, response source
-Redirect.handle_POST = Redirect.handle_GET
-
---- Handle a HEAD request.
--- @class function
--- @param request Request object
--- @return status code, header table, response source
-function Redirect.handle_HEAD(self, request)
- local stat, head = self:handle_GET(request)
- return stat, head
-end
diff --git a/libs/lucid-http/luasrc/lucid/http/handler/file.lua b/libs/lucid-http/luasrc/lucid/http/handler/file.lua
deleted file mode 100644
index 4f29c8bd2..000000000
--- a/libs/lucid-http/luasrc/lucid/http/handler/file.lua
+++ /dev/null
@@ -1,272 +0,0 @@
---[[
-
-HTTP server implementation for LuCI - file handler
-(c) 2008 Steven Barth <steven@midlink.org>
-(c) 2008 Freifunk Leipzig / Jo-Philipp Wich <xm@leipzig.freifunk.net>
-
-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
-
-$Id$
-
-]]--
-
-local ipairs, type, tonumber = ipairs, type, tonumber
-local os = require "os"
-local nixio = require "nixio", require "nixio.util"
-local fs = require "nixio.fs"
-local util = require "luci.util"
-local ltn12 = require "luci.ltn12"
-local srv = require "luci.lucid.http.server"
-local string = require "string"
-
-local prot = require "luci.http.protocol"
-local date = require "luci.http.protocol.date"
-local mime = require "luci.http.protocol.mime"
-local cond = require "luci.http.protocol.conditionals"
-
---- File system handler
--- @cstyle instance
-module "luci.lucid.http.handler.file"
-
---- Create a simple file system handler.
--- @class function
--- @param name Name
--- @param docroot Physical Document Root
--- @param options Options
--- @return Simple file system handler object
-Simple = util.class(srv.Handler)
-
-function Simple.__init__(self, name, docroot, options)
- srv.Handler.__init__(self, name)
- self.docroot = docroot
- self.realdocroot = fs.realpath(self.docroot)
-
- options = options or {}
- self.dirlist = not options.noindex
- self.error404 = options.error404
-end
-
---- Parse a range request.
--- @param request Request object
--- @param size File size
--- @return offset, length, range header or boolean status
-function Simple.parse_range(self, request, size)
- if not request.headers.Range then
- return true
- end
-
- local from, to = request.headers.Range:match("bytes=([0-9]*)-([0-9]*)")
- if not (from or to) then
- return true
- end
-
- from, to = tonumber(from), tonumber(to)
- if not (from or to) then
- return true
- elseif not from then
- from, to = size - to, size - 1
- elseif not to then
- to = size - 1
- end
-
- -- Not satisfiable
- if from >= size then
- return false
- end
-
- -- Normalize
- if to >= size then
- to = size - 1
- end
-
- local range = "bytes " .. from .. "-" .. to .. "/" .. size
- return from, (1 + to - from), range
-end
-
---- Translate path and return file information.
--- @param uri Request URI
--- @return physical file path, file information
-function Simple.getfile(self, uri)
- if not self.realdocroot then
- self.realdocroot = fs.realpath(self.docroot)
- end
- local file = fs.realpath(self.docroot .. uri)
- if not file or file:sub(1, #self.realdocroot) ~= self.realdocroot then
- return uri
- end
- return file, fs.stat(file)
-end
-
---- Handle a GET request.
--- @param request Request object
--- @return status code, header table, response source
-function Simple.handle_GET(self, request)
- local file, stat = self:getfile(prot.urldecode(request.env.PATH_INFO, true))
-
- if stat then
- if stat.type == "reg" then
-
- -- Generate Entity Tag
- local etag = cond.mk_etag( stat )
-
- -- Check conditionals
- local ok, code, hdrs
-
- ok, code, hdrs = cond.if_modified_since( request, stat )
- if ok then
- ok, code, hdrs = cond.if_match( request, stat )
- if ok then
- ok, code, hdrs = cond.if_unmodified_since( request, stat )
- if ok then
- ok, code, hdrs = cond.if_none_match( request, stat )
- if ok then
- local f, err = nixio.open(file)
-
- if f then
- local code = 200
- local o, s, r = self:parse_range(request, stat.size)
-
- if not o then
- return self:failure(416, "Invalid Range")
- end
-
- local headers = {
- ["Cache-Control"] = "max-age=29030400",
- ["Last-Modified"] = date.to_http( stat.mtime ),
- ["Content-Type"] = mime.to_mime( file ),
- ["ETag"] = etag,
- ["Accept-Ranges"] = "bytes",
- }
-
- if o == true then
- s = stat.size
- else
- code = 206
- headers["Content-Range"] = r
- f:seek(o)
- end
-
- headers["Content-Length"] = s
-
- -- Send Response
- return code, headers, srv.IOResource(f, s)
- else
- return self:failure( 403, err:gsub("^.+: ", "") )
- end
- else
- return code, hdrs
- end
- else
- return code, hdrs
- end
- else
- return code, hdrs
- end
- else
- return code, hdrs
- end
-
- elseif stat.type == "dir" then
-
- local ruri = request.env.REQUEST_URI:gsub("/$", "")
- local duri = prot.urldecode( ruri, true )
- local root = self.docroot
-
- -- check for index files
- local index_candidates = {
- "index.html", "index.htm", "default.html", "default.htm",
- "index.txt", "default.txt"
- }
-
- -- try to find an index file and redirect to it
- for i, candidate in ipairs( index_candidates ) do
- local istat = fs.stat(
- root .. "/" .. duri .. "/" .. candidate
- )
-
- if istat ~= nil and istat.type == "reg" then
- return 302, { Location = ruri .. "/" .. candidate }
- end
- end
-
-
- local html = string.format(
- '<?xml version="1.0" encoding="utf-8"?>\n' ..
- '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ' ..
- '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n'..
- '<html xmlns="http://www.w3.org/1999/xhtml" ' ..
- 'xml:lang="en" lang="en">\n' ..
- '<head>\n' ..
- '<title>Index of %s/</title>\n' ..
- '<style type="text/css">\n' ..
- 'body { color:#000000 } ' ..
- 'li { border-bottom:1px dotted #CCCCCC; padding:3px } ' ..
- 'small { font-size:60%%; color:#333333 } ' ..
- 'p { margin:0 }' ..
- '\n</style></head><body><h1>Index of %s/</h1><hr /><ul>'..
- '<li><p><a href="%s/../">../</a> ' ..
- '<small>(parent directory)</small><br />' ..
- '<small></small></li>',
- duri, duri, ruri
- )
-
- local entries = fs.dir( file )
-
- if type(entries) == "function" then
- for i, e in util.vspairs(nixio.util.consume(entries)) do
- local estat = fs.stat( file .. "/" .. e )
-
- if estat.type == "dir" then
- html = html .. string.format(
- '<li><p><a href="%s/%s/">%s/</a> ' ..
- '<small>(directory)</small><br />' ..
- '<small>Changed: %s</small></li>',
- ruri, prot.urlencode( e ), e,
- date.to_http( estat.mtime )
- )
- else
- html = html .. string.format(
- '<li><p><a href="%s/%s">%s</a> ' ..
- '<small>(%s)</small><br />' ..
- '<small>Size: %i Bytes | ' ..
- 'Changed: %s</small></li>',
- ruri, prot.urlencode( e ), e,
- mime.to_mime( e ),
- estat.size, date.to_http( estat.mtime )
- )
- end
- end
-
- html = html .. '</ul><hr /><address>LuCId-HTTPd' ..
- '</address></body></html>'
-
- return 200, {
- ["Date"] = date.to_http( os.time() );
- ["Content-Type"] = "text/html; charset=utf-8";
- }, ltn12.source.string(html)
- else
- return self:failure(403, "Permission denied")
- end
- else
- return self:failure(403, "Unable to transmit " .. stat.type .. " " .. file)
- end
- else
- if self.error404 then
- return 302, { Location = self.error404 }
- else
- return self:failure(404, "No such file: " .. file)
- end
- end
-end
-
---- Handle a HEAD request.
--- @param request Request object
--- @return status code, header table, response source
-function Simple.handle_HEAD(self, ...)
- local stat, head = self:handle_GET(...)
- return stat, head
-end
diff --git a/libs/lucid-http/luasrc/lucid/http/handler/luci.lua b/libs/lucid-http/luasrc/lucid/http/handler/luci.lua
deleted file mode 100644
index b6d92deec..000000000
--- a/libs/lucid-http/luasrc/lucid/http/handler/luci.lua
+++ /dev/null
@@ -1,113 +0,0 @@
---[[
-LuCId HTTP-Slave
-(c) 2009 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
-
-$Id$
-]]--
-
-local dsp = require "luci.dispatcher"
-local util = require "luci.util"
-local http = require "luci.http"
-local ltn12 = require "luci.ltn12"
-local srv = require "luci.lucid.http.server"
-local coroutine = require "coroutine"
-local type = type
-
---- LuCI web handler
--- @cstyle instance
-module "luci.lucid.http.handler.luci"
-
---- Create a LuCI web handler.
--- @class function
--- @param name Name
--- @param prefix Dispatching prefix
--- @return LuCI web handler object
-Luci = util.class(srv.Handler)
-
-function Luci.__init__(self, name, prefix)
- srv.Handler.__init__(self, name)
- self.prefix = prefix
- dsp.indexcache = "/tmp/luci-indexcache"
-end
-
---- Handle a HEAD request.
--- @param request Request object
--- @return status code, header table, response source
-function Luci.handle_HEAD(self, ...)
- local stat, head = self:handle_GET(...)
- return stat, head
-end
-
---- Handle a POST request.
--- @param request Request object
--- @return status code, header table, response source
-function Luci.handle_POST(self, ...)
- return self:handle_GET(...)
-end
-
---- Handle a GET request.
--- @param request Request object
--- @return status code, header table, response source
-function Luci.handle_GET(self, request, sourcein)
- local r = http.Request(
- request.env,
- sourcein
- )
-
- local res, id, data1, data2 = true, 0, nil, nil
- local headers = {}
- local status = 200
- local active = true
-
- local x = coroutine.create(dsp.httpdispatch)
- while not id or id < 3 do
- res, id, data1, data2 = coroutine.resume(x, r, self.prefix)
-
- if not res then
- status = 500
- headers["Content-Type"] = "text/plain"
- return status, headers, ltn12.source.string(id)
- end
-
- if id == 1 then
- status = data1
- elseif id == 2 then
- if not headers[data1] then
- headers[data1] = data2
- elseif type(headers[data1]) ~= "table" then
- headers[data1] = {headers[data1], data2}
- else
- headers[data1][#headers[data1]+1] = data2
- end
- end
- end
-
- if id == 6 then
- while (coroutine.resume(x)) do end
- return status, headers, srv.IOResource(data1, data2)
- end
-
- local function iter()
- local res, id, data = coroutine.resume(x)
- if not res then
- return nil, id
- elseif not id or not active then
- return true
- elseif id == 5 then
- active = false
- while (coroutine.resume(x)) do end
- return nil
- elseif id == 4 then
- return data
- end
- end
-
- return status, headers, iter
-end
-
diff --git a/libs/lucid-http/luasrc/lucid/http/server.lua b/libs/lucid-http/luasrc/lucid/http/server.lua
deleted file mode 100644
index fd5f7cdd8..000000000
--- a/libs/lucid-http/luasrc/lucid/http/server.lua
+++ /dev/null
@@ -1,600 +0,0 @@
---[[
-LuCId HTTP-Slave
-(c) 2009 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
-
-$Id$
-]]--
-
-local ipairs, pairs = ipairs, pairs
-local tostring, tonumber = tostring, tonumber
-local pcall, assert, type = pcall, assert, type
-local set_memory_limit = set_memory_limit
-
-local os = require "os"
-local nixio = require "nixio"
-local util = require "luci.util"
-local ltn12 = require "luci.ltn12"
-local proto = require "luci.http.protocol"
-local table = require "table"
-local date = require "luci.http.protocol.date"
-
---- HTTP Daemon
--- @cstyle instance
-module "luci.lucid.http.server"
-
-VERSION = "1.0"
-
-statusmsg = {
- [200] = "OK",
- [206] = "Partial Content",
- [301] = "Moved Permanently",
- [302] = "Found",
- [304] = "Not Modified",
- [400] = "Bad Request",
- [401] = "Unauthorized",
- [403] = "Forbidden",
- [404] = "Not Found",
- [405] = "Method Not Allowed",
- [408] = "Request Time-out",
- [411] = "Length Required",
- [412] = "Precondition Failed",
- [416] = "Requested range not satisfiable",
- [500] = "Internal Server Error",
- [503] = "Server Unavailable",
-}
-
---- Create a new IO resource response.
--- @class function
--- @param fd File descriptor
--- @param len Length of data
--- @return IO resource
-IOResource = util.class()
-
-function IOResource.__init__(self, fd, len)
- self.fd, self.len = fd, len
-end
-
-
---- Create a server handler.
--- @class function
--- @param name Name
--- @return Handler
-Handler = util.class()
-
-function Handler.__init__(self, name)
- self.name = name or tostring(self)
-end
-
---- Create a failure reply.
--- @param code HTTP status code
--- @param msg Status message
--- @return status code, header table, response source
-function Handler.failure(self, code, msg)
- return code, { ["Content-Type"] = "text/plain" }, ltn12.source.string(msg)
-end
-
---- Add an access restriction.
--- @param restriction Restriction specification
-function Handler.restrict(self, restriction)
- if not self.restrictions then
- self.restrictions = {restriction}
- else
- self.restrictions[#self.restrictions+1] = restriction
- end
-end
-
---- Enforce access restrictions.
--- @param request Request object
--- @return nil or HTTP statuscode, table of headers, response source
-function Handler.checkrestricted(self, request)
- if not self.restrictions then
- return
- end
-
- local localif, user, pass
-
- for _, r in ipairs(self.restrictions) do
- local stat = true
- if stat and r.interface then -- Interface restriction
- if not localif then
- for _, v in ipairs(request.server.interfaces) do
- if v.addr == request.env.SERVER_ADDR then
- localif = v.name
- break
- end
- end
- end
-
- if r.interface ~= localif then
- stat = false
- end
- end
-
- if stat and r.user then -- User restriction
- local rh, pwe
- if not user then
- rh = (request.headers.Authorization or ""):match("Basic (.*)")
- rh = rh and nixio.bin.b64decode(rh) or ""
- user, pass = rh:match("(.*):(.*)")
- pass = pass or ""
- end
- pwe = nixio.getsp and nixio.getsp(r.user) or nixio.getpw(r.user)
- local pwh = (user == r.user) and pwe and (pwe.pwdp or pwe.passwd)
- if not pwh or #pwh < 1 or nixio.crypt(pass, pwh) ~= pwh then
- stat = false
- end
- end
-
- if stat then
- request.env.HTTP_AUTH_USER, request.env.HTTP_AUTH_PASS = user, pass
- return
- end
- end
-
- return 401, {
- ["WWW-Authenticate"] = ('Basic realm=%q'):format(self.name),
- ["Content-Type"] = 'text/plain'
- }, ltn12.source.string("Unauthorized")
-end
-
---- Process a request.
--- @param request Request object
--- @param sourcein Request data source
--- @return HTTP statuscode, table of headers, response source
-function Handler.process(self, request, sourcein)
- local stat, code, hdr, sourceout
-
- local stat, code, msg = self:checkrestricted(request)
- if stat then -- Access Denied
- return stat, code, msg
- end
-
- -- Detect request Method
- local hname = "handle_" .. request.env.REQUEST_METHOD
- if self[hname] then
- -- Run the handler
- stat, code, hdr, sourceout = pcall(self[hname], self, request, sourcein)
-
- -- Check for any errors
- if not stat then
- return self:failure(500, code)
- end
- else
- return self:failure(405, statusmsg[405])
- end
-
- return code, hdr, sourceout
-end
-
-
---- Create a Virtual Host.
--- @class function
--- @return Virtual Host
-VHost = util.class()
-
-function VHost.__init__(self)
- self.handlers = {}
-end
-
---- Process a request and invoke the appropriate handler.
--- @param request Request object
--- @param ... Additional parameters passed to the handler
--- @return HTTP statuscode, table of headers, response source
-function VHost.process(self, request, ...)
- local handler
- local hlen = -1
- local uri = request.env.SCRIPT_NAME
- local sc = ("/"):byte()
-
- -- SCRIPT_NAME
- request.env.SCRIPT_NAME = ""
-
- -- Call URI part
- request.env.PATH_INFO = uri
-
- if self.default and uri == "/" then
- return 302, {Location = self.default}
- end
-
- for k, h in pairs(self.handlers) do
- if #k > hlen then
- if uri == k or (uri:sub(1, #k) == k and uri:byte(#k+1) == sc) then
- handler = h
- hlen = #k
- request.env.SCRIPT_NAME = k
- request.env.PATH_INFO = uri:sub(#k+1)
- end
- end
- end
-
- if handler then
- return handler:process(request, ...)
- else
- return 404, nil, ltn12.source.string("No such handler")
- end
-end
-
---- Get a list of registered handlers.
--- @return Table of handlers
-function VHost.get_handlers(self)
- return self.handlers
-end
-
---- Register handler with a given URI prefix.
--- @oaram match URI prefix
--- @param handler Handler object
-function VHost.set_handler(self, match, handler)
- self.handlers[match] = handler
-end
-
--- Remap IPv6-IPv4-compatibility addresses back to IPv4 addresses.
-local function remapipv6(adr)
- local map = "::ffff:"
- if adr:sub(1, #map) == map then
- return adr:sub(#map+1)
- else
- return adr
- end
-end
-
--- Create a source that decodes chunked-encoded data from a socket.
-local function chunksource(sock, buffer)
- buffer = buffer or ""
- return function()
- local output
- local _, endp, count = buffer:find("^([0-9a-fA-F]+);?.-\r\n")
- while not count and #buffer <= 1024 do
- local newblock, code = sock:recv(1024 - #buffer)
- if not newblock then
- return nil, code
- end
- buffer = buffer .. newblock
- _, endp, count = buffer:find("^([0-9a-fA-F]+);?.-\r\n")
- end
- count = tonumber(count, 16)
- if not count then
- return nil, -1, "invalid encoding"
- elseif count == 0 then
- return nil
- elseif count + 2 <= #buffer - endp then
- output = buffer:sub(endp+1, endp+count)
- buffer = buffer:sub(endp+count+3)
- return output
- else
- output = buffer:sub(endp+1, endp+count)
- buffer = ""
- if count - #output > 0 then
- local remain, code = sock:recvall(count-#output)
- if not remain then
- return nil, code
- end
- output = output .. remain
- count, code = sock:recvall(2)
- else
- count, code = sock:recvall(count+2-#buffer+endp)
- end
- if not count then
- return nil, code
- end
- return output
- end
- end
-end
-
--- Create a sink that chunk-encodes data and writes it on a given socket.
-local function chunksink(sock)
- return function(chunk, err)
- if not chunk then
- return sock:writeall("0\r\n\r\n")
- else
- return sock:writeall(("%X\r\n%s\r\n"):format(#chunk, tostring(chunk)))
- end
- end
-end
-
-
---- Create a server object.
--- @class function
--- @return Server object
-Server = util.class()
-
-function Server.__init__(self)
- self.vhosts = {}
-end
-
---- Get a list of registered virtual hosts.
--- @return Table of virtual hosts
-function Server.get_vhosts(self)
- return self.vhosts
-end
-
---- Register a virtual host with a given name.
--- @param name Hostname
--- @param vhost Virtual host object
-function Server.set_vhost(self, name, vhost)
- self.vhosts[name] = vhost
-end
-
---- Send a fatal error message to given client and close the connection.
--- @param client Client socket
--- @param code HTTP status code
--- @param msg status message
-function Server.error(self, client, code, msg)
- hcode = tostring(code)
-
- client:writeall( "HTTP/1.0 " .. hcode .. " " ..
- statusmsg[code] .. "\r\n" )
- client:writeall( "Connection: close\r\n" )
- client:writeall( "Content-Type: text/plain\r\n\r\n" )
-
- if msg then
- client:writeall( "HTTP-Error " .. code .. ": " .. msg .. "\r\n" )
- end
-
- client:close()
-end
-
-local hdr2env = {
- ["Content-Length"] = "CONTENT_LENGTH",
- ["Content-Type"] = "CONTENT_TYPE",
- ["Content-type"] = "CONTENT_TYPE",
- ["Accept"] = "HTTP_ACCEPT",
- ["Accept-Charset"] = "HTTP_ACCEPT_CHARSET",
- ["Accept-Encoding"] = "HTTP_ACCEPT_ENCODING",
- ["Accept-Language"] = "HTTP_ACCEPT_LANGUAGE",
- ["Connection"] = "HTTP_CONNECTION",
- ["Cookie"] = "HTTP_COOKIE",
- ["Host"] = "HTTP_HOST",
- ["Referer"] = "HTTP_REFERER",
- ["User-Agent"] = "HTTP_USER_AGENT"
-}
-
---- Parse the request headers and prepare the environment.
--- @param source line-based input source
--- @return Request object
-function Server.parse_headers(self, source)
- local env = {}
- local req = {env = env, headers = {}}
- local line, err
-
- repeat -- Ignore empty lines
- line, err = source()
- if not line then
- return nil, err
- end
- until #line > 0
-
- env.REQUEST_METHOD, env.REQUEST_URI, env.SERVER_PROTOCOL =
- line:match("^([A-Z]+) ([^ ]+) (HTTP/1%.[01])$")
-
- if not env.REQUEST_METHOD then
- return nil, "invalid magic"
- end
-
- local key, envkey, val
- repeat
- line, err = source()
- if not line then
- return nil, err
- elseif #line > 0 then
- key, val = line:match("^([%w-]+)%s?:%s?(.*)")
- if key then
- req.headers[key] = val
- envkey = hdr2env[key]
- if envkey then
- env[envkey] = val
- end
- else
- return nil, "invalid header line"
- end
- else
- break
- end
- until false
-
- env.SCRIPT_NAME, env.QUERY_STRING = env.REQUEST_URI:match("([^?]*)%??(.*)")
- return req
-end
-
---- Handle a new client connection.
--- @param client client socket
--- @param env superserver environment
-function Server.process(self, client, env)
- local sourcein = function() end
- local sourcehdr = client:linesource()
- local sinkout
- local buffer
-
- local close = false
- local stat, code, msg, message, err
-
- env.config.memlimit = tonumber(env.config.memlimit)
- if env.config.memlimit and set_memory_limit then
- set_memory_limit(env.config.memlimit)
- end
-
- client:setsockopt("socket", "rcvtimeo", 5)
- client:setsockopt("socket", "sndtimeo", 5)
-
- repeat
- -- parse headers
- message, err = self:parse_headers(sourcehdr)
-
- -- any other error
- if not message or err then
- if err == 11 then -- EAGAIN
- break
- else
- return self:error(client, 400, err)
- end
- end
-
- -- Prepare sources and sinks
- buffer = sourcehdr(true)
- sinkout = client:sink()
- message.server = env
-
- if client:is_tls_socket() then
- message.env.HTTPS = "on"
- end
-
- -- Addresses
- message.env.REMOTE_ADDR = remapipv6(env.host)
- message.env.REMOTE_PORT = env.port
-
- local srvaddr, srvport = client:getsockname()
- message.env.SERVER_ADDR = remapipv6(srvaddr)
- message.env.SERVER_PORT = srvport
-
- -- keep-alive
- if message.env.SERVER_PROTOCOL == "HTTP/1.1" then
- close = (message.env.HTTP_CONNECTION == "close")
- else
- close = not message.env.HTTP_CONNECTION
- or message.env.HTTP_CONNECTION == "close"
- end
-
- -- Uncomment this to disable keep-alive
- close = close or env.config.nokeepalive
-
- if message.env.REQUEST_METHOD == "GET"
- or message.env.REQUEST_METHOD == "HEAD" then
- -- Be happy
-
- elseif message.env.REQUEST_METHOD == "POST" then
- -- If we have a HTTP/1.1 client and an Expect: 100-continue header
- -- respond with HTTP 100 Continue message
- if message.env.SERVER_PROTOCOL == "HTTP/1.1"
- and message.headers.Expect == '100-continue' then
- client:writeall("HTTP/1.1 100 Continue\r\n\r\n")
- end
-
- if message.headers['Transfer-Encoding'] and
- message.headers['Transfer-Encoding'] ~= "identity" then
- sourcein = chunksource(client, buffer)
- buffer = nil
- elseif message.env.CONTENT_LENGTH then
- local len = tonumber(message.env.CONTENT_LENGTH)
- if #buffer >= len then
- sourcein = ltn12.source.string(buffer:sub(1, len))
- buffer = buffer:sub(len+1)
- else
- sourcein = ltn12.source.cat(
- ltn12.source.string(buffer),
- client:blocksource(nil, len - #buffer)
- )
- end
- else
- return self:error(client, 411, statusmsg[411])
- end
-
- close = true
- else
- return self:error(client, 405, statusmsg[405])
- end
-
-
- local host = self.vhosts[message.env.HTTP_HOST] or self.vhosts[""]
- if not host then
- return self:error(client, 404, "No virtual host found")
- end
-
- local code, headers, sourceout = host:process(message, sourcein)
- headers = headers or {}
-
- -- Post process response
- if sourceout then
- if util.instanceof(sourceout, IOResource) then
- if not headers["Content-Length"] then
- headers["Content-Length"] = sourceout.len
- end
- end
- if not headers["Content-Length"] and not close then
- if message.env.SERVER_PROTOCOL == "HTTP/1.1" then
- headers["Transfer-Encoding"] = "chunked"
- sinkout = chunksink(client)
- else
- close = true
- end
- end
- elseif message.env.REQUEST_METHOD ~= "HEAD" then
- headers["Content-Length"] = 0
- end
-
- if close then
- headers["Connection"] = "close"
- else
- headers["Connection"] = "Keep-Alive"
- headers["Keep-Alive"] = "timeout=5, max=50"
- end
-
- headers["Date"] = date.to_http(os.time())
- local header = {
- message.env.SERVER_PROTOCOL .. " " .. tostring(code) .. " "
- .. statusmsg[code],
- "Server: LuCId-HTTPd/" .. VERSION
- }
-
-
- for k, v in pairs(headers) do
- if type(v) == "table" then
- for _, h in ipairs(v) do
- header[#header+1] = k .. ": " .. h
- end
- else
- header[#header+1] = k .. ": " .. v
- end
- end
-
- header[#header+1] = ""
- header[#header+1] = ""
-
- -- Output
- stat, code, msg = client:writeall(table.concat(header, "\r\n"))
-
- if sourceout and stat then
- local closefd
- if util.instanceof(sourceout, IOResource) then
- if not headers["Transfer-Encoding"] then
- stat, code, msg = sourceout.fd:copyz(client, sourceout.len)
- closefd = sourceout.fd
- sourceout = nil
- else
- closefd = sourceout.fd
- sourceout = sourceout.fd:blocksource(nil, sourceout.len)
- end
- end
-
- if sourceout then
- stat, msg = ltn12.pump.all(sourceout, sinkout)
- end
-
- if closefd then
- closefd:close()
- end
- end
-
-
- -- Write errors
- if not stat then
- if msg then
- nixio.syslog("err", "Error sending data to " .. env.host ..
- ": " .. msg .. "\n")
- end
- break
- end
-
- if buffer then
- sourcehdr(buffer)
- end
- until close
-
- client:shutdown()
- client:close()
-end
diff --git a/libs/lucid-rpc/Makefile b/libs/lucid-rpc/Makefile
deleted file mode 100644
index f7fac7740..000000000
--- a/libs/lucid-rpc/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-include ../../build/config.mk
-include ../../build/module.mk
diff --git a/libs/lucid-rpc/docs/OVERVIEW b/libs/lucid-rpc/docs/OVERVIEW
deleted file mode 100644
index 9da870065..000000000
--- a/libs/lucid-rpc/docs/OVERVIEW
+++ /dev/null
@@ -1,19 +0,0 @@
- LuCId JSON-RPC Server Slave
-
-*** Abstract ***
-The LuCId JSON-RPC server slave implements the JSON-RPC 1.0 and 2.0 protocol
-to allow efficient light-weight remote procedure calling.
-It provides notification support and several unofficial protocol extensions such
-as:
- * Close notifications
- * Raw TCP switching to transfer BLOBs efficiently
- * Client notification
-
-
-*** Workflow ***
-After receiving an incoming connection from LuCId, the slave analyses the
-request and passes it to the matching handler. The handler will enforce
-access restriction and deserialize the payload data and invokes the assigned
-Lua function in a protected way. In case of a success the handler will serialize
-the response and send it to the client - otherwise a detailed error message
-will be returned. \ No newline at end of file
diff --git a/libs/lucid-rpc/luasrc/lucid/rpc.lua b/libs/lucid-rpc/luasrc/lucid/rpc.lua
deleted file mode 100644
index 417e57214..000000000
--- a/libs/lucid-rpc/luasrc/lucid/rpc.lua
+++ /dev/null
@@ -1,51 +0,0 @@
---[[
-LuCI - Lua Development Framework
-
-Copyright 2009 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
-
-$Id$
-]]
-
-local require, ipairs, pcall = require, ipairs, pcall
-local srv = require "luci.lucid.rpc.server"
-
-module "luci.lucid.rpc"
-
---- Prepare the RPC-daemon and its associated publishers.
--- @param publisher Table of publishers
--- @return factory callback or nil, error message
-function factory(publisher)
- local root = srv.Module()
- local server = srv.Server(root)
-
- for _, r in ipairs(publisher) do
- for _, m in ipairs(r.export) do
- local s, mod = pcall(require, r.namespace .. "." .. m)
- if s and mod then
- local module = mod._factory()
-
- if r.exec then
- for _, x in ipairs(r.exec) do
- if x:sub(1,1) == ":" then
- module:restrict({interface = x:sub(2)})
- else
- module:restrict({user = x})
- end
- end
- end
-
- root:add(m, module)
- else
- return nil, mod
- end
- end
- end
-
- return function(...) return server:process(...) end
-end \ No newline at end of file
diff --git a/libs/lucid-rpc/luasrc/lucid/rpc/ruci.lua b/libs/lucid-rpc/luasrc/lucid/rpc/ruci.lua
deleted file mode 100644
index f0910c7f0..000000000
--- a/libs/lucid-rpc/luasrc/lucid/rpc/ruci.lua
+++ /dev/null
@@ -1,85 +0,0 @@
---[[
-LuCIRPCd
-(c) 2009 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
-
-$Id$
-]]--
-local uci = require "luci.model.uci"
-local tostring, getmetatable, pairs = tostring, getmetatable, pairs
-local error, type = error, type
-local nixio = require "nixio"
-local srv = require "luci.lucid.rpc.server"
-
---- Remote UCI functions.
-module "luci.lucid.rpc.ruci"
-
--- Prepare the remote UCI functions.
-function _factory()
- local m = srv.Module("Remote UCI API")
-
- for k, v in pairs(_M) do
- if type(v) == "function" and v ~= _factory then
- m:add(k, srv.Method.extended(v))
- end
- end
-
- return m
-end
-
--- Get the associate RUCI instance.
-local function getinst(session, name)
- return session.ruci and session.ruci[name]
-end
-
--- Set a new RUCI instance.
-local function setinst(session, obj)
- session.ruci = session.ruci or {}
- local name = tostring(obj):match("0x([a-z0-9]+)")
- session.ruci[name] = obj
- return name
-end
-
-
-local Cursor = getmetatable(uci.cursor())
-
-for name, func in pairs(Cursor) do
- _M[name] = function(session, inst, ...)
- inst = getinst(session, inst)
- return inst[name](inst, ...)
- end
-end
-
---- Generate a new RUCI cursor.
--- @param session Session object
--- @param ... Parameters passed to the UCI constructor
--- @return RUCI instance
-function cursor(session, ...)
- return setinst(session, uci.cursor(...))
-end
-
---- Generate a new RUCI state cursor.
--- @param session Session object
--- @param ... Parameters passed to the UCI constructor
--- @return RUCI instance
-function cursor_state(session, ...)
- return setinst(session, uci.cursor_state(...))
-end
-
---- Custom foreach function.
--- @param session Session object
--- @param inst RUCI instance
--- @param config UCI config
--- @param sectiontype UCI sectiontype
--- @return section data
-function foreach(session, inst, config, sectiontype)
- local inst = getinst(session, inst)
- local secs = {}
- inst:foreach(config, sectiontype, function(s) secs[#secs+1] = s end)
- return secs
-end \ No newline at end of file
diff --git a/libs/lucid-rpc/luasrc/lucid/rpc/server.lua b/libs/lucid-rpc/luasrc/lucid/rpc/server.lua
deleted file mode 100644
index 18b004d8b..000000000
--- a/libs/lucid-rpc/luasrc/lucid/rpc/server.lua
+++ /dev/null
@@ -1,338 +0,0 @@
---[[
-LuCI - Lua Development Framework
-
-Copyright 2009 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
-
-$Id$
-]]
-
-local ipairs, pairs = ipairs, pairs
-local tostring, tonumber = tostring, tonumber
-local pcall, assert, type, unpack = pcall, assert, type, unpack
-
-local nixio = require "nixio"
-local json = require "luci.json"
-local util = require "luci.util"
-local table = require "table"
-local ltn12 = require "luci.ltn12"
-
---- RPC daemom.
--- @cstyle instance
-module "luci.lucid.rpc.server"
-
-RQLIMIT = 32 * nixio.const.buffersize
-VERSION = "1.0"
-
-ERRNO_PARSE = -32700
-ERRNO_INVALID = -32600
-ERRNO_UNKNOWN = -32001
-ERRNO_TIMEOUT = -32000
-ERRNO_NOTFOUND = -32601
-ERRNO_NOACCESS = -32002
-ERRNO_INTERNAL = -32603
-ERRNO_NOSUPPORT = -32003
-
-ERRMSG = {
- [ERRNO_PARSE] = "Parse error.",
- [ERRNO_INVALID] = "Invalid request.",
- [ERRNO_TIMEOUT] = "Connection timeout.",
- [ERRNO_UNKNOWN] = "Unknown error.",
- [ERRNO_NOTFOUND] = "Method not found.",
- [ERRNO_NOACCESS] = "Access denied.",
- [ERRNO_INTERNAL] = "Internal error.",
- [ERRNO_NOSUPPORT] = "Operation not supported."
-}
-
-
---- Create an RPC method wrapper.
--- @class function
--- @param method Lua function
--- @param description Method description
--- @return Wrapped RPC method
-Method = util.class()
-
---- Create an extended wrapped RPC method.
--- @class function
--- @param method Lua function
--- @param description Method description
--- @return Wrapped RPC method
-function Method.extended(...)
- local m = Method(...)
- m.call = m.xcall
- return m
-end
-
-function Method.__init__(self, method, description)
- self.description = description
- self.method = method
-end
-
---- Extended call the associated function.
--- @param session Session storage
--- @param argv Request parameters
--- @return function call response
-function Method.xcall(self, session, argv)
- return self.method(session, unpack(argv))
-end
-
---- Standard call the associated function.
--- @param session Session storage
--- @param argv Request parameters
--- @return function call response
-function Method.call(self, session, argv)
- return self.method(unpack(argv))
-end
-
---- Process a given request and create a JSON response.
--- @param session Session storage
--- @param request Requested method
--- @param argv Request parameters
-function Method.process(self, session, request, argv)
- local stat, result = pcall(self.call, self, session, argv)
-
- if stat then
- return { result=result }
- else
- return { error={
- code=ERRNO_UNKNOWN,
- message=ERRMSG[ERRNO_UNKNOWN],
- data=result
- } }
- end
-end
-
--- Remap IPv6-IPv4-compatibility addresses to IPv4 addresses
-local function remapipv6(adr)
- local map = "::ffff:"
- if adr:sub(1, #map) == map then
- return adr:sub(#map+1)
- else
- return adr
- end
-end
-
-
---- Create an RPC module.
--- @class function
--- @param description Method description
--- @return RPC module
-Module = util.class()
-
-function Module.__init__(self, description)
- self.description = description
- self.handler = {}
-end
-
---- Add a handler.
--- @param k key
--- @param v handler
-function Module.add(self, k, v)
- self.handler[k] = v
-end
-
---- Add an access restriction.
--- @param restriction Restriction specification
-function Module.restrict(self, restriction)
- if not self.restrictions then
- self.restrictions = {restriction}
- else
- self.restrictions[#self.restrictions+1] = restriction
- end
-end
-
---- Enforce access restrictions.
--- @param request Request object
--- @return nil or HTTP statuscode, table of headers, response source
-function Module.checkrestricted(self, session, request, argv)
- if not self.restrictions then
- return
- end
-
- for _, r in ipairs(self.restrictions) do
- local stat = true
- if stat and r.interface then -- Interface restriction
- if not session.localif then
- for _, v in ipairs(session.env.interfaces) do
- if v.addr == session.localaddr then
- session.localif = v.name
- break
- end
- end
- end
-
- if r.interface ~= session.localif then
- stat = false
- end
- end
-
- if stat and r.user and session.user ~= r.user then -- User restriction
- stat = false
- end
-
- if stat then
- return
- end
- end
-
- return {error={code=ERRNO_NOACCESS, message=ERRMSG[ERRNO_NOACCESS]}}
-end
-
---- Register a handler, submodule or function.
--- @param m entity
--- @param descr description
--- @return Module (self)
-function Module.register(self, m, descr)
- descr = descr or {}
- for k, v in pairs(m) do
- if util.instanceof(v, Method) then
- self.handler[k] = v
- elseif type(v) == "table" then
- self.handler[k] = Module()
- self.handler[k]:register(v, descr[k])
- elseif type(v) == "function" then
- self.handler[k] = Method(v, descr[k])
- end
- end
- return self
-end
-
---- Process a request.
--- @param session Session storage
--- @param request Request object
--- @param argv Request parameters
--- @return JSON response object
-function Module.process(self, session, request, argv)
- local first, last = request:match("^([^.]+).?(.*)$")
-
- local stat = self:checkrestricted(session, request, argv)
- if stat then -- Access Denied
- return stat
- end
-
- local hndl = first and self.handler[first]
- if not hndl then
- return {error={code=ERRNO_NOTFOUND, message=ERRMSG[ERRNO_NOTFOUND]}}
- end
-
- session.chain[#session.chain+1] = self
- return hndl:process(session, last, argv)
-end
-
-
---- Create a server object.
--- @class function
--- @param root Root module
--- @return Server object
-Server = util.class()
-
-function Server.__init__(self, root)
- self.root = root
-end
-
---- Get the associated root module.
--- @return Root module
-function Server.get_root(self)
- return self.root
-end
-
---- Set a new root module.
--- @param root Root module
-function Server.set_root(self, root)
- self.root = root
-end
-
---- Create a JSON reply.
--- @param jsonrpc JSON-RPC version
--- @param id Message id
--- @param res Result
--- @param err Error
--- @reutrn JSON response source
-function Server.reply(self, jsonrpc, id, res, err)
- id = id or json.null
-
- -- 1.0 compatibility
- if jsonrpc ~= "2.0" then
- jsonrpc = nil
- res = res or json.null
- err = err or json.null
- end
-
- return json.Encoder(
- {id=id, result=res, error=err, jsonrpc=jsonrpc}, BUFSIZE
- ):source()
-end
-
---- Handle a new client connection.
--- @param client client socket
--- @param env superserver environment
-function Server.process(self, client, env)
- local decoder
- local sinkout = client:sink()
- client:setopt("socket", "sndtimeo", 90)
- client:setopt("socket", "rcvtimeo", 90)
-
- local close = false
- local session = {server = self, chain = {}, client = client, env = env,
- localaddr = remapipv6(client:getsockname())}
- local req, stat, response, result, cb
-
- repeat
- local oldchunk = decoder and decoder.chunk
- decoder = json.ActiveDecoder(client:blocksource(nil, RQLIMIT))
- decoder.chunk = oldchunk
-
- result, response, cb = nil, nil, nil
-
- -- Read one request
- stat, req = pcall(decoder.get, decoder)
-
- if stat then
- if type(req) == "table" and type(req.method) == "string"
- and (not req.params or type(req.params) == "table") then
- req.params = req.params or {}
- result, cb = self.root:process(session, req.method, req.params)
- if type(result) == "table" then
- if req.id ~= nil then
- response = self:reply(req.jsonrpc, req.id,
- result.result, result.error)
- end
- close = result.close
- else
- if req.id ~= nil then
- response = self:reply(req.jsonrpc, req.id, nil,
- {code=ERRNO_INTERNAL, message=ERRMSG[ERRNO_INTERNAL]})
- end
- end
- else
- response = self:reply(req.jsonrpc, req.id,
- nil, {code=ERRNO_INVALID, message=ERRMSG[ERRNO_INVALID]})
- end
- else
- if nixio.errno() ~= nixio.const.EAGAIN then
- response = self:reply("2.0", nil,
- nil, {code=ERRNO_PARSE, message=ERRMSG[ERRNO_PARSE]})
- --[[else
- response = self:reply("2.0", nil,
- nil, {code=ERRNO_TIMEOUT, message=ERRMSG_TIMEOUT})]]
- end
- close = true
- end
-
- if response then
- ltn12.pump.all(response, sinkout)
- end
-
- if cb then
- close = cb(client, session, self) or close
- end
- until close
-
- client:shutdown()
- client:close()
-end
diff --git a/libs/lucid-rpc/luasrc/lucid/rpc/system.lua b/libs/lucid-rpc/luasrc/lucid/rpc/system.lua
deleted file mode 100644
index cf3aa6abe..000000000
--- a/libs/lucid-rpc/luasrc/lucid/rpc/system.lua
+++ /dev/null
@@ -1,101 +0,0 @@
---[[
-LuCI - Lua Development Framework
-
-Copyright 2009 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
-
-$Id$
-]]
-
-local type, ipairs = type, ipairs
-local srv = require "luci.lucid.rpc.server"
-local nixio = require "nixio"
-local lucid = require "luci.lucid"
-
---- Internal system functions.
-module "luci.lucid.rpc.system"
-
--- Prepare the RPC module.
-function _factory()
- local mod = srv.Module("System functions"):register({
- echo = echo,
- void = void,
- multicall = srv.Method.extended(multicall),
- authenticate = srv.Method.extended(authenticate)
- })
- mod.checkrestricted = function(self, session, request, ...)
- if request ~= "authenticate" then
- return srv.Module.checkrestricted(self, session, request, ...)
- end
- end
- return mod
-end
-
---- Simple echo test function.
--- @param object to be echoed object
--- @return echo object
-function echo(object)
- return object
-end
-
---- Simple void test function.
-function void()
-
-end
-
---- Accumulate different requests and execute them.
--- @param session Session object
--- @param ...
--- @return overall response object
-function multicall(session, ...)
- local server, responses, response = session.server, {}, nil
- for k, req in ipairs({...}) do
- response = nil
- if type(req) == "table" and type(req.method) == "string"
- and (not req.params or type(req.params) == "table") then
- req.params = req.params or {}
- result = server.root:process(session, req.method, req.params)
- if type(result) == "table" then
- if req.id ~= nil then
- response = {jsonrpc=req.jsonrpc, id=req.id,
- result=result.result, error=result.error}
- end
- else
- if req.id ~= nil then
- response = {jsonrpc=req.jsonrpc, id=req.id,
- result=nil, error={code=srv.ERRNO_INTERNAL,
- message=srv.ERRMSG[ERRNO_INTERNAL]}}
- end
- end
- end
- responses[k] = response
- end
- return responses
-end
-
---- Create or use a new authentication token.
--- @param session Session object
--- @param type Authentication type
--- @param entity Authentication enttity (username)
--- @param key Authentication key (password)
--- @return boolean status
-function authenticate(session, type, entity, key)
- if not type then
- session.user = nil
- return true
- elseif type == "plain" then
- local pwe = nixio.getsp and nixio.getsp(entity) or nixio.getpw(entity)
- local pwh = pwe and (pwe.pwdp or pwe.passwd)
- if not pwh or #pwh < 1 or nixio.crypt(key, pwh) ~= pwh then
- return nil
- else
- session.user = entity
- return true
- end
- end
-end \ No newline at end of file
diff --git a/libs/lucid/Makefile b/libs/lucid/Makefile
deleted file mode 100644
index f7fac7740..000000000
--- a/libs/lucid/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-include ../../build/config.mk
-include ../../build/module.mk
diff --git a/libs/lucid/docs/OVERVIEW b/libs/lucid/docs/OVERVIEW
deleted file mode 100644
index ca742ddd6..000000000
--- a/libs/lucid/docs/OVERVIEW
+++ /dev/null
@@ -1,75 +0,0 @@
- LuCId Network Superserver in Lua
-
-*** Abstract ***
-LuCId is a network superserver written in Lua based on the nixio POSIX library.
-It supports IPv4, IPv6, TLS, asynchronous and synchronous IO and can be extended
-to handle any kind of IO events on file descriptors. LuCId is also able to
-generate RSA private keys and self-signed certificates on demand if the px5g
-keymaster library is available. Both nixio and px5g are libraries created
-by the LuCI developers.
-
-
-*** Configuration ***
-LuCId uses the UCI Universal Configuration Interface as configuration backend.
-
-There are 4 types of configuration sections and one named section defined:
-The main section of type "lucid" defines the basic framework parameters of LuCId
-These include:
- * pollinterval: Internal polling interval
- * threadlimit: Overall maximum number of child processes
- * daemonize: Whether to daemonize at startup
- * debug: Whether to enable debug output in syslog
-
-
-The "tcpserver" section type provides the framework for TCP servers:
-Parameters:
- * entrypoint: Lua module entrypoint (provides a prepare_daemon function)
-
-The "daemon" sections define instances of servers.
-Parameters may include:
- * slave: Server slave
- * publisher: Publishers to be served by this daemon
- * enabled: Flag (0/1) whether this daemon should be started
- * address: List of ports / addresses to be bound too, if applicable
- * encryption: Flag (disabled/enabled) whether to enforce encryption
- * tls: Reference to the TLS configuration section to use
-
-The "...Publisher" sections define services to be published through daemons.
-Publishers definitions should be daemon and protocol independent whenever
-possible. Publishers should also implement access restrictions for certain
-network interfaces and for specified UNIX user accounts.
-Publishers usually define but are not required to use the following Parameters:
- * name: Published Name
- * physical: Physical source path
- * virtual: Virtual resource path
- * domain: Any kind of domain or realm specification
- * read: ACL containing entities allowed to read the given resource
- * write: -"-
- * exec: -"-
-
-The "tls" sections describe TLS security specifications for TCP servers.
-Parameters:
- * key: Private Key file
- * cert: Certificate file
- * type: Type of certificate and key files (pem, asn1)
- * generate: Flag (0/1) to determine whether LuCId should generate
- keys and self-signed certificates if the certificate is not available and
- the px5g RSA Keymaster is available
-
-
-
-*** Workflow ***
-In the preparation phase LuCId loads its configuration using the specification
-given above and prepares its servers, daemons and publishers. It also allocates
-resources such as binding sockets or preparing encryption credentials.
-If everything could be setup correctly LuCId will daemonize - if requested. If
-any errors occur in the preparation phase, LuCId will write to the system logger
-and exit.
-
-After daemonizing the main process is responsible for keeping a list of
-file descriptors that LuCId is polling regularly to handle incoming data events.
-Data events are for example new TCP connection attempts which could cause the
-superserver to fork a new process and invoke a registered handler.
-
-Whenever a sub-process is about to be generate LuCId checks if given resource
-limits are still met. \ No newline at end of file
diff --git a/libs/lucid/hostfiles/etc/config/lucid b/libs/lucid/hostfiles/etc/config/lucid
deleted file mode 100644
index a88835cdd..000000000
--- a/libs/lucid/hostfiles/etc/config/lucid
+++ /dev/null
@@ -1,75 +0,0 @@
-config lucid main
- option pollinterval 15000
- option daemon 1
- option debug 1
- list supports tcpserver
- list supports server
-
-config DirectoryPublisher webroot
- option name 'Webserver Share'
- option physical host/www
- option virtual ''
- option domain ''
-
-config LuciWebPublisher luciweb
- option name 'LuCI Webapplication'
- option physical ''
- list virtual /luci
- option domain ''
- option home 1
-
-config RPCPublisher mainrpc
- option namespace 'luci.lucid.rpc'
- list export system
- list export ruci
- list exec ':lo'
- list exec 'root'
-
-config tcpserver httpd
- option entrypoint "luci.lucid.http"
- list supports DirectoryPublisher
- list supports LuciWebPublisher
-
-config tcpserver rpcd
- option entrypoint "luci.lucid.rpc"
- list supports RPCPublisher
-
-config daemon http
- option slave httpd
- list address 8080
- list publisher webroot
- list publisher luciweb
- option enabled 1
-
-config daemon https
- option slave httpd
- list address 4443
- list publisher webroot
- list publisher luciweb
- option enabled 1
- option encryption enable
- option tls sdk_tls
-
-config tls sdk_tls
- option generate 1
- option key /tmp/lucid-tls.key
- option cert /tmp/lucid-tls.cert
- option type asn1
-
-config daemon rpc
- option slave rpcd
- list address 12900
- list publisher mainrpc
- option enabled 1
-
-config 'daemon' 'splashr'
- option 'slave' 'httpd'
- list 'address' '8082'
- list 'publisher' 'splashredir'
- option 'enabled' '1'
-
-config 'Redirector' 'splashredir'
- option 'name' 'Splashd'
- option 'virtual' '/'
- option 'physical' ':80/luci/splash'
-
diff --git a/libs/lucid/luasrc/lucid.lua b/libs/lucid/luasrc/lucid.lua
deleted file mode 100644
index 38b34fde9..000000000
--- a/libs/lucid/luasrc/lucid.lua
+++ /dev/null
@@ -1,348 +0,0 @@
---[[
-LuCI - Lua Development Framework
-
-Copyright 2009 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
-
-$Id$
-]]
-
-local nixio = require "nixio"
-local table = require "table"
-local uci = require "luci.model.uci"
-local os = require "os"
-local io = require "io"
-
-local pairs, require, pcall, assert, type = pairs, require, pcall, assert, type
-local ipairs, tonumber, collectgarbage = ipairs, tonumber, collectgarbage
-
-
-module "luci.lucid"
-
-local slaves = {}
-local pollt = {}
-local tickt = {}
-local tpids = {}
-local tcount = 0
-local ifaddrs = nixio.getifaddrs()
-
-cursor = uci.cursor()
-state = uci.cursor_state()
-UCINAME = "lucid"
-
-local cursor = cursor
-local state = state
-local UCINAME = UCINAME
-local SSTATE = "/tmp/.lucid_store"
-
-
---- Starts a new LuCId superprocess.
-function start()
- state:revert(UCINAME, "main")
-
- prepare()
-
- local detach = cursor:get(UCINAME, "main", "daemonize")
- if detach == "1" then
- local stat, code, msg = daemonize()
- if not stat then
- nixio.syslog("crit", "Unable to detach process: " .. msg .. "\n")
- ox.exit(2)
- end
- end
-
- state:set(UCINAME, "main", "pid", nixio.getpid())
- state:save(UCINAME)
-
- run()
-end
-
---- Returns the PID of the currently active LuCId process.
-function running()
- local pid = tonumber(state:get(UCINAME, "main", "pid"))
- return pid and nixio.kill(pid, 0) and pid
-end
-
---- Stops any running LuCId superprocess.
-function stop()
- local pid = tonumber(state:get(UCINAME, "main", "pid"))
- if pid then
- return nixio.kill(pid, nixio.const.SIGTERM)
- end
- return false
-end
-
---- Prepares the slaves, daemons and publishers, allocate resources.
-function prepare()
- local debug = tonumber((cursor:get(UCINAME, "main", "debug")))
-
- nixio.openlog("lucid", "pid", "perror")
- if debug ~= 1 then
- nixio.setlogmask("warning")
- end
-
- cursor:foreach(UCINAME, "daemon", function(config)
- if config.enabled ~= "1" then
- return
- end
-
- local key = config[".name"]
- if not config.slave then
- nixio.syslog("crit", "Daemon "..key.." is missing a slave\n")
- os.exit(1)
- else
- nixio.syslog("info", "Initializing daemon " .. key)
- end
-
- state:revert(UCINAME, key)
-
- local daemon, code, err = prepare_daemon(config)
- if daemon then
- state:set(UCINAME, key, "status", "started")
- nixio.syslog("info", "Prepared daemon " .. key)
- else
- state:set(UCINAME, key, "status", "error")
- state:set(UCINAME, key, "error", err)
- nixio.syslog("err", "Failed to initialize daemon "..key..": "..
- err .. "\n")
- end
- end)
-end
-
---- Run the superprocess if prepared before.
--- This main function of LuCId will wait for events on given file descriptors.
-function run()
- local pollint = tonumber((cursor:get(UCINAME, "main", "pollinterval")))
- local threadlimit = tonumber((cursor:get(UCINAME, "main", "threadlimit")))
-
- while true do
- local stat, code = nixio.poll(pollt, pollint)
-
- if stat and stat > 0 then
- local ok = false
- for _, polle in ipairs(pollt) do
- if polle.revents ~= 0 and polle.handler then
- ok = ok or polle.handler(polle)
- end
- end
- if not ok then
- -- Avoid high CPU usage if thread limit is reached
- nixio.nanosleep(0, 100000000)
- end
- elseif stat == 0 then
- ifaddrs = nixio.getifaddrs()
- end
-
- for _, cb in ipairs(tickt) do
- cb()
- end
-
- local pid, stat, code = nixio.wait(-1, "nohang")
- while pid and pid > 0 do
- nixio.syslog("info", "Buried thread: " .. pid)
- if tpids[pid] then
- tcount = tcount - 1
- if tpids[pid] ~= true then
- tpids[pid](pid, stat, code)
- end
- tpids[pid] = nil
- end
- pid, stat, code = nixio.wait(-1, "nohang")
- end
- end
-end
-
---- Add a file descriptor for the main loop and associate handler functions.
--- @param polle Table containing: {fd = FILE DESCRIPTOR, events = POLL EVENTS,
--- handler = EVENT HANDLER CALLBACK}
--- @see unregister_pollfd
--- @return boolean status
-function register_pollfd(polle)
- pollt[#pollt+1] = polle
- return true
-end
-
---- Unregister a file desciptor and associate handler from the main loop.
--- @param polle Poll descriptor
--- @see register_pollfd
--- @return boolean status
-function unregister_pollfd(polle)
- for k, v in ipairs(pollt) do
- if v == polle then
- table.remove(pollt, k)
- return true
- end
- end
- return false
-end
-
---- Close all registered file descriptors from main loop.
--- This is useful for forked child processes.
-function close_pollfds()
- for k, v in ipairs(pollt) do
- if v.fd and v.fd.close then
- v.fd:close()
- end
- end
-end
-
---- Register a tick function that will be called at each cycle of the main loop.
--- @param cb Callback
--- @see unregister_tick
--- @return boolean status
-function register_tick(cb)
- tickt[#tickt+1] = cb
- return true
-end
-
---- Unregister a tick function from the main loop.
--- @param cb Callback
--- @see register_tick
--- @return boolean status
-function unregister_tick(cb)
- for k, v in ipairs(tickt) do
- if v == cb then
- table.remove(tickt, k)
- return true
- end
- end
- return false
-end
-
---- Tests whether a given number of processes can be created.
--- @oaram num Processes to be created
--- @return boolean status
-function try_process(num)
- local threadlimit = tonumber((cursor:get(UCINAME, "main", "threadlimit")))
- return not threadlimit or (threadlimit - tcount) >= (num or 1)
-end
-
---- Create a new child process from a Lua function and assign a destructor.
--- @param threadcb main function of the new process
--- @param waitcb destructor callback
--- @return process identifier or nil, error code, error message
-function create_process(threadcb, waitcb)
- local threadlimit = tonumber(cursor:get(UCINAME, "main", "threadlimit"))
- if threadlimit and tcount >= threadlimit then
- nixio.syslog("warning", "Cannot create thread: process limit reached")
- return nil
- else
- collectgarbage("collect")
- end
- local pid, code, err = nixio.fork()
- if pid and pid ~= 0 then
- nixio.syslog("info", "Created thread: " .. pid)
- tpids[pid] = waitcb or true
- tcount = tcount + 1
- elseif pid == 0 then
- local code = threadcb()
- os.exit(code)
- else
- nixio.syslog("err", "Unable to fork(): " .. err)
- end
- return pid, code, err
-end
-
---- Prepare a daemon from a given configuration table.
--- @param config Configuration data.
--- @return boolean status or nil, error code, error message
-function prepare_daemon(config)
- nixio.syslog("info", "Preparing daemon " .. config[".name"])
- local modname = cursor:get(UCINAME, config.slave)
- if not modname then
- return nil, -1, "invalid slave"
- end
-
- local stat, module = pcall(require, _NAME .. "." .. modname)
- if not stat or not module.prepare_daemon then
- return nil, -2, "slave type not supported"
- end
-
- config.slave = prepare_slave(config.slave)
-
- return module.prepare_daemon(config, _M)
-end
-
---- Prepare a slave.
--- @param name slave name
--- @return table containing slave module and configuration or nil, error message
-function prepare_slave(name)
- local slave = slaves[name]
- if not slave then
- local config = cursor:get_all(UCINAME, name)
-
- local stat, module = pcall(require, config and config.entrypoint)
- if stat then
- slave = {module = module, config = config}
- end
- end
-
- if slave then
- return slave
- else
- return nil, module
- end
-end
-
---- Return a list of available network interfaces on the host.
--- @return table returned by nixio.getifaddrs()
-function get_interfaces()
- return ifaddrs
-end
-
---- Revoke process privileges.
--- @param user new user name or uid
--- @param group new group name or gid
--- @return boolean status or nil, error code, error message
-function revoke_privileges(user, group)
- if nixio.getuid() == 0 then
- return nixio.setgid(group) and nixio.setuid(user)
- end
-end
-
---- Return a secure UCI cursor.
--- @return UCI cursor
-function securestate()
- local stat = nixio.fs.stat(SSTATE) or {}
- local uid = nixio.getuid()
- if stat.type ~= "dir" or (stat.modedec % 100) ~= 0 or stat.uid ~= uid then
- nixio.fs.remover(SSTATE)
- if not nixio.fs.mkdir(SSTATE, 700) then
- local errno = nixio.errno()
- nixio.syslog("err", "Integrity check on secure state failed!")
- return nil, errno, nixio.perror(errno)
- end
- end
-
- return uci.cursor(nil, SSTATE)
-end
-
---- Daemonize the process.
--- @return boolean status or nil, error code, error message
-function daemonize()
- if nixio.getppid() == 1 then
- return
- end
-
- local pid, code, msg = nixio.fork()
- if not pid then
- return nil, code, msg
- elseif pid > 0 then
- os.exit(0)
- end
-
- nixio.setsid()
- nixio.chdir("/")
-
- local devnull = nixio.open("/dev/null", nixio.open_flags("rdwr"))
- nixio.dup(devnull, nixio.stdin)
- nixio.dup(devnull, nixio.stdout)
- nixio.dup(devnull, nixio.stderr)
-
- return true
-end
diff --git a/libs/lucid/luasrc/lucid/tcpserver.lua b/libs/lucid/luasrc/lucid/tcpserver.lua
deleted file mode 100644
index 266ea29e4..000000000
--- a/libs/lucid/luasrc/lucid/tcpserver.lua
+++ /dev/null
@@ -1,254 +0,0 @@
---[[
-LuCI - Lua Development Framework
-
-Copyright 2009 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
-
-$Id$
-]]
-
-local os = require "os"
-local fs = require "nixio.fs"
-local nixio = require "nixio"
-local lucid = require "luci.lucid"
-
-local ipairs, type, require, setmetatable = ipairs, type, require, setmetatable
-local pairs, print, tostring, unpack = pairs, print, tostring, unpack
-local pcall = pcall
-
-module "luci.lucid.tcpserver"
-
-local cursor = lucid.cursor
-local UCINAME = lucid.UCINAME
-
-local tcpsockets = {}
-
---- Prepare a daemon and allocate its resources. (superserver callback)
--- @param config configuration table
--- @param server LuCId basemodule
--- @return binary data
-function prepare_daemon(config, server)
- nixio.syslog("info", "Preparing TCP-Daemon " .. config[".name"])
- if type(config.address) ~= "table" then
- config.address = {config.address}
- end
-
- local sockets, socket, code, err = {}
- local sopts = {reuseaddr = 1}
- for _, addr in ipairs(config.address) do
- local host, port = addr:match("(.-):?([^:]*)")
- if not host then
- nixio.syslog("err", "Invalid address: " .. addr)
- return nil, -5, "invalid address format"
- elseif #host == 0 then
- host = nil
- end
- socket, code, err = prepare_socket(config.family, host, port, sopts)
- if socket then
- sockets[#sockets+1] = socket
- end
- end
-
- nixio.syslog("info", "Sockets bound for " .. config[".name"])
-
- if #sockets < 1 then
- return nil, -6, "no sockets bound"
- end
-
- nixio.syslog("info", "Preparing publishers for " .. config[".name"])
-
- local publisher = {}
- for k, pname in ipairs(config.publisher) do
- local pdata = cursor:get_all(UCINAME, pname)
- if pdata then
- publisher[#publisher+1] = pdata
- else
- nixio.syslog("err", "Publisher " .. pname .. " not found")
- end
- end
-
- nixio.syslog("info", "Preparing TLS for " .. config[".name"])
-
- local tls = prepare_tls(config.tls)
- if not tls and config.encryption == "enable" then
- for _, s in ipairs(sockets) do
- s:close()
- end
- return nil, -4, "Encryption requested, but no TLS context given"
- end
-
- nixio.syslog("info", "Invoking daemon factory for " .. config[".name"])
- local handler, err = config.slave.module.factory(publisher, config)
- if not handler then
- for _, s in ipairs(sockets) do
- s:close()
- end
- return nil, -3, err
- else
- local pollin = nixio.poll_flags("in")
- for _, s in ipairs(sockets) do
- server.register_pollfd({
- fd = s,
- events = pollin,
- revents = 0,
- handler = accept,
- accept = handler,
- config = config,
- publisher = publisher,
- tls = tls
- })
- end
- return true
- end
-end
-
---- Accept a new TCP connection. (server callback)
--- @param polle Poll descriptor
--- @return handler process id or nil, error code, error message
-function accept(polle)
- if not lucid.try_process() then
- return false
- end
- local socket, host, port = polle.fd:accept()
- if not socket then
- return nixio.syslog("warning", "accept() failed: " .. port)
- end
-
- socket:setblocking(true)
-
- local function thread()
- lucid.close_pollfds()
- local inst = setmetatable({
- host = host, port = port, interfaces = lucid.get_interfaces()
- }, {__index = polle})
- if polle.config.encryption then
- socket = polle.tls:create(socket)
- if not socket:accept() then
- socket:close()
- return nixio.syslog("warning", "TLS handshake failed: " .. host)
- end
- end
-
- return polle.accept(socket, inst)
- end
-
- local stat = {lucid.create_process(thread)}
- socket:close()
- return unpack(stat)
-end
-
---- Prepare a TCP server socket.
--- @param family protocol family ["inetany", "inet6", "inet"]
--- @param host host
--- @param port port
--- @param opts table of socket options
--- @param backlog socket backlog
--- @return socket, final socket family
-function prepare_socket(family, host, port, opts, backlog)
- nixio.syslog("info", "Preparing socket for port " .. port)
- backlog = backlog or 1024
- family = family or "inetany"
- opts = opts or {}
-
- local inetany = family == "inetany"
- family = inetany and "inet6" or family
-
- local socket, code, err = nixio.socket(family, "stream")
- if not socket and inetany then
- family = "inet"
- socket, code, err = nixio.socket(family, "stream")
- end
-
- if not socket then
- return nil, code, err
- end
-
- for k, v in pairs(opts) do
- socket:setsockopt("socket", k, v)
- end
-
- local stat, code, err = socket:bind(host, port)
- if not stat then
- return nil, code, err
- end
-
- stat, code, err = socket:listen(backlog)
- if not stat then
- return nil, code, err
- end
-
- socket:setblocking(false)
-
- return socket, family
-end
-
---- Prepare a TLS server context and load keys and certificates.
--- May invoke px5g to create keys and certificate on demand if available.
--- @param tlskey TLS configuration identifier
--- @return TLS server conext or nil
-function prepare_tls(tlskey)
- local tls
- if nixio.tls and tlskey and cursor:get(UCINAME, tlskey) then
- tls = nixio.tls("server")
-
- local make = cursor:get(UCINAME, tlskey, "generate") == "1"
- local key = cursor:get(UCINAME, tlskey, "key")
- local xtype = make and "asn1" or cursor:get(UCINAME, tlskey, "type")
- local cert = cursor:get(UCINAME, tlskey, "cert")
- local ciphers = cursor:get(UCINAME, tlskey, "ciphers")
-
- if make and (not fs.access(key) or not fs.access(cert)) then
- local CN = cursor:get(UCINAME, tlskey, "CN")
- local O = cursor:get(UCINAME, tlskey, "O")
- local bits = 2048
-
- local data = {
- CN = CN or nixio.uname().nodename,
- O = not O and "LuCId Keymaster" or #O > 0 and O
- }
-
- local stat, px5g = pcall(require, "px5g")
- if not stat then
- return nixio.syslog("err", "Unable to load PX5G Keymaster")
- end
-
- nixio.syslog("warning", "PX5G: Generating private key")
- local rk = px5g.genkey(bits)
- local keyfile = nixio.open(key, "w", 600)
- if not rk or not keyfile or not keyfile:writeall(rk:asn1()) then
- return nixio.syslog("err", "Unable to generate private key")
- end
- keyfile:close()
-
- nixio.syslog("warning", "PX5G: Generating self-signed certificate")
- if not fs.writefile(cert, rk:create_selfsigned(data,
- os.time(), os.time() + 3600 * 24 * 366 * 15)) then
- return nixio.syslog("err", "Unable to generate certificate")
- end
- end
-
- if cert then
- if not tls:set_cert(cert, xtype) then
- nixio.syslog("err", "Unable to load certificate: " .. cert)
- end
- end
- if key then
- if not tls:set_key(key, xtype) then
- nixio.syslog("err", "Unable to load private key: " .. key)
- end
- end
-
- if ciphers then
- if type(ciphers) == "table" then
- ciphers = table.concat(ciphers, ":")
- end
- tls:set_ciphers(ciphers)
- end
- end
- return tls
-end
diff --git a/libs/lucid/root/etc/config/lucid b/libs/lucid/root/etc/config/lucid
deleted file mode 100644
index 07c32c16c..000000000
--- a/libs/lucid/root/etc/config/lucid
+++ /dev/null
@@ -1,52 +0,0 @@
-config lucid main
- option pollinterval 15000
- option threadlimit 10
- option daemonize 1
- option debug 0
- list supports tcpserver
- list supports server
-
-config DirectoryPublisher webroot
- option name 'Webserver Share'
- option physical /www
- option virtual ''
- option domain ''
-
-config LuciWebPublisher luciweb
- option name 'LuCI Webapplication'
- option physical ''
- option home 1
- list virtual /luci
- list virtual /cgi-bin/luci
- option domain ''
-
-config tcpserver httpd
- option entrypoint "luci.lucid.http"
- list supports DirectoryPublisher
- list supports LuciWebPublisher
-
-config daemon http
- option slave httpd
- list address 80
- list publisher webroot
- list publisher luciweb
- option nokeepalive 1
- option memlimit 1572864
- option enabled 1
-
-config daemon https
- option slave httpd
- list address 443
- list publisher webroot
- list publisher luciweb
- option nokeepalive 1
- option memlimit 1572864
- option enabled 1
- option tls maincert
- option encryption enable
-
-config tls maincert
- option key /etc/nixio/rsa_main.der
- option cert /etc/nixio/cert_main.der
- option type asn1
- option generate 1
diff --git a/libs/lucid/root/etc/init.d/lucid b/libs/lucid/root/etc/init.d/lucid
deleted file mode 100755
index 1b2b04ed4..000000000
--- a/libs/lucid/root/etc/init.d/lucid
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh /etc/rc.common
-PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
-NAME=lucid
-DESC="LuCId superserver"
-START=49
-
-test -x $DAEMON || exit 0
-set -e
-
-start() {
- echo -n "Starting $DESC: $NAME"
- lua -lluci.lucid -e 'luci.lucid.start()'
- echo "."
-}
-
-stop() {
- echo -n "Stopping $DESC: $NAME"
- lua -lluci.lucid -e 'luci.lucid.stop()'
- echo "."
-}
-
-restart() {
- # echo -n "Restarting $DESC: $NAME... "
- # start-stop-daemon -K -s HUP -q -x $DAEMON
- # echo "done."
- stop
- sleep 3
- start
-}
-
-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."
- restart
-}