/* * kissd - KiSS PC-Link Daemon * * Copyright (C) 2005 Stelian Pop * * Heavily based on kiss4lin, * Copyright (C) 2004 Jacob Kolding * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #include #include #include "config.h" #include "kissdx.h" #include "connection.h" #include "utils.h" static void convert_slashes(char *p) { /* convert backslashes and find EOL */ while (*p) { if (*p == '\\') *p = '/'; p++; } } static void remove_eol(char *p) { while (*p) { if (*p == '\n' || *p == '\r') { *p = '\0'; break; } p++; } } static void time_to_string(unsigned int seconds, char *timebuf, size_t bufsize) { if (seconds) { if (seconds < 3600) snprintf(timebuf, bufsize, " (%d:%02d)", seconds / 60, seconds % 60); else snprintf(timebuf, bufsize, " (%d:%02d:%02d)", seconds / 3600, (seconds % 3600) / 60, seconds % 60); } else timebuf[0] = '\0'; } int handle_playlist(char *path) { enum { m3u, pls, m3u_ext, pls_v2 } file_type = m3u; int first_line = 1; char *cwd; char pathbuf[PATH_MAX]; char buffer[PATH_MAX]; FILE *fp; char time[25]; char line[2 * PATH_MAX]; char filename[PATH_MAX]; /* add some slack for time and extension */ char title[PATH_MAX + sizeof(time) + 4]; int len, seconds; char fullpath[PATH_MAX]; /* dirname modifies path */ strncpy(pathbuf, path, PATH_MAX); cwd = dirname(pathbuf); if (strstr(path, ".pls\0")) file_type = pls; /* playlist within playlist, strip off parent playlist */ if (strstr(cwd, ".m3u\0") || strstr(cwd, ".pls\0")) { strncpy(buffer, cwd, PATH_MAX); cwd = dirname(buffer); snprintf(pathbuf, PATH_MAX, "%s/%s", cwd, basename(path)); path = pathbuf; } logv("handle_playlists(%s)", path); fp = fopen(path, "r"); if (fp == NULL) { log("handle_playlists(%s): error: %s", path, strerror(errno)); return -1; } title[0] = 0; seconds = 0; filename[0] = 0; while (fgets(buffer, sizeof(buffer), fp) != NULL) { remove_eol(buffer); strcpy(buffer, convert_charset(buffer, cept_playlist, cept_server)); /* skip empty lines */ if (*buffer == '\0') continue; if (first_line) { if (file_type == m3u && !strcmp(buffer, "#EXTM3U")) file_type = m3u_ext; else if (file_type == pls && !strcmp(buffer, "[playlist]")) file_type = pls_v2; first_line = 0; } convert_slashes(buffer); switch (file_type) { case m3u_ext: if (!*title && !strncasecmp(buffer, "#EXTINF:", 8)) { char *p1 = strchr(buffer, ':'); char *p2 = strchr(buffer, ','); if (!p2) continue; *p2 = '\0'; seconds = atoi(p1 + 1); strncpy(title, p2 + 1, PATH_MAX); continue; } if (*title && !*filename) { strncpy(filename, buffer, PATH_MAX); break; /* done with this title */ } /* continue with next line */ continue; case pls_v2: if (!*filename && !strncasecmp(buffer, "file", 4)) { char *p = strchr(buffer, '='); if (p++) strncpy(filename, p, PATH_MAX); continue; } if (*filename && !*title && !strncasecmp(buffer, "title", 5)) { char *p = strchr(buffer, '='); if (p++) strncpy(title, p, PATH_MAX); continue; } if (*title && !seconds && !strncasecmp(buffer, "length", 6)) { char *p = strchr(buffer, '='); if (p++) seconds = atoi(p); break; /* done with this title */ } /* continue with next line */ continue; case m3u: case pls: default: strncpy(filename, buffer, PATH_MAX); strncpy(title, basename(buffer), PATH_MAX); seconds = 0; } /* Playlist within playlist */ if (strstr(filename, ".m3u\0") || strstr(filename, ".pls\0")) len = snprintf(line, PATH_MAX, "%s|%s|1", title, filename); else { /* Put time into title */ time_to_string(seconds, time, sizeof(time)); strcat(title, time); /* Ensure that the title ends with a valid audio filetype. KISS does not show titles without it */ if (!list_contains_extension(config.audiofileextensions, title)) strcat(title, ".mp3"); /* handle relative and absolute paths */ if (*filename == '/' || !strncmp(filename, "http:", 5)) strncpy(fullpath, filename, sizeof fullpath); else snprintf(fullpath, sizeof fullpath, "%s/%s", cwd, filename); // Change the filename extension if it has an extension that is to be renamed // and there is no real file with the same name and the target extension. rename_filetype_outgoing(fullpath); len = snprintf(line, sizeof line, "%s|%s|0", title, fullpath); } if (len > 0) send_list_line_to_player(line); title[0] = 0; seconds = 0; filename[0] = 0; } fclose(fp); return 0; }