Commit 026cefdb authored by Led's avatar Led

0.6.1

parent d44d5753
ver 0.6.1 (2003/5/29)
1) Add conf file support
2) Fix a bug when doing mp3stop (do wait3(NULL,WNOHANG|WUNTRACED,NULL))
3) Fix a bug when fork'ing, fflush file buffers before forking so the
child doesn't print the same stuff in the buffer.
ver 0.6.0 (2003/5/25) ver 0.6.0 (2003/5/25)
1) Add ogg vorbis support 1) Add ogg vorbis support
2) Fix two bugs relating to tables, one for search by title, and one where we 2) Fix two bugs relating to tables, one for search by title, and one where we
freed the tables before directories, causing a segfault freed the tables before directories, causing a segfault
3) The info command has been removed.
ver 0.5.0-0.5.2 ver 0.5.0-0.5.2
Initial release(s). Support for MP3 via mpg123 Initial release(s). Support for MP3 via mpg123
...@@ -82,6 +82,17 @@ $ mpd-x.x.x/mpd 2100 mp3 playlists mpd.log mpd.err ...@@ -82,6 +82,17 @@ $ mpd-x.x.x/mpd 2100 mp3 playlists mpd.log mpd.err
Note: The first time you run mpd, it will "explore" your mp3 directory for Note: The first time you run mpd, it will "explore" your mp3 directory for
mp3's. mp3's.
Also, for MPD >= 0.6.1, mpd can alternatively use config file. In this case,
run mpd like this:
$ mpd <config file>
an example would be:
$ mpd playlists/.mpdconf
A sample config file is included with the source of MPD, mpdconf.example .
Using MPD Using MPD
--------- ---------
......
...@@ -16,7 +16,7 @@ DFLAGS = -MM $(INCLUDES) $(HAVE_OGG) ...@@ -16,7 +16,7 @@ DFLAGS = -MM $(INCLUDES) $(HAVE_OGG)
SOURCES = main.c buffer2array.c mpg123.c interface.c command.c playlist.c ls.c \ SOURCES = main.c buffer2array.c mpg123.c interface.c command.c playlist.c ls.c \
id3v2lib/charset.c id3v2lib/lib_id3v2.3.c id3v1lib/lib_id3v1.c \ id3v2lib/charset.c id3v2lib/lib_id3v2.3.c id3v1lib/lib_id3v1.c \
id3v2lib/lib_id3v2.2.c song.c list.c directory.c tables.c utils.c \ id3v2lib/lib_id3v2.2.c song.c list.c directory.c tables.c utils.c \
tag.c player.c ogg.c listen.c tag.c player.c ogg.c listen.c conf.c
OBJECTS = $(SOURCES:.c=.o) OBJECTS = $(SOURCES:.c=.o)
DEPENDFILE = Makefile.depend DEPENDFILE = Makefile.depend
......
Music Player Daemon (MPD) - UPGRADING Music Player Daemon (MPD) - UPGRADING
Upgrading from 0.5.x to 0.6.0 Upgrading from 0.5.x to 0.6.x
----------------------------- -----------------------------
If you have not compiled MPD with "make ogg", then nothing is needed. If you have not compiled MPD with "make ogg", then nothing is needed.
......
...@@ -22,14 +22,15 @@ ...@@ -22,14 +22,15 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
int buffer2array(char * buffer, char *** array) { int buffer2array(char * origBuffer, char *** array) {
int bufferLength = strlen(buffer);
int quotes = 0; int quotes = 0;
int count = 0; int count = 0;
int i; int i;
int curr; int curr;
char * markArray = malloc(sizeof(char)*(bufferLength+1));
int * beginArray; int * beginArray;
char * buffer = strdup(origBuffer);
int bufferLength = strlen(buffer);
char * markArray = malloc(sizeof(char)*(bufferLength+1));
for(curr=0;curr<bufferLength;curr++) { for(curr=0;curr<bufferLength;curr++) {
if(!quotes && buffer[curr]==' ') { if(!quotes && buffer[curr]==' ') {
...@@ -98,6 +99,7 @@ int buffer2array(char * buffer, char *** array) { ...@@ -98,6 +99,7 @@ int buffer2array(char * buffer, char *** array) {
free(markArray); free(markArray);
free(beginArray); free(beginArray);
free(buffer);
return count; return count;
} }
...@@ -105,7 +105,7 @@ int processCommand(FILE * fp, int argArrayLength, char ** argArray) { ...@@ -105,7 +105,7 @@ int processCommand(FILE * fp, int argArrayLength, char ** argArray) {
fprintf(fp,"%s wrong number of arguments for \"%s\"\n",COMMAND_RESPOND_ERROR,argArray[0]); fprintf(fp,"%s wrong number of arguments for \"%s\"\n",COMMAND_RESPOND_ERROR,argArray[0]);
return -1; return -1;
} }
return playerStop(fp); return stopPlaylist(fp);
} }
else if(0==strcmp(argArray[0],COMMAND_PAUSE)) { else if(0==strcmp(argArray[0],COMMAND_PAUSE)) {
if(argArrayLength!=1) { if(argArrayLength!=1) {
......
/* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "conf.h"
#include "utils.h"
#include "buffer2array.h"
#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STRING_SIZE MAXPATHLEN+80
#define CONF_NUMBER_OF_PARAMS 7
#define CONF_NUMBER_OF_PATHS 4
#define CONF_MPG123_COMMAND_DEFAULT "mpg123 -b 2048 -R foo"
#define CONF_MPG123_PROCESS_DEFAULT "mpg123"
char conf_strings[CONF_NUMBER_OF_PARAMS][24] = {
"mpg123_command",
"port",
"music_directory",
"playlist_directory",
"log_file",
"error_file",
"mpg123_process"
};
int conf_absolutePaths[CONF_NUMBER_OF_PATHS] = {
CONF_MUSIC_DIRECTORY,
CONF_PLAYLIST_DIRECTORY,
CONF_LOG_FILE,
CONF_ERROR_FILE
};
char * conf_params[CONF_NUMBER_OF_PARAMS];
void initConf() {
int i;
for(i=0;i<CONF_NUMBER_OF_PARAMS;i++) conf_params[i] = NULL;
/* we don't specify these on the command line */
conf_params[CONF_MPG123_COMMAND] = strdup(CONF_MPG123_COMMAND_DEFAULT);
conf_params[CONF_MPG123_PROCESS] = strdup(CONF_MPG123_PROCESS_DEFAULT);
}
char ** readConf(char * file) {
FILE * fp;
char string[MAX_STRING_SIZE+1];
char ** array;
int i;
/* we don't specify these on the command line */
free(conf_params[CONF_MPG123_COMMAND]);
free(conf_params[CONF_MPG123_PROCESS]);
conf_params[CONF_MPG123_COMMAND] = NULL;
conf_params[CONF_MPG123_PROCESS] = NULL;
if(!(fp=fopen(file,"r"))) {
fprintf(stderr,"problems opening file %s for reading\n",file);
exit(-1);
}
while(myFgets(string,sizeof(string),fp)) {
if(2!=buffer2array(string,&array)) {
fprintf(stderr,"need two args in conf at: %s\n",string);
exit(-1);
}
i = 0;
while(i<CONF_NUMBER_OF_PARAMS && 0!=strcmp(conf_strings[i],array[0])) i++;
if(i>=CONF_NUMBER_OF_PARAMS) {
fprintf(stderr,"unrecognized line in conf: %s\n",string);
exit(-1);
}
if(conf_params[i]!=NULL) {
fprintf(stderr,"%s has already been assigned\n",conf_strings[i]);
exit(-1);
}
conf_params[i] = strdup(array[1]);
free(array[0]);
free(array[1]);
free(array);
}
fclose(fp);
for(i=0;i<CONF_NUMBER_OF_PARAMS;i++) {
if(conf_params[i] == NULL) {
fprintf(stderr,"%s is unassinged in conf file\n",conf_strings[i]);
exit(-1);
}
}
for(i=0;i<CONF_NUMBER_OF_PATHS;i++) {
if(conf_params[conf_absolutePaths[i]][0]!='/') {
fprintf(stderr,"\"%s\" is not an absolute path\n",conf_params[conf_absolutePaths[i]]);
exit(-1);
}
}
return conf_params;
}
char ** getConf() {
return conf_params;
}
void writeConf(char * file) {
int i;
FILE * fp;
if(!(fp=fopen(file,"w"))) {
fprintf(stderr, "problems open file %s for writing\n",file);
exit(-1);
}
for(i=0;i<CONF_NUMBER_OF_PARAMS;i++) {
fprintf(fp,"%s \"%s\"\n",conf_strings[i],conf_params[i]);
}
fclose(fp);
}
/* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef CONF_H
#define CONF_H
#define CONF_MPG123_COMMAND 0
#define CONF_PORT 1
#define CONF_MUSIC_DIRECTORY 2
#define CONF_PLAYLIST_DIRECTORY 3
#define CONF_LOG_FILE 4
#define CONF_ERROR_FILE 5
#define CONF_MPG123_PROCESS 6
/* do not free the return value, it is a static variable */
char ** readConf(char * file);
char ** getConf();
void initConf();
void writeConf(char * file);
#endif
...@@ -27,8 +27,9 @@ ...@@ -27,8 +27,9 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#include <string.h> #include <string.h>
#include <fcntl.h>
#define VERSION "0.6.0" #define VERSION "0.6.1"
#define GREETING "MPD" #define GREETING "MPD"
#define INTERFACE_MAX_BUFFER_LENGTH 1024 #define INTERFACE_MAX_BUFFER_LENGTH 1024
...@@ -50,6 +51,8 @@ Interface interfaces[INTERFACE_MAX_CONNECTIONS]; ...@@ -50,6 +51,8 @@ Interface interfaces[INTERFACE_MAX_CONNECTIONS];
void openInterface(Interface * interface, int fd) { void openInterface(Interface * interface, int fd) {
assert(interface->open==0); assert(interface->open==0);
fcntl(fd,F_SETFD,FD_CLOEXEC);
interface->bufferLength = 0; interface->bufferLength = 0;
interface->fd = fd; interface->fd = fd;
...@@ -180,6 +183,16 @@ void closeAllInterfaces() { ...@@ -180,6 +183,16 @@ void closeAllInterfaces() {
} }
} }
void closeAllInterfaceFDs() {
int i;
for(i=0;i<INTERFACE_MAX_CONNECTIONS;i++) {
if(interfaces[i].open) {
close(interfaces[i].fd);
}
}
}
void closeOldInterfaces() { void closeOldInterfaces() {
int i; int i;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
void initInterfaces(); void initInterfaces();
void openAInterface(int fd); void openAInterface(int fd);
void closeAllInterfaces(); void closeAllInterfaces();
void closeAllInterfaceFDs();
void closeOldInterfaces(); void closeOldInterfaces();
int readInputFromInterfaces(); int readInputFromInterfaces();
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "tables.h" #include "tables.h"
#include "player.h" #include "player.h"
#include "listen.h" #include "listen.h"
#include "conf.h"
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
...@@ -35,6 +36,7 @@ ...@@ -35,6 +36,7 @@
void usage(char * argv[]) { void usage(char * argv[]) {
fprintf(stderr,"usage: %s <port> <mp3/ogg dir> <playlist dir> <log file> <error file>\n",argv[0]); fprintf(stderr,"usage: %s <port> <mp3/ogg dir> <playlist dir> <log file> <error file>\n",argv[0]);
fprintf(stderr,"or: %s <conf file>\n",argv[0]);
} }
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
...@@ -42,55 +44,78 @@ int main(int argc, char * argv[]) { ...@@ -42,55 +44,78 @@ int main(int argc, char * argv[]) {
struct stat st; struct stat st;
FILE * out; FILE * out;
FILE * err; FILE * err;
char * portStr;
char * musicDirArg;
char * playlistDirArg;
char * logFile;
char * errorFile;
if(argc!=6) { if(argc!=6 && argc!=2) {
usage(argv); usage(argv);
return -1; return -1;
} }
if((port = atoi(argv[1]))<0) { initConf();
if(argc==6) {
portStr = argv[1];
musicDirArg = argv[2];
playlistDirArg = argv[3];
logFile = argv[4];
errorFile = argv[5];
}
else if(argc==2) {
char ** conf = readConf(argv[1]);
portStr = conf[CONF_PORT];
musicDirArg = conf[CONF_MUSIC_DIRECTORY];
playlistDirArg = conf[CONF_PLAYLIST_DIRECTORY];
logFile = conf[CONF_LOG_FILE];
errorFile = conf[CONF_ERROR_FILE];
}
if((port = atoi(portStr))<0) {
fprintf(stderr,"problem with port number\n"); fprintf(stderr,"problem with port number\n");
return -1; return -1;
} }
if(NULL==(out=fopen(argv[4],"a"))) { if(NULL==(out=fopen(logFile,"a"))) {
fprintf(stderr,"problem opening file \"%s\" for writing\n",argv[3]); fprintf(stderr,"problem opening file \"%s\" for writing\n",logFile);
return -1; return -1;
} }
if(NULL==(err=fopen(argv[5],"a"))) { if(NULL==(err=fopen(errorFile,"a"))) {
fprintf(stderr,"problem opening file \"%s\" for writing\n",argv[3]); fprintf(stderr,"problem opening file \"%s\" for writing\n",errorFile);
return -1; return -1;
} }
if((stat(argv[2],&st))<0) { if((stat(musicDirArg,&st))<0) {
fprintf(stderr,"problem stat'ing \"%s\"\n",argv[2]); fprintf(stderr,"problem stat'ing \"%s\"\n",musicDirArg);
return -1; return -1;
} }
if(!S_ISDIR(st.st_mode)) { if(!S_ISDIR(st.st_mode)) {
fprintf(stderr,"\"%s\" is not a directory\n",argv[2]); fprintf(stderr,"\"%s\" is not a directory\n",musicDirArg);
return -1; return -1;
} }
if(argv[3][0]=='/') { if(playlistDirArg[0]=='/') {
strcpy(playlistDir,argv[3]); strcpy(playlistDir,playlistDirArg);
} }
else { else {
getcwd(playlistDir,MAXPATHLEN-strlen(argv[3])-1); getcwd(playlistDir,MAXPATHLEN-strlen(playlistDirArg)-1);
strcat(playlistDir,"/"); strcat(playlistDir,"/");
strcat(playlistDir,argv[3]); strcat(playlistDir,playlistDirArg);
strcat(playlistDir,"/"); strcat(playlistDir,"/");
} }
if((stat(playlistDir,&st))<0) { if((stat(playlistDir,&st))<0) {
fprintf(stderr,"problem stat'ing \"%s\"\n",argv[3]); fprintf(stderr,"problem stat'ing \"%s\"\n",playlistDirArg);
return -1; return -1;
} }
if(!S_ISDIR(st.st_mode)) { if(!S_ISDIR(st.st_mode)) {
fprintf(stderr,"\"%s\" is not a directory\n",argv[3]); fprintf(stderr,"\"%s\" is not a directory\n",playlistDirArg);
return -1; return -1;
} }
chdir(argv[2]); chdir(musicDirArg);
initTables(); initTables();
...@@ -119,6 +144,7 @@ int main(int argc, char * argv[]) { ...@@ -119,6 +144,7 @@ int main(int argc, char * argv[]) {
dup2(fileno(err),STDERR_FILENO); dup2(fileno(err),STDERR_FILENO);
while(COMMAND_RETURN_KILL!=readInputFromInterfaces()) { while(COMMAND_RETURN_KILL!=readInputFromInterfaces()) {
nextSongInPlaylistIfPlayerStopped();
playerProcessMessages(); playerProcessMessages();
getConnections(listenSocket); getConnections(listenSocket);
closeOldInterfaces(); closeOldInterfaces();
......
port "2100"
music_directory "/home/shank/mp3"
playlist_directory "/home/shank/playlists"
log_file "/home/shank/mpd.log"
error_file "/home/shank/mpd.error"
mpg123_command "mpg123 -b 2048 -R foo"
mpg123_process "mpg123"
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "player.h" #include "player.h"
#include "ls.h" #include "ls.h"
#include "listen.h" #include "listen.h"
#include "conf.h"
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
...@@ -36,7 +37,7 @@ ...@@ -36,7 +37,7 @@
#define MAX_BUFFER_LENGTH 1024 #define MAX_BUFFER_LENGTH 1024
#define MPG123_PLAYER_BUFFER_SIZE "2048" #define MAX_ARGS 100
int mpg123_pid = 0; int mpg123_pid = 0;
int mpg123_send = 0; int mpg123_send = 0;
...@@ -52,21 +53,26 @@ int mpg123_leavePlay = 0; ...@@ -52,21 +53,26 @@ int mpg123_leavePlay = 0;
int mpg123_leavePause = 0; int mpg123_leavePause = 0;
int mpg123_error = 0; int mpg123_error = 0;
int mpg123_lastFrame = 0; int mpg123_lastFrame = 0;
char mpg123_currentSong[MAXPATHLEN+1] = "\0";
int mpg123readline();
void mpg123_sigHandler(int signal) { void mpg123_sigHandler(int signal) {
if(signal==SIGCHLD) { if(signal==SIGCHLD) {
wait3(NULL,WNOHANG,NULL); wait3(NULL,WNOHANG,NULL);
mpg123_pid = 0; mpg123_pid = 0;
close(mpg123_recv); if(mpg123_recv) close(mpg123_recv);
close(mpg123_send); if(mpg123_send) close(mpg123_send);
close(mpg123_stderr); if(mpg123_stderr) close(mpg123_stderr);
mpg123_send = 0;
mpg123_recv = 0;
mpg123_stderr = 0;
if(mpg123_state==PLAYER_STATE_PLAY) { if(mpg123_state==PLAYER_STATE_PLAY) {
mpg123_state = PLAYER_STATE_STOP;
mpg123_leavePlay = 1; mpg123_leavePlay = 1;
fprintf(stderr,"mpg123 died while playing\n"); fprintf(stderr,"mpg123 died while playing \"%s\"\n",mpg123_currentSong);
nextSongInPlaylist(stderr);
} }
else mpg123_state = PLAYER_STATE_STOP; mpg123_state = PLAYER_STATE_STOP;
mpg123_currentSong[0] = '\0';
} }
} }
...@@ -74,6 +80,7 @@ int mpg123init() { ...@@ -74,6 +80,7 @@ int mpg123init() {
int fd_send[2], fd_recv[2], fd_stderr[2]; int fd_send[2], fd_recv[2], fd_stderr[2];
mpg123_error = 0; mpg123_error = 0;
mpg123_currentSong[0] = '\0';
if(socketpair(AF_UNIX,SOCK_STREAM,0,fd_send)<0) { if(socketpair(AF_UNIX,SOCK_STREAM,0,fd_send)<0) {
fprintf(stderr,"%s Problems socketpair'ing\n",COMMAND_RESPOND_ERROR); fprintf(stderr,"%s Problems socketpair'ing\n",COMMAND_RESPOND_ERROR);
...@@ -91,9 +98,21 @@ int mpg123init() { ...@@ -91,9 +98,21 @@ int mpg123init() {
signal(SIGPIPE,SIG_IGN); signal(SIGPIPE,SIG_IGN);
signal(SIGCHLD,mpg123_sigHandler); signal(SIGCHLD,mpg123_sigHandler);
fflush(NULL);
mpg123_pid = fork(); mpg123_pid = fork();
if(mpg123_pid==0) { if(mpg123_pid==0) {
char * args[MAX_ARGS+1];
int i;
i = 0;
args[i] = strtok(strdup((getConf())[CONF_MPG123_COMMAND])," ");
while(i<MAX_ARGS && args[i]) {
i++;
args[i] = strtok(NULL," ");
}
close(listenSocket); close(listenSocket);
closeAllInterfaces(); closeAllInterfaces();
close(fd_send[0]); close(fd_send[0]);
...@@ -106,9 +125,9 @@ int mpg123init() { ...@@ -106,9 +125,9 @@ int mpg123init() {
dup2(fd_stderr[1],STDERR_FILENO); dup2(fd_stderr[1],STDERR_FILENO);
close(fd_stderr[1]); close(fd_stderr[1]);
if(execlp("mpg123","mpg123","-b",MPG123_PLAYER_BUFFER_SIZE,"-R","foo",NULL)<0) { if(execvp(args[0],args)) {
fprintf(stderr,"%s Problems spawning mpg123\n",COMMAND_RESPOND_ERROR); fprintf(stderr,"%s Problems spawning mpg123\n",COMMAND_RESPOND_ERROR);
return -1; exit(-1);
} }
} }
else if(mpg123_pid<0) { else if(mpg123_pid<0) {
...@@ -156,8 +175,8 @@ int mpg123play(FILE * fp, char * file) { ...@@ -156,8 +175,8 @@ int mpg123play(FILE * fp, char * file) {
} }
mpg123_leavePlay = 0; mpg123_leavePlay = 0;
mpg123_state = PLAYER_STATE_PLAY; mpg123_state = PLAYER_STATE_PLAY;
strcpy(mpg123_currentSong,file);
sprintf(string,"LOAD %s\n",file); sprintf(string,"LOAD %s\n",file);
if(write(mpg123_send,string,strlen(string))<0) { if(write(mpg123_send,string,strlen(string))<0) {
...@@ -172,7 +191,6 @@ int mpg123play(FILE * fp, char * file) { ...@@ -172,7 +191,6 @@ int mpg123play(FILE * fp, char * file) {
} }
if(mpg123_error) { if(mpg123_error) {
fprintf(fp,"%s problems playing \"%s\"\n",COMMAND_RESPOND_ERROR,file); fprintf(fp,"%s problems playing \"%s\"\n",COMMAND_RESPOND_ERROR,file);
/*nextSongInPlaylist(stderr);*/
mpg123kill(); mpg123kill();
return -1; return -1;
} }
...@@ -182,19 +200,33 @@ int mpg123play(FILE * fp, char * file) { ...@@ -182,19 +200,33 @@ int mpg123play(FILE * fp, char * file) {
int mpg123stop(FILE * fp) { int mpg123stop(FILE * fp) {
if(mpg123_pid>0) { if(mpg123_pid>0) {
char string[1024]; int i;
char string[80];
fd_set fdsr;
struct timeval tv;
FD_ZERO(&fdsr);
FD_SET(mpg123_send,&fdsr);
tv.tv_sec = tv.tv_usec = 0;
if(mpg123_state==PLAYER_STATE_PAUSE) { if(mpg123_state==PLAYER_STATE_PAUSE) {
if(mpg123pause(fp)<0) return -1; if(mpg123pause(fp)<0) return -1;
} }
mpg123_state = PLAYER_STATE_STOP; mpg123_state = PLAYER_STATE_STOP;
i = 0;
sprintf(string,"QUIT\n"); sprintf(string,"QUIT\n");
if(write(mpg123_send,string,strlen(string))<0) { if(write(mpg123_send,string,strlen(string))<0) {
fprintf(fp,"%s problems write'ing\n",COMMAND_RESPOND_ERROR); fprintf(fp,"%s problems write'ing\n",COMMAND_RESPOND_ERROR);
return -1; return -1;
} }
waitpid(mpg123_pid,NULL,WUNTRACED); /* wait upto 1 s to get SIGCHLD */
while(i<10 && mpg123_pid>0) {
usleep(100000); /* wait for 10ms for mpg123 to die */
wait3(NULL,WNOHANG|WUNTRACED,NULL);
while(mpg123readline());
i++;
}
if(mpg123_pid>0) { if(mpg123_pid>0) {
fprintf(fp,"oh shit\n"); fprintf(stderr,"mpg123 didn't die!\n");
mpg123kill(); mpg123kill();
} }
} }
...@@ -231,27 +263,28 @@ int mpg123pause(FILE * fp) { ...@@ -231,27 +263,28 @@ int mpg123pause(FILE * fp) {
} }
int mpg123readline() { int mpg123readline() {
int rc;
fd_set fdsr; fd_set fdsr;
struct timeval tv; struct timeval tv;
FD_ZERO(&fdsr); FD_ZERO(&fdsr);
FD_SET(mpg123_recv,&fdsr); FD_SET(mpg123_recv,&fdsr);
tv.tv_sec = tv.tv_usec = 0; tv.tv_sec = tv.tv_usec = 0;
if(select(mpg123_recv+1,&fdsr,NULL,NULL,&tv)==1) { while(select(mpg123_recv+1,&fdsr,NULL,NULL,&tv)==1) {
int rc; FD_ZERO(&fdsr);
while(1) { FD_SET(mpg123_recv,&fdsr);
rc = read(mpg123_recv,mpg123_buffer+mpg123_bufferLength,1); rc = read(mpg123_recv,mpg123_buffer+mpg123_bufferLength,1);
if(rc<=0) { if(rc<=0) {
/*mpg123_pid = 0; /*mpg123_pid = 0;
mpg123_state = PLAYER_STATE_STOP;*/ mpg123_state = PLAYER_STATE_STOP;*/
return -1; return 0;
} }
if(mpg123_buffer[mpg123_bufferLength]=='\0' || mpg123_buffer[mpg123_bufferLength]=='\n' || mpg123_bufferLength == MAX_BUFFER_LENGTH) { if(mpg123_buffer[mpg123_bufferLength]=='\0' || mpg123_buffer[mpg123_bufferLength]=='\n' || mpg123_bufferLength == MAX_BUFFER_LENGTH) {
mpg123_buffer[mpg123_bufferLength] = '\0'; mpg123_buffer[mpg123_bufferLength] = '\0';
mpg123_bufferLength = 0; mpg123_bufferLength = 0;
return -1; return -1;
}
mpg123_bufferLength++;
} }
mpg123_bufferLength++;
} }
return 0; return 0;
...@@ -276,8 +309,8 @@ int mpg123gotErrors() { ...@@ -276,8 +309,8 @@ int mpg123gotErrors() {
if(errorBuffer[errorBufferLength]=='\0' || errorBuffer[errorBufferLength]=='\n' || errorBufferLength == MAX_BUFFER_LENGTH) { if(errorBuffer[errorBufferLength]=='\0' || errorBuffer[errorBufferLength]=='\n' || errorBufferLength == MAX_BUFFER_LENGTH) {
errorBuffer[errorBufferLength] = '\0'; errorBuffer[errorBufferLength] = '\0';
errorBufferLength = 0; errorBufferLength = 0;
fprintf(stderr,"%s %s\n",COMMAND_RESPOND_ERROR,errorBuffer); fprintf(stderr,"%s file: \"%s\" : %s\n",COMMAND_RESPOND_ERROR,mpg123_currentSong,errorBuffer);
if(!strncmp("Junk",errorBuffer,strlen("Junk"))) { if(0==strncmp("Junk at the beginning",errorBuffer,strlen("Junk"))) {
return 0; return 0;
} }
mpg123kill(); mpg123kill();
...@@ -309,8 +342,7 @@ int mpg123processMessages() { ...@@ -309,8 +342,7 @@ int mpg123processMessages() {
else if(0==strcmp(c[0],"@P")) { else if(0==strcmp(c[0],"@P")) {
if(mpg123_state==PLAYER_STATE_PLAY && atoi(c[1])==PLAYER_STATE_STOP) { if(mpg123_state==PLAYER_STATE_PLAY && atoi(c[1])==PLAYER_STATE_STOP) {
if(!mpg123_leavePlay) { if(!mpg123_leavePlay) {
mpg123_leavePlay=1; mpg123_leavePlay=1; mpg123_error=1;
mpg123_error = 1;
} }
} }
else if(mpg123_state==PLAYER_STATE_PLAY && atoi(c[1])==PLAYER_STATE_PAUSE) { else if(mpg123_state==PLAYER_STATE_PLAY && atoi(c[1])==PLAYER_STATE_PAUSE) {
...@@ -336,7 +368,6 @@ int mpg123processMessages() { ...@@ -336,7 +368,6 @@ int mpg123processMessages() {
mpg123_elapsedTime = mpg123_reportedElapsedTime+time(NULL)-mpg123_lastFrame; mpg123_elapsedTime = mpg123_reportedElapsedTime+time(NULL)-mpg123_lastFrame;
if(!mpg123_error && mpg123_leavePlay && mpg123_elapsedTime>=mpg123_totalTime) { if(!mpg123_error && mpg123_leavePlay && mpg123_elapsedTime>=mpg123_totalTime) {
mpg123stop(stderr); mpg123stop(stderr);
nextSongInPlaylist(stderr);
} }
} }
...@@ -344,10 +375,14 @@ int mpg123processMessages() { ...@@ -344,10 +375,14 @@ int mpg123processMessages() {
} }
void mpg123kill() { void mpg123kill() {
/* new stuff to try */ char * string;
//kill(-1,SIGKILL);
/* old new stuff to try */ string = malloc(strlen("killall -KILL ")+strlen((getConf())[CONF_MPG123_PROCESS])+1);
if(mpg123_pid>0) system("killall -KILL mpg123"); string[0] = '\0';
strcat(string,"killall -KILL ");
strcat(string,(getConf())[CONF_MPG123_PROCESS]);
if(mpg123_pid>0) system(string);
free(string);
mpg123_state = PLAYER_STATE_STOP; mpg123_state = PLAYER_STATE_STOP;
mpg123_sigHandler(SIGCHLD); mpg123_sigHandler(SIGCHLD);
} }
......
...@@ -64,6 +64,7 @@ int ogg_leavePlay = 1; ...@@ -64,6 +64,7 @@ int ogg_leavePlay = 1;
int ogg_leavePause = 1; int ogg_leavePause = 1;
char ogg_buffer[MAX_BUFFER_LENGTH+1]; char ogg_buffer[MAX_BUFFER_LENGTH+1];
int ogg_bufferLength = 0; int ogg_bufferLength = 0;
char ogg_currentSong[MAXPATHLEN+1] = "\0";
int ogg_GO(char * file, FILE * in, FILE * out) { int ogg_GO(char * file, FILE * in, FILE * out) {
OggVorbis_File vf; OggVorbis_File vf;
...@@ -160,12 +161,11 @@ void ogg_sigHandler(int signal) { ...@@ -160,12 +161,11 @@ void ogg_sigHandler(int signal) {
close(ogg_send); close(ogg_send);
ogg_leavePause = 1; ogg_leavePause = 1;
if(ogg_state==PLAYER_STATE_PLAY) { if(ogg_state==PLAYER_STATE_PLAY) {
ogg_state = PLAYER_STATE_STOP;
ogg_leavePlay = 1; ogg_leavePlay = 1;
fprintf(stderr,"ogg died while playing\n"); fprintf(stderr,"ogg died while playing \%s\"\n",ogg_currentSong);
nextSongInPlaylist(stderr);
} }
else ogg_state = PLAYER_STATE_STOP; ogg_state = PLAYER_STATE_STOP;
ogg_currentSong[0] = '\0';
} }
} }
...@@ -184,6 +184,8 @@ int oggInit(char * file) { ...@@ -184,6 +184,8 @@ int oggInit(char * file) {
signal(SIGPIPE,SIG_IGN); signal(SIGPIPE,SIG_IGN);
signal(SIGCHLD,ogg_sigHandler); signal(SIGCHLD,ogg_sigHandler);
fflush(NULL);
ogg_pid = fork(); ogg_pid = fork();
if(ogg_pid==0) { if(ogg_pid==0) {
...@@ -248,6 +250,8 @@ int oggPlay(FILE * fp, char * file) { ...@@ -248,6 +250,8 @@ int oggPlay(FILE * fp, char * file) {
} }
ogg_leavePlay = 0; ogg_leavePlay = 0;
ogg_currentSong[0] = '\0';
strcpy(ogg_currentSong,file);
ogg_state = PLAYER_STATE_PLAY; ogg_state = PLAYER_STATE_PLAY;
...@@ -340,10 +344,9 @@ int oggProcessMessages() { ...@@ -340,10 +344,9 @@ int oggProcessMessages() {
} }
else if(0==strcmp(c[0],OGG_DONE)) { else if(0==strcmp(c[0],OGG_DONE)) {
wait3(NULL,WNOHANG,NULL); wait3(NULL,WNOHANG,NULL);
nextSongInPlaylist(stderr);
} }
else if(0==strcmp(c[0],OGG_ERROR)) { else if(0==strcmp(c[0],OGG_ERROR)) {
fprintf(stderr,"ogg error: %s\n",c[1]); fprintf(stderr,"ogg error: file \"%s\" : %s\n",ogg_currentSong,c[1]);
} }
else if(0==strcmp(c[0],OGG_START)) { else if(0==strcmp(c[0],OGG_START)) {
ogg_leavePlay = 1; ogg_leavePlay = 1;
......
...@@ -45,4 +45,6 @@ int getPlayerElapsedTime(); ...@@ -45,4 +45,6 @@ int getPlayerElapsedTime();
int getPlayerState(); int getPlayerState();
void nextSongInPlaylistIfPlayerStopped();
#endif #endif
...@@ -30,8 +30,12 @@ ...@@ -30,8 +30,12 @@
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#define PLAYLIST_STATE_STOP 0
#define PLAYLIST_STATE_PLAY 1
Playlist playlist; Playlist playlist;
char playlistDir[MAXPATHLEN+1]; char playlistDir[MAXPATHLEN+1];
int playlist_state = PLAYLIST_STATE_STOP;
void initPlaylist() { void initPlaylist() {
playlist.length = 0; playlist.length = 0;
...@@ -39,15 +43,6 @@ void initPlaylist() { ...@@ -39,15 +43,6 @@ void initPlaylist() {
memset(playlist.songs,(int)NULL,sizeof(char *)*PLAYLIST_MAX_LENGTH); memset(playlist.songs,(int)NULL,sizeof(char *)*PLAYLIST_MAX_LENGTH);
} }
int checkThatPlaylistIsStopped(FILE * fp) {
if(getPlayerState()!=PLAYER_STATE_STOP) {
fprintf(fp,"%s playlist is not stopped\n",COMMAND_RESPOND_ERROR);
return -1;
}
return 0;
}
int clearPlaylist(FILE * fp) { int clearPlaylist(FILE * fp) {
int i; int i;
...@@ -64,7 +59,7 @@ int clearPlaylist(FILE * fp) { ...@@ -64,7 +59,7 @@ int clearPlaylist(FILE * fp) {
int addToPlaylist(FILE * fp, char * file) { int addToPlaylist(FILE * fp, char * file) {
if(!isMusic(file)) { if(!isMusic(file)) {
fprintf(fp,"%s \"%s\" is not a mp3\n",COMMAND_RESPOND_ERROR,file); fprintf(fp,"%s \"%s\" is not a mp3/ogg\n",COMMAND_RESPOND_ERROR,file);
return -1; return -1;
} }
...@@ -124,7 +119,6 @@ void swapSongs(int song1, int song2) { ...@@ -124,7 +119,6 @@ void swapSongs(int song1, int song2) {
int deleteFromPlaylist(FILE * fp, int song) { int deleteFromPlaylist(FILE * fp, int song) {
int i; int i;
int state = getPlayerState();
if(song<0) { if(song<0) {
fprintf(fp,"%s need a positive interger\n",COMMAND_RESPOND_ERROR); fprintf(fp,"%s need a positive interger\n",COMMAND_RESPOND_ERROR);
...@@ -142,45 +136,54 @@ int deleteFromPlaylist(FILE * fp, int song) { ...@@ -142,45 +136,54 @@ int deleteFromPlaylist(FILE * fp, int song) {
playlist.length--; playlist.length--;
if(state!=PLAYER_STATE_STOP && playlist.current==song) { if(playlist_state!=PLAYLIST_STATE_STOP && playlist.current==song) {
if(playlist.current>=playlist.length) return playerStop(fp); if(playlist.current>=playlist.length) return playerStop(fp);
else return playPlaylist(fp,playlist.current); else return playPlaylist(fp,playlist.current);
} }
else if(state!=PLAYER_STATE_STOP && playlist.current>song) { else if(playlist_state!=PLAYLIST_STATE_STOP && playlist.current>song) {
playlist.current--; playlist.current--;
} }
return 0; return 0;
} }
int stopPlaylist(FILE * fp) {
if(playerStop(fp)<0) return -1;
playlist_state = PLAYLIST_STATE_STOP;
return 0;
}
int playPlaylist(FILE * fp, int song) { int playPlaylist(FILE * fp, int song) {
if(song<0) { if(song<0) {
fprintf(fp,"%s need a positive interger\n",COMMAND_RESPOND_ERROR); fprintf(fp,"%s need a positive interger\n",COMMAND_RESPOND_ERROR);
playlist_state = PLAYLIST_STATE_STOP;
return -1; return -1;
} }
if(song>=playlist.length) { if(song>=playlist.length) {
fprintf(fp,"%s song doesn't exist\n",COMMAND_RESPOND_ERROR); fprintf(fp,"%s song doesn't exist\n",COMMAND_RESPOND_ERROR);
playlist_state = PLAYLIST_STATE_STOP;
return -1; return -1;
} }
if(playerStop(fp)<0) return -1; if(playerStop(fp)<0) return -1;
playlist.current = song; playlist.current = song;
playlist_state = PLAYLIST_STATE_PLAY;
return playerPlay(fp,(playlist.songs[song])->file); return playerPlay(fp,(playlist.songs[song])->file);
} }
int nextSongInPlaylist(FILE * fp) { void nextSongInPlaylistIfPlayerStopped() {
while(playlist.current<playlist.length-1) { if(playlist_state==PLAYLIST_STATE_PLAY && getPlayerState()==PLAYER_STATE_STOP) {
playlist.current++; nextSongInPlaylist(stderr);
if(playerPlay(fp,(playlist.songs[playlist.current])->file)==0) return 0;
} }
/*if(playlist.current==playlist.length-1) { }
mpg123_stopAtEnd = 1;
int nextSongInPlaylist(FILE * fp) {
if(playlist.current<playlist.length-1) {
return playPlaylist(fp,playlist.current+1);
} }
else { else return stopPlaylist(fp);;
mpg123stop(fp);
}*/
return 0; return 0;
} }
......
...@@ -47,6 +47,8 @@ int deleteFromPlaylist(FILE * fp, int song); ...@@ -47,6 +47,8 @@ int deleteFromPlaylist(FILE * fp, int song);
int playlistInfo(FILE * fp, int song); int playlistInfo(FILE * fp, int song);
int stopPlaylist(FILE * fp);
int playPlaylist(FILE * fp, int song); int playPlaylist(FILE * fp, int song);
int nextSongInPlaylist(FILE * fp); int nextSongInPlaylist(FILE * fp);
......
...@@ -129,6 +129,7 @@ int searchForSongsInAlbumTable(FILE * fp,char * search) { ...@@ -129,6 +129,7 @@ int searchForSongsInAlbumTable(FILE * fp,char * search) {
album = (SongList *)node->data; album = (SongList *)node->data;
if(printSongInfoFromList(fp,album)<0) { if(printSongInfoFromList(fp,album)<0) {
free(dup); free(dup);
free(dupSearch);
return -1; return -1;
} }
ret = 0; ret = 0;
...@@ -156,6 +157,7 @@ int searchForSongsInArtistTable(FILE * fp,char * search) { ...@@ -156,6 +157,7 @@ int searchForSongsInArtistTable(FILE * fp,char * search) {
artist = (SongList *)node->data; artist = (SongList *)node->data;
if(printSongInfoFromList(fp,artist)<0) { if(printSongInfoFromList(fp,artist)<0) {
free(dup); free(dup);
free(dupSearch);
return -1; return -1;
} }
ret = 0; ret = 0;
...@@ -183,6 +185,7 @@ int searchForSongsInTitleTable(FILE * fp,char * search) { ...@@ -183,6 +185,7 @@ int searchForSongsInTitleTable(FILE * fp,char * search) {
if(strstr(dup,dupSearch)) { if(strstr(dup,dupSearch)) {
if(printSongInfo(fp,song)<0) { if(printSongInfo(fp,song)<0) {
free(dup); free(dup);
free(dupSearch);
return -1; return -1;
} }
ret = 0; ret = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment