contrib/lar: refresh openwrt patch
[project/luci.git] / contrib / lar / openwrt / 050-lar-source-loader.patch
1 diff -Nbur 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-11 01:02:45.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 md5.o larlib.o
10  
11  LUA_T= lua
12  LUA_O= lua.o
13 diff -Nbur 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-13 16:51:07.000000000 +0200
16 @@ -0,0 +1,328 @@
17 +/*
18 + * lar - Lua Archive Library
19 + *
20 + *   Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
21 + *
22 + *  Licensed under the Apache License, Version 2.0 (the "License");
23 + *  you may not use this file except in compliance with the License.
24 + *  You may obtain a copy of the License at
25 + *
26 + *      http://www.apache.org/licenses/LICENSE-2.0
27 + *
28 + *  Unless required by applicable law or agreed to in writing, software
29 + *  distributed under the License is distributed on an "AS IS" BASIS,
30 + *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 + *  See the License for the specific language governing permissions and
32 + *  limitations under the License.
33 + */
34 +
35 +
36 +#include "lar.h"
37 +
38 +static int lar_read32( int fd, uint32_t *val )
39 +{
40 +       uint8_t buffer[5];
41 +
42 +       if( read(fd, buffer, 4) < 4 )
43 +               LAR_DIE("Unexpected EOF while reading data");
44 +
45 +       buffer[4] = 0;
46 +       *val = ntohl(*((uint32_t *) buffer));
47 +
48 +       return 0;
49 +}
50 +
51 +static int lar_read16( int fd, uint16_t *val )
52 +{
53 +       uint8_t buffer[3];
54 +
55 +       if( read(fd, buffer, 2) < 2 )
56 +               LAR_DIE("Unexpected EOF while reading data");
57 +
58 +       buffer[2] = 0;
59 +       *val = ntohs(*((uint16_t *) buffer));
60 +
61 +       return 0;
62 +}
63 +
64 +static void lar_md5( char *md5, const char *data, int len )
65 +{
66 +       md5_state_t state;
67 +
68 +       md5_init(&state);
69 +       md5_append(&state, (const md5_byte_t *)data, len);
70 +       md5_finish(&state, (md5_byte_t *)md5);
71 +}
72 +
73 +static int lar_read_filenames( lar_archive *ar )
74 +{
75 +       int i;
76 +       int j;
77 +       char *filelist;
78 +       size_t pgof;
79 +       size_t pgsz = getpagesize();
80 +       lar_index *idx_ptr;
81 +       lar_index *idx_filelist = ar->index;
82 +
83 +       while(idx_filelist)
84 +       {
85 +               if( idx_filelist->type == LAR_TYPE_FILELIST )
86 +                       break;
87 +
88 +               idx_filelist = idx_filelist->next;
89 +       }
90 +
91 +       if( idx_filelist != NULL )
92 +       {
93 +               pgof = ( idx_filelist->offset % pgsz );
94 +
95 +               filelist = mmap(
96 +                       0, idx_filelist->length + pgof, PROT_READ, MAP_PRIVATE,
97 +                       ar->fd, idx_filelist->offset - pgof
98 +               );
99 +
100 +               if( filelist == MAP_FAILED )
101 +                       LAR_DIE("Failed to mmap() file list");
102 +
103 +
104 +               idx_ptr = ar->index;
105 +               i = pgof;
106 +
107 +               while(idx_ptr)
108 +               {
109 +                       if( idx_ptr->type == LAR_TYPE_REGULAR )
110 +                       {
111 +                               j = strlen(&filelist[i]) + 1;
112 +
113 +                               if( (j >= LAR_FNAME_BUFFER) ||
114 +                                   ((i+j) > (idx_filelist->length+pgof)) )
115 +                                               LAR_DIE("Filename exceeds maximum allowed length");
116 +
117 +                               idx_ptr->filename = (char *)malloc(j);
118 +                               memcpy(idx_ptr->filename, &filelist[i], j);
119 +
120 +                               i += j;
121 +                       }
122 +
123 +                       idx_ptr = idx_ptr->next;
124 +               }
125 +
126 +               munmap(filelist, idx_filelist->length + pgof);
127 +
128 +               return 1;
129 +       }
130 +
131 +       return 0;
132 +}
133 +
134 +lar_index * lar_get_index( lar_archive *ar )
135 +{
136 +       uint32_t i;
137 +       uint32_t idx_offset;
138 +       uint32_t idx_length;
139 +       lar_index *idx_map;
140 +       lar_index *idx_ptr;
141 +
142 +       if( lseek(ar->fd, -(sizeof(idx_offset)), SEEK_END) == -1 )
143 +               LAR_DIE("Unable to seek to end of archive");
144 +
145 +       lar_read32(ar->fd, &idx_offset);
146 +       idx_length = ( ar->length - idx_offset - sizeof(idx_offset) );
147 +
148 +       if( lseek(ar->fd, idx_offset, SEEK_SET) == -1 )
149 +               LAR_DIE("Unable to seek to archive index");
150 +
151 +
152 +       idx_map = NULL;
153 +
154 +       for( i = 0; i < idx_length; i += (sizeof(lar_index) - 2 * sizeof(char *)) )
155 +       {
156 +               idx_ptr = (lar_index *)malloc(sizeof(lar_index));
157 +               idx_ptr->filename = NULL;
158 +
159 +               lar_read32(ar->fd, &idx_ptr->offset);
160 +               lar_read32(ar->fd, &idx_ptr->length);
161 +               lar_read16(ar->fd, &idx_ptr->type);
162 +               lar_read16(ar->fd, &idx_ptr->flags);
163 +
164 +               if(read(ar->fd,&idx_ptr->id,sizeof(idx_ptr->id)) < sizeof(idx_ptr->id))
165 +                       LAR_DIE("Unexpected EOF while reading member id");
166 +
167 +               idx_ptr->next = idx_map;
168 +               idx_map = idx_ptr;
169 +       }
170 +
171 +       return idx_map;
172 +}
173 +
174 +lar_member * lar_mmap_member( lar_archive *ar, lar_index *idx_ptr )
175 +{
176 +       lar_member *member;
177 +       size_t pgsz = getpagesize();
178 +       size_t pgof = ( idx_ptr->offset % pgsz );
179 +
180 +       char *memberdata = mmap(
181 +               0, idx_ptr->length + pgof, PROT_READ, MAP_PRIVATE,
182 +               ar->fd, idx_ptr->offset - pgof
183 +       );
184 +
185 +       if( memberdata == MAP_FAILED )
186 +               LAR_DIE("Failed to mmap() member data");
187 +
188 +       member = (lar_member *)malloc(sizeof(lar_member));
189 +       member->type   = idx_ptr->type;
190 +       member->flags  = idx_ptr->flags;
191 +       member->length = idx_ptr->length;
192 +       member->data   = &memberdata[pgof];
193 +
194 +       member->mmap   = memberdata;
195 +       member->mlen   = idx_ptr->length + pgof;
196 +
197 +       return member;
198 +}
199 +
200 +lar_member * lar_open_member( lar_archive *ar, const char *name )
201 +{
202 +       lar_index *idx_ptr = ar->index;
203 +       char mbid[sizeof(idx_ptr->id)];
204 +
205 +       lar_md5(mbid, name, strlen(name));
206 +
207 +       while(idx_ptr)
208 +       {
209 +               if( !strncmp(mbid, idx_ptr->id, sizeof(mbid)) )
210 +                       return lar_mmap_member(ar, idx_ptr);
211 +
212 +               idx_ptr = idx_ptr->next;
213 +       }
214 +
215 +       return NULL;
216 +}
217 +
218 +int lar_close_member( lar_member *member )
219 +{
220 +       int stat = munmap(member->mmap, member->mlen);
221 +       free(member);
222 +       member = NULL;
223 +
224 +       return stat;
225 +}
226 +
227 +lar_archive * lar_open( const char *filename )
228 +{
229 +       int fd;
230 +       struct stat as;
231 +       lar_archive *ar;
232 +
233 +       if( stat(filename, &as) == -1 )
234 +               return NULL;
235 +
236 +       if( !(as.st_mode & S_IFREG) )
237 +               return NULL;
238 +
239 +       if( (fd = open(filename, O_RDONLY)) != -1 )
240 +       {
241 +               ar = (lar_archive *)malloc(sizeof(lar_archive));
242 +               ar->fd       = fd;
243 +               ar->length   = as.st_size;
244 +               ar->index    = lar_get_index(ar);
245 +               strncpy(ar->filename, filename, sizeof(ar->filename));
246 +
247 +               ar->has_filenames = lar_read_filenames(ar);
248 +
249 +               return ar;
250 +       }
251 +
252 +       return NULL;
253 +}
254 +
255 +int lar_close( lar_archive *ar )
256 +{
257 +       lar_index *idx_head;
258 +       lar_index *idx_next;
259 +
260 +       close(ar->fd);
261 +
262 +       idx_head = ar->index;
263 +       do {
264 +               idx_next = idx_head->next;
265 +               free(idx_head->filename);
266 +               free(idx_head);
267 +       } while( (idx_head = idx_next) != NULL );
268 +
269 +       free(ar);
270 +       ar = NULL;
271 +
272 +       return 0;
273 +}
274 +
275 +lar_archive * lar_find_archive( const char *package, const char *path, int pkg )
276 +{
277 +       uint32_t i;
278 +       uint32_t j;
279 +       uint32_t seg = 1;
280 +       uint32_t len = 0;
281 +       uint32_t pln = 0;
282 +       char sep = ( pkg ? '.' : '/' );
283 +       struct stat s;
284 +       LAR_FNAME(buffer);
285 +
286 +       if( path )
287 +       {
288 +               for( pln = 0; path[pln] != '\0'; pln++ )
289 +                       if( pln >= (sizeof(buffer) - 5) )
290 +                               LAR_DIE("Library path exceeds maximum allowed length");
291 +
292 +               memcpy(buffer, path, pln);
293 +       }
294 +
295 +       if( buffer[pln-1] != '/' )
296 +               buffer[pln++] = '/';
297 +
298 +       for( len = 0; package[len] != '\0'; len++ )
299 +       {
300 +               if( len >= (sizeof(buffer) - 5 - pln) )
301 +                       LAR_DIE("Package name exceeds maximum allowed length");
302 +
303 +               if( package[len] == sep ) seg++;
304 +       }
305 +
306 +       while( seg > 0 )
307 +       {
308 +               for( i = 0, j = 1; (i < len) && (j <= seg); i++ )
309 +               {
310 +                       if( package[i] == sep ) {
311 +                               if( j < seg ) j++; else break;
312 +                       }
313 +
314 +                       buffer[pln+i] = ( package[i] == sep ) ? LAR_DIRSEP : package[i];
315 +               }
316 +
317 +               strcpy(&buffer[pln+i], ".lar");
318 +
319 +               if( (stat(buffer, &s) > -1) && (s.st_mode & S_IFREG) )
320 +                       return lar_open(buffer);
321 +
322 +               seg--;
323 +       }
324 +
325 +       return NULL;
326 +}
327 +
328 +lar_member * lar_find_member( lar_archive *ar, const char *package )
329 +{
330 +       int len;
331 +       LAR_FNAME(buffer);
332 +
333 +       for( len = 0; package[len] != '\0'; len++ )
334 +       {
335 +               if( len >= (sizeof(buffer) - 5) )
336 +                       LAR_DIE("Package name exceeds maximum allowed length");
337 +
338 +               buffer[len] = ( package[len] == '.' ) ? '/' : package[len];
339 +       }
340 +
341 +       strcpy(&buffer[len], ".lua");
342 +
343 +       return lar_open_member(ar, buffer);
344 +}
345 diff -Nbur lua-5.1.4.orig/src/lar.h lua-5.1.4/src/lar.h
346 --- lua-5.1.4.orig/src/lar.h    1970-01-01 01:00:00.000000000 +0100
347 +++ lua-5.1.4/src/lar.h 2009-04-13 17:13:47.000000000 +0200
348 @@ -0,0 +1,108 @@
349 +/*
350 + * lar - Lua Archive Library
351 + *
352 + *   Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
353 + *
354 + *  Licensed under the Apache License, Version 2.0 (the "License");
355 + *  you may not use this file except in compliance with the License.
356 + *  You may obtain a copy of the License at
357 + *
358 + *      http://www.apache.org/licenses/LICENSE-2.0
359 + *
360 + *  Unless required by applicable law or agreed to in writing, software
361 + *  distributed under the License is distributed on an "AS IS" BASIS,
362 + *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
363 + *  See the License for the specific language governing permissions and
364 + *  limitations under the License.
365 + */
366 +
367 +
368 +#ifndef __LAR_H
369 +#define __LAR_H
370 +
371 +#include <stdio.h>
372 +#include <stdlib.h>
373 +#include <unistd.h>
374 +#include <stdint.h>
375 +#include <fcntl.h>
376 +#include <string.h>
377 +#include <errno.h>
378 +#include <arpa/inet.h>
379 +#include <sys/types.h>
380 +#include <sys/mman.h>
381 +#include <sys/stat.h>
382 +
383 +#include "md5.h"
384 +
385 +#define LAR_DIE(s) \
386 +       do { \
387 +               fprintf(stderr, "%s(%i): %s(): %s\n", \
388 +                       __FILE__, __LINE__, __FUNCTION__, s); \
389 +               if( errno ) fprintf(stderr, "%s(%i): %s\n", \
390 +                       __FILE__, __LINE__, strerror(errno) ); \
391 +               exit(1); \
392 +       } while(0)
393 +
394 +
395 +#define LAR_FNAME_BUFFER 1024
396 +#define LAR_FNAME(s) char s[LAR_FNAME_BUFFER]
397 +
398 +#define LAR_TYPE_REGULAR       0x0000
399 +#define LAR_TYPE_FILELIST      0xFFFF
400 +
401 +#ifdef __WIN32__
402 +#define LAR_DIRSEP     '\\'
403 +#else
404 +#define LAR_DIRSEP     '/'
405 +#endif
406 +
407 +
408 +struct lar_index_item {
409 +       uint32_t offset;
410 +       uint32_t length;
411 +       uint16_t type;
412 +       uint16_t flags;
413 +       char id[16];
414 +       char *filename;
415 +       struct lar_index_item *next;
416 +};
417 +
418 +struct lar_member_item {
419 +       uint16_t type;
420 +       uint16_t flags;
421 +       uint32_t length;
422 +       char *data;
423 +       char *mmap;
424 +       size_t mlen;
425 +};
426 +
427 +struct lar_archive_handle {
428 +       int fd;
429 +       int has_filenames;
430 +       off_t length;
431 +       char filename[LAR_FNAME_BUFFER];
432 +       struct lar_index_item *index;
433 +};
434 +
435 +typedef struct lar_index_item lar_index;
436 +typedef struct lar_member_item lar_member;
437 +typedef struct lar_archive_handle lar_archive;
438 +
439 +
440 +lar_index * lar_get_index( lar_archive *ar );
441 +
442 +lar_member * lar_mmap_member( lar_archive *ar, lar_index *idx_ptr );
443 +
444 +lar_member * lar_open_member( lar_archive *ar, const char *name );
445 +
446 +int lar_close_member( lar_member *member );
447 +
448 +lar_archive * lar_open( const char *filename );
449 +
450 +int lar_close( lar_archive *ar );
451 +
452 +lar_archive * lar_find_archive( const char *package, const char *path, int pkg);
453 +
454 +lar_member * lar_find_member( lar_archive *ar, const char *package );
455 +
456 +#endif
457 diff -Nbur lua-5.1.4.orig/src/larlib.c lua-5.1.4/src/larlib.c
458 --- lua-5.1.4.orig/src/larlib.c 1970-01-01 01:00:00.000000000 +0100
459 +++ lua-5.1.4/src/larlib.c      2009-04-13 16:51:15.000000000 +0200
460 @@ -0,0 +1,540 @@
461 +/*
462 + * lar - Lua Archive Library
463 + *
464 + *   Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
465 + *
466 + *  Licensed under the Apache License, Version 2.0 (the "License");
467 + *  you may not use this file except in compliance with the License.
468 + *  You may obtain a copy of the License at
469 + *
470 + *      http://www.apache.org/licenses/LICENSE-2.0
471 + *
472 + *  Unless required by applicable law or agreed to in writing, software
473 + *  distributed under the License is distributed on an "AS IS" BASIS,
474 + *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
475 + *  See the License for the specific language governing permissions and
476 + *  limitations under the License.
477 + */
478 +
479 +
480 +#include "lua.h"
481 +#include "lualib.h"
482 +#include "lauxlib.h"
483 +#include "lar.h"
484 +
485 +typedef struct {
486 +       int fd;
487 +       char *data;
488 +       size_t length;
489 +} mmap_handle;
490 +
491 +static int larlib_perror( lua_State *L, const char *message )
492 +{
493 +       lua_pushnil(L);
494 +       lua_pushstring(L, message);
495 +
496 +       return 2;
497 +}
498 +
499 +int larlib_open( lua_State *L )
500 +{
501 +       lar_archive *ar, **udata;
502 +       const char *filename = luaL_checkstring( L, 1 );
503 +
504 +       if( filename != NULL && (ar = lar_open(filename)) != NULL )
505 +       {
506 +               if( (udata = lua_newuserdata(L, sizeof(lar_archive *))) != NULL )
507 +               {
508 +                       *udata = ar;
509 +                       luaL_getmetatable(L, "lar.archive");
510 +                       lua_setmetatable(L, -2);
511 +               }
512 +               else
513 +               {
514 +                       return luaL_error(L, "Out of memory");
515 +               }
516 +       }
517 +       else
518 +       {
519 +               return larlib_perror(L, "Archive not found");
520 +       }
521 +
522 +       return 1;
523 +}
524 +
525 +int larlib_find( lua_State *L )
526 +{
527 +       const char *filename = luaL_checkstring( L, 1 );
528 +       const char *basepath = luaL_optstring( L, 2, "./" );
529 +       int is_pkg = strstr(filename, "/") ? 0 : 1;
530 +       lar_archive *ar, **udata;
531 +
532 +       if( ((ar = lar_find_archive(filename, basepath, is_pkg)) != NULL) ||
533 +           ((ar = lar_find_archive(filename, LUA_LDIR, is_pkg)) != NULL) ||
534 +               ((ar = lar_find_archive(filename, LUA_CDIR, is_pkg)) != NULL) )
535 +       {
536 +               if( (udata = lua_newuserdata(L, sizeof(lar_archive *))) != NULL )
537 +               {
538 +                       *udata = ar;
539 +                       luaL_getmetatable(L, "lar.archive");
540 +                       lua_setmetatable(L, -2);
541 +               }
542 +               else
543 +               {
544 +                       return luaL_error(L, "Out of memory");
545 +               }
546 +       }
547 +       else
548 +       {
549 +               return larlib_perror(L, "Archive not found");
550 +       }
551 +
552 +       return 1;
553 +}
554 +
555 +int larlib_md5( lua_State *L )
556 +{
557 +       int i;
558 +       char md5[16], md5_hex[33];
559 +       const char *data = luaL_checkstring( L, 1 );
560 +       md5_state_t state;
561 +
562 +       md5_init(&state);
563 +       md5_append(&state, (const md5_byte_t *)data, strlen(data));
564 +       md5_finish(&state, (md5_byte_t *)md5);
565 +
566 +       for( i = 0; i < 16; i++ )
567 +               sprintf(&md5_hex[i*2], "%02x", (unsigned char)md5[i]);
568 +
569 +       lua_pushstring(L, md5_hex);
570 +       return 1;
571 +}
572 +
573 +int larlib_md5_file( lua_State *L )
574 +{
575 +       int i, fd, len;
576 +       char md5[16], md5_hex[33], buffer[1024];
577 +       const char *filename = luaL_checkstring( L, 1 );
578 +       md5_state_t state;
579 +
580 +       if( (fd = open(filename, O_RDONLY)) != -1 )
581 +       {
582 +               md5_init(&state);
583 +
584 +               while( (len = read(fd, buffer, 1024)) > 0 )
585 +                       md5_append(&state, (const md5_byte_t *)buffer, len);
586 +
587 +               md5_finish(&state, (md5_byte_t *)md5);
588 +
589 +               for( i = 0; i < 16; i++ )
590 +                       sprintf(&md5_hex[i*2], "%02x", (unsigned char)md5[i]);
591 +
592 +               close(fd);
593 +               lua_pushstring(L, md5_hex);
594 +       }
595 +       else
596 +       {
597 +               return larlib_perror(L, strerror(errno));
598 +       }
599 +
600 +       return 1;
601 +}
602 +
603 +static int larlib_mkpath( const char *name, const char *path, char *buffer )
604 +{
605 +       int nlen = strlen(name);
606 +       int plen = strlen(path);
607 +
608 +       if( (nlen + plen + 1) <= 1024 )
609 +       {
610 +               strcpy(buffer, path);
611 +
612 +               if( buffer[plen-1] != '/' )
613 +                       buffer[plen++] = '/';
614 +
615 +               strcpy(&buffer[plen], name);
616 +               buffer[plen + nlen] = '\0';
617 +
618 +               return 0;
619 +       }
620 +
621 +       return 1;
622 +}
623 +
624 +static int larlib__gc( lua_State *L )
625 +{
626 +       lar_archive **archive = luaL_checkudata( L, 1, "lar.archive" );
627 +
628 +       if( *archive )
629 +               lar_close(*archive);
630 +
631 +       *archive = NULL;
632 +       return 0;
633 +}
634 +
635 +
636 +static int larlib_member__open( lua_State *L, lar_member *mb )
637 +{
638 +       lar_archive **archive = NULL;
639 +       const char *filename = NULL;
640 +       lar_member **udata;
641 +
642 +       if( mb == NULL )
643 +       {
644 +               *archive = luaL_checkudata( L, 1, "lar.archive" );
645 +               filename = luaL_checkstring( L, 2 );
646 +       }
647 +
648 +       if( mb != NULL || (mb = lar_open_member(*archive, filename)) != NULL )
649 +       {
650 +               if( (udata = lua_newuserdata(L, sizeof(lar_member *))) != NULL )
651 +               {
652 +                       *udata = mb;
653 +                       luaL_getmetatable(L, "lar.member");
654 +                       lua_setmetatable(L, -2);
655 +               }
656 +               else
657 +               {
658 +                       return luaL_error(L, "Out of memory");
659 +               }
660 +       }
661 +       else
662 +       {
663 +               return larlib_perror(L, "Member not found in archive");
664 +       }
665 +
666 +       return 1;
667 +}
668 +
669 +int larlib_member_open( lua_State *L )
670 +{
671 +       return larlib_member__open( L, NULL );
672 +}
673 +
674 +int larlib_member_find( lua_State *L )
675 +{
676 +       lar_archive **archive = luaL_checkudata( L, 1, "lar.archive" );
677 +       const char *package = luaL_checkstring( L, 2 );
678 +       lar_member *mb, **udata;
679 +
680 +       if( (mb = lar_find_member(*archive, package)) != NULL )
681 +       {
682 +               if( (udata = lua_newuserdata(L, sizeof(lar_member *))) != NULL )
683 +               {
684 +                       *udata = mb;
685 +                       luaL_getmetatable(L, "lar.member");
686 +                       lua_setmetatable(L, -2);
687 +               }
688 +               else
689 +               {
690 +                       return luaL_error(L, "Out of memory");
691 +               }
692 +       }
693 +       else
694 +       {
695 +               return larlib_perror(L, "Member not found in archive");
696 +       }
697 +
698 +       return 1;
699 +}
700 +
701 +int larlib_member_size( lua_State *L )
702 +{
703 +       lar_member **member = luaL_checkudata( L, 1, "lar.member" );
704 +       lua_pushnumber(L, (*member)->length);
705 +       return 1;
706 +}
707 +
708 +int larlib_member_type( lua_State *L )
709 +{
710 +       lar_member **member = luaL_checkudata( L, 1, "lar.member" );
711 +       lua_pushnumber(L, (*member)->type);
712 +       return 1;
713 +}
714 +
715 +int larlib_member_flags( lua_State *L )
716 +{
717 +       lar_member **member = luaL_checkudata( L, 1, "lar.member" );
718 +       lua_pushnumber(L, (*member)->flags);
719 +       return 1;
720 +}
721 +
722 +int larlib_member_read( lua_State *L )
723 +{
724 +       lar_member **member = luaL_checkudata( L, 1, "lar.member" );
725 +       int start  = luaL_checknumber( L, 2 );
726 +       int length = luaL_optnumber( L, 3, (*member)->length );
727 +       char *stringcopy;
728 +
729 +       if( (start >= 0) && (start < (*member)->length) && (length > 0) )
730 +       {
731 +               if( (start + length) >= (*member)->length )
732 +                       length = (*member)->length - start;
733 +
734 +               if( (stringcopy = (char *)malloc(length + 1)) != NULL )
735 +               {
736 +                       memcpy(stringcopy, &(*member)->data[start], length);
737 +                       stringcopy[length] = '\0';
738 +                       lua_pushstring(L, stringcopy);
739 +                       free(stringcopy);
740 +               }
741 +               else
742 +               {
743 +                       return luaL_error(L, "Out of memory");
744 +               }
745 +       }
746 +       else
747 +       {
748 +               return larlib_perror(L, "Invalid argument");
749 +       }
750 +
751 +       return 1;
752 +}
753 +
754 +int larlib_member_data( lua_State *L )
755 +{
756 +       lar_member **member = luaL_checkudata( L, 1, "lar.member" );
757 +       lua_pushstring(L, (*member)->data);
758 +       return 1;
759 +}
760 +
761 +int larlib_member_load( lua_State *L )
762 +{
763 +       lar_member **member = luaL_checkudata( L, 1, "lar.member" );
764 +       int status = luaL_loadbuffer( L, (*member)->data, (*member)->length,
765 +               "=(lar member)" );
766 +
767 +       if( status )
768 +       {
769 +               lua_pushnil(L);
770 +               lua_insert(L, -2);
771 +               return 2;
772 +       }
773 +
774 +       return 1;
775 +}
776 +
777 +static int larlib_member__gc( lua_State *L )
778 +{
779 +       lar_member **member = luaL_checkudata( L, 1, "lar.member" );
780 +
781 +       if( *member )
782 +               lar_close_member(*member);
783 +
784 +       *member = NULL;
785 +       return 0;
786 +}
787 +
788 +
789 +static int larlib_mmfile__open( lua_State *L, const char *filename )
790 +{
791 +       struct stat s;
792 +       mmap_handle *fh, **udata;
793 +
794 +       if( filename == NULL )
795 +               filename = (const char *)luaL_checkstring( L, 1 );
796 +
797 +       if( (fh = (mmap_handle *)malloc(sizeof(mmap_handle))) == NULL )
798 +               return larlib_perror(L, "Out of memory");
799 +
800 +       if( stat(filename, &s) > -1 && (fh->fd = open(filename, O_RDONLY)) > -1 )
801 +       {
802 +               fh->length = s.st_size;
803 +               fh->data   = mmap( 0, s.st_size, PROT_READ, MAP_PRIVATE, fh->fd, 0 );
804 +
805 +               if( fh->data == MAP_FAILED )
806 +                       return larlib_perror(L, "Failed to mmap() file");
807 +
808 +               if( (udata = lua_newuserdata(L, sizeof(char *))) != NULL )
809 +               {
810 +                       *udata = fh;
811 +                       luaL_getmetatable(L, "lar.mmfile");
812 +                       lua_setmetatable(L, -2);
813 +               }
814 +               else
815 +               {
816 +                       return larlib_perror(L, "Out of memory");
817 +               }
818 +       }
819 +       else
820 +       {
821 +               return larlib_perror(L, strerror(errno));
822 +       }
823 +
824 +       return 1;
825 +}
826 +
827 +int larlib_mmfile_open( lua_State *L )
828 +{
829 +       return larlib_mmfile__open(L, NULL);
830 +}
831 +
832 +int larlib_mmfile_size( lua_State *L )
833 +{
834 +       mmap_handle **fh = luaL_checkudata( L, 1, "lar.mmfile" );
835 +       lua_pushnumber(L, (*fh)->length);
836 +       return 1;
837 +}
838 +
839 +int larlib_mmfile_read( lua_State *L )
840 +{
841 +       mmap_handle **fh = luaL_checkudata( L, 1, "lar.mmfile" );
842 +       int start  = luaL_checknumber( L, 2 );
843 +       int length = luaL_optnumber( L, 3, (*fh)->length );
844 +       char *stringcopy;
845 +
846 +       if( (start >= 0) && (start < (*fh)->length) && (length > 0) )
847 +       {
848 +               if( (start + length) >= (*fh)->length )
849 +                       length = (*fh)->length - start;
850 +
851 +               if( (stringcopy = (char *)malloc(length + 1)) != NULL )
852 +               {
853 +                       memcpy(stringcopy, &(*fh)->data[start], length);
854 +                       stringcopy[length] = '\0';
855 +                       lua_pushstring(L, stringcopy);
856 +                       free(stringcopy);
857 +               }
858 +               else
859 +               {
860 +                       return luaL_error(L, "Out of memory");
861 +               }
862 +       }
863 +       else
864 +       {
865 +               return larlib_perror(L, "Invalid argument");
866 +       }
867 +
868 +       return 1;
869 +}
870 +
871 +int larlib_mmfile_data( lua_State *L )
872 +{
873 +       mmap_handle **fh = luaL_checkudata( L, 1, "lar.mmfile" );
874 +       lua_pushstring(L, (*fh)->data);
875 +       return 1;
876 +}
877 +
878 +int larlib_mmfile_load( lua_State *L )
879 +{
880 +       mmap_handle **fh = luaL_checkudata( L, 1, "lar.mmfile" );
881 +       int status = luaL_loadbuffer(L, (*fh)->data, (*fh)->length, "=(mmap file)");
882 +
883 +       if( status )
884 +       {
885 +               lua_pushnil(L);
886 +               lua_insert(L, -2);
887 +               return 2;
888 +       }
889 +
890 +       return 1;
891 +}
892 +
893 +static int larlib_mmfile__gc( lua_State *L )
894 +{
895 +       mmap_handle **fh = luaL_checkudata( L, 1, "lar.mmfile" );
896 +
897 +       if( *fh )
898 +       {
899 +               close((*fh)->fd);
900 +               munmap((*fh)->data, (*fh)->length);
901 +               free(*fh);
902 +               *fh = NULL;
903 +       }
904 +
905 +       return 0;
906 +}
907 +
908 +
909 +int larlib_findfile( lua_State *L )
910 +{
911 +       int i;
912 +       const char *filename = luaL_checkstring( L, 1 );
913 +       const char *basepath = luaL_optstring( L, 2, "./" );
914 +       char filepath[1024];
915 +       struct stat s;
916 +       lar_archive *ar;
917 +       lar_member  *mb;
918 +
919 +       const char *searchpath[3] = { basepath, LUA_LDIR, LUA_CDIR };
920 +
921 +       for( i = 0; i < 3; i++ )
922 +               if( !larlib_mkpath(filename, searchpath[i], filepath) )
923 +                       if( stat(filepath, &s) > -1 && (s.st_mode & S_IFREG) )
924 +                               return larlib_mmfile__open( L, filepath );
925 +
926 +       for( i = 0; i < 3; i++ )
927 +               if( (ar = lar_find_archive(filename, searchpath[i], 0)) != NULL )
928 +                       if( (mb = lar_open_member(ar, filename)) != NULL )
929 +                               return larlib_member__open( L, mb );
930 +
931 +       return larlib_perror(L, "File not found");
932 +}
933 +
934 +
935 +static const luaL_reg LAR_REG[] = {
936 +       { "open",                       larlib_open             },
937 +       { "find",                       larlib_find             },
938 +       { "md5",                        larlib_md5                      },
939 +       { "md5_file",           larlib_md5_file         },
940 +       { "mmap",                       larlib_mmfile_open      },
941 +       { "findfile",           larlib_findfile         },
942 +       { NULL,                         NULL                            }
943 +};
944 +
945 +static const luaL_reg LAR_ARCHIVE_REG[] = {
946 +       { "member",                     larlib_member_open      },
947 +       { "find",                       larlib_member_find      },
948 +       { "__gc",                       larlib__gc                      },
949 +       { NULL,                         NULL                            }
950 +};
951 +
952 +static const luaL_reg LAR_MEMBER_REG[] = {
953 +       { "size",                       larlib_member_size      },
954 +       { "type",                       larlib_member_type      },
955 +       { "flags",                      larlib_member_flags     },
956 +       { "read",                       larlib_member_read      },
957 +       { "data",                       larlib_member_data      },
958 +       { "load",                       larlib_member_load      },
959 +       { "__gc",                       larlib_member__gc       },
960 +       { NULL,                         NULL                            }
961 +};
962 +
963 +static const luaL_reg LAR_MMFILE_REG[] = {
964 +       { "size",                       larlib_mmfile_size      },
965 +       { "read",                       larlib_mmfile_read      },
966 +       { "data",                       larlib_mmfile_data      },
967 +       { "load",                       larlib_mmfile_load      },
968 +       { "__gc",                       larlib_mmfile__gc       },
969 +       { NULL,                         NULL                            }
970 +};
971 +
972 +
973 +LUALIB_API int luaopen_larlib( lua_State *L )
974 +{
975 +       luaL_newmetatable(L, "lar");
976 +       luaL_register(L, NULL, LAR_REG);
977 +       lua_pushvalue(L, -1);
978 +       lua_setfield(L, -2, "__index");
979 +       lua_setglobal(L, "lar");
980 +
981 +       luaL_newmetatable(L, "lar.archive");
982 +       luaL_register(L, NULL, LAR_ARCHIVE_REG);
983 +       lua_pushvalue(L, -1);
984 +       lua_setfield(L, -2, "__index");
985 +       lua_setglobal(L, "lar.archive");
986 +
987 +       luaL_newmetatable(L, "lar.member");
988 +       luaL_register(L, NULL, LAR_MEMBER_REG);
989 +       lua_pushvalue(L, -1);
990 +       lua_setfield(L, -2, "__index");
991 +       lua_setglobal(L, "lar.member");
992 +
993 +       luaL_newmetatable(L, "lar.mmfile");
994 +       luaL_register(L, NULL, LAR_MMFILE_REG);
995 +       lua_pushvalue(L, -1);
996 +       lua_setfield(L, -2, "__index");
997 +       lua_setglobal(L, "lar.mmfile");
998 +
999 +       return 1;
1000 +}
1001 diff -Nbur lua-5.1.4.orig/src/linit.c lua-5.1.4/src/linit.c
1002 --- lua-5.1.4.orig/src/linit.c  2009-04-06 21:36:52.000000000 +0200
1003 +++ lua-5.1.4/src/linit.c       2009-04-11 01:27:00.000000000 +0200
1004 @@ -23,6 +23,7 @@
1005    {LUA_STRLIBNAME, luaopen_string},
1006    {LUA_MATHLIBNAME, luaopen_math},
1007    {LUA_DBLIBNAME, luaopen_debug},
1008 +  {LUA_LARLIBNAME, luaopen_larlib},
1009    {NULL, NULL}
1010  };
1011  
1012 diff -Nbur lua-5.1.4.orig/src/loadlib.c lua-5.1.4/src/loadlib.c
1013 --- lua-5.1.4.orig/src/loadlib.c        2009-04-06 21:36:52.000000000 +0200
1014 +++ lua-5.1.4/src/loadlib.c     2009-04-11 01:04:47.000000000 +0200
1015 @@ -21,6 +21,7 @@
1016  #include "lauxlib.h"
1017  #include "lualib.h"
1018  
1019 +#include "lar.h"
1020  
1021  /* prefix for open functions in C libraries */
1022  #define LUA_POF                "luaopen_"
1023 @@ -388,6 +389,36 @@
1024  }
1025  
1026  
1027 +static int loader_Lar (lua_State *L) {
1028 +  lar_archive *ar;
1029 +  lar_member  *mb;
1030 +  const char  *name = luaL_checkstring(L, 1);
1031 +
1032 +  if( (ar = lar_find_archive(name, "./", 1))     ||
1033 +      (ar = lar_find_archive(name, LUA_LDIR, 1)) ||
1034 +      (ar = lar_find_archive(name, LUA_CDIR, 1))
1035 +  ) {
1036 +    if( (mb = lar_find_member(ar, name)) != NULL ) {
1037 +      if( luaL_loadbuffer(L, mb->data, mb->length, ar->filename) != 0 ) {
1038 +        luaL_error(L, "error while loading lar member '%s':\n\t%s",
1039 +          name, lua_tostring(L, -1));
1040 +      }
1041 +      lar_close_member(mb);
1042 +    }
1043 +    else {
1044 +      lua_pushfstring(L, "\n\tno matching lar member " LUA_QS " in " LUA_QS,
1045 +        name, ar->filename);
1046 +    }
1047 +    lar_close(ar);
1048 +  }
1049 +  else {
1050 +    lua_pushfstring(L, "\n\tno matching lar archive for " LUA_QS, name);
1051 +  }
1052 +
1053 +  return 1;
1054 +}
1055 +
1056 +
1057  static const char *mkfuncname (lua_State *L, const char *modname) {
1058    const char *funcname;
1059    const char *mark = strchr(modname, *LUA_IGMARK);
1060 @@ -621,7 +652,7 @@
1061  
1062  
1063  static const lua_CFunction loaders[] =
1064 -  {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
1065 +  {loader_preload, loader_Lua, loader_Lar, loader_C, loader_Croot, NULL};
1066  
1067  
1068  LUALIB_API int luaopen_package (lua_State *L) {
1069 diff -Nbur lua-5.1.4.orig/src/lualib.h lua-5.1.4/src/lualib.h
1070 --- lua-5.1.4.orig/src/lualib.h 2009-04-06 21:36:52.000000000 +0200
1071 +++ lua-5.1.4/src/lualib.h      2009-04-11 01:28:24.000000000 +0200
1072 @@ -39,6 +39,9 @@
1073  #define LUA_LOADLIBNAME        "package"
1074  LUALIB_API int (luaopen_package) (lua_State *L);
1075  
1076 +#define LUA_LARLIBNAME "lar"
1077 +LUALIB_API int (luaopen_larlib) (lua_State *L);
1078 +
1079  
1080  /* open all previous libraries */
1081  LUALIB_API void (luaL_openlibs) (lua_State *L); 
1082 diff -Nbur lua-5.1.4.orig/src/md5.c lua-5.1.4/src/md5.c
1083 --- lua-5.1.4.orig/src/md5.c    1970-01-01 01:00:00.000000000 +0100
1084 +++ lua-5.1.4/src/md5.c 2009-04-10 23:07:56.000000000 +0200
1085 @@ -0,0 +1,381 @@
1086 +/*
1087 +  Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved.
1088 +
1089 +  This software is provided 'as-is', without any express or implied
1090 +  warranty.  In no event will the authors be held liable for any damages
1091 +  arising from the use of this software.
1092 +
1093 +  Permission is granted to anyone to use this software for any purpose,
1094 +  including commercial applications, and to alter it and redistribute it
1095 +  freely, subject to the following restrictions:
1096 +
1097 +  1. The origin of this software must not be misrepresented; you must not
1098 +     claim that you wrote the original software. If you use this software
1099 +     in a product, an acknowledgment in the product documentation would be
1100 +     appreciated but is not required.
1101 +  2. Altered source versions must be plainly marked as such, and must not be
1102 +     misrepresented as being the original software.
1103 +  3. This notice may not be removed or altered from any source distribution.
1104 +
1105 +  L. Peter Deutsch
1106 +  ghost@aladdin.com
1107 +
1108 + */
1109 +/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
1110 +/*
1111 +  Independent implementation of MD5 (RFC 1321).
1112 +
1113 +  This code implements the MD5 Algorithm defined in RFC 1321, whose
1114 +  text is available at
1115 +       http://www.ietf.org/rfc/rfc1321.txt
1116 +  The code is derived from the text of the RFC, including the test suite
1117 +  (section A.5) but excluding the rest of Appendix A.  It does not include
1118 +  any code or documentation that is identified in the RFC as being
1119 +  copyrighted.
1120 +
1121 +  The original and principal author of md5.c is L. Peter Deutsch
1122 +  <ghost@aladdin.com>.  Other authors are noted in the change history
1123 +  that follows (in reverse chronological order):
1124 +
1125 +  2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
1126 +       either statically or dynamically; added missing #include <string.h>
1127 +       in library.
1128 +  2002-03-11 lpd Corrected argument list for main(), and added int return
1129 +       type, in test program and T value program.
1130 +  2002-02-21 lpd Added missing #include <stdio.h> in test program.
1131 +  2000-07-03 lpd Patched to eliminate warnings about "constant is
1132 +       unsigned in ANSI C, signed in traditional"; made test program
1133 +       self-checking.
1134 +  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1135 +  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
1136 +  1999-05-03 lpd Original version.
1137 + */
1138 +
1139 +#include "md5.h"
1140 +#include <string.h>
1141 +
1142 +#undef BYTE_ORDER      /* 1 = big-endian, -1 = little-endian, 0 = unknown */
1143 +#ifdef ARCH_IS_BIG_ENDIAN
1144 +#  define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
1145 +#else
1146 +#  define BYTE_ORDER 0
1147 +#endif
1148 +
1149 +#define T_MASK ((md5_word_t)~0)
1150 +#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
1151 +#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
1152 +#define T3    0x242070db
1153 +#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
1154 +#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
1155 +#define T6    0x4787c62a
1156 +#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
1157 +#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
1158 +#define T9    0x698098d8
1159 +#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
1160 +#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
1161 +#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
1162 +#define T13    0x6b901122
1163 +#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
1164 +#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
1165 +#define T16    0x49b40821
1166 +#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
1167 +#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
1168 +#define T19    0x265e5a51
1169 +#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
1170 +#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
1171 +#define T22    0x02441453
1172 +#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
1173 +#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
1174 +#define T25    0x21e1cde6
1175 +#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
1176 +#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
1177 +#define T28    0x455a14ed
1178 +#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
1179 +#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
1180 +#define T31    0x676f02d9
1181 +#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
1182 +#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
1183 +#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
1184 +#define T35    0x6d9d6122
1185 +#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
1186 +#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
1187 +#define T38    0x4bdecfa9
1188 +#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
1189 +#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
1190 +#define T41    0x289b7ec6
1191 +#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
1192 +#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
1193 +#define T44    0x04881d05
1194 +#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
1195 +#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
1196 +#define T47    0x1fa27cf8
1197 +#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
1198 +#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
1199 +#define T50    0x432aff97
1200 +#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
1201 +#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
1202 +#define T53    0x655b59c3
1203 +#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
1204 +#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
1205 +#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
1206 +#define T57    0x6fa87e4f
1207 +#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
1208 +#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
1209 +#define T60    0x4e0811a1
1210 +#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
1211 +#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
1212 +#define T63    0x2ad7d2bb
1213 +#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
1214 +
1215 +
1216 +static void
1217 +md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
1218 +{
1219 +    md5_word_t
1220 +       a = pms->abcd[0], b = pms->abcd[1],
1221 +       c = pms->abcd[2], d = pms->abcd[3];
1222 +    md5_word_t t;
1223 +#if BYTE_ORDER > 0
1224 +    /* Define storage only for big-endian CPUs. */
1225 +    md5_word_t X[16];
1226 +#else
1227 +    /* Define storage for little-endian or both types of CPUs. */
1228 +    md5_word_t xbuf[16];
1229 +    const md5_word_t *X;
1230 +#endif
1231 +
1232 +    {
1233 +#if BYTE_ORDER == 0
1234 +       /*
1235 +        * Determine dynamically whether this is a big-endian or
1236 +        * little-endian machine, since we can use a more efficient
1237 +        * algorithm on the latter.
1238 +        */
1239 +       static const int w = 1;
1240 +
1241 +       if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
1242 +#endif
1243 +#if BYTE_ORDER <= 0            /* little-endian */
1244 +       {
1245 +           /*
1246 +            * On little-endian machines, we can process properly aligned
1247 +            * data without copying it.
1248 +            */
1249 +           if (!((data - (const md5_byte_t *)0) & 3)) {
1250 +               /* data are properly aligned */
1251 +               X = (const md5_word_t *)data;
1252 +           } else {
1253 +               /* not aligned */
1254 +               memcpy(xbuf, data, 64);
1255 +               X = xbuf;
1256 +           }
1257 +       }
1258 +#endif
1259 +#if BYTE_ORDER == 0
1260 +       else                    /* dynamic big-endian */
1261 +#endif
1262 +#if BYTE_ORDER >= 0            /* big-endian */
1263 +       {
1264 +           /*
1265 +            * On big-endian machines, we must arrange the bytes in the
1266 +            * right order.
1267 +            */
1268 +           const md5_byte_t *xp = data;
1269 +           int i;
1270 +
1271 +#  if BYTE_ORDER == 0
1272 +           X = xbuf;           /* (dynamic only) */
1273 +#  else
1274 +#    define xbuf X             /* (static only) */
1275 +#  endif
1276 +           for (i = 0; i < 16; ++i, xp += 4)
1277 +               xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
1278 +       }
1279 +#endif
1280 +    }
1281 +
1282 +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
1283 +
1284 +    /* Round 1. */
1285 +    /* Let [abcd k s i] denote the operation
1286 +       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
1287 +#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
1288 +#define SET(a, b, c, d, k, s, Ti)\
1289 +  t = a + F(b,c,d) + X[k] + Ti;\
1290 +  a = ROTATE_LEFT(t, s) + b
1291 +    /* Do the following 16 operations. */
1292 +    SET(a, b, c, d,  0,  7,  T1);
1293 +    SET(d, a, b, c,  1, 12,  T2);
1294 +    SET(c, d, a, b,  2, 17,  T3);
1295 +    SET(b, c, d, a,  3, 22,  T4);
1296 +    SET(a, b, c, d,  4,  7,  T5);
1297 +    SET(d, a, b, c,  5, 12,  T6);
1298 +    SET(c, d, a, b,  6, 17,  T7);
1299 +    SET(b, c, d, a,  7, 22,  T8);
1300 +    SET(a, b, c, d,  8,  7,  T9);
1301 +    SET(d, a, b, c,  9, 12, T10);
1302 +    SET(c, d, a, b, 10, 17, T11);
1303 +    SET(b, c, d, a, 11, 22, T12);
1304 +    SET(a, b, c, d, 12,  7, T13);
1305 +    SET(d, a, b, c, 13, 12, T14);
1306 +    SET(c, d, a, b, 14, 17, T15);
1307 +    SET(b, c, d, a, 15, 22, T16);
1308 +#undef SET
1309 +
1310 +     /* Round 2. */
1311 +     /* Let [abcd k s i] denote the operation
1312 +          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
1313 +#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
1314 +#define SET(a, b, c, d, k, s, Ti)\
1315 +  t = a + G(b,c,d) + X[k] + Ti;\
1316 +  a = ROTATE_LEFT(t, s) + b
1317 +     /* Do the following 16 operations. */
1318 +    SET(a, b, c, d,  1,  5, T17);
1319 +    SET(d, a, b, c,  6,  9, T18);
1320 +    SET(c, d, a, b, 11, 14, T19);
1321 +    SET(b, c, d, a,  0, 20, T20);
1322 +    SET(a, b, c, d,  5,  5, T21);
1323 +    SET(d, a, b, c, 10,  9, T22);
1324 +    SET(c, d, a, b, 15, 14, T23);
1325 +    SET(b, c, d, a,  4, 20, T24);
1326 +    SET(a, b, c, d,  9,  5, T25);
1327 +    SET(d, a, b, c, 14,  9, T26);
1328 +    SET(c, d, a, b,  3, 14, T27);
1329 +    SET(b, c, d, a,  8, 20, T28);
1330 +    SET(a, b, c, d, 13,  5, T29);
1331 +    SET(d, a, b, c,  2,  9, T30);
1332 +    SET(c, d, a, b,  7, 14, T31);
1333 +    SET(b, c, d, a, 12, 20, T32);
1334 +#undef SET
1335 +
1336 +     /* Round 3. */
1337 +     /* Let [abcd k s t] denote the operation
1338 +          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
1339 +#define H(x, y, z) ((x) ^ (y) ^ (z))
1340 +#define SET(a, b, c, d, k, s, Ti)\
1341 +  t = a + H(b,c,d) + X[k] + Ti;\
1342 +  a = ROTATE_LEFT(t, s) + b
1343 +     /* Do the following 16 operations. */
1344 +    SET(a, b, c, d,  5,  4, T33);
1345 +    SET(d, a, b, c,  8, 11, T34);
1346 +    SET(c, d, a, b, 11, 16, T35);
1347 +    SET(b, c, d, a, 14, 23, T36);
1348 +    SET(a, b, c, d,  1,  4, T37);
1349 +    SET(d, a, b, c,  4, 11, T38);
1350 +    SET(c, d, a, b,  7, 16, T39);
1351 +    SET(b, c, d, a, 10, 23, T40);
1352 +    SET(a, b, c, d, 13,  4, T41);
1353 +    SET(d, a, b, c,  0, 11, T42);
1354 +    SET(c, d, a, b,  3, 16, T43);
1355 +    SET(b, c, d, a,  6, 23, T44);
1356 +    SET(a, b, c, d,  9,  4, T45);
1357 +    SET(d, a, b, c, 12, 11, T46);
1358 +    SET(c, d, a, b, 15, 16, T47);
1359 +    SET(b, c, d, a,  2, 23, T48);
1360 +#undef SET
1361 +
1362 +     /* Round 4. */
1363 +     /* Let [abcd k s t] denote the operation
1364 +          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
1365 +#define I(x, y, z) ((y) ^ ((x) | ~(z)))
1366 +#define SET(a, b, c, d, k, s, Ti)\
1367 +  t = a + I(b,c,d) + X[k] + Ti;\
1368 +  a = ROTATE_LEFT(t, s) + b
1369 +     /* Do the following 16 operations. */
1370 +    SET(a, b, c, d,  0,  6, T49);
1371 +    SET(d, a, b, c,  7, 10, T50);
1372 +    SET(c, d, a, b, 14, 15, T51);
1373 +    SET(b, c, d, a,  5, 21, T52);
1374 +    SET(a, b, c, d, 12,  6, T53);
1375 +    SET(d, a, b, c,  3, 10, T54);
1376 +    SET(c, d, a, b, 10, 15, T55);
1377 +    SET(b, c, d, a,  1, 21, T56);
1378 +    SET(a, b, c, d,  8,  6, T57);
1379 +    SET(d, a, b, c, 15, 10, T58);
1380 +    SET(c, d, a, b,  6, 15, T59);
1381 +    SET(b, c, d, a, 13, 21, T60);
1382 +    SET(a, b, c, d,  4,  6, T61);
1383 +    SET(d, a, b, c, 11, 10, T62);
1384 +    SET(c, d, a, b,  2, 15, T63);
1385 +    SET(b, c, d, a,  9, 21, T64);
1386 +#undef SET
1387 +
1388 +     /* Then perform the following additions. (That is increment each
1389 +        of the four registers by the value it had before this block
1390 +        was started.) */
1391 +    pms->abcd[0] += a;
1392 +    pms->abcd[1] += b;
1393 +    pms->abcd[2] += c;
1394 +    pms->abcd[3] += d;
1395 +}
1396 +
1397 +void
1398 +md5_init(md5_state_t *pms)
1399 +{
1400 +    pms->count[0] = pms->count[1] = 0;
1401 +    pms->abcd[0] = 0x67452301;
1402 +    pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
1403 +    pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
1404 +    pms->abcd[3] = 0x10325476;
1405 +}
1406 +
1407 +void
1408 +md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
1409 +{
1410 +    const md5_byte_t *p = data;
1411 +    int left = nbytes;
1412 +    int offset = (pms->count[0] >> 3) & 63;
1413 +    md5_word_t nbits = (md5_word_t)(nbytes << 3);
1414 +
1415 +    if (nbytes <= 0)
1416 +       return;
1417 +
1418 +    /* Update the message length. */
1419 +    pms->count[1] += nbytes >> 29;
1420 +    pms->count[0] += nbits;
1421 +    if (pms->count[0] < nbits)
1422 +       pms->count[1]++;
1423 +
1424 +    /* Process an initial partial block. */
1425 +    if (offset) {
1426 +       int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
1427 +
1428 +       memcpy(pms->buf + offset, p, copy);
1429 +       if (offset + copy < 64)
1430 +           return;
1431 +       p += copy;
1432 +       left -= copy;
1433 +       md5_process(pms, pms->buf);
1434 +    }
1435 +
1436 +    /* Process full blocks. */
1437 +    for (; left >= 64; p += 64, left -= 64)
1438 +       md5_process(pms, p);
1439 +
1440 +    /* Process a final partial block. */
1441 +    if (left)
1442 +       memcpy(pms->buf, p, left);
1443 +}
1444 +
1445 +void
1446 +md5_finish(md5_state_t *pms, md5_byte_t digest[16])
1447 +{
1448 +    static const md5_byte_t pad[64] = {
1449 +       0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1450 +       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1451 +       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1452 +       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1453 +    };
1454 +    md5_byte_t data[8];
1455 +    int i;
1456 +
1457 +    /* Save the length before padding. */
1458 +    for (i = 0; i < 8; ++i)
1459 +       data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
1460 +    /* Pad to 56 bytes mod 64. */
1461 +    md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
1462 +    /* Append the length. */
1463 +    md5_append(pms, data, 8);
1464 +    for (i = 0; i < 16; ++i)
1465 +       digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
1466 +}
1467 diff -Nbur lua-5.1.4.orig/src/md5.h lua-5.1.4/src/md5.h
1468 --- lua-5.1.4.orig/src/md5.h    1970-01-01 01:00:00.000000000 +0100
1469 +++ lua-5.1.4/src/md5.h 2009-04-10 23:07:56.000000000 +0200
1470 @@ -0,0 +1,91 @@
1471 +/*
1472 +  Copyright (C) 1999, 2002 Aladdin Enterprises.  All rights reserved.
1473 +
1474 +  This software is provided 'as-is', without any express or implied
1475 +  warranty.  In no event will the authors be held liable for any damages
1476 +  arising from the use of this software.
1477 +
1478 +  Permission is granted to anyone to use this software for any purpose,
1479 +  including commercial applications, and to alter it and redistribute it
1480 +  freely, subject to the following restrictions:
1481 +
1482 +  1. The origin of this software must not be misrepresented; you must not
1483 +     claim that you wrote the original software. If you use this software
1484 +     in a product, an acknowledgment in the product documentation would be
1485 +     appreciated but is not required.
1486 +  2. Altered source versions must be plainly marked as such, and must not be
1487 +     misrepresented as being the original software.
1488 +  3. This notice may not be removed or altered from any source distribution.
1489 +
1490 +  L. Peter Deutsch
1491 +  ghost@aladdin.com
1492 +
1493 + */
1494 +/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
1495 +/*
1496 +  Independent implementation of MD5 (RFC 1321).
1497 +
1498 +  This code implements the MD5 Algorithm defined in RFC 1321, whose
1499 +  text is available at
1500 +       http://www.ietf.org/rfc/rfc1321.txt
1501 +  The code is derived from the text of the RFC, including the test suite
1502 +  (section A.5) but excluding the rest of Appendix A.  It does not include
1503 +  any code or documentation that is identified in the RFC as being
1504 +  copyrighted.
1505 +
1506 +  The original and principal author of md5.h is L. Peter Deutsch
1507 +  <ghost@aladdin.com>.  Other authors are noted in the change history
1508 +  that follows (in reverse chronological order):
1509 +
1510 +  2002-04-13 lpd Removed support for non-ANSI compilers; removed
1511 +       references to Ghostscript; clarified derivation from RFC 1321;
1512 +       now handles byte order either statically or dynamically.
1513 +  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1514 +  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
1515 +       added conditionalization for C++ compilation from Martin
1516 +       Purschke <purschke@bnl.gov>.
1517 +  1999-05-03 lpd Original version.
1518 + */
1519 +
1520 +#ifndef md5_INCLUDED
1521 +#  define md5_INCLUDED
1522 +
1523 +/*
1524 + * This package supports both compile-time and run-time determination of CPU
1525 + * byte order.  If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
1526 + * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
1527 + * defined as non-zero, the code will be compiled to run only on big-endian
1528 + * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
1529 + * run on either big- or little-endian CPUs, but will run slightly less
1530 + * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
1531 + */
1532 +
1533 +typedef unsigned char md5_byte_t; /* 8-bit byte */
1534 +typedef unsigned int md5_word_t; /* 32-bit word */
1535 +
1536 +/* Define the state of the MD5 Algorithm. */
1537 +typedef struct md5_state_s {
1538 +    md5_word_t count[2];       /* message length in bits, lsw first */
1539 +    md5_word_t abcd[4];                /* digest buffer */
1540 +    md5_byte_t buf[64];                /* accumulate block */
1541 +} md5_state_t;
1542 +
1543 +#ifdef __cplusplus
1544 +extern "C" 
1545 +{
1546 +#endif
1547 +
1548 +/* Initialize the algorithm. */
1549 +void md5_init(md5_state_t *pms);
1550 +
1551 +/* Append a string to the message. */
1552 +void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
1553 +
1554 +/* Finish the message and return the digest. */
1555 +void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
1556 +
1557 +#ifdef __cplusplus
1558 +}  /* end extern "C" */
1559 +#endif
1560 +
1561 +#endif /* md5_INCLUDED */