Exemple #1
0
static void cleanup(void) {
	rmsckif();

	if(haskey(& rc, "unix") && getpid() == ppid)
		unlink(value(& rc, "unix"));

	empty(& data);
	empty(& rc);
	empty(& track);

	freelist(& playlist);

	if(current_station) {
		free(current_station);
		current_station = NULL;
	}

	if(subfork)
		waitpid(subfork, NULL, 0);

	dump_queue();

	/* Clean cache. */
	if(!access(rcpath("cache"), R_OK | W_OK | X_OK)) {
		const char * cache = rcpath("cache");
		DIR * directory = opendir(cache);

		if(directory != NULL) {
			time_t expiry = 24 * 60 * 60; /* Expiration after 24h. */
			struct dirent * entry;
			struct stat status;
			char path[PATH_MAX];

			if(haskey(& rc, "expiry"))
				expiry = atoi(value(& rc, "expiry"));

			while((entry = readdir(directory)) != NULL) {
				snprintf(path, sizeof(path), "%s/%s", cache, entry->d_name);

				if(!stat(path, & status)) {
					if(status.st_mtime < (time(NULL) - expiry)) {
						unlink(path);
					}
				}
			}

			closedir(directory);
		}
	}

	if(playfork)
		kill(playfork, SIGUSR1);
}
Exemple #2
0
/*
   Takes pointer to a playlist, forks off a playback process and tries to play
   the next track in the playlist. If there's already a playback process, it's
   killed first (which means the currently played track is skipped).
   */
int play(struct playlist * list) {
  unsigned i;
  int pipefd[2];
  char * keys [] = {
    "creator", "title", "album", "duration", "station",
    "lastfm:trackauth", "trackpage", "artistpage", "albumpage",
    "image", "freeTrackURL",
  };

  assert(list != NULL);

  if(!list->left)
    return 0;

  if(playfork) {
    kill(playfork, SIGUSR1);
    return !0;
  }

  enable(QUIET);

  empty(& track);

  for(i = 0; i < (sizeof(keys) / sizeof(char *)); ++i)
    set(& track, keys[i], value(& list->track->track, keys[i]));

  if(pipe(pipefd) != 0)
    return !0;

  playfork = fork();

  if(!playfork) {
    FILE * fd = NULL;
    const char * location = value(& list->track->track, "location");

    close(pipefd[1]);
    rmsckif();

    subfork = 0;

    if(location != NULL) {
      fetch(location, & fd, NULL, NULL);

      if(fd != NULL) {
        /*
           If there was an error, tell the main process about it by
           sending SIGUSR2.
           */
        if(!playback(fd, pipefd[0]))
          kill(getppid(), SIGUSR2);

        close(pipefd[0]);
        fshutdown(& fd);
      }
    }

    exit(EXIT_SUCCESS);
  }

  close(pipefd[0]);

  if(playpipe != 0)
    close(playpipe);

  playpipe = pipefd[1];

  return !0;
}