Module mpdpopm::commands

source ·
Expand description

Running commands on the server

Introduction

mpdpopm allows for running arbitrary programs on the server in response to server events or external commands (to keep ID3 tags up-to-date when a song is rated, for instance). This may seem like a vulnerability if your MPD server is listening on a socket, but it’s not like callers can execute arbitrary code: certain events can trigger commands that you, the MPD server owner have configured.

The Generalized Command Framework

In addition to fixed commands (i.e. commands that are run in response to particular events, like rating a song, or completing a track), mpdpopm provides a generalized command framework by which you can map arbitrary messages sent to the mpdpopm channel to code execution on the server side. A generalized command can be described as:

  1. the command name: commands shall be named according to the regular expression: [a-zA-Z][-a-zA-Z0-9]+

  2. command parameters: a command may take parameters; the parameters are defined by an array of zero or more instances of:

    • parameter name: parameter names shall match the regex: [a-zA-Z][-a-zA-Z0-9]+

    • parameter type: parameters may be a:

      • general/string

      • song (empty means “current”, otherwise song URI, maybe someday index into playlist)

    parameters beyond a certain point may be marked “optional”; optional parameters that are not provided shall be given a default value (the empty string for general parameters, or the current track for a song parameter)

  3. program to run, with arguments; arguments can be:

    • string literals (program options, for instance)

    • replacement parameters

      • %1, %2, %3… will be replaced with the parameter in the corresponding position above

      • %full-file will expand to the absolute path to the song named by the track argument, if present; if this parameter is used, and the track is not provided in the command arguments, it is an error

      • %rating, %play-count & %last-played will expand to the value of the corresponding sticker, if present. If any of these are used, and the track is not provided in the command arguments, it is an error. If the corresponding sticker is not present in the sticker database, default values of 0, 0, and Jan. 1 1970 (i.e. Unix epoch) will be provided instead.

Quoting

MPD breaks up commands into their constituent tokens on the basis of whitespace:

token := [a-zA-Z0-09~!@#$%^&*()-=_+[]{}\|;:<>,./?]+ | "([ \t'a-zA-Z0-09~!@#$%^&*()-=_+[]{}|;:<>,./?]|\"|\\)"

In other words, a token is any group of ASCII, non-whitespace characters except for ’ & “ (even ). In order to include space, tab, ’ or “ the token must be enclosed in double quotes at which point “ and \ (but not ’) must be backslash-escaped. Details can be found here and here.

This means that when invoking generalized commands via the MPD messages mechanism, the entire command will need to be quoted twice on the client side. An example will help illustrate. Suppose the command is named myfind and we wish to pass an argument which contains both ’ characters & spaces:

myfind (Artist == 'foo' and rating > '***')
^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
cmd    argument

Since the argument contains spaces and ’-s we’ll need to enclose it in double quotes (at which point the ’ characters become permissible):

myfind "(Artist == 'foo' and rating > '***')"

Since this entire command will itself be a single token in the “sendmessage” command, we need to quote it in its entirety on the client side:

"myfind \"(Artist == 'foo' and rating > '***')\""

(Enclose the entire command in double-quotes, then backslash-escape any “ or \ characters therein).

The MPD docs suggest using a client library such as libmpdclient to do the quoting, but the implementation is straightforward.

Structs

Enums

  • An mpdpopm command error
  • Describes the formal parameter type
  • Describes the sort of database update that should take place on command completion

Functions

  • Process a replacement string with replacement parameters of the form “%param” given a lookup table for parameter replacements. Literal `%’-s can be expressed as “%%”.
  • Start process cmd with args I & return; the results will be available asynchronously

Type Aliases