/* ** load.c ** $Id: load.c,v 1.27 2002/05/20 00:45:56 brian Exp $ */ #include "mod_mp3.h" /* This is where we chew up a lot of shared memory */ MP3_EXPORT(mp3_data *) mp3_create_content(pool *p, char *filename, char *name, char *signature, int flag) { mp3_data *bank; struct stat buf; int fd = -1; caddr_t temp; if(stat(filename, &buf)) { #ifdef DEBUG printf("Could not open %s(%s)\n", filename, strerror(errno)); #endif return NULL; } ap_no2slash(filename); bank = ap_pcalloc (p, sizeof (mp3_data)); bank->filename = ap_pstrdup(p, filename); bank->size = buf.st_size; bank->data = NULL; bank->time = buf.st_mtime; bank->signature = signature ? ap_pstrdup(p, signature) : (char *)ap_md5(p, filename); bank->name = NULL; bank->artist = NULL; bank->album = NULL; bank->comment = NULL; bank->track = NULL; bank->year = NULL; bank->genre = NULL; /* Yes, this is redundanct at the moment */ /* Ok, long run we need to check this */ fd = ap_popenf(p, filename, O_RDONLY, 0); /* Need to come back and look at this later, since this will eat up memory */ get_id3_tag(p, fd, bank); if(!bank->name) bank->name = ap_pstrdup(p, name); #ifdef DEBUG printf("Adding %s\n", bank->name); #endif if(flag) { lseek(fd, 0, SEEK_SET); temp = mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, fd, 0); if((temp ==(caddr_t)-1)) printf("Woops, blew up\n"); bank->data = temp; } ap_pclosef(p, fd); return bank; } MP3_EXPORT(int) load_playlist(pool *p, mp3_conf *cfg, char *file, int cache_enabled) { FILE *file_ptr; char buf[HUGE_STRING_LEN]; int length = 0; if (!(file_ptr = ap_pfopen (p, file, "r"))) { /* Question this Brian */ return HTTP_NOT_FOUND; } while (fgets (buf, sizeof (buf), file_ptr)) { length = strlen(buf); buf[length-1] = '\0'; if(load_file(p, cfg, buf, buf, cache_enabled) != OK) { /* Need to add an error message here */ } } ap_pfclose (p, file_ptr); return OK; } MP3_EXPORT(int) load_file(pool *p, mp3_conf *cfg, char *file, char *name, int cache_enabled) { mp3_data *bank = NULL; if(!( bank = mp3_create_content(p, file, name, NULL, cache_enabled))) { return HTTP_NOT_FOUND; } /* *(mp3_data **) ap_push_array (files) = (mp3_data *) bank; */ if(cfg->dispatch->set) { cfg->dispatch->set(cfg->context, p, bank); } else { fprintf(stderr, "Trying to load data into handler %s that does not support this operation.\n", cfg->dispatch->name); } return OK; } int array_search(const char *param, array_header *list) { const char **strings = (const char **)list->elts; int x = 0; for(x = 0; x < list->nelts ; x++) { if(!mp3_match(strings[x], param)){ return 1; } } return 0; } int name_check(const char *param, array_header *accept, array_header *deny) { if(accept) { if(array_search(param, accept)) { if(deny) { if(array_search(param, deny)) { printf("Denied %s \n", param); return 0; } } printf("Accepted %s \n", param); return 1; } else { printf("Denied %s \n", param); return 0; } } if(deny) { if(array_search(param, deny)) { printf("Denied %s \n", param); return 0; } } return 1; } MP3_EXPORT(int) load_directory(pool *p, mp3_conf *cfg, char *param) { pool *temp_pool = NULL; char *temp=NULL; struct stat sbuf; DIR *dir; struct dirent *file = NULL; array_header *directories = NULL; char **directory = NULL; int x = 0; temp_pool = ap_make_sub_pool(p); directories = ap_make_array (temp_pool, 15, sizeof (char *)); *(char **) ap_push_array (directories) = ap_pstrdup (temp_pool, param); while ( x < directories->nelts) { directory = (char **)directories->elts; param = directory[x]; x++; if (!(dir = ap_popendir(temp_pool, param))) { continue; } else { while((file = readdir(dir))) { if (!name_check(file->d_name, cfg->accept, cfg->deny)) { continue; } if(stat((temp = ap_pstrcat(temp_pool, param, "/", file->d_name, NULL)), &sbuf) == 0){ /*************************************/ if(S_ISREG(sbuf.st_mode)) { /*************************************/ if(load_file(p, cfg, temp, file->d_name, cfg->cache_enabled) != OK) { /* Need to add an error message here */ } /*************************************/ } else if(S_ISDIR(sbuf.st_mode)) { if(file->d_name[0] != '.') { #ifdef DEBUG printf("Stacking %s\n", temp); #endif *(char **) ap_push_array (directories) = ap_pstrdup (temp_pool, temp); } } /*************************************/ } else { #ifdef DEBUG printf("Could not stat %s\n", temp); #endif } } ap_pclosedir(temp_pool, dir); } } ap_destroy_pool(temp_pool); return OK; }