diff -rawuN mt-daapd-0.2.1.1/contrib/mt-daapd-ssc-script mt-daapd-0.2.1.1-ssc/contrib/mt-daapd-ssc-script
--- mt-daapd-0.2.1.1/contrib/mt-daapd-ssc-script	1970-01-01 02:00:00.000000000 +0200
+++ mt-daapd-0.2.1.1-ssc/contrib/mt-daapd-ssc-script	2005-02-20 23:15:46.089725739 +0200
@@ -0,0 +1,155 @@
+#!/usr/bin/perl
+#
+#   -*- perl -*-
+#
+#  ----------------------------------------------------------------------
+#  Server side media format conversion script for mt-daapd.
+#  ----------------------------------------------------------------------
+#  Copyright & 2005
+#  Timo J. Rinne <tri@iki.fi>
+#  ----------------------------------------------------------------------
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+
+#
+# This is quite rudimentary.  Obvious TODO list is as follows:
+#
+# - Start streaming immediatey instead of first converting the entire file.
+# - Implement Apple Lossless, somehow, someone, PLEASE!
+# - Possibly implement some kind of caching.
+#
+# I'll probably never have time for above things, but now it should
+# be easy for someone to take this over, since basically all you have
+# to do is to make the filter program and tweak the configuration.
+#
+#                                                            //tri
+#
+
+require 'sys/syscall.ph';
+
+use IO::Handle;
+use IO::File;
+
+$SIG{PIPE} = 'IGNORE';
+
+{
+  umask(0077);
+  if ($#ARGV != 1) {
+    usage();
+  }
+  my ($fn) = $ARGV[0];
+  my ($off) = 0 + $ARGV[1];
+  if ($off < 0) {
+    usage();
+  }
+  if ($fn =~ m/^..*\.mp3/i) {
+    mp3_proc($fn, $off);
+  } elsif ($fn =~ m/^..*\.wav$/i) {
+    wav_proc($fn, $off);
+  } elsif ($fn =~ m/^..*\.ogg$/i) {
+    ogg_proc($fn, $off);
+  } else {
+    printf STDERR "File \"%s\" is in unknown format.\n", $fn;
+    exit -1;
+  }
+  exit;
+}
+
+sub usage
+{
+  print STDERR "usage: ssc-script file offset\n";
+  exit -1;
+}
+
+sub tmp_file
+{
+  my ($r) = sprintf "/tmp/t-%d.wav", $$;
+  return $r;
+}
+
+sub wav_loop
+{
+  my ($f) = shift;
+  my ($off) = shift;
+  my ($buf);
+  my ($buflen);
+  my ($buftry) = 1024;
+
+  if ($off != 0) {
+    sysseek($f, $off, 1);
+  }
+
+  while (1) {
+    $buflen = sysread($f, $buf, $buftry);
+    if ($buflen < 1)
+      {
+	return 1;
+      }
+    if (syswrite (STDOUT, $buf) != $buflen)
+      {
+	print STDERR "Write failed.\n";
+	return undef;
+      }
+  }
+}
+
+sub mp3_proc
+{
+  my ($fn) = shift;
+  my ($off) = shift;
+  my ($tf) = tmp_file();
+  my ($f) = undef;
+
+  unlink($tf);
+  if (system('mpg123', '--quiet',  '--wav', "$tf", "$fn") == 0) {
+    if (open($f, "< $tf")) {
+      wav_loop($f, $off);
+      close($f);
+    }
+  }
+  unlink($tf);
+}
+
+sub wav_proc
+{
+  my ($fn) = shift;
+  my ($off) = shift;
+  my ($tf) = tmp_file();
+  my ($f) = undef;
+
+  if (! open($f, "< $fn")) {
+    return undef;
+  }
+  wav_loop($f, $off);
+  close($f);
+}
+
+sub ogg_proc
+{
+  my ($fn) = shift;
+  my ($off) = shift;
+  my ($tf) = tmp_file();
+  my ($f) = undef;
+
+  unlink($tf);
+  if (system('oggdec', '--quiet', '-o', "$tf", "$fn") == 0) {
+    if (open($f, "< $tf")) {
+      wav_loop($f, $off);
+      close($f);
+    }
+  }
+  unlink($tf);
+}
diff -rawuN mt-daapd-0.2.1.1/contrib/mt-daapd.conf-ssc mt-daapd-0.2.1.1-ssc/contrib/mt-daapd.conf-ssc
--- mt-daapd-0.2.1.1/contrib/mt-daapd.conf-ssc	1970-01-01 02:00:00.000000000 +0200
+++ mt-daapd-0.2.1.1-ssc/contrib/mt-daapd.conf-ssc	2005-02-20 23:14:48.258504058 +0200
@@ -0,0 +1,276 @@
+# $Id: mt-daapd.conf,v 1.15 2004/12/29 06:20:26 rpedde Exp $
+#
+# This is the mt-daapd config file.
+#
+# If you have problems or questions with the format of this file,
+# direct your questions to rpedde@users.sourceforge.net.
+#
+# You can also check the website at http://mt-daapd.sourceforge.net,
+# as there is a growing documentation library there, peer-supported
+# forums and possibly more.
+#
+
+
+#
+# web_root (required)
+#
+# Location of the admin web pages.
+#
+# If you installed from .RPM, .deb, or tarball with --prefix=/usr, then
+# this is correct. 
+#
+# If you installed from tarball without --prefix=/usr, then the correct
+# path is probably /usr/local/share/mt-daapd/admin-root.
+#
+
+web_root	/usr/share/mt-daapd/admin-root
+
+#
+# port (required)
+#
+# What port to listen on.  It is possible to use a different
+# port, but this is the default iTunes port
+#
+
+port		3689
+
+#
+# admin_pw (required)
+#
+# This is the password to the administrative pages
+#
+
+admin_pw	mt-daapd
+
+#
+# db_dir (required)
+#
+# This is where mt-daapd stores its database of song information.  
+#
+# If you installed from .RPM or .deb, then this directory already
+# exists.  If not, then YOU MUST CREATE THIS DIRECTORY!
+#
+
+db_dir		/var/cache/mt-daapd
+
+#
+# mp3_dir (required)
+#
+# Location of the mp3 files to share.  Note that because the
+# files are stored in the database by inode, these must be
+# in the same physical filesystem.
+#
+
+mp3_dir		/mnt/mp3
+
+#
+# servername (required)
+#
+# This is both the name of the server as advertised
+# via rendezvous, and the name of the database
+# exported via DAAP.  Also know as "What shows up in iTunes".
+#
+
+servername	mt-daapd
+
+#
+# runas (required)
+#
+# This is the user to drop privs to if running as
+# root.  If mt-daapd is not started as root, this
+# configuration option is ignored.  Notice that this
+# must be specified whether the server is running
+# as root or not.
+#
+
+runas	nobody
+
+#
+# playlist (optional)
+#
+# This is the location of a playlist file.
+# This is for Apple-style "Smart Playlists"
+# See the mt-daapd.playlist file in the 
+# contrib directory for syntax and examples
+#
+# This doesn't control static playlists... these
+# are controlled with the "process_m3u" directive
+# below.
+#
+
+playlist	/etc/mt-daapd.playlist
+
+#
+# password (optional)
+#
+# This is the password required to listen to MP3 files
+# i.e. the password that iTunes prompts for
+#
+
+#password	mp3
+
+#
+# extensions (optional)
+#
+# These are the file extensions that the daap server will
+# try to index and serve.  By default, it only indexes and
+# serves .mp3 files.  It can also server .m4a and .m4p files,
+# and just about any other files, really.  Unfortunately, while
+# it can *attempt* to serve other files (.ogg?), iTunes won't
+# play them.  Perhaps this would be useful on Linux with
+# Rhythmbox, once it understands daap.  (hurry up!)
+#
+#
+
+extensions .mp3,.m4a,.wav,.ogg
+
+#
+# ssc_extensions (optional)
+#
+# List of file extensions belonging to the files daap server
+# performs internal format conversion and present to clients
+# as WAV files.  Extensions must also be present in 'extensions'
+# configuration value, or files are not probed in the first
+# place.
+#
+ssc_extensions .mp3,.ogg
+
+#
+# ssc_prog (optional)
+#
+# Program that is used in server side format conversion.
+# Program must accept following command line syntax:
+#     ssc_prog filename offset
+# Parameter filename is the real name of the file that is
+# to be converted and streamed, offset is number of bytes
+# that are skipped from the beginning of the _output_ file
+# before streaming is started.  The resulting wav file (or
+# rest of the file after initial seek) is written to the
+# standard output by the ssc_prog program.  This is typically
+# a script that is a front end for different conversion tools
+# handling different formats.
+#
+
+ssc_prog /etc/mt-daapd-ssc-script
+
+#
+# logfile (optional)
+#
+# This is the file to log to.  If this is not configured,
+# then it will log to the syslog.
+#
+# Not that the -d <level> switch will control the log verbosity.
+# By default, it runs at log level 1.  Log level 9 will churn
+# out scads of useless debugging information.  Values in between
+# will vary the amount of logging you get.
+#
+
+#logfile /var/log/mt-daapd.log
+
+#
+# art_filename (optional)
+#
+# There is experimental support thanks to Hiren Joshi
+# (hirenj@mooh.org) for dynamically adding art to the id3v2
+# header as it is streamed (!!).  If you were using a music system
+# like zina or andromeda, for example, with cover art called 
+# "_folderOpenImage.jpg", you could use the parameter
+# art_file _folderOpenImage.jpg and if the file _folderOpenImage.jpg
+# was located in the same folder as the .mp3 file, it would appear
+# in iTunes.  Cool, eh? 
+#
+
+#art_filename _folderOpenImage.jpg
+
+#
+# rescan_interval
+#
+# How often to check the file system to see if any mp3 files
+# have been added or removed. 
+#
+# if not specified, the default is 0, which disables background scanning.
+#
+# If background rescanning is disabled, a scan can still be forced from the 
+# "status" page of the administrative web interface
+#
+# Setting a rescan_interval lower than the time it takes to rescan
+# won't hurt anything, it will just waste CPU, and make connect times
+# to the daap server longer.
+#
+#
+
+#rescan_interval 300
+
+# always_scan 
+#
+# The default behavior is not not do background rescans of the
+# filesystem unless there are clients connected.  The thought is to
+# allow the drives to spin down unless they are in use.  This might be
+# of more importance in IDE drives that aren't designed to be run
+# 24x7.  Forcing a scan through the web interface will always work
+# though, even if no users are connected.
+
+# always_scan 0
+
+# 
+# process_m3u
+#
+# By default m3u processing is turned off, since most m3u files
+# sitting around in peoples mp3 directories have bad paths, and
+# I hear about it.  :)
+#
+# If you are sure your m3u files have good paths (i.e. unixly pathed,
+# with relative paths relative to the directory the m3u is in), then
+# you can turn on m3u processing by setting this directive to 1.
+#
+# I'm not sure "unixly" is a word, but you get the idea.
+#
+
+# process_m3u 0
+
+#
+# scan_type
+# 
+#
+# This sets how aggressively mp3 files should be scanned to determine
+# file length.  There are three values:
+#
+# 0 (Normal) 
+#   Just scan the first mp3 frame to try and calculate size.  This will
+#   be accurate for most files, but VBR files without an Xing tag will
+#   probably have wildly inaccurate file times.  This is the default.
+#
+# 1 (Aggressive)
+#   This checks the bitrates of 10 frames in the middle of the song.  
+#   This will still be inaccurate for VBR files without an Xing tag,
+#   but they probably won't be quite as inaccurate as 0.  This takes
+#   more time, obviously, although the time hit will only happen the
+#   first time you scan a particular file.
+#
+# 2 (Painfully aggressive)
+#   This walks through the entire song, counting the number of frames.
+#   This should result in accurate song times, but will take the most
+#   time.  Again, this will only have to be incurred the first time
+#   the file is indexed.
+# 
+
+# scan_type  0
+
+#
+# compress
+#
+# Whether to use gzip content-encoding when transferring playlists etc.
+# This was contributed as a patch by Ciamac Moallemi just prior to the 0.2.1
+# release, and as such, hasn't gotten as much testing as other features.
+#
+# This feature should substantially speed up transfers of large databases
+# and playlists.
+#
+# It will eventually default to 1, but currently it defaults to 0.
+#
+
+# compress 0
+
+
+
+
diff -rawuN mt-daapd-0.2.1.1/src/Makefile.am mt-daapd-0.2.1.1-ssc/src/Makefile.am
--- mt-daapd-0.2.1.1/src/Makefile.am	2005-02-05 23:27:19.000000000 +0200
+++ mt-daapd-0.2.1.1-ssc/src/Makefile.am	2005-02-20 23:14:48.267502692 +0200
@@ -28,6 +28,7 @@
 	mp3-scanner.h mp3-scanner.c playlist.c playlist.h \
 	rend-unix.h lexer.l parser.y strcasestr.c strcasestr.h strsep.c \
 	redblack.c redblack.h dynamic-art.c dynamic-art.h query.c query.h \
+	ssc.c ssc.h \
 	$(PRENDSRC) $(ORENDSRC) $(HRENDSRC) $(OGGVORBISSRC)
 
 EXTRA_DIST = mDNS.c mDNSClientAPI.h mDNSDebug.h mDNSPosix.c \
diff -rawuN mt-daapd-0.2.1.1/src/configfile.c mt-daapd-0.2.1.1-ssc/src/configfile.c
--- mt-daapd-0.2.1.1/src/configfile.c	2005-01-30 07:18:07.000000000 +0200
+++ mt-daapd-0.2.1.1-ssc/src/configfile.c	2005-02-20 23:15:02.626323121 +0200
@@ -116,6 +116,8 @@
     { 1,0,0,CONFIG_TYPE_INT,"compress",(void*)&config.compress,config_emit_int },
     { 1,0,0,CONFIG_TYPE_STRING,"playlist",(void*)&config.playlist,config_emit_string },
     { 1,0,0,CONFIG_TYPE_STRING,"extensions",(void*)&config.extensions,config_emit_string },
+    { 1,0,0,CONFIG_TYPE_STRING,"ssc_extensions",(void*)&config.ssc_extensions,config_emit_string },
+    { 1,0,0,CONFIG_TYPE_STRING,"ssc_prog",(void*)&config.ssc_prog,config_emit_string },
     { 1,0,0,CONFIG_TYPE_STRING,"password",(void*)&config.readpassword, config_emit_string },
     { 1,0,0,CONFIG_TYPE_STRING,"logfile",(void*)&config.logfile, config_emit_string },
     { 0,0,0,CONFIG_TYPE_SPECIAL,"release",(void*)VERSION,config_emit_literal },
@@ -274,6 +276,8 @@
 
     /* DWB: use alloced space so it can be freed without errors */
     config.extensions=strdup(".mp3");
+    config.ssc_extensions=strdup("");
+    config.ssc_prog=strdup("");
 
     /* DWB: use alloced space so it can be freed without errors */
     config.servername=strdup("mt-daapd " VERSION);
@@ -478,6 +482,8 @@
     if(ws_getvar(pwsc,"password") && strlen(ws_getvar(pwsc,"password")))
 	fprintf(configfile,"password\t%s\n",ws_getvar(pwsc,"password"));
     fprintf(configfile,"extensions\t%s\n",ws_getvar(pwsc,"extensions"));
+    fprintf(configfile,"ssc_extensions\t%s\n",ws_getvar(pwsc,"ssc_extensions"));
+    fprintf(configfile,"ssc_prog\t%s\n",ws_getvar(pwsc,"ssc_prog"));
     fprintf(configfile,"db_dir\t\t%s\n",ws_getvar(pwsc,"db_dir"));
     fprintf(configfile,"rescan_interval\t%s\n",ws_getvar(pwsc,"rescan_interval"));
     fprintf(configfile,"scan_type\t%s\n",ws_getvar(pwsc,"scan_type"));
diff -rawuN mt-daapd-0.2.1.1/src/daapd.h mt-daapd-0.2.1.1-ssc/src/daapd.h
--- mt-daapd-0.2.1.1/src/daapd.h	2005-01-30 08:58:36.000000000 +0200
+++ mt-daapd-0.2.1.1-ssc/src/daapd.h	2005-02-20 23:14:48.261503602 +0200
@@ -64,6 +64,8 @@
     char *runas;          /**< Who to drop privs to (if run as root) */
     char *dbdir;          /**< Where to put the db file */
     char *extensions;     /**< What music file extentions to process */
+    char *ssc_extensions; /**< What extensions are converted in server */
+    char *ssc_prog;       /**< Server side music format converter prog */
     char *artfilename;    /**< What filename to merge coverart with */
     char *logfile;        /**< What file to use as a logfile */
     STATS stats;          /**< Stats structure (see above) */
diff -rawuN mt-daapd-0.2.1.1/src/main.c mt-daapd-0.2.1.1-ssc/src/main.c
--- mt-daapd-0.2.1.1/src/main.c	2005-02-05 23:27:19.000000000 +0200
+++ mt-daapd-0.2.1.1-ssc/src/main.c	2005-02-20 23:14:48.262503451 +0200
@@ -78,6 +78,7 @@
 #include "mp3-scanner.h"
 #include "webserver.h"
 #include "playlist.h"
+#include "ssc.h"
 #include "dynamic-art.h"
 
 #ifndef WITHOUT_MDNS
@@ -184,6 +185,7 @@
 
     MP3FILE *pmp3;
     int file_fd;
+    FILE *file_ptr; /* for possible conv filter */
     int session_id=0;
 
     int img_fd;
@@ -194,6 +196,8 @@
     off_t real_len;
     off_t file_len;
 
+    char *real_path;
+
     int bytes_copied=0;
 
     GZIP_STREAM *gz;
@@ -384,6 +388,77 @@
 	if(!pmp3) {
 	    DPRINTF(E_LOG,L_DAAP|L_WS|L_DB,"Could not find requested item %lu\n",item);
 	    ws_returnerror(pwsc,404,"File Not Found");
+	} else if ((real_path=server_side_convert_path(pmp3->path)) != NULL) {
+	    // The file should be converted in the server side.
+	    DPRINTF(E_WARN,L_WS,"Thread %d: Autoconvert file %s for client\n",
+		    pwsc->threadno,real_path);
+	    file_ptr=server_side_convert_open(real_path,offset);
+	    if (file_ptr) {
+		file_fd = fileno(file_ptr);
+	    } else {
+		file_fd = -1;
+	    }
+	    if(file_fd == -1) {
+		if (file_ptr) {
+		    server_side_convert_close(file_ptr);
+		}
+		pwsc->error=errno;
+		DPRINTF(E_WARN,L_WS,
+			"Thread %d: Error opening %s for conversion\n",
+			pwsc->threadno,real_path);
+		ws_returnerror(pwsc,404,"Not found");
+		config_set_status(pwsc,session_id,NULL);
+		db_dispose(pmp3);
+		free(pmp3);
+		free(real_path);
+	    } else {
+		// DWB:  fix content-type to correctly reflect data
+		// content type (dmap tagged) should only be used on
+		// dmap protocol requests, not the actually song data
+		if(pmp3->type)
+		    ws_addresponseheader(pwsc,"Content-Type","audio/%s",
+					 pmp3->type);
+		// Also content-length -heade would be nice, but since
+		// we don't really know it here, so let's leave it out.
+		ws_addresponseheader(pwsc,"Connection","Close");
+
+		if(!offset)
+		    ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n");
+		else {
+		    // This is actually against the protocol, since
+		    // range MUST be explicit according to HTTP-standard
+		    // Seems to work at least with iTunes.
+		    ws_addresponseheader(pwsc,
+					 "Content-Range","bytes %ld-*/*",
+					 (long)offset);
+		    ws_writefd(pwsc,"HTTP/1.1 206 Partial Content\r\n");
+		}
+
+		ws_emitheaders(pwsc);
+
+		config_set_status(pwsc,session_id,
+				  "Streaming file via convert filter '%s'",
+				  pmp3->fname);
+		DPRINTF(E_LOG,L_WS,
+			"Session %d: Streaming file '%s' to %s (offset %ld)\n",
+			session_id,pmp3->fname, pwsc->hostname,(long)offset);
+		
+		if(!offset)
+		    config.stats.songs_served++; /* FIXME: remove stat races */
+		if((bytes_copied=copyfile(file_fd,pwsc->fd)) == -1) {
+		    DPRINTF(E_INF,L_WS,
+			    "Error copying converted file to remote... %s\n",
+			    strerror(errno));
+		} else {
+		    DPRINTF(E_INF,L_WS,
+			    "Finished streaming converted file to remote\n");
+		}
+		server_side_convert_close(file_ptr);
+		config_set_status(pwsc,session_id,NULL);
+		db_dispose(pmp3);
+		free(pmp3);
+		free(real_path);
+	    }
 	} else {
 	    /* got the file, let's open and serve it */
 	    file_fd=r_open2(pmp3->path,O_RDONLY);
@@ -634,8 +709,8 @@
 	    switch(sig) {
 	    case SIGCLD:
 		DPRINTF(E_LOG,L_MAIN,"Got CLD signal.  Reaping\n");
-		while (wait(&status)) {
-		};
+		while (wait3(&status, WNOHANG, NULL) > 0) {
+		}
 		break;
 	    case SIGINT:
 		DPRINTF(E_LOG,L_MAIN,"Got INT signal. Notifying daap server.\n");
diff -rawuN mt-daapd-0.2.1.1/src/mp3-scanner.c mt-daapd-0.2.1.1-ssc/src/mp3-scanner.c
--- mt-daapd-0.2.1.1/src/mp3-scanner.c	2005-02-05 23:27:19.000000000 +0200
+++ mt-daapd-0.2.1.1-ssc/src/mp3-scanner.c	2005-02-20 23:14:48.264503147 +0200
@@ -50,6 +50,7 @@
 #include "err.h"
 #include "mp3-scanner.h"
 #include "playlist.h"
+#include "ssc.h"
 
 #ifndef HAVE_STRCASESTR
 # include "strcasestr.h"
@@ -384,6 +385,7 @@
     char mp3_path[PATH_MAX];
     struct stat sb;
     int modified_time;
+    char *ext;
 
     if((current_dir=opendir(path)) == NULL) {
 	return -1;
@@ -428,9 +430,8 @@
 		       config.process_m3u){
 			/* we found an m3u file */
 			scan_static_playlist(path, pde, &sb);
-		    } else if (strcasestr(config.extensions,
-					  (char*)&pde->d_name[strlen(pde->d_name) - 4])) {
-			
+		    } else if (((ext = strrchr(pde->d_name, '.')) != NULL) &&
+			       (strcasestr(config.extensions, ext))) {
 			/* only scan if it's been changed, or empty db */
 			modified_time=sb.st_mtime;
 			DPRINTF(E_DBG,L_SCAN,"FS Mod time: %d\n",modified_time);
@@ -532,8 +533,8 @@
     DPRINTF(E_INF,L_SCAN,"Found music file: %s\n",pde->d_name);
     
     memset((void*)&mp3file,0,sizeof(mp3file));
-    mp3file.path=mp3_path;
-    mp3file.fname=pde->d_name;
+    mp3file.path=strdup(mp3_path);
+    mp3file.fname=strdup(pde->d_name);
     if(strlen(pde->d_name) > 4)
 	mp3file.type=strdup(strrchr(pde->d_name, '.') + 1);
     
@@ -556,6 +557,8 @@
 	    mp3file.time_added=psb->st_ctime;
         mp3file.time_modified=psb->st_mtime;
 
+	server_side_convert_set(&mp3file);
+
 	DPRINTF(E_DBG,L_SCAN," Date Added: %d\n",mp3file.time_added);
 
 	db_add(&mp3file);
@@ -941,6 +944,8 @@
  * Free up the tags that were dynamically allocated
  */
 int scan_freetags(MP3FILE *pmp3) {
+    MAYBEFREE(pmp3->path);
+    MAYBEFREE(pmp3->fname);
     MAYBEFREE(pmp3->title);
     MAYBEFREE(pmp3->artist);
     MAYBEFREE(pmp3->album);
@@ -1768,3 +1773,4 @@
     /* Ogg used to be set as an item_kind of 4.  Dunno why */
     song->item_kind = 2;
 }
+
diff -rawuN mt-daapd-0.2.1.1/src/ssc.c mt-daapd-0.2.1.1-ssc/src/ssc.c
--- mt-daapd-0.2.1.1/src/ssc.c	1970-01-01 02:00:00.000000000 +0200
+++ mt-daapd-0.2.1.1-ssc/src/ssc.c	2005-02-20 23:15:02.627322969 +0200
@@ -0,0 +1,162 @@
+/*
+ * $Id$
+ * Implementation file for server side format conversion.
+ *
+ * Copyright (C) 2005 Timo J. Rinne (tri@iki.fi)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#define _POSIX_PTHREAD_SEMANTICS
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <id3tag.h>
+#include <limits.h>
+#include <restart.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netinet/in.h>  /* htons and friends */
+#include <sys/stat.h>
+#include <dirent.h>      /* why here?  For osx 10.2, of course! */
+
+#include "daapd.h"
+#include "db-memory.h"
+#include "err.h"
+#include "mp3-scanner.h"
+#include "ssc.h"
+
+#ifndef HAVE_STRCASESTR
+# include "strcasestr.h"
+#endif
+
+/**
+ * If path is server side convertable, return the path to real file.
+ *
+ * @param path char * to the path in the database.
+ */
+char *server_side_convert_path(char *path)
+{
+    char *r = NULL;
+
+    if (path &&
+	(strlen(path) > strlen(SERVER_SIDE_CONVERT_SUFFIX)) &&
+	(strcmp(path + strlen(path) - strlen(SERVER_SIDE_CONVERT_SUFFIX),
+		SERVER_SIDE_CONVERT_SUFFIX) == 0)) {
+	/* Lose the artificial suffix.  Could use strndup here.*/
+	r = strdup(path);
+	r[strlen(path) - strlen(SERVER_SIDE_CONVERT_SUFFIX)] = '\0';
+    }
+
+    return r;
+}
+
+/**
+ * Check if the file entry (otherwise complete) is such that
+ * file should be converted in server end to wav-format.
+ * If so, the info is modified accordingly and non-zero return
+ * value is returned.
+ *
+ * @param song MP3FILE of the file to possibly set to server side conversion
+ */
+int server_side_convert_set(MP3FILE *pmp3)
+{
+    char *fname, *path, *description, *ext;
+
+    if ((!config.ssc_extensions) ||
+	(!config.ssc_extensions[0]) ||
+	(!config.ssc_prog) ||
+	(!config.ssc_prog[0]) ||
+	(!pmp3->fname) ||
+	(!pmp3->path) ||
+	(!pmp3->type) ||
+	((strlen(pmp3->fname) > strlen(SERVER_SIDE_CONVERT_SUFFIX)) &&
+	 (strcmp(pmp3->fname +
+		 strlen(pmp3->fname) -
+		 strlen(SERVER_SIDE_CONVERT_SUFFIX),
+		 SERVER_SIDE_CONVERT_SUFFIX) == 0))) {
+	return 0;
+    }
+
+    if (((ext = strrchr(pmp3->path, '.')) != NULL) &&
+	(strcasestr(config.ssc_extensions, ext))) {
+	fname = (char *)malloc(strlen(pmp3->fname) +
+			       strlen(SERVER_SIDE_CONVERT_SUFFIX) + 1);
+	path = (char *)malloc(strlen(pmp3->path) +
+			      strlen(SERVER_SIDE_CONVERT_SUFFIX) + 1);
+	description = (char *)malloc(strlen(pmp3->description) +
+				     strlen(SERVER_SIDE_CONVERT_DESCR) + 1);
+	strcpy(fname, pmp3->fname);
+	strcat(fname, SERVER_SIDE_CONVERT_SUFFIX);
+	free(pmp3->fname);
+	pmp3->fname = fname;
+	strcpy(path, pmp3->path);
+	strcat(path, SERVER_SIDE_CONVERT_SUFFIX);
+	free(pmp3->path);
+	pmp3->path = path;
+	strcpy(description, pmp3->description);
+	strcat(description, SERVER_SIDE_CONVERT_DESCR);
+	free(pmp3->description);
+	pmp3->description = description;
+	free(pmp3->type);
+	pmp3->type = strdup("wav");
+	if (pmp3->samplerate > 0) {
+	    // Here we guess that it's always 16 bit stereo samples,
+	    // which is accurate enough for now.
+	    pmp3->bitrate = (pmp3->samplerate * 4 * 8) / 1000;
+	}
+	return 1;
+    }
+    return 0;
+}
+
+/**
+ * Open the source file with convert fiter.
+ *
+ * @param path char * to the real filename.
+ * @param offset off_t to the point in file where the streaming starts.
+ */
+FILE *server_side_convert_open(char *path, off_t offset)
+{
+    char *cmd;
+    FILE *f;
+
+    cmd=(char *)malloc(strlen(config.ssc_prog) +
+		       strlen(path) +
+		       64);
+    sprintf(cmd, "%s \"%s\" %ld",
+	    config.ssc_prog, path, (long)offset);
+    f = popen(cmd, "r");
+    return f;
+}
+
+/**
+ * Open the source file with convert fiter.
+ *
+ * @param FILE * returned by server_side_convert_open be closed.
+ */
+void server_side_convert_close(FILE *f)
+{
+    if (f)
+	pclose(f);
+    return;
+}
+
diff -rawuN mt-daapd-0.2.1.1/src/ssc.h mt-daapd-0.2.1.1-ssc/src/ssc.h
--- mt-daapd-0.2.1.1/src/ssc.h	1970-01-01 02:00:00.000000000 +0200
+++ mt-daapd-0.2.1.1-ssc/src/ssc.h	2005-02-20 23:14:48.266502844 +0200
@@ -0,0 +1,34 @@
+/*
+ * $Id$
+ * Implementation file for server side format conversion.
+ *
+ * Copyright (C) 2005 Timo J. Rinne (tri@iki.fi)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _SCC_H_
+#define _SCC_H_
+
+#define SERVER_SIDE_CONVERT_SUFFIX ".-*-ssc-*-.wav"
+#define SERVER_SIDE_CONVERT_DESCR  " (converted to WAV)"
+
+extern int server_side_convert_set(MP3FILE *pmp3);
+extern char *server_side_convert_path(char *path);
+extern FILE *server_side_convert_open(char *path, off_t offset);
+extern void server_side_convert_close(FILE *f);
+
+#endif /* _SCC_H_ */
+
