1 diff -Nurb lua-5.1.4.orig/src/Makefile lua-5.1.4/src/Makefile
2 --- lua-5.1.4.orig/src/Makefile 2009-04-06 21:36:52.000000000 +0200
3 +++ lua-5.1.4/src/Makefile 2009-04-06 23:04:42.000000000 +0200
5 lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \
6 lundump.o lvm.o lzio.o lnum.o
7 LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \
8 - lstrlib.o loadlib.o linit.o
9 + lstrlib.o loadlib.o linit.o lar.o
13 diff -Nurb lua-5.1.4.orig/src/lar.c lua-5.1.4/src/lar.c
14 --- lua-5.1.4.orig/src/lar.c 1970-01-01 01:00:00.000000000 +0100
15 +++ lua-5.1.4/src/lar.c 2009-04-07 00:35:55.000000000 +0200
19 +int lar_read32( int fd, uint32_t *val )
23 + if( read(fd, buffer, 4) < 4 )
24 + LAR_DIE("Unexpected EOF while reading data");
27 + *val = ntohl(*((uint32_t *) buffer));
32 +int lar_read16( int fd, uint16_t *val )
36 + if( read(fd, buffer, 2) < 2 )
37 + LAR_DIE("Unexpected EOF while reading data");
40 + *val = ntohs(*((uint16_t *) buffer));
45 +lar_index * lar_get_index( lar_archive *ar )
48 + uint32_t idx_offset;
49 + uint32_t idx_length;
50 + lar_index *idx_map, *idx_ptr;
52 + if( lseek(ar->fd, -(sizeof(idx_offset)), SEEK_END) == -1 )
53 + LAR_DIE("Unable to seek to end of archive");
55 + lar_read32(ar->fd, &idx_offset);
56 + idx_length = ( ar->length - idx_offset - sizeof(idx_offset) );
58 + if( lseek(ar->fd, idx_offset, SEEK_SET) == -1 )
59 + LAR_DIE("Unable to seek to archive index");
64 + for( i = 0; i < idx_length; \
65 + i += (sizeof(lar_index) - sizeof(char *))
67 + idx_ptr = (lar_index *)malloc(sizeof(lar_index));
69 + lar_read32(ar->fd, &idx_ptr->noffset);
70 + lar_read32(ar->fd, &idx_ptr->nlength);
71 + lar_read32(ar->fd, &idx_ptr->foffset);
72 + lar_read32(ar->fd, &idx_ptr->flength);
73 + lar_read16(ar->fd, &idx_ptr->type);
74 + lar_read16(ar->fd, &idx_ptr->flags);
76 + idx_ptr->next = idx_map;
83 +uint32_t lar_get_filename( lar_archive *ar,
84 + lar_index *idx_ptr, char *filename
86 + if( idx_ptr->nlength >= LAR_FNAME_BUFFER )
87 + LAR_DIE("Filename exceeds maximum allowed length");
89 + if( lseek(ar->fd, idx_ptr->noffset, SEEK_SET) == -1 )
90 + LAR_DIE("Unexpected EOF while seeking filename");
92 + if( read(ar->fd, filename, idx_ptr->nlength) < idx_ptr->nlength )
93 + LAR_DIE("Unexpected EOF while reading filename");
95 + filename[idx_ptr->nlength] = 0;
97 + return idx_ptr->nlength;
100 +lar_member * lar_open_member( lar_archive *ar, const char *name )
102 + lar_index *idx_ptr = ar->index;
103 + lar_member *member;
104 + char memberfile[LAR_FNAME_BUFFER];
106 + size_t pgsz = getpagesize();
110 + lar_get_filename(ar, idx_ptr, memberfile);
112 + if( !strncmp(memberfile, name, idx_ptr->nlength) )
115 + 0, idx_ptr->flength + ( idx_ptr->foffset % pgsz ),
116 + PROT_READ, MAP_PRIVATE, ar->fd,
117 + idx_ptr->foffset - ( idx_ptr->foffset % pgsz )
120 + if( memberdata == MAP_FAILED )
121 + LAR_DIE("Failed to mmap() member data");
123 + member = (lar_member *)malloc(sizeof(lar_member));
124 + member->type = idx_ptr->type;
125 + member->flags = idx_ptr->flags;
126 + member->length = idx_ptr->flength;
127 + member->data = &memberdata[idx_ptr->foffset % pgsz];
129 + member->mmap = memberdata;
130 + member->mlen = idx_ptr->flength + ( idx_ptr->foffset % pgsz );
135 + idx_ptr = idx_ptr->next;
141 +int lar_close_member( lar_member *member )
143 + int stat = munmap(member->mmap, member->mlen);
149 +lar_archive * lar_open( const char *filename )
155 + if( stat(filename, &as) == -1 )
158 + if( !(as.st_mode & S_IFREG) )
161 + if( (fd = open(filename, O_RDONLY)) != -1 )
163 + ar = (lar_archive *)malloc(sizeof(lar_archive));
165 + ar->length = as.st_size;
166 + ar->index = lar_get_index(ar);
167 + strncpy(ar->filename, filename, sizeof(ar->filename));
175 +int lar_close( lar_archive *ar )
177 + lar_index *idx_head;
178 + lar_index *idx_next;
182 + idx_head = ar->index;
184 + idx_next = idx_head->next;
186 + } while( (idx_head = idx_next) != NULL );
193 +lar_archive * lar_find_archive( const char *package, const char *path )
204 + for( pln = 0; path[pln] != '\0'; pln++ )
205 + if( pln >= (sizeof(buffer) - 5) )
206 + LAR_DIE("Library path exceeds maximum allowed length");
208 + memcpy(buffer, path, pln);
211 + for( len = 0; package[len] != '\0'; len++ )
213 + if( len >= (sizeof(buffer) - 5 - pln) )
214 + LAR_DIE("Package name exceeds maximum allowed length");
216 + if( package[len] == '.' ) seg++;
221 + for( i = 0, j = 1; (i < len) && (j <= seg); i++ )
223 + if( package[i] == '.' ) {
224 + if( j < seg ) j++; else break;
227 + buffer[pln+i] = ( package[i] == '.' ) ? LAR_DIRSEP : package[i];
230 + buffer[pln+i+0] = '.'; buffer[pln+i+1] = 'l'; buffer[pln+i+2] = 'a';
231 + buffer[pln+i+3] = 'r'; buffer[pln+i+4] = '\0';
233 + if( (stat(buffer, &s) > -1) && (s.st_mode & S_IFREG) )
234 + return lar_open(buffer);
242 +lar_member * lar_find_member( lar_archive *ar, const char *package )
247 + for( len = 0; package[len] != '\0'; len++ )
249 + if( len >= (sizeof(buffer) - 5) )
250 + LAR_DIE("Package name exceeds maximum allowed length");
252 + buffer[len] = ( package[len] == '.' ) ? '/' : package[len];
255 + buffer[len+0] = '.'; buffer[len+1] = 'l'; buffer[len+2] = 'u';
256 + buffer[len+3] = 'a'; buffer[len+4] = '\0';
258 + return lar_open_member(ar, buffer);
260 diff -Nurb lua-5.1.4.orig/src/lar.h lua-5.1.4/src/lar.h
261 --- lua-5.1.4.orig/src/lar.h 1970-01-01 01:00:00.000000000 +0100
262 +++ lua-5.1.4/src/lar.h 2009-04-06 23:06:31.000000000 +0200
274 +#include <arpa/inet.h>
275 +#include <sys/types.h>
276 +#include <sys/mman.h>
277 +#include <sys/stat.h>
280 +#define LAR_DIE(s) \
282 + fprintf(stderr, "%s(%i): %s(): %s\n", \
283 + __FILE__, __LINE__, __FUNCTION__, s); \
284 + if( errno ) fprintf(stderr, "%s(%i): %s\n", \
285 + __FILE__, __LINE__, strerror(errno) ); \
290 +#define LAR_FNAME_BUFFER 1024
291 +#define LAR_FNAME(s) char s[LAR_FNAME_BUFFER]
294 +#define LAR_DIRSEP '\\'
296 +#define LAR_DIRSEP '/'
300 +struct lar_index_item {
307 + struct lar_index_item *next;
310 +struct lar_member_item {
319 +struct lar_archive_handle {
322 + char filename[LAR_FNAME_BUFFER];
323 + struct lar_index_item *index;
326 +typedef struct lar_index_item lar_index;
327 +typedef struct lar_member_item lar_member;
328 +typedef struct lar_archive_handle lar_archive;
331 +int lar_read32( int fd, uint32_t *val );
332 +int lar_read16( int fd, uint16_t *val );
334 +lar_index * lar_get_index( lar_archive *ar );
336 +uint32_t lar_get_filename( lar_archive *ar,
337 + lar_index *idx_ptr, char *filename );
339 +lar_member * lar_open_member( lar_archive *ar, const char *name );
341 +int lar_close_member( lar_member *member );
343 +lar_archive * lar_open( const char *filename );
345 +int lar_close( lar_archive *ar );
347 +lar_archive * lar_find_archive( const char *package, const char *path );
349 +lar_member * lar_find_member( lar_archive *ar, const char *package );
352 diff -Nurb lua-5.1.4.orig/src/loadlib.c lua-5.1.4/src/loadlib.c
353 --- lua-5.1.4.orig/src/loadlib.c 2009-04-06 21:36:52.000000000 +0200
354 +++ lua-5.1.4/src/loadlib.c 2009-04-07 01:55:21.000000000 +0200
361 /* prefix for open functions in C libraries */
362 #define LUA_POF "luaopen_"
367 +static int loader_Lar (lua_State *L) {
370 + const char *name = luaL_checkstring(L, 1);
372 + if( (ar = lar_find_archive(name, "./")) ||
373 + (ar = lar_find_archive(name, LUA_LDIR)) ||
374 + (ar = lar_find_archive(name, LUA_CDIR))
376 + if( (mb = lar_find_member(ar, name)) != NULL ) {
377 + if( luaL_loadbuffer(L, mb->data, mb->length, ar->filename) != 0 ) {
378 + luaL_error(L, "error while loading lar member '%s':\n\t%s",
379 + name, lua_tostring(L, -1));
381 + lar_close_member(mb);
384 + lua_pushfstring(L, "\n\tno matching lar member " LUA_QS " in " LUA_QS,
385 + name, ar->filename);
390 + lua_pushfstring(L, "\n\tno matching lar archive for " LUA_QS, name);
397 static const char *mkfuncname (lua_State *L, const char *modname) {
398 const char *funcname;
399 const char *mark = strchr(modname, *LUA_IGMARK);
403 static const lua_CFunction loaders[] =
404 - {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
405 + {loader_preload, loader_Lua, loader_Lar, loader_C, loader_Croot, NULL};
408 LUALIB_API int luaopen_package (lua_State *L) {