2 * lmo - Lua Machine Objects - Base functions
4 * Copyright (C) 2009-2010 Jo-Philipp Wich <xm@subsignal.org>
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 extern char _lmo_error
[1024];
23 static int lmo_read32( int fd
, uint32_t *val
)
25 if( read(fd
, val
, 4) < 4 )
33 static char * error(const char *message
, int add_errno
)
35 memset(_lmo_error
, 0, sizeof(_lmo_error
));
38 snprintf(_lmo_error
, sizeof(_lmo_error
),
39 "%s: %s", message
, strerror(errno
));
41 snprintf(_lmo_error
, sizeof(_lmo_error
), "%s", message
);
46 const char * lmo_error(void)
51 lmo_archive_t
* lmo_open(const char *file
)
54 uint32_t idx_offset
= 0;
58 lmo_archive_t
*ar
= NULL
;
59 lmo_entry_t
*head
= NULL
;
60 lmo_entry_t
*entry
= NULL
;
62 if( stat(file
, &s
) == -1 )
64 error("Can not stat file", 1);
68 if( (in
= open(file
, O_RDONLY
)) == -1 )
70 error("Can not open file", 1);
74 if( lseek(in
, -sizeof(uint32_t), SEEK_END
) == -1 )
76 error("Can not seek to eof", 1);
80 if( lmo_read32(in
, &idx_offset
) != 4 )
82 error("Unexpected EOF while reading index offset", 0);
86 if( lseek(in
, (off_t
)idx_offset
, SEEK_SET
) == -1 )
88 error("Can not seek to index offset", 1);
92 if( (ar
= (lmo_archive_t
*) malloc(sizeof(lmo_archive_t
))) != NULL
)
95 ar
->length
= idx_offset
;
97 fcntl(ar
->fd
, F_SETFD
, fcntl(ar
->fd
, F_GETFD
) | FD_CLOEXEC
);
100 i
< (s
.st_size
- sizeof(uint32_t));
101 i
+= (4 * sizeof(uint32_t))
103 if( (entry
= (lmo_entry_t
*) malloc(sizeof(lmo_entry_t
))) != NULL
)
105 if( (lmo_read32(ar
->fd
, &entry
->key_id
) == 4) &&
106 (lmo_read32(ar
->fd
, &entry
->val_id
) == 4) &&
107 (lmo_read32(ar
->fd
, &entry
->offset
) == 4) &&
108 (lmo_read32(ar
->fd
, &entry
->length
) == 4)
115 error("Unexpected EOF while reading index entry", 0);
121 error("Out of memory", 0);
128 if( lseek(ar
->fd
, 0, SEEK_SET
) == -1 )
130 error("Can not seek to start", 1);
134 if( (ar
->mmap
= mmap(NULL
, ar
->length
, PROT_READ
, MAP_PRIVATE
, ar
->fd
, 0)) == MAP_FAILED
)
136 error("Failed to memory map archive contents", 1);
144 error("Out of memory", 0);
158 while( entry
!= NULL
)
170 if( (ar
->mmap
!= NULL
) && (ar
->mmap
!= MAP_FAILED
) )
171 munmap(ar
->mmap
, ar
->length
);
180 void lmo_close(lmo_archive_t
*ar
)
182 lmo_entry_t
*head
= NULL
;
183 lmo_entry_t
*entry
= NULL
;
189 while( entry
!= NULL
)
198 if( (ar
->mmap
!= NULL
) && (ar
->mmap
!= MAP_FAILED
) )
199 munmap(ar
->mmap
, ar
->length
);
208 int lmo_lookup(lmo_archive_t
*ar
, const char *key
, char *dest
, int len
)
210 uint32_t look_key
= sfh_hash(key
, strlen(key
));
219 while( entry
!= NULL
)
221 if( entry
->key_id
== look_key
)
223 copy_len
= ((len
- 1) > entry
->length
) ? entry
->length
: (len
- 1);
224 memcpy(dest
, &ar
->mmap
[entry
->offset
], copy_len
);
225 dest
[copy_len
] = '\0';