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); }
/* 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; }