int mime_types_init(void) { if (hashtable_is_initialized(&ht_mime_types)) return 1; LOGGER_INFO("initializing mime types"); int fd = open(MIME_TYPES, O_RDONLY); struct stat st; if (0 > fstat(fd, &st)) return LOGGER_PERROR("mime_types fstat"), close(fd), -1; void *mem = mmap(NULL, st.st_size + 1, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (MAP_FAILED == mem) return LOGGER_PERROR("mime_types mmap"), close(fd), -1; hashtable_init(&ht_mime_types, 4096); char *content = (char *)mem; char *content_end = content + st.st_size; while (content < content_end) { // find end of line char *line = content, *p = line; for (; p < content_end && *p != '\n'; ++p); *p = 0; // mmap'd one extra byte to avoid checks content = p + 1; p = strchrnul(line, '#'); *p = 0; // truncate line after comment p = line; char *saveptr; char *mime = strtok_r(p, MIME_DELIMS, &saveptr); if (!mime) continue; char *ext; while (NULL != (ext = strtok_r(NULL, MIME_DELIMS, &saveptr))) { for (p = ext; *p; *p = tolower(*p), ++p); hashtable_insert(&ht_mime_types, ext, strlen(ext), mime, strlen(mime) + 1); } } munmap(mem, st.st_size + 1); close(fd); return 0; }
int mime_types_init(void) { if (hashtable_is_initialized(&ht_mime_types) > 0) return 1; LOGGER_INFO("initializing mime types"); int fd = open(MIME_TYPES, O_RDONLY); /* if can't find mime file, use copy - needed for mac osx */ if (0 > fd) { build_mime_table(mime_file, mime_file+sizeof(mime_file)); } else { struct stat st; if (0 > fstat(fd, &st)) return LOGGER_PERROR("mime_types fstat"), close(fd), -1; void *mem = mmap(NULL, st.st_size + 1, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (MAP_FAILED == mem) return LOGGER_PERROR("mime_types mmap"), close(fd), -1; build_mime_table((char *)mem, mem + st.st_size); munmap(mem, st.st_size + 1); close(fd); } return 0; }