3 int lar_read32( int fd
, uint32_t *val
)
7 if( read(fd
, buffer
, 4) < 4 )
8 LAR_DIE("Unexpected EOF while reading data");
11 *val
= ntohl(*((uint32_t *) buffer
));
16 int lar_read16( int fd
, uint16_t *val
)
20 if( read(fd
, buffer
, 2) < 2 )
21 LAR_DIE("Unexpected EOF while reading data");
24 *val
= ntohs(*((uint16_t *) buffer
));
29 lar_index
* lar_get_index( lar_archive
*ar
)
37 if( lseek(ar
->fd
, -(sizeof(idx_offset
)), SEEK_END
) == -1 )
38 LAR_DIE("Unable to seek to end of archive");
40 lar_read32(ar
->fd
, &idx_offset
);
41 idx_length
= ( ar
->length
- idx_offset
- sizeof(idx_offset
) );
43 if( lseek(ar
->fd
, idx_offset
, SEEK_SET
) == -1 )
44 LAR_DIE("Unable to seek to archive index");
49 for( i
= 0; i
< idx_length
; i
+= (sizeof(lar_index
) - sizeof(char *)) ) {
50 idx_ptr
= (lar_index
*)malloc(sizeof(lar_index
));
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
);
56 lar_read16(ar
->fd
, &idx_ptr
->type
);
57 lar_read16(ar
->fd
, &idx_ptr
->flags
);
59 idx_ptr
->next
= idx_map
;
66 uint32_t lar_get_filename( lar_archive
*ar
, lar_index
*idx_ptr
, char *filename
)
68 if( idx_ptr
->nlength
>= LAR_FNAME_BUFFER
)
69 LAR_DIE("Filename exceeds maximum allowed length");
71 if( lseek(ar
->fd
, idx_ptr
->noffset
, SEEK_SET
) == -1 )
72 LAR_DIE("Unexpected EOF while seeking filename");
74 if( read(ar
->fd
, filename
, idx_ptr
->nlength
) < idx_ptr
->nlength
)
75 LAR_DIE("Unexpected EOF while reading filename");
77 filename
[idx_ptr
->nlength
] = '\0';
79 return idx_ptr
->nlength
;
82 lar_member
* lar_open_member( lar_archive
*ar
, const char *name
)
84 lar_index
*idx_ptr
= ar
->index
;
88 size_t pgsz
= getpagesize();
89 LAR_FNAME(memberfile
);
93 lar_get_filename(ar
, idx_ptr
, memberfile
);
95 if( !strncmp(memberfile
, name
, idx_ptr
->nlength
) )
97 pgof
= ( idx_ptr
->foffset
% pgsz
);
100 0, idx_ptr
->flength
+ pgof
, PROT_READ
, MAP_PRIVATE
,
101 ar
->fd
, idx_ptr
->foffset
- pgof
104 if( memberdata
== MAP_FAILED
)
105 LAR_DIE("Failed to mmap() member data");
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
];
113 member
->mmap
= memberdata
;
114 member
->mlen
= idx_ptr
->flength
+ pgof
;
119 idx_ptr
= idx_ptr
->next
;
125 int lar_close_member( lar_member
*member
)
127 int stat
= munmap(member
->mmap
, member
->mlen
);
133 lar_archive
* lar_open( const char *filename
)
139 if( stat(filename
, &as
) == -1 )
142 if( !(as
.st_mode
& S_IFREG
) )
145 if( (fd
= open(filename
, O_RDONLY
)) != -1 )
147 ar
= (lar_archive
*)malloc(sizeof(lar_archive
));
149 ar
->length
= as
.st_size
;
150 ar
->index
= lar_get_index(ar
);
151 strncpy(ar
->filename
, filename
, sizeof(ar
->filename
));
159 int lar_close( lar_archive
*ar
)
166 idx_head
= ar
->index
;
168 idx_next
= idx_head
->next
;
170 } while( (idx_head
= idx_next
) != NULL
);
177 lar_archive
* lar_find_archive( const char *package
, const char *path
)
189 for( pln
= 0; path
[pln
] != '\0'; pln
++ )
190 if( pln
>= (sizeof(buffer
) - 5) )
191 LAR_DIE("Library path exceeds maximum allowed length");
193 memcpy(buffer
, path
, pln
);
196 for( len
= 0; package
[len
] != '\0'; len
++ )
198 if( len
>= (sizeof(buffer
) - 5 - pln
) )
199 LAR_DIE("Package name exceeds maximum allowed length");
201 if( package
[len
] == '.' ) seg
++;
206 for( i
= 0, j
= 1; (i
< len
) && (j
<= seg
); i
++ )
208 if( package
[i
] == '.' ) {
209 if( j
< seg
) j
++; else break;
212 buffer
[pln
+i
] = ( package
[i
] == '.' ) ? LAR_DIRSEP
: package
[i
];
215 strcpy(&buffer
[pln
+i
], ".lar");
217 if( (stat(buffer
, &s
) > -1) && (s
.st_mode
& S_IFREG
) )
218 return lar_open(buffer
);
226 lar_member
* lar_find_member( lar_archive
*ar
, const char *package
)
231 for( len
= 0; package
[len
] != '\0'; len
++ )
233 if( len
>= (sizeof(buffer
) - 5) )
234 LAR_DIE("Package name exceeds maximum allowed length");
236 buffer
[len
] = ( package
[len
] == '.' ) ? '/' : package
[len
];
239 strcpy(&buffer
[len
], ".lua");
241 return lar_open_member(ar
, buffer
);