+ /** Amplification value. */
+ uint8_t amp;
+};
+
+/**
+ * Events caused by changes to an afs table.
+ *
+ * Whenever an afs table changes, an event is generated which causes afs to
+ * call the event handlers of all other tables. For example, if an audio file
+ * is added, the event handler of the mood table checks the new file for
+ * admissibility.
+ */
+enum afs_events {
+ /** An attribute was added. */
+ ATTRIBUTE_ADD,
+ /** An attribute was renamed. */
+ ATTRIBUTE_RENAME,
+ /** An attribute was removed. */
+ ATTRIBUTE_REMOVE,
+ /** The afs info struct of an audio file changed. */
+ AFSI_CHANGE,
+ /** The afh info struct of an audio file changed. */
+ AFHI_CHANGE,
+ /** An audio file was renamed. */
+ AUDIO_FILE_RENAME,
+ /** An audio file was added. */
+ AUDIO_FILE_ADD,
+ /** An audio file is about to be removed. */
+ AUDIO_FILE_REMOVE,
+ /** A new blob was added. */
+ BLOB_ADD,
+ /** A blob was renamed. */
+ BLOB_RENAME,
+ /** A blob is about to be removed. */
+ BLOB_REMOVE,
+};
+
+/**
+ * Used as data for \ref afs_event() for events of type \p ATTRIBUTE_ADD.
+ */
+struct rmatt_event_data {
+ /** The name of the attribute being added. */
+ const char *name;
+ /** Its bit number. */
+ unsigned char bitnum;
+};
+
+/**
+ * Used as data for \ref afs_event() for events of type \p ATTRIBUTE_AFSI_CHANGE.
+ */
+struct afsi_change_event_data {
+ /** Pointer to the row that has changed. */
+ struct osl_row *aft_row;
+ /** Afs info before the change. */
+ struct afs_info *old_afsi;
+};
+
+/** Function pointers for table handling. */
+struct afs_table {
+ /** Initializes the other pointers in this struct. */
+ void (*init)(struct afs_table *t);
+ /** The name of this table. */
+ const char *name;
+ /** Gets called on startup and on \p SIGHUP. */
+ int (*open)(const char *base_dir);
+ /** Gets called on shutdown and on \p SIGHUP. */
+ void (*close)(void);
+ /** Called by the \a init afs command. */
+ int (*create)(const char *);
+ /** Handles afs events. */
+ int (*event_handler)(enum afs_events event, struct para_buffer *pb,
+ void *data);
+};
+
+/** How audio files are selected by afs. */
+enum play_mode {
+ /** Admissible files are determined by a mood definition. */
+ PLAY_MODE_MOOD,
+ /** All listed files are admissible. */
+ PLAY_MODE_PLAYLIST,
+};
+
+/**
+ * Codes used for communication between the server and the afs process.
+ *
+ * Before forking the afs child, para_server creates a bidirectional pipe
+ * through which both processes communicate. Usually para_server requests a new
+ * audio file in order to start streaming or when the end of the current audio file
+ * has been reached. The afs process responds to such a request by sending
+ * back an eight byte buffer. The first four bytes is the uint32_t
+ * representation of the code, usually \p NEXT_AUDIO_FILE if an admissible
+ * audio file was found, successfully opened and verified. The other four bytes
+ * represent the shared memory id of the shared memory area that contains
+ * details about the audio file to be streamed next. The open file descriptor
+ * of that file is also passed from afs to para_server through the same pipe.
+ */
+enum afs_server_code {
+ /** An audio file was successfully opened. */
+ NEXT_AUDIO_FILE,
+ /** No admissible audio file was found. */
+ NO_ADMISSIBLE_FILES,