contrib/lar: get rid of hardcoded buffer size in larlib
[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 17:24:57.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) <= LAR_FNAME_BUFFER )
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 + struct stat s;
915 + lar_archive *ar;
916 + lar_member *mb;
917 + LAR_FNAME(filepath);
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 */