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