nuclear@6: #include nuclear@6: #include nuclear@6: #include "mime.h" nuclear@6: #include "rbtree.h" nuclear@6: nuclear@6: /* TODO: do proper content detection */ nuclear@6: struct mime_type { nuclear@6: const char *suffix, *type; nuclear@6: }; nuclear@6: nuclear@6: static struct mime_type def_types[] = { nuclear@6: {"txt", "text/plain"}, nuclear@6: {"htm", "text/html"}, nuclear@6: {"html", "text/html"}, nuclear@6: {"png", "image/png"}, nuclear@6: {"jpg", "image/jpeg"}, nuclear@6: {"jpeg", "image/jpeg"}, nuclear@6: {"gif", "image/gif"}, nuclear@6: {"bmp", "image/bmp"}, nuclear@6: {"cgi", 0} nuclear@6: , nuclear@6: {0, 0} nuclear@6: }; nuclear@6: nuclear@6: static int init_types(void); nuclear@6: static void del_func(struct rbnode *node, void *cls); nuclear@6: nuclear@6: static struct rbtree *types; nuclear@6: nuclear@6: static int init_types(void) nuclear@6: { nuclear@6: int i; nuclear@6: nuclear@6: if(types) return 0; nuclear@6: nuclear@7: if((types = rb_create(RB_KEY_STRING))) { nuclear@6: return -1; nuclear@6: } nuclear@6: rb_set_delete_func(types, del_func, 0); nuclear@6: nuclear@6: for(i=0; def_types[i].suffix; i++) { nuclear@6: add_mime_type(def_types[i].suffix, def_types[i].type); nuclear@6: } nuclear@6: return 0; nuclear@6: } nuclear@6: nuclear@6: static void del_func(struct rbnode *node, void *cls) nuclear@6: { nuclear@6: free(node->key); nuclear@6: free(node->data); nuclear@6: } nuclear@6: nuclear@6: int add_mime_type(const char *suffix, const char *type) nuclear@6: { nuclear@6: init_types(); nuclear@6: nuclear@6: return rb_insert(types, strdup(suffix), strdup(type)); nuclear@6: } nuclear@6: nuclear@6: const char *mime_type(const char *path) nuclear@6: { nuclear@6: const char *suffix; nuclear@6: nuclear@6: init_types(); nuclear@6: nuclear@6: if((suffix = strrchr(path, '.'))) { nuclear@6: struct rbnode *node = rb_find(types, (void*)(suffix + 1)); nuclear@6: if(node) { nuclear@6: return node->data; nuclear@6: } nuclear@6: } nuclear@6: return "text/plain"; nuclear@6: }