jukeboxのメインスクリプト

#!/bin/sh

#######################
#
# Simple MP3 Jukebox
# KAWAMATA, Yoshihiro
# kaw@on.rim.or.jp
#
#######################

#=====
# utility functions / routines
#=====

# terminate process
#
terminate () {
    [ $# -ne 0 ] &&  echo "$@"
    rm -rf ctrl/playing
    [ -r ctrl/finish ] && . ctrl/finish
}

# trap for ^C
#
trap 'terminate "Aborted by user" ; exit' 2

# check flags,
# fetch a file,
# play it
#
# Usage: play_one_action { local_file | URL }
#
play_one_action () {
    [ $# -eq 0 ] && return

    # halt, reboot or exit
    #
    if [ -f ctrl/halt ]; then
	terminate "Halting..."
	rm -f ctrl/halt
	/sbin/shutdown -hp now
        sleep 86400

    elif [ -f ctrl/reboot ]; then
	terminate "Rebooting..."
	rm -f ctrl/reboot
	/sbin/shutdown -r now
        sleep 86400

    elif [ -f ctrl/restart ]; then
	terminate "Restarting script..."
	rm -f ctrl/restart
	exec $progfile

    elif [ -f ctrl/exit ]; then
	terminate "Exiting..."
	rm -f ctrl/exit
	exit
    fi

    # clean non-MP3 file and empty directories under spool
    #
    if [ -f ctrl/clean ]; then
	echo "Clearning dirs..."
	rm -f ctrl/clean
	find $src $dest oneshot oneshot_finished -type f \! \( -iname '*.mp3' -o -iname 
'*.url' \) -print0 | xargs -0 rm -f
	for d in $src $dest oneshot oneshot_finished; do
	    (cd $d  && find . -type d -print | sort -r | xargs rmdir >/dev/null 2>&1)
	done
    fi

    # pause playing
    #
    if [ -f ctrl/pause ]; then
	echo "Pausing..."
	while [ -f ctrl/pause ]; do
	  sleep 15
	done
    fi

    # play MP3 file
    #
    # ... invoke MP3 player with high priority
    #
    case "$1" in
	http://*.mp3|ftp://*.mp3)
	    #
	    # Cats are buffers against network stall.
	    # Please adjust its numbers, if necessary.
	    #
	    echo "$1" > ctrl/playing/contents
	    ftp -o - "$1" |cat|cat|cat| nice -n -15 /usr/local/bin/mpg123 $opts -
	    ;;
	*.[Mm][Pp]3)
	    if [ -f "$1" ]; then
		echo "$1" > ctrl/playing/contents
		nice -n -15 /usr/local/bin/mpg123 $opts "$1"
	    else
		echo "Cannot find $1"
	    fi
	    ;;
    esac
}


# move played file to another directory.
# directory hierarchy preserved.
#
# Usage: movefile srcpath desttop
#
movefile () {
    [ $# -lt 2 ] && return
    [ -f $1 ] || return
    destdir=$2/${1#*/}
    destdir=${destdir%[^/]*}
    if [ -d $destdir ]; then
	mv $1 $destdir
    else
	su mp3play -c "mkdir -p $destdir" && mv $1 $destdir
    fi
}


#=====
# Running code from here
#=====

# Base and current directory is where script placed.
#
progfile=$0
cd `dirname $progfile` || exit 1

# check if another player running
#
if mkdir ctrl/playing; then
    date > ctrl/playing/started
    chmod 0755 ctrl/playing
else
    echo "Another player running"
    exit 1
fi

# remove stale files
#
rm -f ctrl/exit ctrl/reboot ctrl/halt

# user initialization
#
[ -r ctrl/init ] && . ctrl/init

#=====
# main loop ... play MP3 and its control
#=====
while :; do
    # parameters to MP3 player
    #
    unset opts
    [ -f ctrl/mpg123opts ] && opts=`cat ctrl/mpg123opts`

    # We have two spool directories for infinite loop
    # ... spool0 and spool1.
    #
    # set direction of file movement
    # between two spools
    # when every MP3 file played
    #
    if [ -f ctrl/reverse ]; then
	 src=spool1
	dest=spool0
    else
	 src=spool0
	dest=spool1
    fi

    # playlist is symlink to spool for playing.
    #
    rm -f playlist
    ln -s $src playlist

    # for every MP3 files
    #	control and/or playing
    #
    # xNOPLAY is a sentinel to run inner loop
    #
    for playfile in xNOPLAY `find $src -type f \( -iname '*.mp3' -o -iname '*.u
rl' \) | sort`; do

	# retrieve resource location
	#
	case "$playfile" in
	    *.[Uu][Rr][Ll])
		mp3reslist=`cat $playfile`
		;;
	    *.[Mm][Pp]3|xNOPLAY)
		mp3reslist=$playfile
		;;
	esac

	# for every MP3 resource ...
	#
	for mp3res in $mp3reslist; do

	    # perform one shot playlist
	    #
	    while :; do
		for oneshot in xNOPLAY `find oneshot -type f \( -iname '*.mp3' -o -iname '*.u
rl' \) | sort`; do
		    # retrieve resource location
		    #
		    case "$oneshot" in
			*.[Uu][Rr][Ll])
			    oneshot_mp3res=`cat $oneshot`
			    ;;
			*.[Mm][Pp]3|xNOPLAY)
			    oneshot_mp3res=$oneshot
			    ;;
		    esac

		    for os_mp3 in $oneshot_mp3res; do

		        # check if resource file removed
		        #
			if [ -f $oneshot ]; then
			    play_one_action $os_mp3
			fi

		        # rescan all contents
		        #
			if [ -f ctrl/rescan ]; then
			    echo "Rescanning playlist..."
			    break 5
			fi
		    done

		    movefile $oneshot oneshot_finished
		done
		[ X"$oneshot" = XxNOPLAY ] && break
	    done

	    play_one_action $mp3res

	    # restart at current spool
	    #
	    if [ -f ctrl/rescan ]; then
		echo "Rescanning playlist..."
		break 2
	    fi
	done

	# move played file to the other spool
	#
	movefile $playfile $dest
    done

    # pause when no MP3 files in spools
    #
    if [ X"$playfile$oneshot" = XxNOPLAYxNOPLAY ]; then
	noplay=Z$noplay
	echo "No file to play : $noplay"
	if [ $noplay = ZZ ]; then
	    echo "Now sleeping for 60 secs..."
	    sleep 60
	    noplay=""
	fi
    else
	noplay=""
    fi

    # role change of spools
    # (not changing when rescan)
    #
    if [ -f ctrl/rescan ]; then
	rm -f ctrl/rescan
    else
	if [ -f ctrl/reverse ]; then
	    rm -f ctrl/reverse
	else
	    touch ctrl/reverse
	fi
    fi
done

kqueue / kevent というものを初めて使ってみた;

#include <stdio.h>

#include <sys/types.h>
#include <dirent.h>

#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>

main () {
 /*
  *  Open current working directory
  */
  DIR *d;
  int dfd;
  int err;

  if (!(d = opendir("."))) {
    perror("opendir");
    exit(1);
  }

 /*
  *  create and register kernel event queue
  */
  int kq;
  struct kevent kev;

  if ((kq = kqueue()) == -1) {
    perror("kqueue");
    closedir(d);
    exit(1);
  }

  EV_SET(&kev, dirfd(d), EVFILT_VNODE, EV_ADD|EV_CLEAR, NOTE_WRITE, 0, NULL);

  if (kevent(kq, &kev, 1, NULL, 0, NULL) < 0) {
    perror("kevent on register");
    closedir(d);
    exit(1);
  }

  int retval;

 /*
  *  then go monitoring
  */
  if (0 < kevent(kq, NULL, 0, &kev, 1, NULL)) {
    printf("dir changed.\n");
  } else {
    perror("kevent on nofity");
    closedir(d);
    exit(1);
  }

 /*
  *  normal exit
  */
  closedir(d);
  exit(0);
}

Front page   New Page list Search Recent changes   Help   RSS of recent changes