chiark / gitweb /
build fixes
[disorder] / lib / queue.c
index c7d32a4213ca5cbb0a7c767dbbbff4116624f74f..466fe7ba229f2bb8c6debd39e19de5cef87340b1 100644 (file)
 #include <string.h>
 #include <stdio.h>
 #include <errno.h>
-#include <stdlib.h>
-#include <time.h>
 #include <stddef.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <unistd.h>
 
 #include "mem.h"
 #include "queue.h"
 #include "log.h"
-#include "configuration.h"
 #include "split.h"
 #include "syscalls.h"
-#include "charset.h"
 #include "table.h"
-#include "inputline.h"
 #include "printf.h"
-#include "plugin.h"
-#include "basen.h"
-#include "eventlog.h"
-#include "disorder.h"
 
 const char *playing_states[] = {
   "failed",
@@ -59,29 +47,6 @@ const char *playing_states[] = {
   "unplayed"
 };
 
-/* the head of the queue is played next, so normally we add to the tail */
-struct queue_entry qhead = { &qhead, &qhead, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
-/* the head of the recent list is the oldest thing, the tail the most recently
- * played */
-struct queue_entry phead = { &phead, &phead, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
-static long pcount;
-
-/* add new entry @n@ to a doubly linked list just after @b@ */
-static void l_add(struct queue_entry *b, struct queue_entry *n) {
-  n->prev = b;
-  n->next = b->next;
-  n->next->prev = n;
-  n->prev->next = n;
-}
-
-/* remove an entry from a doubly-linked list */
-static void l_remove(struct queue_entry *node) {
-  node->next->prev = node->prev;
-  node->prev->next = node->next;
-}
-
 #define VALUE(q, offset, type) *(type *)((char *)q + offset)
 
 static int unmarshall_long(char *data, struct queue_entry *q,
@@ -224,30 +189,6 @@ int queue_unmarshall_vec(struct queue_entry *q, int nvec, char **vec,
   return 0;
 }
 
-void queue_fix_sofar(struct queue_entry *q) {
-  long sofar;
-  
-  /* Fake up SOFAR field for currently-playing tracks that don't have it filled
-   * in by the speaker process.  XXX this horrible bodge should go away when we
-   * have a more general implementation of pausing as that field will always
-   * have to be right for the playing track. */
-  if((q->state == playing_started
-      || q->state == playing_paused)
-     && q->type & DISORDER_PLAYER_PAUSES
-     && (q->type & DISORDER_PLAYER_TYPEMASK) != DISORDER_PLAYER_RAW) {
-    if(q->lastpaused) {
-      if(q->uptopause == -1)           /* Don't know how far thru. */
-       sofar = -1;
-      else if(q->lastresumed)          /* Has been paused and resumed. */
-       sofar = q->uptopause + time(0) - q->lastresumed;
-      else                             /* Currently paused. */
-       sofar = q->uptopause;
-    } else                             /* Never been paused. */
-      sofar = time(0) - q->played;
-    q->sofar = sofar;
-  }
-}
-
 char *queue_marshall(const struct queue_entry *q) {
   unsigned n;
   const char *vec[sizeof fields / sizeof *fields], *v;
@@ -271,237 +212,6 @@ char *queue_marshall(const struct queue_entry *q) {
   return r;
 }
 
-static void queue_read_error(const char *msg,
-                            void *u) {
-  fatal(0, "error parsing queue %s: %s", (const char *)u, msg);
-}
-
-static void queue_do_read(struct queue_entry *head, const char *path) {
-  char *buffer;
-  FILE *fp;
-  struct queue_entry *q;
-
-  if(!(fp = fopen(path, "r"))) {
-    if(errno == ENOENT)
-      return;                  /* no queue */
-    fatal(errno, "error opening %s", path);
-  }
-  head->next = head->prev = head;
-  while(!inputline(path, fp, &buffer, '\n')) {
-    q = xmalloc(sizeof *q);
-    queue_unmarshall(q, buffer, queue_read_error, (void *)path);
-    if(head == &qhead
-       && (!q->track
-          || !q->when))
-      fatal(0, "incomplete queue entry in %s", path);
-    l_add(head->prev, q);
-  }
-  if(ferror(fp)) fatal(errno, "error reading %s", path);
-  fclose(fp);
-}
-
-void queue_read(void) {
-  queue_do_read(&qhead, config_get_file("queue"));
-}
-
-void recent_read(void) {
-  struct queue_entry *q;
-
-  queue_do_read(&phead, config_get_file("recent"));
-  /* reset pcount after loading */
-  pcount = 0;
-  q = phead.next;
-  while(q != &phead) {
-    ++pcount;
-    q = q->next;
-  }
-}
-
-static void queue_do_write(const struct queue_entry *head, const char *path) {
-  char *tmp;
-  FILE *fp;
-  struct queue_entry *q;
-
-  byte_xasprintf(&tmp, "%s.new", path);
-  if(!(fp = fopen(tmp, "w"))) fatal(errno, "error opening %s", tmp);
-  for(q = head->next; q != head; q = q->next)
-    if(fprintf(fp, "%s\n", queue_marshall(q)) < 0)
-      fatal(errno, "error writing %s", tmp);
-  if(fclose(fp) < 0) fatal(errno, "error closing %s", tmp);
-  if(rename(tmp, path) < 0) fatal(errno, "error replacing %s", path);
-}
-
-void queue_write(void) {
-  queue_do_write(&qhead, config_get_file("queue"));
-}
-
-void recent_write(void) {
-  queue_do_write(&phead, config_get_file("recent"));
-}
-
-void queue_id(struct queue_entry *q) {
-  static unsigned long serial;
-  unsigned long a[3];
-  char buffer[128];
-
-  a[0] = serial++ & 0xFFFFFFFFUL;
-  a[1] = time(0) & 0xFFFFFFFFUL;
-  a[2] = getpid() & 0xFFFFFFFFUL;
-  basen(a, 3, buffer, sizeof buffer, 62);
-  q->id = xstrdup(buffer);
-}
-
-struct queue_entry *queue_add(const char *track, const char *submitter,
-                             int where) {
-  struct queue_entry *q;
-
-  q = xmalloc(sizeof *q);
-  q->track = xstrdup(track);
-  q->submitter = submitter ? xstrdup(submitter) : 0;
-  q->state = playing_unplayed;
-  queue_id(q);
-  time(&q->when);
-  switch(where) {
-  case WHERE_START:
-    l_add(&qhead, q);
-    break;
-  case WHERE_END:
-    l_add(qhead.prev, q);
-    break;
-  case WHERE_BEFORE_RANDOM:
-    if(qhead.prev == &qhead            /* Empty queue. */
-       || qhead.prev->state != playing_random) /* No random track */
-      l_add(qhead.prev, q);
-    else
-      l_add(qhead.prev->prev, q);      /* Before random track. */
-    break;
-  }
-  /* submitter will be a null pointer for a scratch */
-  if(submitter)
-    notify_queue(track, submitter);
-  eventlog_raw("queue", queue_marshall(q), (const char *)0);
-  return q;
-}
-
-int queue_move(struct queue_entry *q, int delta, const char *who) {
-  int moved = 0;
-  char buffer[20];
-
-  /* not the most efficient approach but hopefuly relatively comprehensible:
-   * the idea is that for each step we determine which nodes are affected, and
-   * fill in all the links starting at the 'prev' end and moving towards the
-   * 'next' end. */
-  
-  while(delta > 0 && q->prev != &qhead) {
-    struct queue_entry *n, *p, *pp;
-
-    n = q->next;
-    p = q->prev;
-    pp = p->prev;
-    pp->next = q;
-    q->prev = pp;
-    q->next = p;
-    p->prev = q;
-    p->next = n;
-    n->prev = p;
-    --delta;
-    ++moved;
-  }
-
-  while(delta < 0 && q->next != &qhead) {
-    struct queue_entry *n, *p, *nn;
-
-    p = q->prev;
-    n = q->next;
-    nn = n->next;
-    p->next = n;
-    n->prev = p;
-    n->next = q;
-    q->prev = n;
-    q->next = nn;
-    nn->prev = q;
-    ++delta;
-    --moved;
-  }
-
-  if(moved) {
-    info("user %s moved %s", who, q->id);
-    notify_queue_move(q->track, who);
-    sprintf(buffer, "%d", moved);
-    eventlog("moved", who, (char *)0);
-  }
-  
-  return delta;
-}
-
-static int find_in_list(struct queue_entry *needle,
-                       int nqs, struct queue_entry **qs) {
-  int n;
-
-  for(n = 0; n < nqs; ++n)
-    if(qs[n] == needle)
-      return 1;
-  return 0;
-}
-
-void queue_moveafter(struct queue_entry *target,
-                    int nqs, struct queue_entry **qs,
-                    const char *who) {
-  struct queue_entry *q;
-  int n;
-
-  /* Normalize */
-  if(!target)
-    target = &qhead;
-  else
-    while(find_in_list(target, nqs, qs))
-      target = target->prev;
-  /* Do the move */
-  for(n = 0; n < nqs; ++n) {
-    q = qs[n];
-    l_remove(q);
-    l_add(target, q);
-    target = q;
-    /* Log the individual tracks */
-    info("user %s moved %s", who, q->id);
-    notify_queue_move(q->track, who);
-  }
-  /* Report that the queue changed to the event log */
-  eventlog("moved", who, (char *)0);
-}
-
-void queue_remove(struct queue_entry *which, const char *who) {
-  if(who) {
-    info("user %s removed %s", who, which->id);
-    notify_queue_move(which->track, who);
-  }
-  eventlog("removed", which->id, who, (const char *)0);
-  l_remove(which);
-}
-
-struct queue_entry *queue_find(const char *key) {
-  struct queue_entry *q;
-
-  for(q = qhead.next;
-      q != &qhead && strcmp(q->track, key) && strcmp(q->id, key);
-      q = q->next)
-    ;
-  return q != &qhead ? q : 0;
-}
-
-void queue_played(struct queue_entry *q) {
-  while(pcount && pcount >= config->history) {
-    eventlog("recent_removed", phead.next->id, (char *)0);
-    l_remove(phead.next);
-    pcount--;
-  }
-  if(config->history) {
-    eventlog_raw("recent_added", queue_marshall(q), (char *)0);
-    l_add(phead.prev, q);
-    ++pcount;
-  }
-}
-
 /*
 Local Variables:
 c-basic-offset:2
@@ -509,4 +219,3 @@ comment-column:40
 fill-column:79
 End:
 */
-/* arch-tag:62474dd3e75e5483b61b6befe2c523cc */