Commit 53f5a137 authored by Led's avatar Led

0.8.3

parent d94eaf58
...@@ -44,6 +44,13 @@ find <string type> <string what> ...@@ -44,6 +44,13 @@ find <string type> <string what>
kill kill
kill mpd kill mpd
list <string type> <string arg1>
list all tags of _type_
_type_ should be "album" or "artist"
_arg1_ is an optional paramter when type is album, this specifies
to list albums by a artist, where artist is specified with
arg1
listall <string directory> listall <string directory>
lists all songs and directories in _directory_ (recursively) lists all songs and directories in _directory_ (recursively)
_directory_ is optional _directory_ is optional
...@@ -89,6 +96,7 @@ repeat <int state> ...@@ -89,6 +96,7 @@ repeat <int state>
search <string type> <string what> search <string type> <string what>
same as "find" but searches for any song that contain _what_ same as "find" but searches for any song that contain _what_
search is not case sensitive
shuffle shuffle
shuffles the current playlist shuffles the current playlist
......
ver 0.8.3 (2003/8/12)
1) Fix a compilation error on older linux systems
2) Fix a bug in searching by title
3) Add "list" command
4) Add config options for specifying libao driver/plugin and options
5) Add config option to specify which address to bind to
6) Add support for loading and saving absolute pathnames in saved playlists
7) Playlist no longer creates duplicate entries for song data (more me
efficient)
8) Songs deleted from the db are now removed for the playlist as well
ver 0.8.2 (2003/7/22) ver 0.8.2 (2003/7/22)
1) Increased the connection que for listen() from 0 to 5 1) Increased the connection que for listen() from 0 to 5
2) Cleanup configure makefiles so that mpd uses MPD_LIBS and MPD_CFLAGS 2) Cleanup configure makefiles so that mpd uses MPD_LIBS and MPD_CFLAGS
......
...@@ -28,7 +28,7 @@ For Flac support, you need Flac 1.1.0 or greater. ...@@ -28,7 +28,7 @@ For Flac support, you need Flac 1.1.0 or greater.
Download Download
-------- --------
Get the latest release from of MPD from http://musicpd.sourceforge.net Get the latest release from of MPD from http://www.musicpd.org
Compile Compile
------- -------
...@@ -90,6 +90,6 @@ Using MPD ...@@ -90,6 +90,6 @@ Using MPD
--------- ---------
You can download a web interface (phpMp) to MPD at You can download a web interface (phpMp) to MPD at
http://musicpd.sourceforge.net . http://www.musicpd.org .
MPD can be interfaced directly using telnet (see COMMANDS, if you are brave). MPD can be interfaced directly using telnet (see COMMANDS, if you are brave).
bin_PROGRAMS = mpd bin_PROGRAMS = mpd
SUBDIRS = $(ID3_SUBDIR) $(MAD_SUBDIR) SUBDIRS = $(ID3_SUBDIR) $(MAD_SUBDIR)
man_MANS = mpd.1 man_MANS = mpd.1
pkgdata_DATA = mpdconf.example README INSTALL pkgdata_DATA =
EXTRA_DIST = COMMANDS UPGRADING $(pkgdata_DATA) $(man_MANS) docdir = $(prefix)/share/doc/$(PACKAGE)
doc_DATA = README UPGRADING
EXTRA_DIST = mpdconf.example COMMANDS COPYING $(pkgdata_DATA) $(man_MANS) $(doc_DATA)
mpd_headers = buffer2array.h interface.h command.h playlist.h ls.h \ mpd_headers = buffer2array.h interface.h command.h playlist.h ls.h \
song.h list.h directory.h tables.h utils.h path.h flac_decode.h \ song.h list.h directory.h tables.h utils.h path.h flac_decode.h \
tag.h player.h listen.h conf.h ogg_decode.h volume.h mp3_decode.h \ tag.h player.h listen.h conf.h ogg_decode.h volume.h mp3_decode.h \
......
Music Player Daemon (MPD) Music Player Daemon (MPD)
http://musicpd.sourceforge.net http://www.musicpd.org
A daemon for playing music (mp3, ogg vorbis, and flac). Music is played A daemon for playing music (mp3, ogg vorbis, and flac). Music is played
through the server's audio device. The daemon stores info about all available through the server's audio device. The daemon stores info about all available
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -17,14 +17,106 @@ ...@@ -17,14 +17,106 @@
*/ */
#include "audio.h" #include "audio.h"
#include "conf.h"
#include <string.h>
int audio_ao_driver_id; int audio_ao_driver_id;
ao_option * audio_ao_options;
void initAudioDriver() {
ao_info * ai;
char * dup;
char * stk1;
char * stk2;
char * n1;
char * key;
char * value;
/*int found;
int i;*/
audio_ao_options = NULL;
ao_initialize();
if(strcmp(AUDIO_AO_DRIVER_DEFAULT,(getConf())[CONF_AO_DRIVER])==0) {
audio_ao_driver_id = ao_default_driver_id();
}
else if((audio_ao_driver_id =
ao_driver_id((getConf())[CONF_AO_DRIVER]))<0) {
fprintf(stderr,"\"%s\" is not a valid ao driver\n",
(getConf())[CONF_AO_DRIVER]);
exit(-1);
}
if((ai = ao_driver_info(audio_ao_driver_id))==NULL) {
fprintf(stderr,"problems getting ao_driver_info\n");
exit(-1);
}
dup = strdup((getConf())[CONF_AO_DRIVER_OPTIONS]);
if(strlen(dup)) {
stk1 = NULL;
n1 = strtok_r(dup,";",&stk1);
while(n1) {
stk2 = NULL;
key = strtok_r(n1,"=",&stk2);
if(!key) {
fprintf(stderr,"problems parsing "
"ao_driver_options \"%s\"\n", n1);
exit(-1);
}
/*found = 0;
for(i=0;i<ai->option_count;i++) {
printf("option: %s\n",ai->options[i]);
if(strcmp(ai->options[i],key)==0) {
found = 1;
break;
}
}
if(!found) {
fprintf(stderr,"\"%s\" is not an option for "
"\"%s\" ao driver\n",key,
ai->short_name);
exit(-1);
}*/
value = strtok_r(NULL,"",&stk2);
if(!value) {
fprintf(stderr,"problems parsing "
"ao_driver_options \"%s\"\n", n1);
exit(-1);
}
ao_append_option(&audio_ao_options,key,value);
n1 = strtok_r(NULL,";",&stk1);
}
}
free(dup);
ao_shutdown();
}
void finishAudioDriver() {
ao_free_options(audio_ao_options);
}
void initAudio() { void initAudio() {
ao_initialize(); ao_initialize();
audio_ao_driver_id = ao_default_driver_id();
} }
void finishAudio() { void finishAudio() {
ao_shutdown(); ao_shutdown();
} }
void audioError() {
fprintf(stderr,"Error opening audio device\n");
if(errno==AO_ENOTLIVE) {
fprintf(stderr,"not a live ao device\n");
}
else if(errno==AO_EOPENDEVICE) {
fprintf(stderr,"not able to open audio device\n");
}
else if(errno==AO_EBADOPTION) {
fprintf(stderr,"bad driver option\n");
}
perror("ao error");
fflush(stderr);
}
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -19,13 +19,22 @@ ...@@ -19,13 +19,22 @@
#ifndef AUDIO_H #ifndef AUDIO_H
#define AUDIO_H #define AUDIO_H
#define AUDIO_AO_DRIVER_DEFAULT "default"
#include <stdio.h> #include <stdio.h>
#include <ao/ao.h> #include <ao/ao.h>
extern int audio_ao_driver_id; extern int audio_ao_driver_id;
extern ao_option * audio_ao_options;
void initAudioDriver();
void finishAudioDriver();
void initAudio(); void initAudio();
void finishAudio(); void finishAudio();
void audioError();
#endif #endif
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -33,7 +33,7 @@ int buffer2array(char * origBuffer, char *** array) { ...@@ -33,7 +33,7 @@ int buffer2array(char * origBuffer, char *** array) {
char * markArray = malloc(sizeof(char)*(bufferLength+1)); 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]==' ' || buffer[curr]=='\t') ) {
markArray[curr] = '0'; markArray[curr] = '0';
} }
else if(buffer[curr] == '\"') { else if(buffer[curr] == '\"') {
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
#define COMMAND_REPEAT "repeat" #define COMMAND_REPEAT "repeat"
#define COMMAND_STATS "stats" #define COMMAND_STATS "stats"
#define COMMAND_CLEAR_ERROR "clearerror" #define COMMAND_CLEAR_ERROR "clearerror"
#define COMMAND_LIST "list"
#define COMMAND_STATUS_VOLUME "volume" #define COMMAND_STATUS_VOLUME "volume"
#define COMMAND_STATUS_STATE "state" #define COMMAND_STATUS_STATE "state"
...@@ -358,7 +359,16 @@ int processCommand(FILE * fp, int argArrayLength, char ** argArray) { ...@@ -358,7 +359,16 @@ int processCommand(FILE * fp, int argArrayLength, char ** argArray) {
return -1; return -1;
} }
if(argArrayLength==2) directory = argArray[1]; if(argArrayLength==2) directory = argArray[1];
printAllIn(fp,directory); return printAllIn(fp,directory);
}
else if(0==strcmp(argArray[0],COMMAND_LIST)) {
char * arg1 = NULL;
if(argArrayLength>3) {
myfprintf(fp,"%s wrong number of arguments for \"%s\"\n",COMMAND_RESPOND_ERROR,argArray[0]);
return -1;
}
if(argArrayLength==3) arg1 = argArray[2];
return printAllKeysOfTable(fp,argArray[1],arg1);
} }
else if(0==strcmp(argArray[0],COMMAND_STATS)) { else if(0==strcmp(argArray[0],COMMAND_STATS)) {
if(argArrayLength!=1) { if(argArrayLength!=1) {
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "utils.h" #include "utils.h"
#include "buffer2array.h" #include "buffer2array.h"
#include "audio.h"
#include <sys/param.h> #include <sys/param.h>
#include <stdio.h> #include <stdio.h>
...@@ -28,20 +29,26 @@ ...@@ -28,20 +29,26 @@
#define MAX_STRING_SIZE MAXPATHLEN+80 #define MAX_STRING_SIZE MAXPATHLEN+80
#define CONF_NUMBER_OF_PARAMS 13 #define CONF_COMMENT '#'
#define CONF_NUMBER_OF_PARAMS 17
#define CONF_NUMBER_OF_PATHS 4 #define CONF_NUMBER_OF_PATHS 4
#define CONF_NUMBER_OF_REQUIRED 5 #define CONF_NUMBER_OF_REQUIRED 5
#define CONF_CONNECTION_TIMEOUT_DEFAULT "60" #define CONF_CONNECTION_TIMEOUT_DEFAULT "60"
#define CONF_MIXER_DEVICE_DEFAULT "/dev/mixer" #define CONF_MIXER_DEVICE_DEFAULT "/dev/mixer"
#define CONF_MAX_CONNECTIONS_DEFAULT "5" #define CONF_MAX_CONNECTIONS_DEFAULT "5"
#define CONF_MAX_PLAYLIST_LENGTH_DEFAULT "4096" #define CONF_MAX_PLAYLIST_LENGTH_DEFAULT "4096"
#define CONF_BUFFER_BEFORE_PLAY_DEFAULT "25%" #define CONF_BUFFER_BEFORE_PLAY_DEFAULT "25%"
#define CONF_STOP_ON_ERROR_DEFAULT "yes" #define CONF_STOP_ON_ERROR_DEFAULT "yes"
#define CONF_MAX_COMMAND_LIST_SIZE_DEFAULT "2048" #define CONF_MAX_COMMAND_LIST_SIZE_DEFAULT "2048"
#define CONF_MAX_OUTPUT_BUFFER_SIZE_DEFAULT "2048" #define CONF_MAX_OUTPUT_BUFFER_SIZE_DEFAULT "2048"
#define CONF_AO_DRIVER_DEFAULT AUDIO_AO_DRIVER_DEFAULT
char conf_strings[CONF_NUMBER_OF_PARAMS][24] = { #define CONF_AO_DRIVER_OPTIONS_DEFAULT ""
#define CONF_SAVE_ABSOLUTE_PATHS_IN_PLAYLISTS_DEFAULT "no"
#define CONF_BIND_TO_ADDRESS_DEFAULT "any"
char * conf_strings[CONF_NUMBER_OF_PARAMS] = {
"port", "port",
"music_directory", "music_directory",
"playlist_directory", "playlist_directory",
...@@ -54,7 +61,11 @@ char conf_strings[CONF_NUMBER_OF_PARAMS][24] = { ...@@ -54,7 +61,11 @@ char conf_strings[CONF_NUMBER_OF_PARAMS][24] = {
"buffer_before_play", "buffer_before_play",
"stop_on_error", "stop_on_error",
"max_command_list_size", "max_command_list_size",
"max_output_buffer_size" "max_output_buffer_size",
"ao_driver",
"ao_driver_options",
"save_absolute_paths_in_playlists",
"bind_to_address"
}; };
int conf_absolutePaths[CONF_NUMBER_OF_PATHS] = { int conf_absolutePaths[CONF_NUMBER_OF_PATHS] = {
...@@ -88,6 +99,10 @@ void initConf() { ...@@ -88,6 +99,10 @@ void initConf() {
conf_params[CONF_STOP_ON_ERROR] = strdup(CONF_STOP_ON_ERROR_DEFAULT); conf_params[CONF_STOP_ON_ERROR] = strdup(CONF_STOP_ON_ERROR_DEFAULT);
conf_params[CONF_MAX_COMMAND_LIST_SIZE] = strdup(CONF_MAX_COMMAND_LIST_SIZE_DEFAULT); conf_params[CONF_MAX_COMMAND_LIST_SIZE] = strdup(CONF_MAX_COMMAND_LIST_SIZE_DEFAULT);
conf_params[CONF_MAX_OUTPUT_BUFFER_SIZE] = strdup(CONF_MAX_OUTPUT_BUFFER_SIZE_DEFAULT); conf_params[CONF_MAX_OUTPUT_BUFFER_SIZE] = strdup(CONF_MAX_OUTPUT_BUFFER_SIZE_DEFAULT);
conf_params[CONF_AO_DRIVER] = strdup(CONF_AO_DRIVER_DEFAULT);
conf_params[CONF_AO_DRIVER_OPTIONS] = strdup(CONF_AO_DRIVER_OPTIONS_DEFAULT);
conf_params[CONF_SAVE_ABSOLUTE_PATHS_IN_PLAYLISTS] = strdup(CONF_SAVE_ABSOLUTE_PATHS_IN_PLAYLISTS_DEFAULT);
conf_params[CONF_BIND_TO_ADDRESS] = strdup(CONF_BIND_TO_ADDRESS_DEFAULT);
} }
char ** readConf(char * file) { char ** readConf(char * file) {
...@@ -95,6 +110,7 @@ char ** readConf(char * file) { ...@@ -95,6 +110,7 @@ char ** readConf(char * file) {
char string[MAX_STRING_SIZE+1]; char string[MAX_STRING_SIZE+1];
char ** array; char ** array;
int i; int i;
int numberOfArgs;
if(!(fp=fopen(file,"r"))) { if(!(fp=fopen(file,"r"))) {
fprintf(stderr,"problems opening file %s for reading\n",file); fprintf(stderr,"problems opening file %s for reading\n",file);
...@@ -102,7 +118,10 @@ char ** readConf(char * file) { ...@@ -102,7 +118,10 @@ char ** readConf(char * file) {
} }
while(myFgets(string,sizeof(string),fp)) { while(myFgets(string,sizeof(string),fp)) {
if(2!=buffer2array(string,&array)) { if(string[0]==CONF_COMMENT) continue;
numberOfArgs = buffer2array(string,&array);
if(numberOfArgs==0) continue;
if(2!=numberOfArgs) {
fprintf(stderr,"need two args in conf at: %s\n",string); fprintf(stderr,"need two args in conf at: %s\n",string);
exit(-1); exit(-1);
} }
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -19,19 +19,23 @@ ...@@ -19,19 +19,23 @@
#ifndef CONF_H #ifndef CONF_H
#define CONF_H #define CONF_H
#define CONF_PORT 0 #define CONF_PORT 0
#define CONF_MUSIC_DIRECTORY 1 #define CONF_MUSIC_DIRECTORY 1
#define CONF_PLAYLIST_DIRECTORY 2 #define CONF_PLAYLIST_DIRECTORY 2
#define CONF_LOG_FILE 3 #define CONF_LOG_FILE 3
#define CONF_ERROR_FILE 4 #define CONF_ERROR_FILE 4
#define CONF_CONNECTION_TIMEOUT 5 #define CONF_CONNECTION_TIMEOUT 5
#define CONF_MIXER_DEVICE 6 #define CONF_MIXER_DEVICE 6
#define CONF_MAX_CONNECTIONS 7 #define CONF_MAX_CONNECTIONS 7
#define CONF_MAX_PLAYLIST_LENGTH 8 #define CONF_MAX_PLAYLIST_LENGTH 8
#define CONF_BUFFER_BEFORE_PLAY 9 #define CONF_BUFFER_BEFORE_PLAY 9
#define CONF_STOP_ON_ERROR 10 #define CONF_STOP_ON_ERROR 10
#define CONF_MAX_COMMAND_LIST_SIZE 11 #define CONF_MAX_COMMAND_LIST_SIZE 11
#define CONF_MAX_OUTPUT_BUFFER_SIZE 12 #define CONF_MAX_OUTPUT_BUFFER_SIZE 12
#define CONF_AO_DRIVER 13
#define CONF_AO_DRIVER_OPTIONS 14
#define CONF_SAVE_ABSOLUTE_PATHS_IN_PLAYLISTS 15
#define CONF_BIND_TO_ADDRESS 16
/* do not free the return value, it is a static variable */ /* do not free the return value, it is a static variable */
char ** readConf(char * file); char ** readConf(char * file);
......
AC_INIT(main.c) AC_INIT(main.c)
AM_INIT_AUTOMAKE(mpd, 0.8.2) AM_INIT_AUTOMAKE(mpd, 0.8.3)
AC_PROG_CC AC_PROG_CC
AC_PROG_INSTALL AC_PROG_INSTALL
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "utils.h" #include "utils.h"
#include "path.h" #include "path.h"
#include "myfprintf.h" #include "myfprintf.h"
#include "playlist.h"
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
...@@ -84,6 +85,7 @@ Directory * newDirectory(Directory * parentDirectory, char * dirname) { ...@@ -84,6 +85,7 @@ Directory * newDirectory(Directory * parentDirectory, char * dirname) {
void freeDirectory(Directory * directory) { void freeDirectory(Directory * directory) {
freeDirectoryList(directory->subDirectories); freeDirectoryList(directory->subDirectories);
removeSongsFromTables(directory->songs); removeSongsFromTables(directory->songs);
deleteSongsFromPlaylist(directory->songs);
freeSongList(directory->songs); freeSongList(directory->songs);
if(directory->name) free(directory->name); if(directory->name) free(directory->name);
free(directory); free(directory);
...@@ -102,6 +104,7 @@ void removeSongFromDirectory(Directory * directory, char * shortname) { ...@@ -102,6 +104,7 @@ void removeSongFromDirectory(Directory * directory, char * shortname) {
if(findInList(directory->songs,shortname,&song)) { if(findInList(directory->songs,shortname,&song)) {
removeASongFromTables((Song *)song); removeASongFromTables((Song *)song);
deleteASongFromPlaylist((Song *)song);
deleteFromList(directory->songs,shortname); deleteFromList(directory->songs,shortname);
} }
} }
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -262,11 +262,11 @@ int flac_decode(char * file, FILE * in, FILE * out) { ...@@ -262,11 +262,11 @@ int flac_decode(char * file, FILE * in, FILE * out) {
tv.tv_usec = 0; tv.tv_usec = 0;
initAudio(); initAudio();
flac_device = ao_open_live(audio_ao_driver_id,&format,NULL); flac_device = ao_open_live(audio_ao_driver_id,&format,
audio_ao_options);
if(flac_device == NULL) { if(flac_device == NULL) {
fprintf(stderr, "%s Error opening device.\n",PLAYER_ERROR); audioError();
fflush(stderr);
pid = flac_decode_pid; pid = flac_decode_pid;
if(pid>0) kill(pid,SIGTERM); if(pid>0) kill(pid,SIGTERM);
return PLAYER_EXIT_ERROR_AUDIO; return PLAYER_EXIT_ERROR_AUDIO;
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
#!/bin/sh #!/bin/sh
# #
# install - install a program, script, or datafile # install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
# #
# Copyright 1991 by the Massachusetts Institute of Technology # This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
# #
# Permission to use, copy, modify, distribute, and sell this software and its # Copyright (C) 1994 X Consortium
# documentation for any purpose is hereby granted without fee, provided that #
# the above copyright notice appear in all copies and that both that # Permission is hereby granted, free of charge, to any person obtaining a copy
# copyright notice and this permission notice appear in supporting # of this software and associated documentation files (the "Software"), to
# documentation, and that the name of M.I.T. not be used in advertising or # deal in the Software without restriction, including without limitation the
# publicity pertaining to distribution of the software without specific, # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# written prior permission. M.I.T. makes no representations about the # sell copies of the Software, and to permit persons to whom the Software is
# suitability of this software for any purpose. It is provided "as is" # furnished to do so, subject to the following conditions:
# without express or implied warranty. #
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
# #
# Calling this script install-sh is preferred over install.sh, to prevent # Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it # `make' implicit rules from creating a file called install from it
...@@ -56,7 +74,7 @@ dir_arg="" ...@@ -56,7 +74,7 @@ dir_arg=""
while [ x"$1" != x ]; do while [ x"$1" != x ]; do
case $1 in case $1 in
-c) instcmd=$cpprog -c) instcmd="$cpprog"
shift shift
continue;; continue;;
...@@ -79,7 +97,7 @@ while [ x"$1" != x ]; do ...@@ -79,7 +97,7 @@ while [ x"$1" != x ]; do
shift shift
continue;; continue;;
-s) stripcmd=$stripprog -s) stripcmd="$stripprog"
shift shift
continue;; continue;;
...@@ -106,7 +124,7 @@ done ...@@ -106,7 +124,7 @@ done
if [ x"$src" = x ] if [ x"$src" = x ]
then then
echo "$0: no input file specified" >&2 echo "install: no input file specified"
exit 1 exit 1
else else
: :
...@@ -115,8 +133,8 @@ fi ...@@ -115,8 +133,8 @@ fi
if [ x"$dir_arg" != x ]; then if [ x"$dir_arg" != x ]; then
dst=$src dst=$src
src="" src=""
if [ -d "$dst" ]; then if [ -d $dst ]; then
instcmd=: instcmd=:
chmodcmd="" chmodcmd=""
else else
...@@ -125,20 +143,20 @@ if [ x"$dir_arg" != x ]; then ...@@ -125,20 +143,20 @@ if [ x"$dir_arg" != x ]; then
else else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad # might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'. # if $src (and thus $dsttmp) contains '*'.
if [ -f "$src" ] || [ -d "$src" ] if [ -f "$src" ] || [ -d "$src" ]
then then
: :
else else
echo "$0: $src does not exist" >&2 echo "install: $src does not exist"
exit 1 exit 1
fi fi
if [ x"$dst" = x ] if [ x"$dst" = x ]
then then
echo "$0: no destination specified" >&2 echo "install: no destination specified"
exit 1 exit 1
else else
: :
...@@ -147,16 +165,16 @@ else ...@@ -147,16 +165,16 @@ else
# If destination is a directory, append the input filename; if your system # If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic # does not like double slashes in filenames, you may need to add some logic
if [ -d "$dst" ] if [ -d $dst ]
then then
dst=$dst/`basename "$src"` dst="$dst"/`basename $src`
else else
: :
fi fi
fi fi
## this sed command emulates the dirname command ## this sed command emulates the dirname command
dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists. # Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script # this part is taken from Noah Friedman's mkinstalldirs script
...@@ -165,73 +183,69 @@ dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` ...@@ -165,73 +183,69 @@ dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
if [ ! -d "$dstdir" ]; then if [ ! -d "$dstdir" ]; then
defaultIFS=' defaultIFS='
' '
IFS="${IFS-$defaultIFS}" IFS="${IFS-${defaultIFS}}"
oIFS=$IFS oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason. # Some sh's can't handle IFS=/ for some reason.
IFS='%' IFS='%'
set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS=$oIFS IFS="${oIFS}"
pathcomp='' pathcomp=''
while [ $# -ne 0 ] ; do while [ $# -ne 0 ] ; do
pathcomp=$pathcomp$1 pathcomp="${pathcomp}${1}"
shift shift
if [ ! -d "$pathcomp" ] ; if [ ! -d "${pathcomp}" ] ;
then then
$mkdirprog "$pathcomp" $mkdirprog "${pathcomp}"
else else
: :
fi fi
pathcomp=$pathcomp/ pathcomp="${pathcomp}/"
done done
fi fi
if [ x"$dir_arg" != x ] if [ x"$dir_arg" != x ]
then then
$doit $instcmd "$dst" && $doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
else else
# If we're going to rename the final executable, determine the name now. # If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ] if [ x"$transformarg" = x ]
then then
dstfile=`basename "$dst"` dstfile=`basename $dst`
else else
dstfile=`basename "$dst" $transformbasename | dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename sed $transformarg`$transformbasename
fi fi
# don't allow the sed command to completely eliminate the filename # don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ] if [ x"$dstfile" = x ]
then then
dstfile=`basename "$dst"` dstfile=`basename $dst`
else else
: :
fi fi
# Make a couple of temp file names in the proper directory. # Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$# dsttmp=$dstdir/#inst.$$#
rmtmp=$dstdir/#rm.$$#
# Trap to clean up temp files at exit.
trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
trap '(exit $?); exit' 1 2 13 15
# Move or copy the file name to the temp name # Move or copy the file name to the temp name
$doit $instcmd "$src" "$dsttmp" && $doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits # and set any options; do chmod last to preserve setuid bits
...@@ -239,38 +253,17 @@ else ...@@ -239,38 +253,17 @@ else
# ignore errors from any of these, just make sure not to ignore # ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command. # errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
# Now remove or move aside any old file at destination location. We try this
# two ways since rm can't unlink itself on some systems and the destination
# file might be busy for other reasons. In this case, the final cleanup
# might fail but the new file should still install successfully.
{
if [ -f "$dstdir/$dstfile" ]
then
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
$doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
{
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit
}
else
:
fi
} &&
# Now rename the file to the real destination. # Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile" $doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi && fi &&
# The final little trick to "correctly" pass the exit status to the exit trap.
{ exit 0
(exit 0); exit
}
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -147,13 +147,17 @@ int interfaceReadInput(Interface * interface) { ...@@ -147,13 +147,17 @@ int interfaceReadInput(Interface * interface) {
argArrayLength = buffer2array((char *)node->data,&argArray); argArrayLength = buffer2array((char *)node->data,&argArray);
ret = processCommand(interface->fp,argArrayLength,argArray); ret = processCommand(interface->fp,argArrayLength,argArray);
freeArgArray(argArray,argArrayLength); freeArgArray(argArray,argArrayLength);
if(ret!=0) break; if(ret!=0 ||
interface->expired) {
break;
}
node = node->nextNode; node = node->nextNode;
} }
if(ret==0) { if(ret==0) {
myfprintf(interface->fp,"%s\n",COMMAND_RESPOND_OK); myfprintf(interface->fp,"%s\n",COMMAND_RESPOND_OK);
} }
else if(ret==COMMAND_RETURN_CLOSE) { else if(ret==COMMAND_RETURN_CLOSE ||
interface->expired) {
closeInterface(interface); closeInterface(interface);
} }
...@@ -189,7 +193,8 @@ int interfaceReadInput(Interface * interface) { ...@@ -189,7 +193,8 @@ int interfaceReadInput(Interface * interface) {
if(ret==0) { if(ret==0) {
myfprintf(interface->fp,"%s\n",COMMAND_RESPOND_OK); myfprintf(interface->fp,"%s\n",COMMAND_RESPOND_OK);
} }
else if(ret==COMMAND_RETURN_CLOSE) { else if(ret==COMMAND_RETURN_CLOSE ||
interface->expired) {
closeInterface(interface); closeInterface(interface);
} }
} }
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2002 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2002 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "listen.h" #include "listen.h"
#include "interface.h" #include "interface.h"
#include "conf.h"
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
...@@ -44,14 +45,27 @@ int establish(unsigned short port) { ...@@ -44,14 +45,27 @@ int establish(unsigned short port) {
int allowReuse = ALLOW_REUSE; int allowReuse = ALLOW_REUSE;
int sock; int sock;
struct sockaddr_in sockAddr; struct sockaddr_in sockAddr;
struct hostent * he;
memset(&sockAddr, 0, sizeof(struct sockaddr_in)); memset(&sockAddr, 0, sizeof(struct sockaddr_in));
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(port); sockAddr.sin_port = htons(port);
sockAddr.sin_addr.s_addr = INADDR_ANY; if(strcmp((getConf())[CONF_BIND_TO_ADDRESS],"any")==0) {
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = INADDR_ANY;
}
else {
if(!(he = gethostbyname((getConf())[CONF_BIND_TO_ADDRESS]))) {
fprintf(stderr,"can't lookup host \"%s\"\n",
(getConf())[CONF_BIND_TO_ADDRESS]);
exit(-1);
}
sockAddr.sin_family = he->h_addrtype;
bcopy((char *)he->h_addr,(char *)&sockAddr.sin_addr.s_addr,
he->h_length);
}
if((sock = socket(AF_INET,SOCK_STREAM,0)) < 0) { if((sock = socket(sockAddr.sin_family,SOCK_STREAM,0)) < 0) {
fprintf(stderr,"socket < 0\n"); fprintf(stderr,"socket < 0\n");
return -1; return -1;
} }
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2002 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2002 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2002 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2002 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "buffer.h" #include "buffer.h"
#include "stats.h" #include "stats.h"
#include "sig_handlers.h" #include "sig_handlers.h"
#include "audio.h"
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
...@@ -98,10 +99,14 @@ int main(int argc, char * argv[]) { ...@@ -98,10 +99,14 @@ int main(int argc, char * argv[]) {
} }
else { else {
getcwd(playlistDir,MAXPATHLEN-strlen(playlistDirArg)-1); getcwd(playlistDir,MAXPATHLEN-strlen(playlistDirArg)-1);
strcat(playlistDir,"/"); if(playlistDir[strlen(playlistDir)-1]!='/') {
strcat(playlistDir,"/");
}
strcat(playlistDir,playlistDirArg); strcat(playlistDir,playlistDirArg);
} }
strcat(playlistDir,"/"); if(playlistDir[strlen(playlistDir)-1]!='/') {
strcat(playlistDir,"/");
}
if((stat(playlistDir,&st))<0) { if((stat(playlistDir,&st))<0) {
fprintf(stderr,"problem stat'ing \"%s\"\n",playlistDirArg); fprintf(stderr,"problem stat'ing \"%s\"\n",playlistDirArg);
return -1; return -1;
...@@ -116,10 +121,10 @@ int main(int argc, char * argv[]) { ...@@ -116,10 +121,10 @@ int main(int argc, char * argv[]) {
} }
else { else {
getcwd(musicDir,MAXPATHLEN-strlen(musicDirArg)-1); getcwd(musicDir,MAXPATHLEN-strlen(musicDirArg)-1);
strcat(musicDir,"/"); if(musicDir[strlen(musicDir)-1]!='/') strcat(musicDir,"/");
strcat(musicDir,musicDirArg); strcat(musicDir,musicDirArg);
} }
strcat(musicDir,"/"); if(musicDir[strlen(musicDir)-1]!='/') strcat(musicDir,"/");
if((stat(musicDir,&st))<0) { if((stat(musicDir,&st))<0) {
fprintf(stderr,"problem stat'ing \"%s\"\n",musicDirArg); fprintf(stderr,"problem stat'ing \"%s\"\n",musicDirArg);
return -1; return -1;
...@@ -142,6 +147,8 @@ int main(int argc, char * argv[]) { ...@@ -142,6 +147,8 @@ int main(int argc, char * argv[]) {
} }
} }
initAudioDriver();
initSigHandlers(); initSigHandlers();
initInterfaces(); initInterfaces();
...@@ -175,6 +182,7 @@ int main(int argc, char * argv[]) { ...@@ -175,6 +182,7 @@ int main(int argc, char * argv[]) {
closeMp3Directory(); closeMp3Directory();
closeTables(); closeTables();
freeBuffer(); freeBuffer();
finishAudioDriver();
return 0; return 0;
} }
...@@ -12,29 +12,18 @@ Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." ...@@ -12,29 +12,18 @@ Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
# process command line arguments # process command line arguments
while test $# -gt 0 ; do while test $# -gt 0 ; do
case $1 in case "${1}" in
-h | --help | --h*) # -h for help -h | --help | --h* ) # -h for help
echo "$usage" 1>&2 echo "${usage}" 1>&2; exit 0 ;;
exit 0 -m ) # -m PERM arg
;; shift
-m) # -m PERM arg test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; }
shift dirmode="${1}"
test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } shift ;;
dirmode=$1 -- ) shift; break ;; # stop option processing
shift -* ) echo "${usage}" 1>&2; exit 1 ;; # unknown option
;; * ) break ;; # first non-opt arg
--) # stop option processing esac
shift
break
;;
-*) # unknown option
echo "$usage" 1>&2
exit 1
;;
*) # first non-opt arg
break
;;
esac
done done
for file for file
...@@ -47,65 +36,64 @@ do ...@@ -47,65 +36,64 @@ do
done done
case $# in case $# in
0) exit 0 ;; 0) exit 0 ;;
esac esac
case $dirmode in case $dirmode in
'') '')
if mkdir -p -- . 2>/dev/null; then if mkdir -p -- . 2>/dev/null; then
echo "mkdir -p -- $*" echo "mkdir -p -- $*"
exec mkdir -p -- "$@" exec mkdir -p -- "$@"
fi fi ;;
;; *)
*) if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
if mkdir -m "$dirmode" -p -- . 2>/dev/null; then echo "mkdir -m $dirmode -p -- $*"
echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@"
exec mkdir -m "$dirmode" -p -- "$@" fi ;;
fi
;;
esac esac
for file for file
do do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift shift
pathcomp= pathcomp=
for d for d
do do
pathcomp="$pathcomp$d" pathcomp="$pathcomp$d"
case $pathcomp in case "$pathcomp" in
-*) pathcomp=./$pathcomp ;; -* ) pathcomp=./$pathcomp ;;
esac esac
if test ! -d "$pathcomp"; then if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp" echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$? mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then if test ! -d "$pathcomp"; then
errstatus=$lasterr errstatus=$lasterr
else else
if test ! -z "$dirmode"; then if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp" echo "chmod $dirmode $pathcomp"
lasterr=""
chmod "$dirmode" "$pathcomp" || lasterr=$? lasterr=""
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -z "$lasterr"; then
errstatus=$lasterr if test ! -z "$lasterr"; then
fi errstatus=$lasterr
fi fi
fi fi
fi fi
fi
pathcomp="$pathcomp/"
done pathcomp="$pathcomp/"
done
done done
exit $errstatus exit $errstatus
# Local Variables: # Local Variables:
# mode: shell-script # mode: shell-script
# sh-indentation: 2 # sh-indentation: 3
# End: # End:
# mkinstalldirs ends here # mkinstalldirs ends here
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <sys/time.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
...@@ -263,7 +264,7 @@ ao_device * initAoDeviceFromMp3DecodeData(mp3DecodeData * data) { ...@@ -263,7 +264,7 @@ ao_device * initAoDeviceFromMp3DecodeData(mp3DecodeData * data) {
format.byte_format = AO_FMT_LITTLE; format.byte_format = AO_FMT_LITTLE;
format.channels = MAD_NCHANNELS(&(data->frame).header); format.channels = MAD_NCHANNELS(&(data->frame).header);
device = ao_open_live(audio_ao_driver_id, &format, NULL); device = ao_open_live(audio_ao_driver_id, &format, audio_ao_options);
return device; return device;
} }
...@@ -370,8 +371,7 @@ int mp3_decode(char * file, FILE * in, FILE * out) { ...@@ -370,8 +371,7 @@ int mp3_decode(char * file, FILE * in, FILE * out) {
mp3_device = initAoDeviceFromMp3DecodeData(&data); mp3_device = initAoDeviceFromMp3DecodeData(&data);
if(mp3_device == NULL) { if(mp3_device == NULL) {
fprintf(stderr, "%s Error opening device.\n",PLAYER_ERROR); audioError();
fflush(stderr);
pid = mp3_decode_pid; pid = mp3_decode_pid;
if(pid>0) kill(pid,SIGTERM); if(pid>0) kill(pid,SIGTERM);
return PLAYER_EXIT_ERROR_AUDIO; return PLAYER_EXIT_ERROR_AUDIO;
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
...@@ -13,7 +13,7 @@ through the server's audio device. The daemon stores info about all available ...@@ -13,7 +13,7 @@ through the server's audio device. The daemon stores info about all available
music, and this info can be easily searched and retrieved. Player control, info music, and this info can be easily searched and retrieved. Player control, info
retrieval, and playlist management can all be managed remotely. retrieval, and playlist management can all be managed remotely.
Read more about MPD on http://musicpd.sourceforge.net Read more about MPD on http://www.musicpd.org
.SH PARAMETERS .SH PARAMETERS
Below are a list of paramters that can be specified in the config file. Each line in the config file should be of the form: Below are a list of paramters that can be specified in the config file. Each line in the config file should be of the form:
.br .br
...@@ -58,5 +58,24 @@ This specifies the maximum size a command list can be (in kilobytes). The defaul ...@@ -58,5 +58,24 @@ This specifies the maximum size a command list can be (in kilobytes). The defaul
.B max_output_buffer_size <size in kB> .B max_output_buffer_size <size in kB>
This specifies the maximum size of the output buffer to a client (in kilobytes). This specifies the maximum size of the output buffer to a client (in kilobytes).
The default is 2048 kilobytes. The default is 2048 kilobytes.
.TP
.B ao_driver <ao plugin>
This specifies the ao plugin to use for audio output. Typical values for
linux include "oss" and "alsa09". The default value is "default".
.TP
.B ao_driver_options <ao plugin options>
This specifies the options to use for the selected ao_driver. For oss, the
only option available is "dsp". For alsa09, the available options are:
"dev", "buf_size", and "periods". Options are assigned using "=" and ";" is
used to seperate options. An example for oss: "dsp=/dev/dsp". An example for
alsa09: "dev=hw:0,0;buf_size=4096". The default value is "".
.TP
.B save_absolute_paths_in_playlists <yes or no>
This specifies whether relative or absolute paths for song filenames are
used when saving playlists. The default value is "no".
.TP
.B bind_to_address <ip address or hostname or any>
This specifies which address mpd binds to and listens on. The default is "any",
which binds to all available addresses.
.SH FILES .SH FILES
A file is created in the playlist directory called ".mpddb". This file is used to store information about songs located in the music directory. A file is created in the playlist directory called ".mpddb". This file is used to store information about songs located in the music directory.
port "2100" # required
music_directory "/home/shank/mp3" port "2100"
playlist_directory "/home/shank/playlists" music_directory "/home/shank/mp3"
log_file "/home/shank/mpd.log" playlist_directory "/home/shank/playlists"
error_file "/home/shank/mpd.error" log_file "/home/shank/mpd.log"
connection_timeout "60" error_file "/home/shank/mpd.error"
mixer_device "/dev/mixer"
max_connections "5" # optional
max_playlist_length "4096" connection_timeout "60"
buffer_before_play "25%" mixer_device "/dev/mixer"
stop_on_error "yes" max_connections "5"
max_command_list_size "2048" max_playlist_length "4096"
max_output_buffer_size "2048" buffer_before_play "25%"
stop_on_error "yes"
max_command_list_size "2048"
max_output_buffer_size "2048"
ao_driver "oss"
ao_driver_options "dsp=/dev/dsp"
save_absolute_paths_in_playlists "no"
# when bind_to_address is set to "any", mpd binds all availabe addresses
bind_to_address "any"
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -173,10 +173,10 @@ int ogg_decode(char * file, FILE * in, FILE * out) { ...@@ -173,10 +173,10 @@ int ogg_decode(char * file, FILE * in, FILE * out) {
initAudio(); initAudio();
ogg_device = ao_open_live(audio_ao_driver_id,&format,NULL); ogg_device = ao_open_live(audio_ao_driver_id,&format,
audio_ao_options);
if(ogg_device == NULL) { if(ogg_device == NULL) {
fprintf(stderr, "%s Error opening device.\n",PLAYER_ERROR); audioError();
fflush(stderr);
pid = ogg_decode_pid; pid = ogg_decode_pid;
if(pid>0) kill(pid,SIGTERM); if(pid>0) kill(pid,SIGTERM);
return PLAYER_EXIT_ERROR_AUDIO; return PLAYER_EXIT_ERROR_AUDIO;
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -184,7 +184,10 @@ int playerPlay(FILE * fp, char * file) { ...@@ -184,7 +184,10 @@ int playerPlay(FILE * fp, char * file) {
if(fp==NULL) fp=stderr; if(fp==NULL) fp=stderr;
if(isMp3(file)) playerType = PLAYER_TYPE_MP3; if(0);
#ifdef HAVE_MAD
else if(isMp3(file)) playerType = PLAYER_TYPE_MP3;
#endif
#ifdef HAVE_OGG #ifdef HAVE_OGG
else if(isOgg(file)) playerType = PLAYER_TYPE_OGG; else if(isOgg(file)) playerType = PLAYER_TYPE_OGG;
#endif #endif
...@@ -192,8 +195,8 @@ int playerPlay(FILE * fp, char * file) { ...@@ -192,8 +195,8 @@ int playerPlay(FILE * fp, char * file) {
else if(isFlac(file)) playerType = PLAYER_TYPE_FLAC; else if(isFlac(file)) playerType = PLAYER_TYPE_FLAC;
#endif #endif
else { else {
myfprintf(fp,"%s \"%s\" is not a file or unknown file type\n",COMMAND_RESPOND_ERROR,file); snprintf(player_error,sizeof(player_error),"\"%s\" is not a file or unknown file type\n",file);
return -1; return 0;
} }
if(playerStop(fp)<0) return -1; if(playerStop(fp)<0) return -1;
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "directory.h" #include "directory.h"
#include "stats.h" #include "stats.h"
#include "myfprintf.h" #include "myfprintf.h"
#include "path.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -36,6 +37,8 @@ ...@@ -36,6 +37,8 @@
#define BITS_FOR_VERSION 31 #define BITS_FOR_VERSION 31
#define PLAYLIST_COMMENT '#'
#define PLAYLIST_STATE_STOP 0 #define PLAYLIST_STATE_STOP 0
#define PLAYLIST_STATE_PLAY 1 #define PLAYLIST_STATE_PLAY 1
#define PLAYLIST_PREV_UNLESS_ELAPSED 10 #define PLAYLIST_PREV_UNLESS_ELAPSED 10
...@@ -48,6 +51,8 @@ int playlist_state = PLAYLIST_STATE_STOP; ...@@ -48,6 +51,8 @@ int playlist_state = PLAYLIST_STATE_STOP;
int playlist_max_length; int playlist_max_length;
int playlist_stopOnError; int playlist_stopOnError;
int playlist_saveAbsolutePaths;
void incrPlaylistVersion() { void incrPlaylistVersion() {
static unsigned long max = ((unsigned long)1<<BITS_FOR_VERSION)-1; static unsigned long max = ((unsigned long)1<<BITS_FOR_VERSION)-1;
playlist.version++; playlist.version++;
...@@ -78,6 +83,19 @@ void initPlaylist() { ...@@ -78,6 +83,19 @@ void initPlaylist() {
exit(-1); exit(-1);
} }
if(strcmp("yes",(getConf())[CONF_SAVE_ABSOLUTE_PATHS_IN_PLAYLISTS])
==0) {
playlist_saveAbsolutePaths = 1;
}
else if(strcmp("no",(getConf())[CONF_SAVE_ABSOLUTE_PATHS_IN_PLAYLISTS])
==0) {
playlist_saveAbsolutePaths = 0;
}
else {
fprintf(stderr,"save_absolute_paths_in_playlist \"%s\" is not yes or no\n",(getConf())[CONF_SAVE_ABSOLUTE_PATHS_IN_PLAYLISTS]);
exit(-1);
}
playlist.songs = malloc(sizeof(Song *)*playlist_max_length); playlist.songs = malloc(sizeof(Song *)*playlist_max_length);
memset(playlist.songs,(int)NULL,sizeof(char *)*playlist_max_length); memset(playlist.songs,(int)NULL,sizeof(char *)*playlist_max_length);
...@@ -88,7 +106,7 @@ int clearPlaylist(FILE * fp) { ...@@ -88,7 +106,7 @@ int clearPlaylist(FILE * fp) {
if(stopPlaylist(fp)<0) return -1; if(stopPlaylist(fp)<0) return -1;
for(i=0;i<playlist.length;i++) freeSong(playlist.songs[i]); for(i=0;i<playlist.length;i++) playlist.songs[i] = NULL;
playlist.length = 0; playlist.length = 0;
incrPlaylistVersion(); incrPlaylistVersion();
...@@ -108,7 +126,7 @@ int addToPlaylist(FILE * fp, char * file) { ...@@ -108,7 +126,7 @@ int addToPlaylist(FILE * fp, char * file) {
return -1; return -1;
} }
playlist.songs[playlist.length] = songDup(song); playlist.songs[playlist.length] = song;
playlist.length++; playlist.length++;
incrPlaylistVersion(); incrPlaylistVersion();
...@@ -170,10 +188,10 @@ int deleteFromPlaylist(FILE * fp, int song) { ...@@ -170,10 +188,10 @@ int deleteFromPlaylist(FILE * fp, int song) {
return -1; return -1;
} }
freeSong(playlist.songs[song]); for(i=song;i<playlist.length-1;i++) {
playlist.songs[song] = NULL; playlist.songs[i] = playlist.songs[i+1];
}
for(i=song;i<playlist.length-1;i++) swapSongs(i,i+1); playlist.songs[playlist.length-1] = NULL;
playlist.length--; playlist.length--;
incrPlaylistVersion(); incrPlaylistVersion();
...@@ -189,6 +207,27 @@ int deleteFromPlaylist(FILE * fp, int song) { ...@@ -189,6 +207,27 @@ int deleteFromPlaylist(FILE * fp, int song) {
return 0; return 0;
} }
void deleteASongFromPlaylist(Song * song) {
int i;
for(i=0;i<playlist.length;i++) {
if(song==playlist.songs[i]) {
deleteFromPlaylist(stderr,i);
}
}
}
void deleteSongsFromPlaylist(SongList * songList) {
ListNode * node = songList->firstNode;
Song * song;
while(node) {
song = (Song *)node->data;
deleteASongFromPlaylist(song);
node = node->nextNode;
}
}
int stopPlaylist(FILE * fp) { int stopPlaylist(FILE * fp) {
if(playerStop(fp)<0) return -1; if(playerStop(fp)<0) return -1;
playlist_state = PLAYLIST_STATE_STOP; playlist_state = PLAYLIST_STATE_STOP;
...@@ -345,7 +384,13 @@ int savePlaylist(FILE * fp, char * file) { ...@@ -345,7 +384,13 @@ int savePlaylist(FILE * fp, char * file) {
} }
for(i=0;i<playlist.length;i++) { for(i=0;i<playlist.length;i++) {
fprintf(fileP,"%s\n",(playlist.songs[i])->file); if(playlist_saveAbsolutePaths) {
fprintf(fileP,"%s%s\n",musicDir,
(playlist.songs[i])->file);
}
else {
fprintf(fileP,"%s\n",(playlist.songs[i])->file);
}
} }
fclose(fileP); fclose(fileP);
...@@ -364,10 +409,16 @@ int loadPlaylist(FILE * fp, char * file) { ...@@ -364,10 +409,16 @@ int loadPlaylist(FILE * fp, char * file) {
} }
while((s[slength] = fgetc(fileP))!=EOF) { while((s[slength] = fgetc(fileP))!=EOF) {
if(s[slength]=='\n') { if(s[slength]=='\n' || s[slength]=='\0') {
s[slength] = '\0'; s[slength] = '\0';
if((addToPlaylist(fp,s))<0) return -1; if(strncmp(s,musicDir,strlen(musicDir))==0) {
strcpy(s,&(s[strlen(musicDir)]));
}
slength = 0; slength = 0;
if(s[0]==PLAYLIST_COMMENT && !getSong(s)) continue;
if((addToPlaylist(fp,s))<0) {
return -1;
}
} }
else if(slength==MAXPATHLEN) { else if(slength==MAXPATHLEN) {
s[slength] = '\0'; s[slength] = '\0';
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -63,6 +63,10 @@ int savePlaylist(FILE * fp, char * file); ...@@ -63,6 +63,10 @@ int savePlaylist(FILE * fp, char * file);
int deletePlaylist(FILE * fp, char * file); int deletePlaylist(FILE * fp, char * file);
void deleteASongFromPlaylist(Song * song);
void deleteSongsFromPlaylist(SongList * songList);
int loadPlaylist(FILE * fp, char * file); int loadPlaylist(FILE * fp, char * file);
int getPlaylistRepeatStatus(); int getPlaylistRepeatStatus();
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -34,9 +34,28 @@ List * albumTable; ...@@ -34,9 +34,28 @@ List * albumTable;
List * artistTable; List * artistTable;
List * songTable; List * songTable;
typedef struct _ArtistData {
SongList * songs;
SongList * albums;
} ArtistData;
ArtistData * newArtistData() {
ArtistData * ad = malloc(sizeof(ArtistData));
ad->songs = makeList(NULL);
ad->albums = makeList(freeList);
return ad;
}
void freeArtistData(ArtistData * ad) {
freeList(ad->songs);
freeList(ad->albums);
}
void initTables() { void initTables() {
albumTable = makeList(freeList); albumTable = makeList(freeList);
artistTable = makeList(freeList); artistTable = makeList((ListFreeDataFunc *)freeArtistData);
songTable = makeList(NULL); songTable = makeList(NULL);
} }
...@@ -46,32 +65,35 @@ void closeTables() { ...@@ -46,32 +65,35 @@ void closeTables() {
freeList(songTable); freeList(songTable);
} }
void addSongToAlbumTable(Song * song) { void addSongToSomeAlbumTable(List * table, Song * song) {
void * album; void * album;
if(!song->tag) return; if(!song->tag) return;
if(!song->tag->title) return; if(!song->tag->title || !strlen(song->tag->title)) return;
if(findInList(albumTable,song->tag->album,&album)) { if(findInList(table,song->tag->album,&album)) {
insertInList((SongList *)album,song->file,song); insertInList((SongList *)album,song->file,song);
} }
else { else {
album = makeList(NULL); album = makeList(NULL);
insertInList(albumTable,song->tag->album,album); insertInList(table,song->tag->album,album);
insertInList(album,song->file,song); insertInList(album,song->file,song);
} }
} }
void addSongToAlbumTable(Song * song) {
addSongToSomeAlbumTable(albumTable,song);
}
void addSongToArtistTable(Song * song) { void addSongToArtistTable(Song * song) {
void * artist; void * artist;
if(!song->tag) return; if(!song->tag) return;
if(!song->tag->artist) return; if(!song->tag->artist || !strlen(song->tag->artist)) return;
if(findInList(artistTable,song->tag->artist,&artist)) { if(!findInList(artistTable,song->tag->artist,&artist)) {
insertInList((SongList *)artist,song->file,song); artist = newArtistData();
}
else {
artist = makeList(NULL);
insertInList(artistTable,song->tag->artist,artist); insertInList(artistTable,song->tag->artist,artist);
insertInList(artist,song->file,song);
} }
insertInList(((ArtistData *)artist)->songs,song->file,song);
addSongToSomeAlbumTable(((ArtistData *)artist)->albums,
song);
} }
void addSongToSongTable(Song * song) { void addSongToSongTable(Song * song) {
...@@ -101,7 +123,7 @@ int findAndPrintSongsInArtistTable(FILE * fp,char * find) { ...@@ -101,7 +123,7 @@ int findAndPrintSongsInArtistTable(FILE * fp,char * find) {
return -1; return -1;
} }
return printSongInfoFromList(fp,(SongList *)artist); return printSongInfoFromList(fp,((ArtistData *)artist)->songs);
} }
int findAndPrintSongsInTable(FILE * fp, char * table, char * find) { int findAndPrintSongsInTable(FILE * fp, char * table, char * find) {
...@@ -142,7 +164,7 @@ int searchForSongsInAlbumTable(FILE * fp,char * search) { ...@@ -142,7 +164,7 @@ int searchForSongsInAlbumTable(FILE * fp,char * search) {
} }
int searchForSongsInArtistTable(FILE * fp,char * search) { int searchForSongsInArtistTable(FILE * fp,char * search) {
SongList * artist; ArtistData * artist;
ListNode * node = artistTable->firstNode; ListNode * node = artistTable->firstNode;
char * dup; char * dup;
char * dupSearch = strDupToUpper(search); char * dupSearch = strDupToUpper(search);
...@@ -150,8 +172,8 @@ int searchForSongsInArtistTable(FILE * fp,char * search) { ...@@ -150,8 +172,8 @@ int searchForSongsInArtistTable(FILE * fp,char * search) {
while(node) { while(node) {
dup = strDupToUpper(node->key); dup = strDupToUpper(node->key);
if(strstr(dup,dupSearch)) { if(strstr(dup,dupSearch)) {
artist = (SongList *)node->data; artist = (ArtistData *)node->data;
if(printSongInfoFromList(fp,artist)<0) { if(printSongInfoFromList(fp,artist->songs)<0) {
free(dup); free(dup);
free(dupSearch); free(dupSearch);
return -1; return -1;
...@@ -174,17 +196,17 @@ int searchForSongsInSongTableByTitle(FILE * fp,char * search) { ...@@ -174,17 +196,17 @@ int searchForSongsInSongTableByTitle(FILE * fp,char * search) {
while(node) { while(node) {
song = (Song *)node->data; song = (Song *)node->data;
if(!song->tag) break; if(song->tag && song->tag->title && strlen(song->tag->title)) {
if(!song->tag->title) break; dup = strDupToUpper(song->tag->title);
dup = strDupToUpper(song->tag->title); if(strstr(dup,dupSearch)) {
if(strstr(dup,dupSearch)) { if(printSongInfo(fp,song)<0) {
if(printSongInfo(fp,song)<0) { free(dup);
free(dup); free(dupSearch);
free(dupSearch); return -1;
return -1; }
} }
free(dup);
} }
free(dup);
node = node->nextNode; node = node->nextNode;
} }
...@@ -236,27 +258,33 @@ int searchForSongsInTable(FILE * fp, char * table, char * search) { ...@@ -236,27 +258,33 @@ int searchForSongsInTable(FILE * fp, char * table, char * search) {
return -1; return -1;
} }
void removeSongFromAlbumTable(Song * song) { void removeSongFromSomeAlbumTable(List * table, Song * song) {
void * album; void * album;
if(!song->tag) return; if(!song->tag) return;
if(!song->tag->album) return; if(!song->tag->album || !strlen(song->tag->album)) return;
if(findInList(albumTable,song->tag->album,&album)) { if(findInList(table,song->tag->album,&album)) {
deleteFromList((SongList *)album,song->file); deleteFromList((SongList *)album,song->file);
if(((SongList *)album)->numberOfNodes==0) { if(((SongList *)album)->numberOfNodes==0) {
deleteFromList(albumTable,song->tag->album); deleteFromList(table,song->tag->album);
} }
} }
} }
void removeSongFromAlbumTable(Song * song) {
removeSongFromSomeAlbumTable(albumTable,song);
}
void removeSongFromArtistTable(Song * song) { void removeSongFromArtistTable(Song * song) {
void * artist; void * artist;
if(!song->tag) return; if(!song->tag) return;
if(!song->tag->artist) return; if(!song->tag->artist || !strlen(song->tag->artist)) return;
if(findInList(artistTable,song->tag->artist,&artist)) { if(findInList(artistTable,song->tag->artist,&artist)) {
deleteFromList((SongList *)artist,song->file); deleteFromList(((ArtistData *)artist)->songs,song->file);
if(((SongList *)artist)->numberOfNodes==0) { removeSongFromSomeAlbumTable(((ArtistData *)artist)->albums,
song);
if(((ArtistData *)artist)->songs->numberOfNodes==0) {
deleteFromList(artistTable,song->tag->artist); deleteFromList(artistTable,song->tag->artist);
} }
} }
...@@ -315,3 +343,60 @@ Song * getSongFromSongTable(char * file) { ...@@ -315,3 +343,60 @@ Song * getSongFromSongTable(char * file) {
return song; return song;
} }
int printAllArtists(FILE * fp) {
ListNode * node = artistTable->firstNode;
while(node) {
myfprintf(fp,"Artist: %s\n",node->key);
node = node->nextNode;
}
return 0;
}
int printAllAlbums(FILE * fp, char * artist) {
if(artist==NULL) {
ListNode * node = albumTable->firstNode;
while(node) {
myfprintf(fp,"Album: %s\n",node->key);
node = node->nextNode;
}
}
else {
void * ad;
if(findInList(artistTable,artist,&ad)) {
ListNode * node = ((ArtistData *)ad)->albums->firstNode;
while(node) {
myfprintf(fp,"Album: %s\n",node->key);
node = node->nextNode;
}
}
else {
myfprintf(fp,"%s artist \"%s\" not found\n",
COMMAND_RESPOND_ERROR,artist);
return -1;
}
}
return 0;
}
int printAllKeysOfTable(FILE * fp, char * table, char * arg1) {
if(strcmp(table,TABLES_ARTIST)==0) {
if(arg1!=NULL) {
myfprintf(fp,"%s %s table takes no args\n",COMMAND_RESPOND_ERROR);
return -1;
}
return printAllArtists(fp);
}
else if(strcmp(table,TABLES_ALBUM)==0) {
return printAllAlbums(fp,arg1);
}
else {
myfprintf(fp,"%s table \"%s\" does not exist or not available for listing\n");
return -1;
}
}
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -46,4 +46,6 @@ unsigned long numberOfAlbums(); ...@@ -46,4 +46,6 @@ unsigned long numberOfAlbums();
Song * getSongFromSongTable(char * file); Song * getSongFromSongTable(char * file);
int printAllKeysOfTable(FILE * fp, char * table, char * arg1);
#endif #endif
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD) /* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net * This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
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