smr/src/smr.c

280 lines
6.9 KiB
C

#include <kore/kore.h>
#include <kore/http.h>
#ifdef BUILD_PROD
#include <luajit.h>
#else
#define LUA_OK 0
#endif
#include <lauxlib.h>
#include <lua.h>
#include <lualib.h>
#include "smr.h"
#include "libkore.h"
#include "libcrypto.h"
#include <dirent.h>
#include <kore/seccomp.h>
int home(struct http_request *);
int post_story(struct http_request *);
int edit_story(struct http_request *);
int edit_bio(struct http_request *);
int read_story(struct http_request *);
int login(struct http_request *);
int logout(struct http_request *);
int claim(struct http_request *);
int download(struct http_request *);
int preview(struct http_request *);
int search(struct http_request *);
int archive(struct http_request *);
int api(struct http_request *);
int style(struct http_request *);
int miligram(struct http_request *);
int delete(struct http_request *);
int do_lua(struct http_request *req, const char *name);
int errhandeler(lua_State *);
lua_State *L;
/* These should be defined in in kore somewhere and included here */
void kore_worker_configure(void);
void kore_worker_teardown(void);
/*
static / index
static / _post post
static / _edit edit
dynamic / .* read
static / _login login
static / _claim claim
*/
/*Allow seccomp things for luajit and sqlite*/
KORE_SECCOMP_FILTER("app",
KORE_SYSCALL_ALLOW(pread64),
KORE_SYSCALL_ALLOW(pwrite64),
KORE_SYSCALL_ALLOW(fdatasync),
KORE_SYSCALL_ALLOW(unlinkat),
KORE_SYSCALL_ALLOW(mremap),
KORE_SYSCALL_ALLOW(newfstatat),
KORE_SYSCALL_ALLOW(getdents64),
KORE_SYSCALL_ALLOW(gettimeofday),
KORE_SYSCALL_ALLOW(fchown)
);
int
errhandeler(lua_State *state){
printf("Error: %s\n",lua_tostring(state,1));//"error"
lua_getglobal(state,"debug");//"error",{debug}
lua_getglobal(state,"print");//"error",{debug},print()
lua_getfield(state,-2,"traceback");//"error",{debug},print(),traceback()
lua_call(state,0,1);//"error",{debug},print(),"traceback"
lua_call(state,1,0);//"error",{debug}
printf("Called print()\n");
lua_getfield(state,-1,"traceback");//"error",{debug},traceback()
printf("got traceback\n");
lua_call(state,0,1);//"error",{debug},"traceback"
lua_pushstring(state,"\n");
printf("called traceback\n");
lua_pushvalue(state,-4);//"error",{debug},"traceback","error"
printf("pushed error\n");
lua_concat(state,3);//"error",{debug},"traceback .. error"
printf("concated\n");
int ref = luaL_ref(state,LUA_REGISTRYINDEX);//"error",{debug}
lua_pop(state,2);//
lua_rawgeti(state,LUA_REGISTRYINDEX,ref);//"traceback .. error"
return 1;
}
int
do_lua(struct http_request *req, const char *name){
//printf("About to do lua %s\n",name);
lua_pushcfunction(L,errhandeler);
lua_getglobal(L,name);//err(),name()
if(!lua_isfunction(L,-1)){
printf("Could not find a method named %s\n",name);
lua_pop(L,2);//
return (KORE_RESULT_OK);
}
lua_pushlightuserdata(L,req);//err,name(),ud_req
int err = lua_pcall(L,1,0,-3);
if(err != LUA_OK){
size_t retlen;
const char *ret = lua_tolstring(L,-1,&retlen);
printf("Failed to run %s: %s\n",name,lua_tostring(L,-1));
http_response(req, 500, ret, retlen);
lua_pop(L,lua_gettop(L));
return (KORE_RESULT_OK);
}
return KORE_RESULT_OK;
}
/***
Called at the endpoint <domain>/_paste.
This method doesn't need any parameters for GET requests,
and expects the following parametrs when POSTing:
* title :: string
* text :: string
* markup :: string - a valid markup type
In addition to the normal assets, this page includes
suggest_tags.js, which suggests tags that have been
submitted to the site before.
@function _G.paste
@custom http_method GET POST
@param http_request req The request to service
***/
int
post_story(struct http_request *req){
return do_lua(req,"paste");
}
int
edit_story(struct http_request *req){
return do_lua(req,"edit");
}
int
edit_bio(struct http_request *req){
return do_lua(req,"edit_bio");
}
int
read_story(struct http_request *req){
return do_lua(req,"read");
}
int
login(struct http_request *req){
return do_lua(req,"login");
}
int
logout(struct http_request *req){
return do_lua(req,"logout");
}
int
claim(struct http_request *req){
return do_lua(req,"claim");
}
int
download(struct http_request *req){
return do_lua(req,"download");
}
int
preview(struct http_request *req){
return do_lua(req,"preview");
}
int
search(struct http_request *req){
return do_lua(req,"search");
}
int
archive(struct http_request *req){
/*
struct kore_fileref *ref = kore_fileref_get("data/archive.zip",1);
if(ref != NULL){
http_response_fileref(ref,HTTP_STATUS_OK,ref);
kore_fileref_release(ref);
return KORE_RESULT_OK;
}else{
char msg[] = "Failed to create file ref";
http_response(req,200,msg,strlen(msg));
return KORE_RESULT_OK;
}
*/
return do_lua(req,"archive");
}
int
api(struct http_request *req){
return do_lua(req,"api");
}
int
home(struct http_request *req){
return do_lua(req,"home");
}
int
delete(struct http_request *req){
return do_lua(req,"delete");
}
void
kore_worker_configure(void){
printf("Configuring worker...\n");
int err;
/*DIR *dp;*/
/*struct dirent *ep;*/
/*dp = opendir("./");*/
/*if(dp != NULL){*/
/*while(ep = readdir(dp)){*/
/*printf("%s\n",ep->d_name);*/
/*}*/
/*closedir(dp);*/
/*}*/
L = luaL_newstate();
// Open libraries
luaL_openlibs(L);
load_kore_libs(L);
load_crypto_libs(L);
// Set package.path
lua_getglobal(L,"package"); // {package}
lua_getfield(L,-1,"path"); // {package}, "package.path"
lua_pushstring(L,";/var/smr/?.lua;/usr/local/share/lua/5.1/?.lua"); // {package}, "package.path", "/var/smr/?.lua"
lua_concat(L,2); //{package}, "package.path;/var/app_name/?.lua"
lua_setfield(L,-2,"path"); //{package}
lua_getfield(L,-1,"cpath");
lua_pushstring(L,";/usr/local/lib/lua/5.1/?.so");
lua_concat(L,2);
lua_setfield(L,-2,"cpath");
lua_pop(L,1);
// Run init
lua_pushcfunction(L,errhandeler);
printf("About to run loadfile...\n");
luaL_loadfile(L,SM_INIT);
printf("Done running loadfile...\n");
if(!lua_isfunction(L,-1)){//failed to loadfile()
printf("Failed to load %s: %s\n",SM_INIT,lua_tostring(L,-1));
lua_pop(L,1);
return;
}
printf("About to pcall\n");
err = lua_pcall(L,0,LUA_MULTRET,-2);
printf("Done pcalling\n");
//err = luaL_dofile(L,"init.lua");
if(err){
printf("Failed to run %s\n",SM_INIT);
return;
}
lua_pushcfunction(L,errhandeler);
lua_getglobal(L,"configure");
err = lua_pcall(L,0,0,-2);
if(err != LUA_OK){
printf("Failed to run configure(): %s\n",lua_tostring(L,-1));
lua_pop(L,2);
return;
}
lua_pop(L,lua_gettop(L));
printf("Finished configuring worker\n");
}
void
kore_worker_teardown(void){
int err;
lua_pushcfunction(L,errhandeler);
lua_getglobal(L,"teardown");
err = lua_pcall(L,0,0,1);
if(err != LUA_OK){
printf("Failed to run configure(): %s\n",lua_tostring(L,-1));
lua_pop(L,2);
return;
}
lua_close(L);
}