diff options
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/lar/openwrt/050-lar-source-loader.patch | 408 |
1 files changed, 408 insertions, 0 deletions
diff --git a/contrib/lar/openwrt/050-lar-source-loader.patch b/contrib/lar/openwrt/050-lar-source-loader.patch new file mode 100644 index 000000000..fbf21f7be --- /dev/null +++ b/contrib/lar/openwrt/050-lar-source-loader.patch @@ -0,0 +1,408 @@ +diff -Nurb lua-5.1.4.orig/src/Makefile lua-5.1.4/src/Makefile +--- lua-5.1.4.orig/src/Makefile 2009-04-06 21:36:52.000000000 +0200 ++++ lua-5.1.4/src/Makefile 2009-04-06 23:04:42.000000000 +0200 +@@ -28,7 +28,7 @@ + lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \ + lundump.o lvm.o lzio.o lnum.o + LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \ +- lstrlib.o loadlib.o linit.o ++ lstrlib.o loadlib.o linit.o lar.o + + LUA_T= lua + LUA_O= lua.o +diff -Nurb lua-5.1.4.orig/src/lar.c lua-5.1.4/src/lar.c +--- lua-5.1.4.orig/src/lar.c 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4/src/lar.c 2009-04-07 00:35:55.000000000 +0200 +@@ -0,0 +1,243 @@ ++#include "lar.h" ++ ++int lar_read32( int fd, uint32_t *val ) ++{ ++ uint8_t buffer[5]; ++ ++ if( read(fd, buffer, 4) < 4 ) ++ LAR_DIE("Unexpected EOF while reading data"); ++ ++ buffer[4] = 0; ++ *val = ntohl(*((uint32_t *) buffer)); ++ ++ return 0; ++} ++ ++int lar_read16( int fd, uint16_t *val ) ++{ ++ uint8_t buffer[3]; ++ ++ if( read(fd, buffer, 2) < 2 ) ++ LAR_DIE("Unexpected EOF while reading data"); ++ ++ buffer[2] = 0; ++ *val = ntohs(*((uint16_t *) buffer)); ++ ++ return 0; ++} ++ ++lar_index * lar_get_index( lar_archive *ar ) ++{ ++ uint32_t i; ++ uint32_t idx_offset; ++ uint32_t idx_length; ++ lar_index *idx_map, *idx_ptr; ++ ++ if( lseek(ar->fd, -(sizeof(idx_offset)), SEEK_END) == -1 ) ++ LAR_DIE("Unable to seek to end of archive"); ++ ++ lar_read32(ar->fd, &idx_offset); ++ idx_length = ( ar->length - idx_offset - sizeof(idx_offset) ); ++ ++ if( lseek(ar->fd, idx_offset, SEEK_SET) == -1 ) ++ LAR_DIE("Unable to seek to archive index"); ++ ++ ++ idx_map = NULL; ++ ++ for( i = 0; i < idx_length; \ ++ i += (sizeof(lar_index) - sizeof(char *)) ++ ) { ++ idx_ptr = (lar_index *)malloc(sizeof(lar_index)); ++ ++ lar_read32(ar->fd, &idx_ptr->noffset); ++ lar_read32(ar->fd, &idx_ptr->nlength); ++ lar_read32(ar->fd, &idx_ptr->foffset); ++ lar_read32(ar->fd, &idx_ptr->flength); ++ lar_read16(ar->fd, &idx_ptr->type); ++ lar_read16(ar->fd, &idx_ptr->flags); ++ ++ idx_ptr->next = idx_map; ++ idx_map = idx_ptr; ++ } ++ ++ return idx_map; ++} ++ ++uint32_t lar_get_filename( lar_archive *ar, ++ lar_index *idx_ptr, char *filename ++) { ++ if( idx_ptr->nlength >= LAR_FNAME_BUFFER ) ++ LAR_DIE("Filename exceeds maximum allowed length"); ++ ++ if( lseek(ar->fd, idx_ptr->noffset, SEEK_SET) == -1 ) ++ LAR_DIE("Unexpected EOF while seeking filename"); ++ ++ if( read(ar->fd, filename, idx_ptr->nlength) < idx_ptr->nlength ) ++ LAR_DIE("Unexpected EOF while reading filename"); ++ ++ filename[idx_ptr->nlength] = 0; ++ ++ return idx_ptr->nlength; ++} ++ ++lar_member * lar_open_member( lar_archive *ar, const char *name ) ++{ ++ lar_index *idx_ptr = ar->index; ++ lar_member *member; ++ char memberfile[LAR_FNAME_BUFFER]; ++ char *memberdata; ++ size_t pgsz = getpagesize(); ++ ++ while(idx_ptr) ++ { ++ lar_get_filename(ar, idx_ptr, memberfile); ++ ++ if( !strncmp(memberfile, name, idx_ptr->nlength) ) ++ { ++ memberdata = mmap( ++ 0, idx_ptr->flength + ( idx_ptr->foffset % pgsz ), ++ PROT_READ, MAP_PRIVATE, ar->fd, ++ idx_ptr->foffset - ( idx_ptr->foffset % pgsz ) ++ ); ++ ++ if( memberdata == MAP_FAILED ) ++ LAR_DIE("Failed to mmap() member data"); ++ ++ member = (lar_member *)malloc(sizeof(lar_member)); ++ member->type = idx_ptr->type; ++ member->flags = idx_ptr->flags; ++ member->length = idx_ptr->flength; ++ member->data = &memberdata[idx_ptr->foffset % pgsz]; ++ ++ member->mmap = memberdata; ++ member->mlen = idx_ptr->flength + ( idx_ptr->foffset % pgsz ); ++ ++ return member; ++ } ++ ++ idx_ptr = idx_ptr->next; ++ } ++ ++ return NULL; ++} ++ ++int lar_close_member( lar_member *member ) ++{ ++ int stat = munmap(member->mmap, member->mlen); ++ free(member); ++ ++ return stat; ++} ++ ++lar_archive * lar_open( const char *filename ) ++{ ++ int fd; ++ struct stat as; ++ lar_archive *ar; ++ ++ if( stat(filename, &as) == -1 ) ++ return NULL; ++ ++ if( !(as.st_mode & S_IFREG) ) ++ return NULL; ++ ++ if( (fd = open(filename, O_RDONLY)) != -1 ) ++ { ++ ar = (lar_archive *)malloc(sizeof(lar_archive)); ++ ar->fd = fd; ++ ar->length = as.st_size; ++ ar->index = lar_get_index(ar); ++ strncpy(ar->filename, filename, sizeof(ar->filename)); ++ ++ return ar; ++ } ++ ++ return NULL; ++} ++ ++int lar_close( lar_archive *ar ) ++{ ++ lar_index *idx_head; ++ lar_index *idx_next; ++ ++ close(ar->fd); ++ ++ idx_head = ar->index; ++ do { ++ idx_next = idx_head->next; ++ free(idx_head); ++ } while( (idx_head = idx_next) != NULL ); ++ ++ free(ar); ++ ++ return 0; ++} ++ ++lar_archive * lar_find_archive( const char *package, const char *path ) ++{ ++ int seg = 1; ++ int len = 0; ++ int pln = 0; ++ int i, j; ++ struct stat s; ++ LAR_FNAME(buffer); ++ ++ if( path ) ++ { ++ for( pln = 0; path[pln] != '\0'; pln++ ) ++ if( pln >= (sizeof(buffer) - 5) ) ++ LAR_DIE("Library path exceeds maximum allowed length"); ++ ++ memcpy(buffer, path, pln); ++ } ++ ++ for( len = 0; package[len] != '\0'; len++ ) ++ { ++ if( len >= (sizeof(buffer) - 5 - pln) ) ++ LAR_DIE("Package name exceeds maximum allowed length"); ++ ++ if( package[len] == '.' ) seg++; ++ } ++ ++ while( seg > 0 ) ++ { ++ for( i = 0, j = 1; (i < len) && (j <= seg); i++ ) ++ { ++ if( package[i] == '.' ) { ++ if( j < seg ) j++; else break; ++ } ++ ++ buffer[pln+i] = ( package[i] == '.' ) ? LAR_DIRSEP : package[i]; ++ } ++ ++ buffer[pln+i+0] = '.'; buffer[pln+i+1] = 'l'; buffer[pln+i+2] = 'a'; ++ buffer[pln+i+3] = 'r'; buffer[pln+i+4] = '\0'; ++ ++ if( (stat(buffer, &s) > -1) && (s.st_mode & S_IFREG) ) ++ return lar_open(buffer); ++ ++ seg--; ++ } ++ ++ return NULL; ++} ++ ++lar_member * lar_find_member( lar_archive *ar, const char *package ) ++{ ++ int len; ++ LAR_FNAME(buffer); ++ ++ for( len = 0; package[len] != '\0'; len++ ) ++ { ++ if( len >= (sizeof(buffer) - 5) ) ++ LAR_DIE("Package name exceeds maximum allowed length"); ++ ++ buffer[len] = ( package[len] == '.' ) ? '/' : package[len]; ++ } ++ ++ buffer[len+0] = '.'; buffer[len+1] = 'l'; buffer[len+2] = 'u'; ++ buffer[len+3] = 'a'; buffer[len+4] = '\0'; ++ ++ return lar_open_member(ar, buffer); ++} +diff -Nurb lua-5.1.4.orig/src/lar.h lua-5.1.4/src/lar.h +--- lua-5.1.4.orig/src/lar.h 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4/src/lar.h 2009-04-06 23:06:31.000000000 +0200 +@@ -0,0 +1,88 @@ ++#ifndef __LAR_H ++#define __LAR_H ++ ++#include <stdio.h> ++#include <stdlib.h> ++#include <unistd.h> ++#include <stdint.h> ++#include <fcntl.h> ++#include <string.h> ++#include <errno.h> ++#include <arpa/inet.h> ++#include <sys/types.h> ++#include <sys/mman.h> ++#include <sys/stat.h> ++ ++ ++#define LAR_DIE(s) \ ++ do { \ ++ fprintf(stderr, "%s(%i): %s(): %s\n", \ ++ __FILE__, __LINE__, __FUNCTION__, s); \ ++ if( errno ) fprintf(stderr, "%s(%i): %s\n", \ ++ __FILE__, __LINE__, strerror(errno) ); \ ++ exit(1); \ ++ } while(0) ++ ++ ++#define LAR_FNAME_BUFFER 1024 ++#define LAR_FNAME(s) char s[LAR_FNAME_BUFFER] ++ ++#ifdef __WIN32__ ++#define LAR_DIRSEP '\\' ++#else ++#define LAR_DIRSEP '/' ++#endif ++ ++ ++struct lar_index_item { ++ uint32_t noffset; ++ uint32_t nlength; ++ uint32_t foffset; ++ uint32_t flength; ++ uint16_t type; ++ uint16_t flags; ++ struct lar_index_item *next; ++}; ++ ++struct lar_member_item { ++ uint16_t type; ++ uint16_t flags; ++ uint32_t length; ++ char *data; ++ char *mmap; ++ size_t mlen; ++}; ++ ++struct lar_archive_handle { ++ int fd; ++ off_t length; ++ char filename[LAR_FNAME_BUFFER]; ++ struct lar_index_item *index; ++}; ++ ++typedef struct lar_index_item lar_index; ++typedef struct lar_member_item lar_member; ++typedef struct lar_archive_handle lar_archive; ++ ++ ++int lar_read32( int fd, uint32_t *val ); ++int lar_read16( int fd, uint16_t *val ); ++ ++lar_index * lar_get_index( lar_archive *ar ); ++ ++uint32_t lar_get_filename( lar_archive *ar, ++ lar_index *idx_ptr, char *filename ); ++ ++lar_member * lar_open_member( lar_archive *ar, const char *name ); ++ ++int lar_close_member( lar_member *member ); ++ ++lar_archive * lar_open( const char *filename ); ++ ++int lar_close( lar_archive *ar ); ++ ++lar_archive * lar_find_archive( const char *package, const char *path ); ++ ++lar_member * lar_find_member( lar_archive *ar, const char *package ); ++ ++#endif +diff -Nurb lua-5.1.4.orig/src/loadlib.c lua-5.1.4/src/loadlib.c +--- lua-5.1.4.orig/src/loadlib.c 2009-04-06 21:36:52.000000000 +0200 ++++ lua-5.1.4/src/loadlib.c 2009-04-07 01:55:21.000000000 +0200 +@@ -21,6 +21,7 @@ + #include "lauxlib.h" + #include "lualib.h" + ++#include "lar.h" + + /* prefix for open functions in C libraries */ + #define LUA_POF "luaopen_" +@@ -388,6 +389,36 @@ + } + + ++static int loader_Lar (lua_State *L) { ++ lar_archive *ar; ++ lar_member *mb; ++ const char *name = luaL_checkstring(L, 1); ++ ++ if( (ar = lar_find_archive(name, "./")) || ++ (ar = lar_find_archive(name, LUA_LDIR)) || ++ (ar = lar_find_archive(name, LUA_CDIR)) ++ ) { ++ if( (mb = lar_find_member(ar, name)) != NULL ) { ++ if( luaL_loadbuffer(L, mb->data, mb->length, ar->filename) != 0 ) { ++ luaL_error(L, "error while loading lar member '%s':\n\t%s", ++ name, lua_tostring(L, -1)); ++ } ++ lar_close_member(mb); ++ } ++ else { ++ lua_pushfstring(L, "\n\tno matching lar member " LUA_QS " in " LUA_QS, ++ name, ar->filename); ++ } ++ lar_close(ar); ++ } ++ else { ++ lua_pushfstring(L, "\n\tno matching lar archive for " LUA_QS, name); ++ } ++ ++ return 1; ++} ++ ++ + static const char *mkfuncname (lua_State *L, const char *modname) { + const char *funcname; + const char *mark = strchr(modname, *LUA_IGMARK); +@@ -621,7 +652,7 @@ + + + static const lua_CFunction loaders[] = +- {loader_preload, loader_Lua, loader_C, loader_Croot, NULL}; ++ {loader_preload, loader_Lua, loader_Lar, loader_C, loader_Croot, NULL}; + + + LUALIB_API int luaopen_package (lua_State *L) { |