00001
00002
00003
00004 #include "copyright.h"
00005 #include "config.h"
00006
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <unistd.h>
00010 #include <dirent.h>
00011 #include <sys/time.h>
00012 #include <sys/stat.h>
00013 #include <sys/types.h>
00014 #include <fcntl.h>
00015 #include <sys/mman.h>
00016 #include <errno.h>
00017 #include <event.h>
00018 #include <string.h>
00019 #include <sys/file.h>
00020 #include <stdint.h>
00021
00022 #include "debug.h"
00023
00024 struct mmdb_t {
00025 void *base;
00026 void *ppos;
00027 void *end;
00028 int length;
00029 int fd;
00030 };
00031
00032 struct mmdb_t *mmdb_open_read(char *filename)
00033 {
00034 struct stat statbuf;
00035 struct mmdb_t *mmdb;
00036 int fd, length;
00037
00038 if(stat(filename, &statbuf) < 0) {
00039 return NULL;
00040 }
00041 mmdb = malloc(sizeof(struct mmdb_t));
00042 if(!mmdb) return NULL;
00043
00044 fd = open(filename, O_RDONLY);
00045 if(!fd) {
00046 free(mmdb);
00047 return NULL;
00048 }
00049
00050 mmdb->fd = fd;
00051 mmdb->length = (statbuf.st_size + 0x3FF) & ~(0x3FF);
00052 mmdb->base =
00053 mmap(NULL, mmdb->length, PROT_READ, MAP_SHARED,
00054 mmdb->fd, 0);
00055 if(!mmdb->base) {
00056 close(mmdb->fd);
00057 free(mmdb);
00058 return NULL;
00059 }
00060 mmdb->end = mmdb->base + mmdb->length;
00061
00062 mmdb->ppos = mmdb->base;
00063 return mmdb;
00064
00065 }
00066
00067 struct mmdb_t *mmdb_open_write(char *filename)
00068 {
00069 struct stat statbuf;
00070 struct mmdb_t *mmdb;
00071 int fd, length;
00072
00073 mmdb = malloc(sizeof(struct mmdb_t));
00074 dperror((fd = open(filename, O_RDWR | O_CREAT, 0644)) < 0);
00075
00076 mmdb->fd = fd;
00077 mmdb->length = 0x400 * 16;
00078 mmdb->base = NULL;
00079 mmdb->ppos = NULL;
00080 dprintk("mmdb->length %d", mmdb->length);
00081 ftruncate(mmdb->fd, mmdb->length);
00082 fsync(mmdb->fd);
00083 mmdb->base =
00084 mmap(NULL, mmdb->length, PROT_READ | PROT_WRITE, MAP_SHARED, mmdb->fd,
00085 0);
00086 dperror(mmdb->base == MAP_FAILED);
00087 mmdb->end = mmdb->base + mmdb->length;
00088 mmdb->ppos = mmdb->base;
00089 return mmdb;
00090 }
00091
00092 void mmdb_resize(struct mmdb_t *mmdb, int length)
00093 {
00094 int offset = 0;
00095 if(mmdb->base) {
00096 offset = mmdb->ppos - mmdb->base;
00097 msync(mmdb->base, mmdb->length, MS_ASYNC);
00098 munmap(mmdb->base, mmdb->length);
00099 mmdb->base = NULL;
00100 mmdb->ppos = NULL;
00101 }
00102 mmdb->length = (length + 0x3FF) & ~(0x3FF);
00103 ftruncate(mmdb->fd, mmdb->length);
00104 mmdb->base =
00105 mmap(NULL, mmdb->length, PROT_READ | PROT_WRITE, MAP_SHARED, mmdb->fd,
00106 0);
00107 dperror(mmdb->base == NULL);
00108 mmdb->end = mmdb->base + mmdb->length;
00109 mmdb->ppos = mmdb->base + offset;
00110 }
00111
00112 void mmdb_close(struct mmdb_t *mmdb)
00113 {
00114 msync(mmdb->base, mmdb->length, MS_SYNC);
00115 munmap(mmdb->base, mmdb->length);
00116 ftruncate(mmdb->fd, mmdb->ppos - mmdb->base);
00117 dprintk("truncating to %d bytes.", mmdb->ppos - mmdb->base);
00118 close(mmdb->fd);
00119 mmdb->fd = 0;
00120 memset(mmdb, 0, sizeof(struct mmdb_t));
00121 free(mmdb);
00122 }
00123
00124 void mmdb_write(struct mmdb_t *mmdb, void *data, int length)
00125 {
00126 if(mmdb->end - mmdb->ppos < length) {
00127 mmdb_resize(mmdb, mmdb->length + length);
00128 }
00129 memcpy(mmdb->ppos, data, length);
00130 mmdb->ppos += length;
00131 }
00132
00133 void mmdb_write_uint32(struct mmdb_t *mmdb, uint32_t data)
00134 {
00135 data = htonl(data);
00136 mmdb_write(mmdb, &data, sizeof(uint32_t));
00137 }
00138
00139 uint32_t mmdb_read_uint32(struct mmdb_t *mmdb)
00140 {
00141 uint32_t data = *((uint32_t *) (mmdb->ppos));
00142 mmdb->ppos += sizeof(uint32_t);
00143 return ntohl(data);
00144 }
00145
00146 unsigned int mmdb_read_uint(struct mmdb_t *mmdb) {
00147 printk("This function is deprecated, please use mmdb_read_uint32 instead.\n");
00148 return (unsigned int)mmdb_read_uint32(mmdb);
00149 }
00150
00151 void mmdb_write_uint(struct mmdb_t *mmdb, unsigned int val) {
00152 printk("This function is deprecated, please use mmdb_write_uint32 instead.\n");
00153 mmdb_write_uint32(mmdb, (uint32_t)val);
00154 return;
00155 }
00156
00157 void mmdb_write_uint64(struct mmdb_t *mmdb, uint64_t data)
00158 {
00159 dprintk("technically, this is not 64 bit safe yet.");
00160 data = htonl(data);
00161 mmdb_write(mmdb, &data, sizeof(uint64_t));
00162 }
00163
00164 uint64_t mmdb_read_uint64(struct mmdb_t *mmdb)
00165 {
00166 dprintk("technically, this is not 64 bit safe yet.");
00167 uint64_t data = *((uint64_t *) (mmdb->ppos));
00168 mmdb->ppos += sizeof(uint64_t);
00169 return ntohl(data);
00170 }
00171
00172 void mmdb_write_single(struct mmdb_t *mmdb, float data)
00173 {
00174 data = htonl(data);
00175 mmdb_write(mmdb, &data, sizeof(float));
00176 }
00177
00178 float mmdb_read_single(struct mmdb_t *mmdb)
00179 {
00180 float data = *((float *) (mmdb->ppos));
00181 mmdb->ppos += sizeof(float);
00182 return ntohl(data);
00183 }
00184
00185 void mmdb_write_double(struct mmdb_t *mmdb, double data)
00186 {
00187 data = htonl(data);
00188 mmdb_write(mmdb, &data, sizeof(double));
00189 }
00190
00191 double mmdb_read_double(struct mmdb_t *mmdb)
00192 {
00193 double data = *((double *) (mmdb->ppos));
00194 mmdb->ppos += sizeof(double);
00195 return ntohl(data);
00196 }
00197
00198
00199 void *mmdb_read(struct mmdb_t *mmdb, void *dest, int length)
00200 {
00201 if((mmdb->end - mmdb->ppos) < length)
00202 return NULL;
00203 memcpy(dest, mmdb->ppos, length);
00204 mmdb->ppos += length;
00205 if(length & 3)
00206 mmdb->ppos += 4 - (length & 3);
00207 return dest;
00208 }
00209
00210 void mmdb_write_opaque(struct mmdb_t *mmdb, void *data, int length)
00211 {
00212 unsigned char *pad = (unsigned char *)"\x00\x00\x00\x00";
00213 mmdb_write_uint32(mmdb, length);
00214 mmdb_write(mmdb, data, length);
00215 if((length & 3) > 0)
00216 mmdb_write(mmdb, pad, 4 - (length & 3));
00217 }
00218
00219 void mmdb_write_string(struct mmdb_t *mmdb, void *data) {
00220 if(data == NULL) {
00221 mmdb_write_uint32(mmdb, 0);
00222 } else {
00223 mmdb_write_opaque(mmdb, data, strlen(data)+1);
00224 }
00225 }
00226
00227 char *mmdb_read_string(struct mmdb_t *mmdb) {
00228 char *tmp;
00229 int length;
00230 length = mmdb_read_uint32(mmdb);
00231 if(length == 0) return NULL;
00232 tmp = malloc(length);
00233 mmdb_read(mmdb, tmp, length);
00234 return tmp;
00235 }
00236
00237 char mmdb_read_opaque(struct mmdb_t *mmdb, void *dest, int maxlength) {
00238 int length = mmdb_read_uint32(mmdb);
00239
00240 if((mmdb->end - mmdb->ppos) < length)
00241 return NULL;
00242 if(length > maxlength) {
00243 memcpy(dest, mmdb->ppos, maxlength);
00244 } else {
00245 memcpy(dest, mmdb->ppos, length);
00246 }
00247 mmdb->ppos += length;
00248 if(length & 3)
00249 mmdb->ppos += 4 - (length & 3);
00250 return dest;
00251 }