/* Handle I/O with playlist files. Reading and writing different types of playlist files. */ #include #include #include #include"cmp3funcs.h" typedef struct { char dirLetter; char *dirMapping; } dirmap_t; void freedirmap(void *node) { dirmap_t *mapping; mapping = (dirmap_t*) node; /* free(mapping->dirMapping); */ } static LLIST buildMapping(); static int doConversions(char *filepath); /* Static Globals */ static LLIST dirmaps; /**************************************************************************** * Read playlist in from file * Returns: nothing ****************************************************************************/ void readlist(char *filepath) { FILE *infile; if (!(infile = fopen(filepath, "r"))) { #ifdef ASS_LOC char temp[MAX_FULL]; sprintf(temp, "%s/%s", ASS_LOC, filepath); if (!(infile = fopen(temp, "r"))) { #endif perror("Cannot find ass file"); return; } #ifdef ASS_LOC } #endif if (dirmaps == NULL) dirmaps = buildMapping(); switch (isPlaylist(filepath)) { case 1: readass(infile); break; case 2: readm3u(infile); break; case 3: readpls(infile); break; default: break; } fclose(infile); } int isPlaylist(char *filename) { char *extention; extention = strrchr(filename, '.'); if (extention == NULL) return(0); extention += 1; if (Strcmp(extention, "ass") == 0) return(1); if (Strcmp(extention, "m3u") == 0) return(2); if (Strcmp(extention, "pls") == 0) return(3); return(0); } void readass(FILE *infile) { int start, dorandom = 0; char charbuff[MAX_FULL+1]; start = shmptr->listlen; while (fgets(charbuff,MAX_FULL,infile)!=NULL) { switch(charbuff[0]) { case '#': break; case '%': system(charbuff+1); break; case '@': dorandom=1; break; case '$': shmptr->repeat = 1; break; case '/': charbuff[strlen(charbuff)-1]='\0'; if (isPlaylist(charbuff)) readlist(charbuff); else pl_addentry(charbuff); break; default : break; } } if (dorandom) pl_randomize(start); } void readm3u(FILE *infile) { char buffer[MAX_FULL]; while (getline(buffer, MAX_FULL, infile) == 1) { if (buffer[0] == '#') continue; if (doConversions(buffer) == 1) pl_addentry(buffer); } } void readpls(FILE *infile) { char buffer[MAX_FULL], *filename; while (getline(buffer, MAX_FULL, infile) == 1) { if ((buffer[0] == '[') || (buffer[0] == '#')) continue; if (!Strncmp(buffer, "file", 4)) { filename = strchr(buffer, '='); if (filename != NULL) { if (doConversions(filename + 1) == 1) pl_addentry(filename + 1); } } } } LLIST buildMapping() { LLIST maplist; INISECT mappingSect; dirmap_t aMap; char mapname[512]; char *retString; int i; int thelen; if (cmp3rc == NULL) return(NULL); mappingSect = ini_getSection(cmp3rc, "drive_mappings"); if (mappingSect == NULL) return(NULL); i = 1; sprintf(mapname, "map%d", i); retString = ini_getValueStringSect(cmp3rc, mappingSect, mapname); if (retString == NULL) return(NULL); maplist = ll_create(sizeof(dirmap_t), &freedirmap); while (retString != NULL) { sprintf(mapname, "map%d", i); retString = ini_getValueStringSect(cmp3rc, mappingSect, mapname); if (retString != NULL) { aMap.dirLetter = tolower(*retString); sprintf(mapname, "map_mount%d", i); retString = ini_getValueStringSect(cmp3rc, mappingSect, mapname); if (retString != NULL) { thelen = strlen(retString); if ((thelen != 1) && (retString[thelen] == '/')) retString[thelen] = '\0'; aMap.dirMapping = retString; ll_addlast(maplist, &aMap); } } i += 1; } if (ll_total(maplist) == 0) { ll_destroy(maplist); return(NULL); } return(maplist); } int doConversions(char *filepath) { dirmap_t *theMap; int i; int thelen; char namebuffer[MAX_FULL]; if (Strncmp("http", filepath, 4) == 0) { return(1); } for (i = 0; i < strlen(filepath); i++) { if (filepath[i] == '\\') filepath[i] = '/'; } if (filepath[0] == '/') return(1); else if (filepath[1] == ':') { if (dirmaps == NULL) return(0); ll_reset(dirmaps); theMap = (dirmap_t*) ll_next(dirmaps); while (theMap != NULL) { if (theMap->dirLetter == tolower(*filepath)) { thelen = strlen(theMap->dirMapping); memmove(filepath + thelen + 1, filepath + 3, strlen(filepath) - 2); memcpy(filepath, theMap->dirMapping, thelen); if (thelen != 1) filepath[thelen+1] = '/'; return(1); } theMap = (dirmap_t*) ll_next(dirmaps); } } else { strcpy(namebuffer, directory); if (directory[1] != '\0') strcat(namebuffer, "/"); strcat(namebuffer, filepath); strcpy(filepath, namebuffer); return(1); } return(0); } /**************************************************************************** * Write current playlist out to file * Returns: nothing ****************************************************************************/ void writelist(char *filepath) { FILE *outfile; char *filename; int i; outfile = fopen(filepath, "w"); if (outfile == NULL) /* XXX - alert person */ return; fprintf(outfile, "##############################################################################\n\ # Dumped Cmp3 playlist ass file\n\ #\n\ # Addable features (on individual lines):\n\ # %%[command] - executes commands initially using system() call\n\ # @ - randomizes this playlist at load time\n\ # $ - turns on repeat mode at load time\n\ #\n\n"); filename = shmptr->plhead; for(i=0; i < shmptr->listlen; i++) { fprintf(outfile, "%s\n",filename); filename += strlen(filename) + 1; } if (shmptr->repeat == 1) fprintf(outfile, "$\n"); fprintf(outfile, "\n# EOF\n"); fclose(outfile); } /* EOF */