NAME
       disorder - plugin interface to DisOrder jukebox

SYNOPSIS
       #include <disorder.h>

DESCRIPTION
       This header file defines the plugin interface to DisOrder.

       The  first  half of this man page describes the functions DisOrder pro-
       vides to plugins; the second half describes the functions that  plugins
       must provide.

MEMORY ALLOCATION
       DisOrder  uses  a garbage collector internally.  Therefore it is recom-
       mended that plugins  use  the  provided  memory  allocation  interface,
       rather than calling malloc(3) etc directly.

       void *disorder_malloc(size_t);
       void *disorder_realloc(void *, size_t);

              These functions behave much like malloc(3) and realloc(3) except
              that they never fail; they always zero out the memory allocated;
              and you do not need to free the result.

              They  may  still  return  a  null pointer if asked for a 0-sized
              allocation.

       void *disorder_malloc_noptr(size_t);
       void *disorder_realloc_noptr(void *, size_t);

              These functions are like malloc(3) and  realloc(3)  except  that
              they  never  fail and you must not put any pointer values in the
              allocated memory.

              They may still return a null pointer  if  asked  for  a  0-sized
              allocation.   They do not guarantee to zero out the memory allo-
              cated.

       char *disorder_strdup(const char *);
       char *disorder_strndup(const char *, size_t);

              These functions are like strdup(3) and  strndup(3)  except  that
              they never fail and you do not need to free the result.

       int disorder_asprintf(char **rp, const char *fmt, ...);
       int disorder_snprintf(char buffer[], size_t bufsize,
                             const char *fmt, ...);

              These  function  are  like  snprintf(3) and asprintf(3).  disor-
              der_asprintf never fails on memory allocation  and  you  do  not
              need to free the results.

              Floating  point  conversions  and wide character support are not
              currently implemented.

              These functions will cope with UTF-8 even if the current  locale
              uses some other encoding.

       "Never  fail"  in  the  above  means  that the process is terminated on
       error.

LOGGING
       Standard error doesn't reliably go anywhere in current versions of Dis-
       Order,  and  whether  syslog  is to be used varies depending on how the
       program is invoked.  Therefore plugins should use  these  functions  to
       log any errors or informational messages.

       void disorder_error(int errno_value, const char *fmt, ...);

              Log an error message.  If errno_value is not 0 then the relevant
              string is included in the error message.

       void disorder_fatal(int errno_value, const char *fmt, ...);

              Log an  error  message  and  then  terminate  the  process.   If
              errno_value is not 0 then the relevant string is included in the
              error message.

              disorder_fatal is the right way to terminate the  process  if  a
              fatal error arises.  You shouldn't usually try to use exit(3) or
              _exit(2).

       void disorder_info(const char *fmt, ...);

              Log a message.

TRACK DATABASE
       The functions in this section provide a  way  of  accessing  the  track
       database.   In  server  plugins  these access the database directly; in
       client plugins the requests  are  transmitted  to  the  server  over  a
       socket.

       All strings in this section are encoded using UTF-8.

       int disorder_track_exists(const char *track);

              This  function  returns  non-0  if track exists and 0 if it does
              not.

       const char *disorder_track_get_data(const char *track,
                                           const char *key);

              This function looks up the value of key for track and returns  a
              pointer to a copy of it.  Do not bother to free the pointer.  If
              the track or key are not found a null pointer is returned.

       int disorder_track_set_data(const char *track,
                                   const char *key,
                                   const char *value);

              This function sets the value of key for track to value.  On suc-
              cess, 0 is returned; on error, -1 is returned.

              If value is a null pointer then the preference is deleted.

              Values  starting  with  an  underscore  are stored in the tracks
              database, and are lost if the track is deleted; they should only
              ever  have values that can be regenerated on demand.  Other val-
              ues are stored in the prefs database and never get automatically
              deleted.

PLUGIN FUNCTIONS
       This  section  describes the functions that you must implement to write
       various plugins.  All of the plugins have at least one standard  imple-
       mentation available in the DisOrder source.

       Some  functions  are  listed as only available in server plugins.  Cur-
       rently this means that they are not even defined outside the server.

       All strings in this section are encoded using UTF-8.

   Tracklength Plugins
       These are server plugins defined by the tracklength directive.

       long disorder_tracklength(const char *track,
                                 const char *path);

              Called to calculate the length of a track.  track is  the  track
              name  (UTF-8)  and  path is the path name if there was one, or a
              null pointer otherwise.  path  will  be  the  same  byte  string
              return  from  the  scanner  plugin,  and  so  presumably encoded
              according to the filesystem encoding.

              To clarify this point, if the track must be  opened  to  compute
              its length, you would normally use path and not track.

              If the return value is positive it should be the track length in
              seconds (round up if it is not an  integral  number  of  seconds
              long).

              If the return value is zero then the track length is unknown.

              If the return value is negative then an error occurred determin-
              ing the track length.

       Tracklength plugins are invoked from a subprocess  of  the  server,  so
       they can block without disturbing the server's operation.

   notify.so
       This is a server plugin.

       void disorder_notify_play(const char *track,
                                 const char *submitter);

              Called  when  track is about to be played.  submitter identifies
              the submitter or is a null pointer if the track was  picked  for
              random play.

       void disorder_notify_scratch(const char *track,
                                    const char *submitter,
                                    const char *scratcher,
                                    int seconds);

              Called  when track is scratched by scratcher.  submitter identi-
              fies the submitter or is a null pointer if the track was  picked
              for  random  play.   seconds  is the number of seconds since the
              track started playing.

       void disorder_notify_not_scratched(const char *track,
                                          const char *submitter);

              Called when track completes without being  scratched  (an  error
              might have occurred though).  submitter identifies the submitter
              or is a null pointer if the track was picked for random play.

       void disorder_notify_queue(const char *track,
                                  const char *submitter);

              Called when track is added to the queue by submitter  (which  is
              never a null pointer).  Not called for scratches.

       void disorder_notify_queue_remove(const char *track,
                                         const char *remover);

              Called  when  track  is  removed from queue by remover (which is
              never a null pointer).

       void disorder_notify_queue_move(const char *track,
                                       const char *remover);

              Called when track is moved in the queue by mover (which is never
              a null pointer).

       void disorder_notify_pause(const char *track,
                                  const char *who);

              Called  when  track  is  paused  by  who  (which might be a null
              pointer).

       void disorder_notify_resume(const char *track,
                                   const char *who);

              Called when track is resumed by  who  (which  might  be  a  null
              pointer).

   Scanner Plugins
       Scanner plugins are server plugins and may have any name; they are cho-
       sen via the configuration file.

       void disorder_scan(const char *root);

              Write a list of files below root to standard output.  Each file-
              name should be in the encoding defined for this root in the con-
              figuration file and should be terminated by character 0.

              It is up to the plugin implementor whether they  prefer  to  use
              stdio or write to file descriptor 1 directly.

              All  the filenames had better start with root as this is used to
              match them back up  to  the  right  collection  to  call  disor-
              der_check on.

       int disorder_check(const char *root, const char *path);

              Check  whether file path under root still exists.  Should return
              1 if it exists, 0 if it does not and -1 on error.  This  is  run
              in the main server process.

       Both  scan and recheck are executed inside a subprocess, so it will not
       break the server if they  block  for  an  extended  period  (though  of
       course,  they  should not gratuitously take longer than necessary to do
       their jobs).

   Player plugins
       Player plugins are server plugins and may have any name; they are  cho-
       sen via the configuration file.

       extern const unsigned long disorder_player_type;

              This  defines  the player type and capabilities.  It should con-
              sist of a single type value ORed with any number  of  capability
              values.  The following are known type values:

              DISORDER_PLAYER_STANDALONE
                     A standalone player that writes directly to some suitable
                     audio device.

              DISORDER_PLAYER_RAW
                     A player that writes raw samples to $DISORDER_RAW_FD.

              Known capabilities are:

              DISORDER_PLAYER_PREFORK
                     Supports the prefork and cleanup calls.

              DISORDER_PLAYER_PAUSES
                     Supports the pause and resume calls.

       void *disorder_play_prefork(const char *track);

              Called before a track is played, if _PREFORK is set.   track  is
              the name of the track in UTF-8.  This function must never block,
              as it runs inside the main loop of the server.

              The return value will be passed to the functions below as  data.
              On error, a null pointer should be returned.

       void disorder_play_cleanup(void *data);

              Called after a track has been completed, if _PREFORK is set, for
              instance to release the memory used by data.  This function must
              never block, as it runs inside the main loop of the server.

       void disorder_play_track(const char *const *parameters,
                                int nparameters,
                                const char *path,
                                const char *track,
                                void *data);

              Play a track.

              path  is  the path name as originally encoded in the filesystem.
              This is the value you should ultimately pass to open(2).

              track is the path name converted to UTF-8.  This value (possibly
              converted  to  some  other encoding) should be used in any logs,
              etc.

              If there is no meaningful path, or if the  track  is  a  scratch
              (where no filename encoding information is available), path will
              be equal to track.

              The parameters are any  additional  arguments  supplied  to  the
              player configuration file command.

              This  function is always called inside a fork, and it should not
              return until playing has finished.

              DisOrder sends the subprocess a signal if the  track  is  to  be
              scratched  (and  when  disorderd is shut down).  By default this
              signal is SIGKILL but it can be reconfigured.

       int disorder_play_pause(long *playedp,
                               void *data);

              Pauses the current track,  for  players  that  support  pausing.
              This  function must never block, as it runs inside the main loop
              of the server.

              On success, should return 0 and set *playedp to  the  number  of
              seconds  played so far of this track, or to -1 if this cannot be
              determined.

              On error, should return -1.

       void disorder_play_resume(void *data);

              Resume playing the current track after a pause.   This  function
              must never block, as it runs inside the main loop of the server.

NOTES
       There  is  no special DisOrder library to link against; the symbols are
       exported by the executables themselves.  (You should NOT  try  to  link
       against  -ldisorder.)   Plugins  must  be separately linked against any
       other libraries they require, even  if  the  DisOrder  executables  are
       already linked against them.

       The  easiest approach is probably to develop the plugin inside the Dis-
       Order tree; then you can just use DisOrder's build system.  This  might
       also make it easier to submit patches if you write something of general
       utility.

       Failing that you can use Libtool, if you make sure to pass the  -module
       option.   For  current  versions  of  DisOrder you only need the shared
       object itself, not the .la file.

       If you know the right runes for your toolchain you could also build the
       modules more directly.

       It  is  possible, up to a point, to implement several plugin interfaces
       from within a single shared object.  If you ever use any of  the  func-
       tions  that  are  listed  as  only  being  available in server plugins,
       though, then you can only use the resulting shared object as  a  server
       plugin.

SEE ALSO
       disorderd(8), disorder(1), disorder_config(5)