Commit 53f5a137 authored by Led's avatar Led

0.8.3

parent d94eaf58
......@@ -44,6 +44,13 @@ find <string type> <string what>
kill
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>
lists all songs and directories in _directory_ (recursively)
_directory_ is optional
......@@ -89,6 +96,7 @@ repeat <int state>
search <string type> <string what>
same as "find" but searches for any song that contain _what_
search is not case sensitive
shuffle
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)
1) Increased the connection que for listen() from 0 to 5
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.
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
-------
......@@ -90,6 +90,6 @@ Using MPD
---------
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).
bin_PROGRAMS = mpd
SUBDIRS = $(ID3_SUBDIR) $(MAD_SUBDIR)
man_MANS = mpd.1
pkgdata_DATA = mpdconf.example README INSTALL
EXTRA_DIST = COMMANDS UPGRADING $(pkgdata_DATA) $(man_MANS)
pkgdata_DATA =
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 \
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 \
......
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
through the server's audio device. The daemon stores info about all available
......
/* 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 project's homepage is: http://www.musicpd.org
*
* 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
......@@ -17,14 +17,106 @@
*/
#include "audio.h"
#include "conf.h"
#include <string.h>
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() {
ao_initialize();
audio_ao_driver_id = ao_default_driver_id();
}
void finishAudio() {
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)
* (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
* it under the terms of the GNU General Public License as published by
......@@ -19,13 +19,22 @@
#ifndef AUDIO_H
#define AUDIO_H
#define AUDIO_AO_DRIVER_DEFAULT "default"
#include <stdio.h>
#include <ao/ao.h>
extern int audio_ao_driver_id;
extern ao_option * audio_ao_options;
void initAudioDriver();
void finishAudioDriver();
void initAudio();
void finishAudio();
void audioError();
#endif
/* 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 project's homepage is: http://www.musicpd.org
*
* 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 Music Player Daemon (MPD)
* (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
* it under the terms of the GNU General Public License as published by
......
/* 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 project's homepage is: http://www.musicpd.org
*
* 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
......@@ -33,7 +33,7 @@ int buffer2array(char * origBuffer, char *** array) {
char * markArray = malloc(sizeof(char)*(bufferLength+1));
for(curr=0;curr<bufferLength;curr++) {
if(!quotes && buffer[curr]==' ') {
if(!quotes && (buffer[curr]==' ' || buffer[curr]=='\t') ) {
markArray[curr] = '0';
}
else if(buffer[curr] == '\"') {
......
/* 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 project's homepage is: http://www.musicpd.org
*
* 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 Music Player Daemon (MPD)
* (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
* it under the terms of the GNU General Public License as published by
......@@ -58,6 +58,7 @@
#define COMMAND_REPEAT "repeat"
#define COMMAND_STATS "stats"
#define COMMAND_CLEAR_ERROR "clearerror"
#define COMMAND_LIST "list"
#define COMMAND_STATUS_VOLUME "volume"
#define COMMAND_STATUS_STATE "state"
......@@ -358,7 +359,16 @@ int processCommand(FILE * fp, int argArrayLength, char ** argArray) {
return -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)) {
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 project's homepage is: http://www.musicpd.org
*
* 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 Music Player Daemon (MPD)
* (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
* it under the terms of the GNU General Public License as published by
......@@ -20,6 +20,7 @@
#include "utils.h"
#include "buffer2array.h"
#include "audio.h"
#include <sys/param.h>
#include <stdio.h>
......@@ -28,20 +29,26 @@
#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_REQUIRED 5
#define CONF_CONNECTION_TIMEOUT_DEFAULT "60"
#define CONF_MIXER_DEVICE_DEFAULT "/dev/mixer"
#define CONF_MAX_CONNECTIONS_DEFAULT "5"
#define CONF_MAX_PLAYLIST_LENGTH_DEFAULT "4096"
#define CONF_BUFFER_BEFORE_PLAY_DEFAULT "25%"
#define CONF_STOP_ON_ERROR_DEFAULT "yes"
#define CONF_MAX_COMMAND_LIST_SIZE_DEFAULT "2048"
#define CONF_MAX_OUTPUT_BUFFER_SIZE_DEFAULT "2048"
char conf_strings[CONF_NUMBER_OF_PARAMS][24] = {
#define CONF_CONNECTION_TIMEOUT_DEFAULT "60"
#define CONF_MIXER_DEVICE_DEFAULT "/dev/mixer"
#define CONF_MAX_CONNECTIONS_DEFAULT "5"
#define CONF_MAX_PLAYLIST_LENGTH_DEFAULT "4096"
#define CONF_BUFFER_BEFORE_PLAY_DEFAULT "25%"
#define CONF_STOP_ON_ERROR_DEFAULT "yes"
#define CONF_MAX_COMMAND_LIST_SIZE_DEFAULT "2048"
#define CONF_MAX_OUTPUT_BUFFER_SIZE_DEFAULT "2048"
#define CONF_AO_DRIVER_DEFAULT AUDIO_AO_DRIVER_DEFAULT
#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",
"music_directory",
"playlist_directory",
......@@ -54,7 +61,11 @@ char conf_strings[CONF_NUMBER_OF_PARAMS][24] = {
"buffer_before_play",
"stop_on_error",
"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] = {
......@@ -88,6 +99,10 @@ void initConf() {
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_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) {
......@@ -95,6 +110,7 @@ char ** readConf(char * file) {
char string[MAX_STRING_SIZE+1];
char ** array;
int i;
int numberOfArgs;
if(!(fp=fopen(file,"r"))) {
fprintf(stderr,"problems opening file %s for reading\n",file);
......@@ -102,7 +118,10 @@ char ** readConf(char * file) {
}
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);
exit(-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 project's homepage is: http://www.musicpd.org
*
* 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
......@@ -19,19 +19,23 @@
#ifndef CONF_H
#define CONF_H
#define CONF_PORT 0
#define CONF_MUSIC_DIRECTORY 1
#define CONF_PLAYLIST_DIRECTORY 2
#define CONF_LOG_FILE 3
#define CONF_ERROR_FILE 4
#define CONF_CONNECTION_TIMEOUT 5
#define CONF_MIXER_DEVICE 6
#define CONF_MAX_CONNECTIONS 7
#define CONF_MAX_PLAYLIST_LENGTH 8
#define CONF_BUFFER_BEFORE_PLAY 9
#define CONF_STOP_ON_ERROR 10
#define CONF_MAX_COMMAND_LIST_SIZE 11
#define CONF_MAX_OUTPUT_BUFFER_SIZE 12
#define CONF_PORT 0
#define CONF_MUSIC_DIRECTORY 1
#define CONF_PLAYLIST_DIRECTORY 2
#define CONF_LOG_FILE 3
#define CONF_ERROR_FILE 4
#define CONF_CONNECTION_TIMEOUT 5
#define CONF_MIXER_DEVICE 6
#define CONF_MAX_CONNECTIONS 7
#define CONF_MAX_PLAYLIST_LENGTH 8
#define CONF_BUFFER_BEFORE_PLAY 9
#define CONF_STOP_ON_ERROR 10
#define CONF_MAX_COMMAND_LIST_SIZE 11
#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 */
char ** readConf(char * file);
......
AC_INIT(main.c)
AM_INIT_AUTOMAKE(mpd, 0.8.2)
AM_INIT_AUTOMAKE(mpd, 0.8.3)
AC_PROG_CC
AC_PROG_INSTALL
......
/* 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 project's homepage is: http://www.musicpd.org
*
* 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
......@@ -24,6 +24,7 @@
#include "utils.h"
#include "path.h"
#include "myfprintf.h"
#include "playlist.h"
#include <string.h>
#include <sys/types.h>
......@@ -84,6 +85,7 @@ Directory * newDirectory(Directory * parentDirectory, char * dirname) {
void freeDirectory(Directory * directory) {
freeDirectoryList(directory->subDirectories);
removeSongsFromTables(directory->songs);
deleteSongsFromPlaylist(directory->songs);
freeSongList(directory->songs);
if(directory->name) free(directory->name);
free(directory);
......@@ -102,6 +104,7 @@ void removeSongFromDirectory(Directory * directory, char * shortname) {
if(findInList(directory->songs,shortname,&song)) {
removeASongFromTables((Song *)song);
deleteASongFromPlaylist((Song *)song);
deleteFromList(directory->songs,shortname);
}
}
......
/* 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 project's homepage is: http://www.musicpd.org
*
* 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 Music Player Daemon (MPD)
* (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
* 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) {
tv.tv_usec = 0;
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) {
fprintf(stderr, "%s Error opening device.\n",PLAYER_ERROR);
fflush(stderr);
audioError();
pid = flac_decode_pid;
if(pid>0) kill(pid,SIGTERM);
return PLAYER_EXIT_ERROR_AUDIO;
......
/* 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 project's homepage is: http://www.musicpd.org
*
* 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
......
#!/bin/sh
#
# 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
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# 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
# `make' implicit rules from creating a file called install from it
......@@ -56,7 +74,7 @@ dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd=$cpprog
-c) instcmd="$cpprog"
shift
continue;;
......@@ -79,7 +97,7 @@ while [ x"$1" != x ]; do
shift
continue;;
-s) stripcmd=$stripprog
-s) stripcmd="$stripprog"
shift
continue;;
......@@ -106,7 +124,7 @@ done
if [ x"$src" = x ]
then
echo "$0: no input file specified" >&2
echo "install: no input file specified"
exit 1
else
:
......@@ -115,8 +133,8 @@ fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d "$dst" ]; then
if [ -d $dst ]; then
instcmd=:
chmodcmd=""
else
......@@ -125,20 +143,20 @@ if [ x"$dir_arg" != x ]; then
else
# 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 [ -f "$src" ] || [ -d "$src" ]
then
:
else
echo "$0: $src does not exist" >&2
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "$0: no destination specified" >&2
echo "install: no destination specified"
exit 1
else
:
......@@ -147,16 +165,16 @@ else
# 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
if [ -d "$dst" ]
if [ -d $dst ]
then
dst=$dst/`basename "$src"`
dst="$dst"/`basename $src`
else
:
fi
fi
## 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.
# this part is taken from Noah Friedman's mkinstalldirs script
......@@ -165,73 +183,69 @@ dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-$defaultIFS}"
IFS="${IFS-${defaultIFS}}"
oIFS=$IFS
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS=$oIFS
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp=$pathcomp$1
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "$pathcomp" ] ;
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "$pathcomp"
$mkdirprog "${pathcomp}"
else
:
fi
pathcomp=$pathcomp/
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd "$dst" &&
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd "$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"$chmodcmd" != x ]; then $doit $chmodcmd "$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"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
if [ x"$transformarg" = x ]
then
dstfile=`basename "$dst"`
dstfile=`basename $dst`
else
dstfile=`basename "$dst" $transformbasename |
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
if [ x"$dstfile" = x ]
then
dstfile=`basename "$dst"`
dstfile=`basename $dst`
else
:
fi
# Make a couple of temp file names in the proper directory.
# Make a temp file name in the proper directory.
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
$doit $instcmd "$src" "$dsttmp" &&
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
......@@ -239,38 +253,17 @@ else
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd "$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"$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
} &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $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"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit
}
exit 0
/* 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 project's homepage is: http://www.musicpd.org
*
* 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
......@@ -147,13 +147,17 @@ int interfaceReadInput(Interface * interface) {
argArrayLength = buffer2array((char *)node->data,&argArray);
ret = processCommand(interface->fp,argArrayLength,argArray);
freeArgArray(argArray,argArrayLength);
if(ret!=0) break;
if(ret!=0 ||
interface->expired) {
break;
}
node = node->nextNode;
}
if(ret==0) {
myfprintf(interface->fp,"%s\n",COMMAND_RESPOND_OK);
}
else if(ret==COMMAND_RETURN_CLOSE) {
else if(ret==COMMAND_RETURN_CLOSE ||
interface->expired) {
closeInterface(interface);
}
......@@ -189,7 +193,8 @@ int interfaceReadInput(Interface * interface) {
if(ret==0) {
myfprintf(interface->fp,"%s\n",COMMAND_RESPOND_OK);
}
else if(ret==COMMAND_RETURN_CLOSE) {
else if(ret==COMMAND_RETURN_CLOSE ||
interface->expired) {
closeInterface(interface);
}
}
......
/* 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 project's homepage is: http://www.musicpd.org
*
* 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 Music Player Daemon (MPD)
* (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
* it under the terms of the GNU General Public License as published by
......
/* 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 project's homepage is: http://www.musicpd.org
*
* 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 Music Player Daemon (MPD)
* (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
* it under the terms of the GNU General Public License as published by
......@@ -18,6 +18,7 @@
#include "listen.h"
#include "interface.h"
#include "conf.h"
#include <unistd.h>
#include <stdio.h>
......@@ -44,14 +45,27 @@ int establish(unsigned short port) {
int allowReuse = ALLOW_REUSE;
int sock;
struct sockaddr_in sockAddr;
struct hostent * he;
memset(&sockAddr, 0, sizeof(struct sockaddr_in));
sockAddr.sin_family = AF_INET;
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");
return -1;
}
......
/* the Music Player Daemon (MPD)
* (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
* it under the terms of the GNU General Public License as published by
......
/* 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 project's homepage is: http://www.musicpd.org
*
* 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 Music Player Daemon (MPD)
* (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
* it under the terms of the GNU General Public License as published by
......
/* the Music Player Daemon (MPD)
* (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
* it under the terms of the GNU General Public License as published by
......@@ -28,6 +28,7 @@
#include "buffer.h"
#include "stats.h"
#include "sig_handlers.h"
#include "audio.h"
#include <unistd.h>
#include <stdio.h>
......@@ -98,10 +99,14 @@ int main(int argc, char * argv[]) {
}
else {
getcwd(playlistDir,MAXPATHLEN-strlen(playlistDirArg)-1);
strcat(playlistDir,"/");
if(playlistDir[strlen(playlistDir)-1]!='/') {
strcat(playlistDir,"/");
}
strcat(playlistDir,playlistDirArg);
}
strcat(playlistDir,"/");
if(playlistDir[strlen(playlistDir)-1]!='/') {
strcat(playlistDir,"/");
}
if((stat(playlistDir,&st))<0) {
fprintf(stderr,"problem stat'ing \"%s\"\n",playlistDirArg);
return -1;
......@@ -116,10 +121,10 @@ int main(int argc, char * argv[]) {
}
else {
getcwd(musicDir,MAXPATHLEN-strlen(musicDirArg)-1);
strcat(musicDir,"/");
if(musicDir[strlen(musicDir)-1]!='/') strcat(musicDir,"/");
strcat(musicDir,musicDirArg);
}
strcat(musicDir,"/");
if(musicDir[strlen(musicDir)-1]!='/') strcat(musicDir,"/");
if((stat(musicDir,&st))<0) {
fprintf(stderr,"problem stat'ing \"%s\"\n",musicDirArg);
return -1;
......@@ -142,6 +147,8 @@ int main(int argc, char * argv[]) {
}
}
initAudioDriver();
initSigHandlers();
initInterfaces();
......@@ -175,6 +182,7 @@ int main(int argc, char * argv[]) {
closeMp3Directory();
closeTables();
freeBuffer();
finishAudioDriver();
return 0;
}
......@@ -12,29 +12,18 @@ Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
# process command line arguments
while test $# -gt 0 ; do
case $1 in
-h | --help | --h*) # -h for help
echo "$usage" 1>&2
exit 0
;;
-m) # -m PERM arg
shift
test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
dirmode=$1
shift
;;
--) # stop option processing
shift
break
;;
-*) # unknown option
echo "$usage" 1>&2
exit 1
;;
*) # first non-opt arg
break
;;
esac
case "${1}" in
-h | --help | --h* ) # -h for help
echo "${usage}" 1>&2; exit 0 ;;
-m ) # -m PERM arg
shift
test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; }
dirmode="${1}"
shift ;;
-- ) shift; break ;; # stop option processing
-* ) echo "${usage}" 1>&2; exit 1 ;; # unknown option
* ) break ;; # first non-opt arg
esac
done
for file
......@@ -47,65 +36,64 @@ do
done
case $# in
0) exit 0 ;;
0) exit 0 ;;
esac
case $dirmode in
'')
if mkdir -p -- . 2>/dev/null; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
fi
;;
*)
if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
fi
;;
'')
if mkdir -p -- . 2>/dev/null; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
fi ;;
*)
if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
fi ;;
esac
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case $pathcomp in
-*) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr=""
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -z "$lasterr"; then
errstatus=$lasterr
fi
fi
fi
fi
pathcomp="$pathcomp/"
done
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr=""
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -z "$lasterr"; then
errstatus=$lasterr
fi
fi
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# sh-indentation: 3
# End:
# mkinstalldirs ends here
/* 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 project's homepage is: http://www.musicpd.org
*
* 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
......@@ -34,6 +34,7 @@
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
......@@ -263,7 +264,7 @@ ao_device * initAoDeviceFromMp3DecodeData(mp3DecodeData * data) {
format.byte_format = AO_FMT_LITTLE;
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;
}
......@@ -370,8 +371,7 @@ int mp3_decode(char * file, FILE * in, FILE * out) {
mp3_device = initAoDeviceFromMp3DecodeData(&data);
if(mp3_device == NULL) {
fprintf(stderr, "%s Error opening device.\n",PLAYER_ERROR);
fflush(stderr);
audioError();
pid = mp3_decode_pid;
if(pid>0) kill(pid,SIGTERM);
return PLAYER_EXIT_ERROR_AUDIO;
......
/* 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 project's homepage is: http://www.musicpd.org
*
* 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
......
......@@ -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
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
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
......@@ -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>
This specifies the maximum size of the output buffer to a client (in 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
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"
music_directory "/home/shank/mp3"
playlist_directory "/home/shank/playlists"
log_file "/home/shank/mpd.log"
error_file "/home/shank/mpd.error"
connection_timeout "60"
mixer_device "/dev/mixer"
max_connections "5"
max_playlist_length "4096"
buffer_before_play "25%"
stop_on_error "yes"
max_command_list_size "2048"
max_output_buffer_size "2048"
# required
port "2100"
music_directory "/home/shank/mp3"
playlist_directory "/home/shank/playlists"
log_file "/home/shank/mpd.log"
error_file "/home/shank/mpd.error"
# optional
connection_timeout "60"
mixer_device "/dev/mixer"
max_connections "5"
max_playlist_length "4096"
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)
* (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
* 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) {
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) {
fprintf(stderr, "%s Error opening device.\n",PLAYER_ERROR);
fflush(stderr);
audioError();
pid = ogg_decode_pid;
if(pid>0) kill(pid,SIGTERM);
return PLAYER_EXIT_ERROR_AUDIO;
......
/* 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 project's homepage is: http://www.musicpd.org
*
* 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 Music Player Daemon (MPD)
* (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
* it under the terms of the GNU General Public License as published by
......
/* 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 project's homepage is: http://www.musicpd.org
*
* 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 Music Player Daemon (MPD)
* (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
* it under the terms of the GNU General Public License as published by
......@@ -184,7 +184,10 @@ int playerPlay(FILE * fp, char * file) {
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
else if(isOgg(file)) playerType = PLAYER_TYPE_OGG;
#endif
......@@ -192,8 +195,8 @@ int playerPlay(FILE * fp, char * file) {
else if(isFlac(file)) playerType = PLAYER_TYPE_FLAC;
#endif
else {
myfprintf(fp,"%s \"%s\" is not a file or unknown file type\n",COMMAND_RESPOND_ERROR,file);
return -1;
snprintf(player_error,sizeof(player_error),"\"%s\" is not a file or unknown file type\n",file);
return 0;
}
if(playerStop(fp)<0) return -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 project's homepage is: http://www.musicpd.org
*
* 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 Music Player Daemon (MPD)
* (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
* it under the terms of the GNU General Public License as published by
......@@ -25,6 +25,7 @@
#include "directory.h"
#include "stats.h"
#include "myfprintf.h"
#include "path.h"
#include <string.h>
#include <stdlib.h>
......@@ -36,6 +37,8 @@
#define BITS_FOR_VERSION 31
#define PLAYLIST_COMMENT '#'
#define PLAYLIST_STATE_STOP 0
#define PLAYLIST_STATE_PLAY 1
#define PLAYLIST_PREV_UNLESS_ELAPSED 10
......@@ -48,6 +51,8 @@ int playlist_state = PLAYLIST_STATE_STOP;
int playlist_max_length;
int playlist_stopOnError;
int playlist_saveAbsolutePaths;
void incrPlaylistVersion() {
static unsigned long max = ((unsigned long)1<<BITS_FOR_VERSION)-1;
playlist.version++;
......@@ -78,6 +83,19 @@ void initPlaylist() {
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);
memset(playlist.songs,(int)NULL,sizeof(char *)*playlist_max_length);
......@@ -88,7 +106,7 @@ int clearPlaylist(FILE * fp) {
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;
incrPlaylistVersion();
......@@ -108,7 +126,7 @@ int addToPlaylist(FILE * fp, char * file) {
return -1;
}
playlist.songs[playlist.length] = songDup(song);
playlist.songs[playlist.length] = song;
playlist.length++;
incrPlaylistVersion();
......@@ -170,10 +188,10 @@ int deleteFromPlaylist(FILE * fp, int song) {
return -1;
}
freeSong(playlist.songs[song]);
playlist.songs[song] = NULL;
for(i=song;i<playlist.length-1;i++) swapSongs(i,i+1);
for(i=song;i<playlist.length-1;i++) {
playlist.songs[i] = playlist.songs[i+1];
}
playlist.songs[playlist.length-1] = NULL;
playlist.length--;
incrPlaylistVersion();
......@@ -189,6 +207,27 @@ int deleteFromPlaylist(FILE * fp, int song) {
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) {
if(playerStop(fp)<0) return -1;
playlist_state = PLAYLIST_STATE_STOP;
......@@ -345,7 +384,13 @@ int savePlaylist(FILE * fp, char * file) {
}
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);
......@@ -364,10 +409,16 @@ int loadPlaylist(FILE * fp, char * file) {
}
while((s[slength] = fgetc(fileP))!=EOF) {
if(s[slength]=='\n') {
if(s[slength]=='\n' || 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;
if(s[0]==PLAYLIST_COMMENT && !getSong(s)) continue;
if((addToPlaylist(fp,s))<0) {
return -1;
}
}
else if(slength==MAXPATHLEN) {
s[slength] = '\0';
......
/* 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 project's homepage is: http://www.musicpd.org
*
* 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
......@@ -63,6 +63,10 @@ int savePlaylist(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 getPlaylistRepeatStatus();
......
/* 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 project's homepage is: http://www.musicpd.org
*
* 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 Music Player Daemon (MPD)
* (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
* it under the terms of the GNU General Public License as published by
......
/* 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 project's homepage is: http://www.musicpd.org
*
* 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 Music Player Daemon (MPD)
* (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
* it under the terms of the GNU General Public License as published by
......
/* 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 project's homepage is: http://www.musicpd.org
*
* 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
......@@ -34,9 +34,28 @@ List * albumTable;
List * artistTable;
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() {
albumTable = makeList(freeList);
artistTable = makeList(freeList);
artistTable = makeList((ListFreeDataFunc *)freeArtistData);
songTable = makeList(NULL);
}
......@@ -46,32 +65,35 @@ void closeTables() {
freeList(songTable);
}
void addSongToAlbumTable(Song * song) {
void addSongToSomeAlbumTable(List * table, Song * song) {
void * album;
if(!song->tag) return;
if(!song->tag->title) return;
if(findInList(albumTable,song->tag->album,&album)) {
if(!song->tag->title || !strlen(song->tag->title)) return;
if(findInList(table,song->tag->album,&album)) {
insertInList((SongList *)album,song->file,song);
}
else {
album = makeList(NULL);
insertInList(albumTable,song->tag->album,album);
insertInList(table,song->tag->album,album);
insertInList(album,song->file,song);
}
}
void addSongToAlbumTable(Song * song) {
addSongToSomeAlbumTable(albumTable,song);
}
void addSongToArtistTable(Song * song) {
void * artist;
if(!song->tag) return;
if(!song->tag->artist) return;
if(findInList(artistTable,song->tag->artist,&artist)) {
insertInList((SongList *)artist,song->file,song);
}
else {
artist = makeList(NULL);
if(!song->tag->artist || !strlen(song->tag->artist)) return;
if(!findInList(artistTable,song->tag->artist,&artist)) {
artist = newArtistData();
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) {
......@@ -101,7 +123,7 @@ int findAndPrintSongsInArtistTable(FILE * fp,char * find) {
return -1;
}
return printSongInfoFromList(fp,(SongList *)artist);
return printSongInfoFromList(fp,((ArtistData *)artist)->songs);
}
int findAndPrintSongsInTable(FILE * fp, char * table, char * find) {
......@@ -142,7 +164,7 @@ int searchForSongsInAlbumTable(FILE * fp,char * search) {
}
int searchForSongsInArtistTable(FILE * fp,char * search) {
SongList * artist;
ArtistData * artist;
ListNode * node = artistTable->firstNode;
char * dup;
char * dupSearch = strDupToUpper(search);
......@@ -150,8 +172,8 @@ int searchForSongsInArtistTable(FILE * fp,char * search) {
while(node) {
dup = strDupToUpper(node->key);
if(strstr(dup,dupSearch)) {
artist = (SongList *)node->data;
if(printSongInfoFromList(fp,artist)<0) {
artist = (ArtistData *)node->data;
if(printSongInfoFromList(fp,artist->songs)<0) {
free(dup);
free(dupSearch);
return -1;
......@@ -174,17 +196,17 @@ int searchForSongsInSongTableByTitle(FILE * fp,char * search) {
while(node) {
song = (Song *)node->data;
if(!song->tag) break;
if(!song->tag->title) break;
dup = strDupToUpper(song->tag->title);
if(strstr(dup,dupSearch)) {
if(printSongInfo(fp,song)<0) {
free(dup);
free(dupSearch);
return -1;
if(song->tag && song->tag->title && strlen(song->tag->title)) {
dup = strDupToUpper(song->tag->title);
if(strstr(dup,dupSearch)) {
if(printSongInfo(fp,song)<0) {
free(dup);
free(dupSearch);
return -1;
}
}
free(dup);
}
free(dup);
node = node->nextNode;
}
......@@ -236,27 +258,33 @@ int searchForSongsInTable(FILE * fp, char * table, char * search) {
return -1;
}
void removeSongFromAlbumTable(Song * song) {
void removeSongFromSomeAlbumTable(List * table, Song * song) {
void * album;
if(!song->tag) return;
if(!song->tag->album) return;
if(findInList(albumTable,song->tag->album,&album)) {
if(!song->tag->album || !strlen(song->tag->album)) return;
if(findInList(table,song->tag->album,&album)) {
deleteFromList((SongList *)album,song->file);
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 * artist;
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)) {
deleteFromList((SongList *)artist,song->file);
if(((SongList *)artist)->numberOfNodes==0) {
deleteFromList(((ArtistData *)artist)->songs,song->file);
removeSongFromSomeAlbumTable(((ArtistData *)artist)->albums,
song);
if(((ArtistData *)artist)->songs->numberOfNodes==0) {
deleteFromList(artistTable,song->tag->artist);
}
}
......@@ -315,3 +343,60 @@ Song * getSongFromSongTable(char * file) {
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)
* (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
* it under the terms of the GNU General Public License as published by
......@@ -46,4 +46,6 @@ unsigned long numberOfAlbums();
Song * getSongFromSongTable(char * file);
int printAllKeysOfTable(FILE * fp, char * table, char * arg1);
#endif
/* 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 project's homepage is: http://www.musicpd.org
*
* 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 Music Player Daemon (MPD)
* (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
* it under the terms of the GNU General Public License as published by
......
/* 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 project's homepage is: http://www.musicpd.org
*
* 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 Music Player Daemon (MPD)
* (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
* it under the terms of the GNU General Public License as published by
......
/* 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 project's homepage is: http://www.musicpd.org
*
* 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 Music Player Daemon (MPD)
* (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
* 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