contrib/lar: add lar support patch for openwrt lua
[project/luci.git] / contrib / lar / openwrt / 050-lar-source-loader.patch
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
4 @@ -28,7 +28,7 @@
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
10
11 LUA_T= lua
12 LUA_O= lua.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
16 @@ -0,0 +1,243 @@
17 +#include "lar.h"
18 +
19 +int lar_read32( int fd, uint32_t *val )
20 +{
21 + uint8_t buffer[5];
22 +
23 + if( read(fd, buffer, 4) < 4 )
24 + LAR_DIE("Unexpected EOF while reading data");
25 +
26 + buffer[4] = 0;
27 + *val = ntohl(*((uint32_t *) buffer));
28 +
29 + return 0;
30 +}
31 +
32 +int lar_read16( int fd, uint16_t *val )
33 +{
34 + uint8_t buffer[3];
35 +
36 + if( read(fd, buffer, 2) < 2 )
37 + LAR_DIE("Unexpected EOF while reading data");
38 +
39 + buffer[2] = 0;
40 + *val = ntohs(*((uint16_t *) buffer));
41 +
42 + return 0;
43 +}
44 +
45 +lar_index * lar_get_index( lar_archive *ar )
46 +{
47 + uint32_t i;
48 + uint32_t idx_offset;
49 + uint32_t idx_length;
50 + lar_index *idx_map, *idx_ptr;
51 +
52 + if( lseek(ar->fd, -(sizeof(idx_offset)), SEEK_END) == -1 )
53 + LAR_DIE("Unable to seek to end of archive");
54 +
55 + lar_read32(ar->fd, &idx_offset);
56 + idx_length = ( ar->length - idx_offset - sizeof(idx_offset) );
57 +
58 + if( lseek(ar->fd, idx_offset, SEEK_SET) == -1 )
59 + LAR_DIE("Unable to seek to archive index");
60 +
61 +
62 + idx_map = NULL;
63 +
64 + for( i = 0; i < idx_length; \
65 + i += (sizeof(lar_index) - sizeof(char *))
66 + ) {
67 + idx_ptr = (lar_index *)malloc(sizeof(lar_index));
68 +
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);
75 +
76 + idx_ptr->next = idx_map;
77 + idx_map = idx_ptr;
78 + }
79 +
80 + return idx_map;
81 +}
82 +
83 +uint32_t lar_get_filename( lar_archive *ar,
84 + lar_index *idx_ptr, char *filename
85 +) {
86 + if( idx_ptr->nlength >= LAR_FNAME_BUFFER )
87 + LAR_DIE("Filename exceeds maximum allowed length");
88 +
89 + if( lseek(ar->fd, idx_ptr->noffset, SEEK_SET) == -1 )
90 + LAR_DIE("Unexpected EOF while seeking filename");
91 +
92 + if( read(ar->fd, filename, idx_ptr->nlength) < idx_ptr->nlength )
93 + LAR_DIE("Unexpected EOF while reading filename");
94 +
95 + filename[idx_ptr->nlength] = 0;
96 +
97 + return idx_ptr->nlength;
98 +}
99 +
100 +lar_member * lar_open_member( lar_archive *ar, const char *name )
101 +{
102 + lar_index *idx_ptr = ar->index;
103 + lar_member *member;
104 + char memberfile[LAR_FNAME_BUFFER];
105 + char *memberdata;
106 + size_t pgsz = getpagesize();
107 +
108 + while(idx_ptr)
109 + {
110 + lar_get_filename(ar, idx_ptr, memberfile);
111 +
112 + if( !strncmp(memberfile, name, idx_ptr->nlength) )
113 + {
114 + memberdata = mmap(
115 + 0, idx_ptr->flength + ( idx_ptr->foffset % pgsz ),
116 + PROT_READ, MAP_PRIVATE, ar->fd,
117 + idx_ptr->foffset - ( idx_ptr->foffset % pgsz )
118 + );
119 +
120 + if( memberdata == MAP_FAILED )
121 + LAR_DIE("Failed to mmap() member data");
122 +
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];
128 +
129 + member->mmap = memberdata;
130 + member->mlen = idx_ptr->flength + ( idx_ptr->foffset % pgsz );
131 +
132 + return member;
133 + }
134 +
135 + idx_ptr = idx_ptr->next;
136 + }
137 +
138 + return NULL;
139 +}
140 +
141 +int lar_close_member( lar_member *member )
142 +{
143 + int stat = munmap(member->mmap, member->mlen);
144 + free(member);
145 +
146 + return stat;
147 +}
148 +
149 +lar_archive * lar_open( const char *filename )
150 +{
151 + int fd;
152 + struct stat as;
153 + lar_archive *ar;
154 +
155 + if( stat(filename, &as) == -1 )
156 + return NULL;
157 +
158 + if( !(as.st_mode & S_IFREG) )
159 + return NULL;
160 +
161 + if( (fd = open(filename, O_RDONLY)) != -1 )
162 + {
163 + ar = (lar_archive *)malloc(sizeof(lar_archive));
164 + ar->fd = fd;
165 + ar->length = as.st_size;
166 + ar->index = lar_get_index(ar);
167 + strncpy(ar->filename, filename, sizeof(ar->filename));
168 +
169 + return ar;
170 + }
171 +
172 + return NULL;
173 +}
174 +
175 +int lar_close( lar_archive *ar )
176 +{
177 + lar_index *idx_head;
178 + lar_index *idx_next;
179 +
180 + close(ar->fd);
181 +
182 + idx_head = ar->index;
183 + do {
184 + idx_next = idx_head->next;
185 + free(idx_head);
186 + } while( (idx_head = idx_next) != NULL );
187 +
188 + free(ar);
189 +
190 + return 0;
191 +}
192 +
193 +lar_archive * lar_find_archive( const char *package, const char *path )
194 +{
195 + int seg = 1;
196 + int len = 0;
197 + int pln = 0;
198 + int i, j;
199 + struct stat s;
200 + LAR_FNAME(buffer);
201 +
202 + if( path )
203 + {
204 + for( pln = 0; path[pln] != '\0'; pln++ )
205 + if( pln >= (sizeof(buffer) - 5) )
206 + LAR_DIE("Library path exceeds maximum allowed length");
207 +
208 + memcpy(buffer, path, pln);
209 + }
210 +
211 + for( len = 0; package[len] != '\0'; len++ )
212 + {
213 + if( len >= (sizeof(buffer) - 5 - pln) )
214 + LAR_DIE("Package name exceeds maximum allowed length");
215 +
216 + if( package[len] == '.' ) seg++;
217 + }
218 +
219 + while( seg > 0 )
220 + {
221 + for( i = 0, j = 1; (i < len) && (j <= seg); i++ )
222 + {
223 + if( package[i] == '.' ) {
224 + if( j < seg ) j++; else break;
225 + }
226 +
227 + buffer[pln+i] = ( package[i] == '.' ) ? LAR_DIRSEP : package[i];
228 + }
229 +
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';
232 +
233 + if( (stat(buffer, &s) > -1) && (s.st_mode & S_IFREG) )
234 + return lar_open(buffer);
235 +
236 + seg--;
237 + }
238 +
239 + return NULL;
240 +}
241 +
242 +lar_member * lar_find_member( lar_archive *ar, const char *package )
243 +{
244 + int len;
245 + LAR_FNAME(buffer);
246 +
247 + for( len = 0; package[len] != '\0'; len++ )
248 + {
249 + if( len >= (sizeof(buffer) - 5) )
250 + LAR_DIE("Package name exceeds maximum allowed length");
251 +
252 + buffer[len] = ( package[len] == '.' ) ? '/' : package[len];
253 + }
254 +
255 + buffer[len+0] = '.'; buffer[len+1] = 'l'; buffer[len+2] = 'u';
256 + buffer[len+3] = 'a'; buffer[len+4] = '\0';
257 +
258 + return lar_open_member(ar, buffer);
259 +}
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
263 @@ -0,0 +1,88 @@
264 +#ifndef __LAR_H
265 +#define __LAR_H
266 +
267 +#include <stdio.h>
268 +#include <stdlib.h>
269 +#include <unistd.h>
270 +#include <stdint.h>
271 +#include <fcntl.h>
272 +#include <string.h>
273 +#include <errno.h>
274 +#include <arpa/inet.h>
275 +#include <sys/types.h>
276 +#include <sys/mman.h>
277 +#include <sys/stat.h>
278 +
279 +
280 +#define LAR_DIE(s) \
281 + do { \
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) ); \
286 + exit(1); \
287 + } while(0)
288 +
289 +
290 +#define LAR_FNAME_BUFFER 1024
291 +#define LAR_FNAME(s) char s[LAR_FNAME_BUFFER]
292 +
293 +#ifdef __WIN32__
294 +#define LAR_DIRSEP '\\'
295 +#else
296 +#define LAR_DIRSEP '/'
297 +#endif
298 +
299 +
300 +struct lar_index_item {
301 + uint32_t noffset;
302 + uint32_t nlength;
303 + uint32_t foffset;
304 + uint32_t flength;
305 + uint16_t type;
306 + uint16_t flags;
307 + struct lar_index_item *next;
308 +};
309 +
310 +struct lar_member_item {
311 + uint16_t type;
312 + uint16_t flags;
313 + uint32_t length;
314 + char *data;
315 + char *mmap;
316 + size_t mlen;
317 +};
318 +
319 +struct lar_archive_handle {
320 + int fd;
321 + off_t length;
322 + char filename[LAR_FNAME_BUFFER];
323 + struct lar_index_item *index;
324 +};
325 +
326 +typedef struct lar_index_item lar_index;
327 +typedef struct lar_member_item lar_member;
328 +typedef struct lar_archive_handle lar_archive;
329 +
330 +
331 +int lar_read32( int fd, uint32_t *val );
332 +int lar_read16( int fd, uint16_t *val );
333 +
334 +lar_index * lar_get_index( lar_archive *ar );
335 +
336 +uint32_t lar_get_filename( lar_archive *ar,
337 + lar_index *idx_ptr, char *filename );
338 +
339 +lar_member * lar_open_member( lar_archive *ar, const char *name );
340 +
341 +int lar_close_member( lar_member *member );
342 +
343 +lar_archive * lar_open( const char *filename );
344 +
345 +int lar_close( lar_archive *ar );
346 +
347 +lar_archive * lar_find_archive( const char *package, const char *path );
348 +
349 +lar_member * lar_find_member( lar_archive *ar, const char *package );
350 +
351 +#endif
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
355 @@ -21,6 +21,7 @@
356 #include "lauxlib.h"
357 #include "lualib.h"
358
359 +#include "lar.h"
360
361 /* prefix for open functions in C libraries */
362 #define LUA_POF "luaopen_"
363 @@ -388,6 +389,36 @@
364 }
365
366
367 +static int loader_Lar (lua_State *L) {
368 + lar_archive *ar;
369 + lar_member *mb;
370 + const char *name = luaL_checkstring(L, 1);
371 +
372 + if( (ar = lar_find_archive(name, "./")) ||
373 + (ar = lar_find_archive(name, LUA_LDIR)) ||
374 + (ar = lar_find_archive(name, LUA_CDIR))
375 + ) {
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));
380 + }
381 + lar_close_member(mb);
382 + }
383 + else {
384 + lua_pushfstring(L, "\n\tno matching lar member " LUA_QS " in " LUA_QS,
385 + name, ar->filename);
386 + }
387 + lar_close(ar);
388 + }
389 + else {
390 + lua_pushfstring(L, "\n\tno matching lar archive for " LUA_QS, name);
391 + }
392 +
393 + return 1;
394 +}
395 +
396 +
397 static const char *mkfuncname (lua_State *L, const char *modname) {
398 const char *funcname;
399 const char *mark = strchr(modname, *LUA_IGMARK);
400 @@ -621,7 +652,7 @@
401
402
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};
406
407
408 LUALIB_API int luaopen_package (lua_State *L) {