Changeset 4426

Show
Ignore:
Timestamp:
04/13/09 16:10:01 (4 years ago)
Author:
jow
Message:

contrib/lar:

  • add lua binding for lar library
  • introduce mmap() support for lua
Location:
luci/trunk/contrib/lar
Files:
3 added
5 modified

Legend:

Unmodified
Added
Removed
  • luci/trunk/contrib/lar/cli.c

    r4410 r4426  
    1919{ 
    2020    lar_index *index = ar->index; 
    21     LAR_FNAME(filename); 
    2221 
    23     while(index) 
     22    if( ar->has_filenames ) 
    2423    { 
    25         lar_get_filename(ar, index, filename); 
    26         printf("%s\n", filename); 
    27         index = index->next; 
     24        while(index) 
     25        { 
     26            if( index->type == LAR_TYPE_REGULAR ) 
     27            { 
     28                printf("%s\n", index->filename); 
     29            } 
     30 
     31            index = index->next; 
     32        } 
     33 
     34        return 0; 
    2835    } 
    2936 
    30     return 0; 
     37    LAR_DIE("The archive contains no file list"); 
     38    return 1; 
    3139} 
    3240 
     
    3745    lar_member *mb; 
    3846 
    39     if( (ar = lar_find_archive(package, path)) != NULL ) 
     47    if( (ar = lar_find_archive(package, path, 1)) != NULL ) 
    4048    { 
    4149        if( (mb = lar_find_member(ar, package)) != NULL ) 
     50        { 
     51            write(fileno(stdout), mb->data, mb->length); 
     52            lar_close_member(mb); 
     53            stat = 0; 
     54        } 
     55 
     56        lar_close(ar); 
     57    } 
     58 
     59    return stat; 
     60} 
     61 
     62int do_findfile( const char *filename, const char *path ) 
     63{ 
     64    int stat = 1; 
     65    lar_archive *ar; 
     66    lar_member *mb; 
     67 
     68    if( (ar = lar_find_archive(filename, path, 0)) != NULL ) 
     69    { 
     70        if( (mb = lar_open_member(ar, filename)) != NULL ) 
    4271        { 
    4372            write(fileno(stdout), mb->data, mb->length); 
     
    5786    int stat = 0; 
    5887 
    59     if( argv[1] != NULL ) 
     88    if( argv[1] != NULL && argv[2] != NULL ) 
    6089    { 
    6190        switch(argv[1][0]) 
     
    81110                stat = do_require(argv[2], argv[3]); 
    82111                break; 
     112 
     113            case 'f': 
     114                stat = do_findfile(argv[2], argv[3]); 
     115                break; 
    83116        } 
    84117 
     
    90123        printf("\tlar show <archive> [<member>]\n"); 
    91124        printf("\tlar require <package> [<path>]\n"); 
     125        printf("\tlar find <filename> [<path>]\n"); 
    92126 
    93127        return 1; 
  • luci/trunk/contrib/lar/lar.c

    r4412 r4426  
     1/* 
     2 * lar - Lua Archive Library 
     3 * 
     4 *   Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> 
     5 * 
     6 *  Licensed under the Apache License, Version 2.0 (the "License"); 
     7 *  you may not use this file except in compliance with the License. 
     8 *  You may obtain a copy of the License at 
     9 * 
     10 *      http://www.apache.org/licenses/LICENSE-2.0 
     11 * 
     12 *  Unless required by applicable law or agreed to in writing, software 
     13 *  distributed under the License is distributed on an "AS IS" BASIS, 
     14 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
     15 *  See the License for the specific language governing permissions and 
     16 *  limitations under the License. 
     17 */ 
     18 
     19 
    120#include "lar.h" 
    221 
    3 int lar_read32( int fd, uint32_t *val ) 
     22static int lar_read32( int fd, uint32_t *val ) 
    423{ 
    524    uint8_t buffer[5]; 
     
    1433} 
    1534 
    16 int lar_read16( int fd, uint16_t *val ) 
     35static int lar_read16( int fd, uint16_t *val ) 
    1736{ 
    1837    uint8_t buffer[3]; 
     
    2342    buffer[2] = 0; 
    2443    *val = ntohs(*((uint16_t *) buffer)); 
     44 
     45    return 0; 
     46} 
     47 
     48static void lar_md5( char *md5, const char *data, int len ) 
     49{ 
     50    md5_state_t state; 
     51 
     52    md5_init(&state); 
     53    md5_append(&state, (const md5_byte_t *)data, len); 
     54    md5_finish(&state, (md5_byte_t *)md5); 
     55} 
     56 
     57static int lar_read_filenames( lar_archive *ar ) 
     58{ 
     59    int i; 
     60    int j; 
     61    char *filelist; 
     62    size_t pgof; 
     63    size_t pgsz = getpagesize(); 
     64    lar_index *idx_ptr; 
     65    lar_index *idx_filelist = ar->index; 
     66 
     67    while(idx_filelist) 
     68    { 
     69        if( idx_filelist->type == LAR_TYPE_FILELIST ) 
     70            break; 
     71 
     72        idx_filelist = idx_filelist->next; 
     73    } 
     74 
     75    if( idx_filelist != NULL ) 
     76    { 
     77        pgof = ( idx_filelist->offset % pgsz ); 
     78 
     79        filelist = mmap( 
     80            0, idx_filelist->length + pgof, PROT_READ, MAP_PRIVATE, 
     81            ar->fd, idx_filelist->offset - pgof 
     82        ); 
     83 
     84        if( filelist == MAP_FAILED ) 
     85            LAR_DIE("Failed to mmap() file list"); 
     86 
     87 
     88        idx_ptr = ar->index; 
     89        i = pgof; 
     90 
     91        while(idx_ptr) 
     92        { 
     93            if( idx_ptr->type == LAR_TYPE_REGULAR ) 
     94            { 
     95                j = strlen(&filelist[i]) + 1; 
     96 
     97                if( (j >= LAR_FNAME_BUFFER) || 
     98                    ((i+j) > (idx_filelist->length+pgof)) ) 
     99                        LAR_DIE("Filename exceeds maximum allowed length"); 
     100 
     101                idx_ptr->filename = (char *)malloc(j); 
     102                memcpy(idx_ptr->filename, &filelist[i], j); 
     103 
     104                i += j; 
     105            } 
     106 
     107            idx_ptr = idx_ptr->next; 
     108        } 
     109 
     110        munmap(filelist, idx_filelist->length + pgof); 
     111 
     112        return 1; 
     113    } 
    25114 
    26115    return 0; 
     
    47136    idx_map = NULL; 
    48137 
    49     for( i = 0; i < idx_length; i += (sizeof(lar_index) - sizeof(char *)) ) { 
     138    for( i = 0; i < idx_length; i += (sizeof(lar_index) - 2 * sizeof(char *)) ) 
     139    { 
    50140        idx_ptr = (lar_index *)malloc(sizeof(lar_index)); 
    51  
    52         lar_read32(ar->fd, &idx_ptr->noffset); 
    53         lar_read32(ar->fd, &idx_ptr->nlength); 
    54         lar_read32(ar->fd, &idx_ptr->foffset); 
    55         lar_read32(ar->fd, &idx_ptr->flength); 
     141        idx_ptr->filename = NULL; 
     142 
     143        lar_read32(ar->fd, &idx_ptr->offset); 
     144        lar_read32(ar->fd, &idx_ptr->length); 
    56145        lar_read16(ar->fd, &idx_ptr->type); 
    57146        lar_read16(ar->fd, &idx_ptr->flags); 
    58147 
     148        if(read(ar->fd,&idx_ptr->id,sizeof(idx_ptr->id)) < sizeof(idx_ptr->id)) 
     149            LAR_DIE("Unexpected EOF while reading member id"); 
     150 
    59151        idx_ptr->next = idx_map; 
    60152        idx_map = idx_ptr; 
     
    64156} 
    65157 
    66 uint32_t lar_get_filename( lar_archive *ar, lar_index *idx_ptr, char *filename ) 
    67 { 
    68     if( idx_ptr->nlength >= LAR_FNAME_BUFFER ) 
    69         LAR_DIE("Filename exceeds maximum allowed length"); 
    70  
    71     if( lseek(ar->fd, idx_ptr->noffset, SEEK_SET) == -1 ) 
    72         LAR_DIE("Unexpected EOF while seeking filename"); 
    73  
    74     if( read(ar->fd, filename, idx_ptr->nlength) < idx_ptr->nlength ) 
    75         LAR_DIE("Unexpected EOF while reading filename"); 
    76  
    77     filename[idx_ptr->nlength] = '\0'; 
    78  
    79     return idx_ptr->nlength; 
     158lar_member * lar_mmap_member( lar_archive *ar, lar_index *idx_ptr ) 
     159{ 
     160    lar_member *member; 
     161    size_t pgsz = getpagesize(); 
     162    size_t pgof = ( idx_ptr->offset % pgsz ); 
     163 
     164    char *memberdata = mmap( 
     165        0, idx_ptr->length + pgof, PROT_READ, MAP_PRIVATE, 
     166        ar->fd, idx_ptr->offset - pgof 
     167    ); 
     168 
     169    if( memberdata == MAP_FAILED ) 
     170        LAR_DIE("Failed to mmap() member data"); 
     171 
     172    member = (lar_member *)malloc(sizeof(lar_member)); 
     173    member->type   = idx_ptr->type; 
     174    member->flags  = idx_ptr->flags; 
     175    member->length = idx_ptr->length; 
     176    member->data   = &memberdata[pgof]; 
     177 
     178    member->mmap   = memberdata; 
     179    member->mlen   = idx_ptr->length + pgof; 
     180 
     181    return member; 
    80182} 
    81183 
     
    83185{ 
    84186    lar_index *idx_ptr = ar->index; 
    85     lar_member *member; 
    86     char *memberdata; 
    87     size_t pgof; 
    88     size_t pgsz = getpagesize(); 
    89     LAR_FNAME(memberfile); 
     187    char mbid[sizeof(idx_ptr->id)]; 
     188 
     189    lar_md5(mbid, name, strlen(name)); 
    90190 
    91191    while(idx_ptr) 
    92192    { 
    93         lar_get_filename(ar, idx_ptr, memberfile); 
    94  
    95         if( !strncmp(memberfile, name, idx_ptr->nlength) ) 
    96         { 
    97             pgof = ( idx_ptr->foffset % pgsz ); 
    98  
    99             memberdata = mmap( 
    100                 0, idx_ptr->flength + pgof, PROT_READ, MAP_PRIVATE, 
    101                 ar->fd, idx_ptr->foffset - pgof 
    102             ); 
    103  
    104             if( memberdata == MAP_FAILED ) 
    105                 LAR_DIE("Failed to mmap() member data"); 
    106  
    107             member = (lar_member *)malloc(sizeof(lar_member)); 
    108             member->type   = idx_ptr->type; 
    109             member->flags  = idx_ptr->flags; 
    110             member->length = idx_ptr->flength; 
    111             member->data   = &memberdata[pgof]; 
    112  
    113             member->mmap   = memberdata; 
    114             member->mlen   = idx_ptr->flength + pgof; 
    115  
    116             return member; 
    117         } 
     193        if( !strncmp(mbid, idx_ptr->id, sizeof(mbid)) ) 
     194            return lar_mmap_member(ar, idx_ptr); 
    118195 
    119196        idx_ptr = idx_ptr->next; 
     
    127204    int stat = munmap(member->mmap, member->mlen); 
    128205    free(member); 
     206    member = NULL; 
    129207 
    130208    return stat; 
     
    151229        strncpy(ar->filename, filename, sizeof(ar->filename)); 
    152230 
     231        ar->has_filenames = lar_read_filenames(ar); 
     232 
    153233        return ar; 
    154234    } 
     
    167247    do { 
    168248        idx_next = idx_head->next; 
     249        free(idx_head->filename); 
    169250        free(idx_head); 
    170251    } while( (idx_head = idx_next) != NULL ); 
    171252 
    172253    free(ar); 
     254    ar = NULL; 
    173255 
    174256    return 0; 
    175257} 
    176258 
    177 lar_archive * lar_find_archive( const char *package, const char *path ) 
     259lar_archive * lar_find_archive( const char *package, const char *path, int pkg ) 
    178260{ 
    179261    uint32_t i; 
     
    182264    uint32_t len = 0; 
    183265    uint32_t pln = 0; 
     266    char sep = ( pkg ? '.' : '/' ); 
    184267    struct stat s; 
    185268    LAR_FNAME(buffer); 
     
    194277    } 
    195278 
     279    if( buffer[pln-1] != '/' ) 
     280        buffer[pln++] = '/'; 
     281 
    196282    for( len = 0; package[len] != '\0'; len++ ) 
    197283    { 
     
    199285            LAR_DIE("Package name exceeds maximum allowed length"); 
    200286 
    201         if( package[len] == '.' ) seg++; 
     287        if( package[len] == sep ) seg++; 
    202288    } 
    203289 
     
    206292        for( i = 0, j = 1; (i < len) && (j <= seg); i++ ) 
    207293        { 
    208             if( package[i] == '.' ) { 
     294            if( package[i] == sep ) { 
    209295                if( j < seg ) j++; else break; 
    210296            } 
    211297 
    212             buffer[pln+i] = ( package[i] == '.' ) ? LAR_DIRSEP : package[i]; 
     298            buffer[pln+i] = ( package[i] == sep ) ? LAR_DIRSEP : package[i]; 
    213299        } 
    214300 
  • luci/trunk/contrib/lar/lar.h

    r4410 r4426  
     1/* 
     2 * lar - Lua Archive Library 
     3 * 
     4 *   Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> 
     5 * 
     6 *  Licensed under the Apache License, Version 2.0 (the "License"); 
     7 *  you may not use this file except in compliance with the License. 
     8 *  You may obtain a copy of the License at 
     9 * 
     10 *      http://www.apache.org/licenses/LICENSE-2.0 
     11 * 
     12 *  Unless required by applicable law or agreed to in writing, software 
     13 *  distributed under the License is distributed on an "AS IS" BASIS, 
     14 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
     15 *  See the License for the specific language governing permissions and 
     16 *  limitations under the License. 
     17 */ 
     18 
     19 
    120#ifndef __LAR_H 
    221#define __LAR_H 
     
    1433#include <sys/stat.h> 
    1534 
     35#include "md5.h" 
    1636 
    1737#define LAR_DIE(s) \ 
     
    2848#define LAR_FNAME(s) char s[LAR_FNAME_BUFFER] 
    2949 
     50#define LAR_TYPE_REGULAR    0x0000 
     51#define LAR_TYPE_FILELIST   0xFFFF 
     52 
    3053#ifdef __WIN32__ 
    3154#define LAR_DIRSEP  '\\' 
     
    3659 
    3760struct lar_index_item { 
    38     uint32_t noffset; 
    39     uint32_t nlength; 
    40     uint32_t foffset; 
    41     uint32_t flength; 
     61    uint32_t offset; 
     62    uint32_t length; 
    4263    uint16_t type; 
    4364    uint16_t flags; 
     65    char id[16]; 
     66    char *filename; 
    4467    struct lar_index_item *next; 
    4568}; 
     
    5679struct lar_archive_handle { 
    5780    int fd; 
     81    int has_filenames; 
    5882    off_t length; 
    5983    char filename[LAR_FNAME_BUFFER]; 
     
    6589typedef struct lar_archive_handle lar_archive; 
    6690 
    67  
    68 int lar_read32( int fd, uint32_t *val ); 
    69 int lar_read16( int fd, uint16_t *val ); 
     91/* 
     92static int lar_read_filenames( lar_archive *ar ); 
     93static int lar_read32( int fd, uint32_t *val ); 
     94static int lar_read16( int fd, uint16_t *val ); 
     95static void lar_md5( char *md5, const char *data, int len ); 
     96*/ 
    7097 
    7198lar_index * lar_get_index( lar_archive *ar ); 
    7299 
    73 uint32_t lar_get_filename( lar_archive *ar, 
    74     lar_index *idx_ptr, char *filename ); 
     100lar_member * lar_mmap_member( lar_archive *ar, lar_index *idx_ptr ); 
    75101 
    76102lar_member * lar_open_member( lar_archive *ar, const char *name ); 
     
    82108int lar_close( lar_archive *ar ); 
    83109 
    84 lar_archive * lar_find_archive( const char *package, const char *path ); 
     110lar_archive * lar_find_archive( const char *package, const char *path, int pkg); 
    85111 
    86112lar_member * lar_find_member( lar_archive *ar, const char *package ); 
  • luci/trunk/contrib/lar/Makefile

    r4405 r4426  
    33LDFLAGS := 
    44 
    5 OBJ = cli.o lar.o 
     5OBJ = cli.o lar.o md5.o 
    66BIN = lar 
    77 
  • luci/trunk/contrib/lar/openwrt/050-lar-source-loader.patch

    r4412 r4426  
    1 diff -Nurb lua-5.1.4.orig/src/Makefile lua-5.1.4/src/Makefile 
     1diff -Nbur lua-5.1.4.orig/src/Makefile lua-5.1.4/src/Makefile 
    22--- lua-5.1.4.orig/src/Makefile 2009-04-06 21:36:52.000000000 +0200 
    3 +++ lua-5.1.4/src/Makefile  2009-04-06 23:04:42.000000000 +0200 
     3+++ lua-5.1.4/src/Makefile  2009-04-11 01:02:45.000000000 +0200 
    44@@ -28,7 +28,7 @@ 
    55    lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o  \ 
     
    77 LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \ 
    88-   lstrlib.o loadlib.o linit.o 
    9 +   lstrlib.o loadlib.o linit.o lar.o 
     9+   lstrlib.o loadlib.o linit.o lar.o md5.o larlib.o 
    1010  
    1111 LUA_T= lua 
    1212 LUA_O= lua.o 
    13 diff -Nurb lua-5.1.4.orig/src/lar.c lua-5.1.4/src/lar.c 
     13diff -Nbur lua-5.1.4.orig/src/lar.c lua-5.1.4/src/lar.c 
    1414--- lua-5.1.4.orig/src/lar.c    1970-01-01 01:00:00.000000000 +0100 
    15 +++ lua-5.1.4/src/lar.c 2009-04-07 03:53:29.000000000 +0200 
    16 @@ -0,0 +1,242 @@ 
     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+ 
    1736+#include "lar.h" 
    1837+ 
    19 +int lar_read32( int fd, uint32_t *val ) 
     38+static int lar_read32( int fd, uint32_t *val ) 
    2039+{ 
    2140+   uint8_t buffer[5]; 
     
    3049+} 
    3150+ 
    32 +int lar_read16( int fd, uint16_t *val ) 
     51+static int lar_read16( int fd, uint16_t *val ) 
    3352+{ 
    3453+   uint8_t buffer[3]; 
     
    3958+   buffer[2] = 0; 
    4059+   *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+   } 
    41130+ 
    42131+   return 0; 
     
    63152+   idx_map = NULL; 
    64153+ 
    65 +   for( i = 0; i < idx_length; i += (sizeof(lar_index) - sizeof(char *)) ) { 
     154+   for( i = 0; i < idx_length; i += (sizeof(lar_index) - 2 * sizeof(char *)) ) 
     155+   { 
    66156+       idx_ptr = (lar_index *)malloc(sizeof(lar_index)); 
    67 + 
    68 +       lar_read32(ar->fd, &idx_ptr->noffset); 
    69 +       lar_read32(ar->fd, &idx_ptr->nlength); 
    70 +       lar_read32(ar->fd, &idx_ptr->foffset); 
    71 +       lar_read32(ar->fd, &idx_ptr->flength); 
     157+       idx_ptr->filename = NULL; 
     158+ 
     159+       lar_read32(ar->fd, &idx_ptr->offset); 
     160+       lar_read32(ar->fd, &idx_ptr->length); 
    72161+       lar_read16(ar->fd, &idx_ptr->type); 
    73162+       lar_read16(ar->fd, &idx_ptr->flags); 
    74163+ 
     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+ 
    75167+       idx_ptr->next = idx_map; 
    76168+       idx_map = idx_ptr; 
     
    80172+} 
    81173+ 
    82 +uint32_t lar_get_filename( lar_archive *ar, lar_index *idx_ptr, char *filename ) 
    83 +{ 
    84 +   if( idx_ptr->nlength >= LAR_FNAME_BUFFER ) 
    85 +       LAR_DIE("Filename exceeds maximum allowed length"); 
    86 + 
    87 +   if( lseek(ar->fd, idx_ptr->noffset, SEEK_SET) == -1 ) 
    88 +       LAR_DIE("Unexpected EOF while seeking filename"); 
    89 + 
    90 +   if( read(ar->fd, filename, idx_ptr->nlength) < idx_ptr->nlength ) 
    91 +       LAR_DIE("Unexpected EOF while reading filename"); 
    92 + 
    93 +   filename[idx_ptr->nlength] = '\0'; 
    94 + 
    95 +   return idx_ptr->nlength; 
     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; 
    96198+} 
    97199+ 
     
    99201+{ 
    100202+   lar_index *idx_ptr = ar->index; 
    101 +   lar_member *member; 
    102 +   char *memberdata; 
    103 +   size_t pgof; 
    104 +   size_t pgsz = getpagesize(); 
    105 +   LAR_FNAME(memberfile); 
     203+   char mbid[sizeof(idx_ptr->id)]; 
     204+ 
     205+   lar_md5(mbid, name, strlen(name)); 
    106206+ 
    107207+   while(idx_ptr) 
    108208+   { 
    109 +       lar_get_filename(ar, idx_ptr, memberfile); 
    110 + 
    111 +       if( !strncmp(memberfile, name, idx_ptr->nlength) ) 
    112 +       { 
    113 +           pgof = ( idx_ptr->foffset % pgsz ); 
    114 + 
    115 +           memberdata = mmap( 
    116 +               0, idx_ptr->flength + pgof, PROT_READ, MAP_PRIVATE, 
    117 +               ar->fd, idx_ptr->foffset - pgof 
    118 +           ); 
    119 + 
    120 +           if( memberdata == MAP_FAILED ) 
    121 +               LAR_DIE("Failed to mmap() member data"); 
    122 + 
    123 +           member = (lar_member *)malloc(sizeof(lar_member)); 
    124 +           member->type   = idx_ptr->type; 
    125 +           member->flags  = idx_ptr->flags; 
    126 +           member->length = idx_ptr->flength; 
    127 +           member->data   = &memberdata[pgof]; 
    128 + 
    129 +           member->mmap   = memberdata; 
    130 +           member->mlen   = idx_ptr->flength + pgof; 
    131 + 
    132 +           return member; 
    133 +       } 
     209+       if( !strncmp(mbid, idx_ptr->id, sizeof(mbid)) ) 
     210+           return lar_mmap_member(ar, idx_ptr); 
    134211+ 
    135212+       idx_ptr = idx_ptr->next; 
     
    143220+   int stat = munmap(member->mmap, member->mlen); 
    144221+   free(member); 
     222+   member = NULL; 
    145223+ 
    146224+   return stat; 
     
    167245+       strncpy(ar->filename, filename, sizeof(ar->filename)); 
    168246+ 
     247+       ar->has_filenames = lar_read_filenames(ar); 
     248+ 
    169249+       return ar; 
    170250+   } 
     
    183263+   do { 
    184264+       idx_next = idx_head->next; 
     265+       free(idx_head->filename); 
    185266+       free(idx_head); 
    186267+   } while( (idx_head = idx_next) != NULL ); 
    187268+ 
    188269+   free(ar); 
     270+   ar = NULL; 
    189271+ 
    190272+   return 0; 
    191273+} 
    192274+ 
    193 +lar_archive * lar_find_archive( const char *package, const char *path ) 
     275+lar_archive * lar_find_archive( const char *package, const char *path, int pkg ) 
    194276+{ 
    195277+   uint32_t i; 
     
    198280+   uint32_t len = 0; 
    199281+   uint32_t pln = 0; 
     282+   char sep = ( pkg ? '.' : '/' ); 
    200283+   struct stat s; 
    201284+   LAR_FNAME(buffer); 
     
    210293+   } 
    211294+ 
     295+   if( buffer[pln-1] != '/' ) 
     296+       buffer[pln++] = '/'; 
     297+ 
    212298+   for( len = 0; package[len] != '\0'; len++ ) 
    213299+   { 
     
    215301+           LAR_DIE("Package name exceeds maximum allowed length"); 
    216302+ 
    217 +       if( package[len] == '.' ) seg++; 
     303+       if( package[len] == sep ) seg++; 
    218304+   } 
    219305+ 
     
    222308+       for( i = 0, j = 1; (i < len) && (j <= seg); i++ ) 
    223309+       { 
    224 +           if( package[i] == '.' ) { 
     310+           if( package[i] == sep ) { 
    225311+               if( j < seg ) j++; else break; 
    226312+           } 
    227313+ 
    228 +           buffer[pln+i] = ( package[i] == '.' ) ? LAR_DIRSEP : package[i]; 
     314+           buffer[pln+i] = ( package[i] == sep ) ? LAR_DIRSEP : package[i]; 
    229315+       } 
    230316+ 
     
    257343+   return lar_open_member(ar, buffer); 
    258344+} 
    259 diff -Nurb lua-5.1.4.orig/src/lar.h lua-5.1.4/src/lar.h 
     345diff -Nbur lua-5.1.4.orig/src/lar.h lua-5.1.4/src/lar.h 
    260346--- lua-5.1.4.orig/src/lar.h    1970-01-01 01:00:00.000000000 +0100 
    261 +++ lua-5.1.4/src/lar.h 2009-04-06 23:06:31.000000000 +0200 
    262 @@ -0,0 +1,88 @@ 
     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+ 
    263368+#ifndef __LAR_H 
    264369+#define __LAR_H 
     
    276381+#include <sys/stat.h> 
    277382+ 
     383+#include "md5.h" 
    278384+ 
    279385+#define LAR_DIE(s) \ 
     
    290396+#define LAR_FNAME(s) char s[LAR_FNAME_BUFFER] 
    291397+ 
     398+#define LAR_TYPE_REGULAR   0x0000 
     399+#define LAR_TYPE_FILELIST  0xFFFF 
     400+ 
    292401+#ifdef __WIN32__ 
    293402+#define LAR_DIRSEP '\\' 
     
    298407+ 
    299408+struct lar_index_item { 
    300 +   uint32_t noffset; 
    301 +   uint32_t nlength; 
    302 +   uint32_t foffset; 
    303 +   uint32_t flength; 
     409+   uint32_t offset; 
     410+   uint32_t length; 
    304411+   uint16_t type; 
    305412+   uint16_t flags; 
     413+   char id[16]; 
     414+   char *filename; 
    306415+   struct lar_index_item *next; 
    307416+}; 
     
    318427+struct lar_archive_handle { 
    319428+   int fd; 
     429+   int has_filenames; 
    320430+   off_t length; 
    321431+   char filename[LAR_FNAME_BUFFER]; 
     
    327437+typedef struct lar_archive_handle lar_archive; 
    328438+ 
    329 + 
    330 +int lar_read32( int fd, uint32_t *val ); 
    331 +int lar_read16( int fd, uint16_t *val ); 
     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+*/ 
    332445+ 
    333446+lar_index * lar_get_index( lar_archive *ar ); 
    334447+ 
    335 +uint32_t lar_get_filename( lar_archive *ar, 
    336 +   lar_index *idx_ptr, char *filename ); 
     448+lar_member * lar_mmap_member( lar_archive *ar, lar_index *idx_ptr ); 
    337449+ 
    338450+lar_member * lar_open_member( lar_archive *ar, const char *name ); 
     
    344456+int lar_close( lar_archive *ar ); 
    345457+ 
    346 +lar_archive * lar_find_archive( const char *package, const char *path ); 
     458+lar_archive * lar_find_archive( const char *package, const char *path, int pkg); 
    347459+ 
    348460+lar_member * lar_find_member( lar_archive *ar, const char *package ); 
    349461+ 
    350462+#endif 
    351 diff -Nurb lua-5.1.4.orig/src/loadlib.c lua-5.1.4/src/loadlib.c 
     463diff -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+} 
     1007diff -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  
     1018diff -Nbur lua-5.1.4.orig/src/loadlib.c lua-5.1.4/src/loadlib.c 
    3521019--- lua-5.1.4.orig/src/loadlib.c    2009-04-06 21:36:52.000000000 +0200 
    353 +++ lua-5.1.4/src/loadlib.c 2009-04-07 01:55:21.000000000 +0200 
     1020+++ lua-5.1.4/src/loadlib.c 2009-04-11 01:04:47.000000000 +0200 
    3541021@@ -21,6 +21,7 @@ 
    3551022 #include "lauxlib.h" 
     
    3691036+  const char  *name = luaL_checkstring(L, 1); 
    3701037+ 
    371 +  if( (ar = lar_find_archive(name, "./"))     || 
    372 +      (ar = lar_find_archive(name, LUA_LDIR)) || 
    373 +      (ar = lar_find_archive(name, LUA_CDIR)) 
     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)) 
    3741041+  ) { 
    3751042+    if( (mb = lar_find_member(ar, name)) != NULL ) { 
     
    4061073  
    4071074 LUALIB_API int luaopen_package (lua_State *L) { 
     1075diff -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);  
     1088diff -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+} 
     1473diff -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 */