contrib/lar:
[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 03:53:29.000000000 +0200
16 @@ -0,0 +1,242 @@
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;
51 +       lar_index *idx_ptr;
52 +
53 +       if( lseek(ar->fd, -(sizeof(idx_offset)), SEEK_END) == -1 )
54 +               LAR_DIE("Unable to seek to end of archive");
55 +
56 +       lar_read32(ar->fd, &idx_offset);
57 +       idx_length = ( ar->length - idx_offset - sizeof(idx_offset) );
58 +
59 +       if( lseek(ar->fd, idx_offset, SEEK_SET) == -1 )
60 +               LAR_DIE("Unable to seek to archive index");
61 +
62 +
63 +       idx_map = NULL;
64 +
65 +       for( i = 0; i < idx_length; i += (sizeof(lar_index) - sizeof(char *)) ) {
66 +               idx_ptr = (lar_index *)malloc(sizeof(lar_index));
67 +
68 +               lar_read32(ar->fd, &idx_ptr->noffset);
69 +               lar_read32(ar->fd, &idx_ptr->nlength);
70 +               lar_read32(ar->fd, &idx_ptr->foffset);
71 +               lar_read32(ar->fd, &idx_ptr->flength);
72 +               lar_read16(ar->fd, &idx_ptr->type);
73 +               lar_read16(ar->fd, &idx_ptr->flags);
74 +
75 +               idx_ptr->next = idx_map;
76 +               idx_map = idx_ptr;
77 +       }
78 +
79 +       return idx_map;
80 +}
81 +
82 +uint32_t lar_get_filename( lar_archive *ar, lar_index *idx_ptr, char *filename )
83 +{
84 +       if( idx_ptr->nlength >= LAR_FNAME_BUFFER )
85 +               LAR_DIE("Filename exceeds maximum allowed length");
86 +
87 +       if( lseek(ar->fd, idx_ptr->noffset, SEEK_SET) == -1 )
88 +               LAR_DIE("Unexpected EOF while seeking filename");
89 +
90 +       if( read(ar->fd, filename, idx_ptr->nlength) < idx_ptr->nlength )
91 +               LAR_DIE("Unexpected EOF while reading filename");
92 +
93 +       filename[idx_ptr->nlength] = '\0';
94 +
95 +       return idx_ptr->nlength;
96 +}
97 +
98 +lar_member * lar_open_member( lar_archive *ar, const char *name )
99 +{
100 +       lar_index *idx_ptr = ar->index;
101 +       lar_member *member;
102 +       char *memberdata;
103 +       size_t pgof;
104 +       size_t pgsz = getpagesize();
105 +       LAR_FNAME(memberfile);
106 +
107 +       while(idx_ptr)
108 +       {
109 +               lar_get_filename(ar, idx_ptr, memberfile);
110 +
111 +               if( !strncmp(memberfile, name, idx_ptr->nlength) )
112 +               {
113 +                       pgof = ( idx_ptr->foffset % pgsz );
114 +
115 +                       memberdata = mmap(
116 +                               0, idx_ptr->flength + pgof, PROT_READ, MAP_PRIVATE,
117 +                               ar->fd, idx_ptr->foffset - pgof
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[pgof];
128 +
129 +                       member->mmap   = memberdata;
130 +                       member->mlen   = idx_ptr->flength + pgof;
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 +       uint32_t i;
196 +       uint32_t j;
197 +       uint32_t seg = 1;
198 +       uint32_t len = 0;
199 +       uint32_t pln = 0;
200 +       struct stat s;
201 +       LAR_FNAME(buffer);
202 +
203 +       if( path )
204 +       {
205 +               for( pln = 0; path[pln] != '\0'; pln++ )
206 +                       if( pln >= (sizeof(buffer) - 5) )
207 +                               LAR_DIE("Library path exceeds maximum allowed length");
208 +
209 +               memcpy(buffer, path, pln);
210 +       }
211 +
212 +       for( len = 0; package[len] != '\0'; len++ )
213 +       {
214 +               if( len >= (sizeof(buffer) - 5 - pln) )
215 +                       LAR_DIE("Package name exceeds maximum allowed length");
216 +
217 +               if( package[len] == '.' ) seg++;
218 +       }
219 +
220 +       while( seg > 0 )
221 +       {
222 +               for( i = 0, j = 1; (i < len) && (j <= seg); i++ )
223 +               {
224 +                       if( package[i] == '.' ) {
225 +                               if( j < seg ) j++; else break;
226 +                       }
227 +
228 +                       buffer[pln+i] = ( package[i] == '.' ) ? LAR_DIRSEP : package[i];
229 +               }
230 +
231 +               strcpy(&buffer[pln+i], ".lar");
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 +       strcpy(&buffer[len], ".lua");
256 +
257 +       return lar_open_member(ar, buffer);
258 +}
259 diff -Nurb lua-5.1.4.orig/src/lar.h lua-5.1.4/src/lar.h
260 --- lua-5.1.4.orig/src/lar.h    1970-01-01 01:00:00.000000000 +0100
261 +++ lua-5.1.4/src/lar.h 2009-04-06 23:06:31.000000000 +0200
262 @@ -0,0 +1,88 @@
263 +#ifndef __LAR_H
264 +#define __LAR_H
265 +
266 +#include <stdio.h>
267 +#include <stdlib.h>
268 +#include <unistd.h>
269 +#include <stdint.h>
270 +#include <fcntl.h>
271 +#include <string.h>
272 +#include <errno.h>
273 +#include <arpa/inet.h>
274 +#include <sys/types.h>
275 +#include <sys/mman.h>
276 +#include <sys/stat.h>
277 +
278 +
279 +#define LAR_DIE(s) \
280 +       do { \
281 +               fprintf(stderr, "%s(%i): %s(): %s\n", \
282 +                       __FILE__, __LINE__, __FUNCTION__, s); \
283 +               if( errno ) fprintf(stderr, "%s(%i): %s\n", \
284 +                       __FILE__, __LINE__, strerror(errno) ); \
285 +               exit(1); \
286 +       } while(0)
287 +
288 +
289 +#define LAR_FNAME_BUFFER 1024
290 +#define LAR_FNAME(s) char s[LAR_FNAME_BUFFER]
291 +
292 +#ifdef __WIN32__
293 +#define LAR_DIRSEP     '\\'
294 +#else
295 +#define LAR_DIRSEP     '/'
296 +#endif
297 +
298 +
299 +struct lar_index_item {
300 +       uint32_t noffset;
301 +       uint32_t nlength;
302 +       uint32_t foffset;
303 +       uint32_t flength;
304 +       uint16_t type;
305 +       uint16_t flags;
306 +       struct lar_index_item *next;
307 +};
308 +
309 +struct lar_member_item {
310 +       uint16_t type;
311 +       uint16_t flags;
312 +       uint32_t length;
313 +       char *data;
314 +       char *mmap;
315 +       size_t mlen;
316 +};
317 +
318 +struct lar_archive_handle {
319 +       int fd;
320 +       off_t length;
321 +       char filename[LAR_FNAME_BUFFER];
322 +       struct lar_index_item *index;
323 +};
324 +
325 +typedef struct lar_index_item lar_index;
326 +typedef struct lar_member_item lar_member;
327 +typedef struct lar_archive_handle lar_archive;
328 +
329 +
330 +int lar_read32( int fd, uint32_t *val );
331 +int lar_read16( int fd, uint16_t *val );
332 +
333 +lar_index * lar_get_index( lar_archive *ar );
334 +
335 +uint32_t lar_get_filename( lar_archive *ar,
336 +       lar_index *idx_ptr, char *filename );
337 +
338 +lar_member * lar_open_member( lar_archive *ar, const char *name );
339 +
340 +int lar_close_member( lar_member *member );
341 +
342 +lar_archive * lar_open( const char *filename );
343 +
344 +int lar_close( lar_archive *ar );
345 +
346 +lar_archive * lar_find_archive( const char *package, const char *path );
347 +
348 +lar_member * lar_find_member( lar_archive *ar, const char *package );
349 +
350 +#endif
351 diff -Nurb lua-5.1.4.orig/src/loadlib.c lua-5.1.4/src/loadlib.c
352 --- lua-5.1.4.orig/src/loadlib.c        2009-04-06 21:36:52.000000000 +0200
353 +++ lua-5.1.4/src/loadlib.c     2009-04-07 01:55:21.000000000 +0200
354 @@ -21,6 +21,7 @@
355  #include "lauxlib.h"
356  #include "lualib.h"
357  
358 +#include "lar.h"
359  
360  /* prefix for open functions in C libraries */
361  #define LUA_POF                "luaopen_"
362 @@ -388,6 +389,36 @@
363  }
364  
365  
366 +static int loader_Lar (lua_State *L) {
367 +  lar_archive *ar;
368 +  lar_member  *mb;
369 +  const char  *name = luaL_checkstring(L, 1);
370 +
371 +  if( (ar = lar_find_archive(name, "./"))     ||
372 +      (ar = lar_find_archive(name, LUA_LDIR)) ||
373 +      (ar = lar_find_archive(name, LUA_CDIR))
374 +  ) {
375 +    if( (mb = lar_find_member(ar, name)) != NULL ) {
376 +      if( luaL_loadbuffer(L, mb->data, mb->length, ar->filename) != 0 ) {
377 +        luaL_error(L, "error while loading lar member '%s':\n\t%s",
378 +          name, lua_tostring(L, -1));
379 +      }
380 +      lar_close_member(mb);
381 +    }
382 +    else {
383 +      lua_pushfstring(L, "\n\tno matching lar member " LUA_QS " in " LUA_QS,
384 +        name, ar->filename);
385 +    }
386 +    lar_close(ar);
387 +  }
388 +  else {
389 +    lua_pushfstring(L, "\n\tno matching lar archive for " LUA_QS, name);
390 +  }
391 +
392 +  return 1;
393 +}
394 +
395 +
396  static const char *mkfuncname (lua_State *L, const char *modname) {
397    const char *funcname;
398    const char *mark = strchr(modname, *LUA_IGMARK);
399 @@ -621,7 +652,7 @@
400  
401  
402  static const lua_CFunction loaders[] =
403 -  {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
404 +  {loader_preload, loader_Lua, loader_Lar, loader_C, loader_Croot, NULL};
405  
406  
407  LUALIB_API int luaopen_package (lua_State *L) {