1/* 2 * Copyright (C) 2009-2010 Julien BLACHE <jb@jblache.org> 3 * 4 * Bits and pieces from mt-daapd: 5 * Copyright (C) 2003 Ron Pedde (ron@pedde.com) 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 22#ifdef HAVE_CONFIG_H 23# include <config.h> 24#endif 25 26#include <stdio.h> 27#include <stdlib.h> 28#include <unistd.h> 29#include <string.h> 30#include <time.h> 31#include <errno.h> 32#include <sys/param.h> 33#include <sys/types.h> 34#include <sys/stat.h> 35#include <sys/ioctl.h> 36#include <fcntl.h> 37#include <dirent.h> 38#include <pthread.h> 39#include <sched.h> 40#include <uninorm.h> 41 42#if defined(__linux__) 43# include <sys/inotify.h> 44#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 45# include <sys/time.h> 46# include <sys/event.h> 47#endif 48 49#if defined(HAVE_SYS_EVENTFD_H) && defined(HAVE_EVENTFD) 50# define USE_EVENTFD 51# include <sys/eventfd.h> 52#endif 53 54#define MAX_MEDIA_FILE 10000 55 56#define REMOTE_NOTIFY_FILE "/tmp/remote_change" 57#define REMOTE_PAIRING_FILE "/tmp/shares/forked_daapd.remote" 58#include <event.h> 59 60#include "logger.h" 61#include "db.h" 62#include "filescanner.h" 63#include "conffile.h" 64#include "misc.h" 65#include "remote_pairing.h" 66 67 68#define F_SCAN_BULK (1 << 0) 69#define F_SCAN_RESCAN (1 << 1) 70 71struct deferred_pl { 72 char *path; 73 struct deferred_pl *next; 74}; 75 76struct stacked_dir { 77 char *path; 78 struct stacked_dir *next; 79}; 80 81 82#ifdef USE_EVENTFD 83static int exit_efd; 84#else 85static int exit_pipe[2]; 86#endif 87static int scan_exit; 88static int inofd; 89static struct event_base *evbase_scan; 90static struct event inoev; 91static struct event exitev; 92static pthread_t tid_scan; 93static struct deferred_pl *playlists; 94static struct stacked_dir *dirstack; 95 96#define ONLY_MUSIC_FILE 97 98static int 99push_dir(struct stacked_dir **s, char *path) 100{ 101 struct stacked_dir *d; 102 103 d = (struct stacked_dir *)malloc(sizeof(struct stacked_dir)); 104 if (!d) 105 { 106 DPRINTF(E_LOG, L_SCAN, "Could not stack directory %s; out of memory\n", path); 107 return -1; 108 } 109 110 d->path = strdup(path); 111 if (!d->path) 112 { 113 DPRINTF(E_LOG, L_SCAN, "Could not stack directory %s; out of memory for path\n", path); 114 return -1; 115 } 116 117 d->next = *s; 118 *s = d; 119 120 return 0; 121} 122 123static char * 124pop_dir(struct stacked_dir **s) 125{ 126 struct stacked_dir *d; 127 char *ret; 128 129 if (!*s) 130 return NULL; 131 132 d = *s; 133 *s = d->next; 134 ret = d->path; 135 136 free(d); 137 138 return ret; 139} 140 141 142static void 143normalize_fixup_tag(char **tag, char *src_tag) 144{ 145 char *norm; 146 size_t len; 147 148 /* Note: include terminating NUL in string length for u8_normalize */ 149 150 if (!*tag) 151 *tag = (char *)u8_normalize(UNINORM_NFD, (uint8_t *)src_tag, strlen(src_tag) + 1, NULL, &len); 152 else 153 { 154 norm = (char *)u8_normalize(UNINORM_NFD, (uint8_t *)*tag, strlen(*tag) + 1, NULL, &len); 155 free(*tag); 156 *tag = norm; 157 } 158} 159 160static void 161fixup_tags(struct media_file_info *mfi) 162{ 163 size_t len; 164 char *tag; 165 char *sep = " - "; 166 167 if (mfi->genre && (strlen(mfi->genre) == 0)) 168 { 169 free(mfi->genre); 170 mfi->genre = NULL; 171 } 172 173 if (mfi->artist && (strlen(mfi->artist) == 0)) 174 { 175 free(mfi->artist); 176 mfi->artist = NULL; 177 } 178 179 if (mfi->title && (strlen(mfi->title) == 0)) 180 { 181 free(mfi->title); 182 mfi->title = NULL; 183 } 184 185 /* 186 * Default to mpeg4 video/audio for unknown file types 187 * in an attempt to allow streaming of DRM-afflicted files 188 */ 189 if (strcmp(mfi->codectype, "unkn") == 0) 190 { 191 if (mfi->has_video) 192 { 193 strcpy(mfi->codectype, "mp4v"); 194 strcpy(mfi->type, "m4v"); 195 } 196 else 197 { 198 strcpy(mfi->codectype, "mp4a"); 199 strcpy(mfi->type, "m4a"); 200 } 201 } 202 203 if (!mfi->artist) 204 { 205 if (mfi->orchestra && mfi->conductor) 206 { 207 len = strlen(mfi->orchestra) + strlen(sep) + strlen(mfi->conductor); 208 tag = (char *)malloc(len + 1); 209 if (tag) 210 { 211 sprintf(tag,"%s%s%s", mfi->orchestra, sep, mfi->conductor); 212 mfi->artist = tag; 213 } 214 } 215 else if (mfi->orchestra) 216 { 217 mfi->artist = strdup(mfi->orchestra); 218 } 219 else if (mfi->conductor) 220 { 221 mfi->artist = strdup(mfi->conductor); 222 } 223 } 224 225 /* Handle TV shows, try to present prettier metadata */ 226 if (mfi->tv_series_name && strlen(mfi->tv_series_name) != 0) 227 { 228 mfi->media_kind = 64; /* tv show */ 229 230 /* Default to artist = series_name */ 231 if (mfi->artist && strlen(mfi->artist) == 0) 232 { 233 free(mfi->artist); 234 mfi->artist = NULL; 235 } 236 237 if (!mfi->artist) 238 mfi->artist = strdup(mfi->tv_series_name); 239 240 /* Default to album = "<series_name>, Season <season_num>" */ 241 if (mfi->album && strlen(mfi->album) == 0) 242 { 243 free(mfi->album); 244 mfi->album = NULL; 245 } 246 247 if (!mfi->album) 248 { 249 len = snprintf(NULL, 0, "%s, Season %d", mfi->tv_series_name, mfi->tv_season_num); 250 251 mfi->album = (char *)malloc(len + 1); 252 if (mfi->album) 253 sprintf(mfi->album, "%s, Season %d", mfi->tv_series_name, mfi->tv_season_num); 254 } 255 } 256 257 /* Check the 4 top-tags are filled */ 258 if (!mfi->artist) 259 mfi->artist = strdup("Unknown artist"); 260 if (!mfi->album) 261 mfi->album = strdup("Unknown album"); 262 if (!mfi->genre) 263 mfi->genre = strdup("Unknown genre"); 264 if (!mfi->title) 265 { 266 /* fname is left untouched by unicode_fixup_mfi() for 267 * obvious reasons, so ensure it is proper UTF-8 268 */ 269 mfi->title = unicode_fixup_string(mfi->fname); 270 if (mfi->title == mfi->fname) 271 mfi->title = strdup(mfi->fname); 272 } 273 274 /* Ensure sort tags are filled and normalized */ 275 normalize_fixup_tag(&mfi->artist_sort, mfi->artist); 276 normalize_fixup_tag(&mfi->album_sort, mfi->album); 277 normalize_fixup_tag(&mfi->title_sort, mfi->title); 278 279 /* If we don't have an album_artist, set it to artist */ 280 if (!mfi->album_artist) 281 { 282 if (mfi->compilation) 283 { 284 mfi->album_artist = strdup(""); 285 mfi->album_artist_sort = strdup(""); 286 } 287 else 288 mfi->album_artist = strdup(mfi->artist); 289 } 290 291 if (!mfi->album_artist_sort && (strcmp(mfi->album_artist, mfi->artist) == 0)) 292 { 293 if(mfi->artist_sort) 294 mfi->album_artist_sort = strdup(mfi->artist_sort); 295 } 296 else 297 normalize_fixup_tag(&mfi->album_artist_sort, mfi->album_artist); 298 299 /* Composer is not one of our mandatory tags, so take extra care */ 300 if (mfi->composer_sort || mfi->composer) 301 normalize_fixup_tag(&mfi->composer_sort, mfi->composer); 302} 303 304int static file_number=0; 305 306static void 307process_media_file(char *file, time_t mtime, off_t size, int compilation) 308{ 309 struct media_file_info mfi; 310 char *filename; 311 char *ext; 312 time_t stamp; 313 int id; 314 int ret; 315 316if(file_number>=MAX_MEDIA_FILE) 317 return; 318 319 db_file_stamp_bypath(file, &stamp, &id); 320 321 if (stamp >= mtime) 322 { 323 db_file_ping(id); 324 return; 325 } 326 327 memset(&mfi, 0, sizeof(struct media_file_info)); 328 329 if (stamp) 330 mfi.id = db_file_id_bypath(file); 331 332 filename = strrchr(file, '/'); 333 if (!filename) 334 { 335 DPRINTF(E_LOG, L_SCAN, "Could not determine filename for %s\n", file); 336 337 return; 338 } 339 340 mfi.fname = strdup(filename + 1); 341 if (!mfi.fname) 342 { 343 DPRINTF(E_WARN, L_SCAN, "Out of memory for fname\n"); 344 345 return; 346 } 347 348 mfi.path = strdup(file); 349 if (!mfi.path) 350 { 351 DPRINTF(E_WARN, L_SCAN, "Out of memory for path\n"); 352 353 free(mfi.fname); 354 return; 355 } 356 357 mfi.time_modified = mtime; 358 mfi.file_size = size; 359 360 ret = -1; 361 362 /* Special cases */ 363 ext = strrchr(file, '.'); 364 if (ext) 365 { 366 if ((strcmp(ext, ".pls") == 0) 367 || (strcmp(ext, ".url") == 0)) 368 { 369 mfi.data_kind = 1; /* url/stream */ 370 371 ret = scan_url_file(file, &mfi); 372 if (ret < 0) 373 goto out; 374 } 375 else if ((strcmp(ext, ".png") == 0) 376 || (strcmp(ext, ".jpg") == 0)) 377 { 378 /* Artwork - don't scan */ 379 goto out; 380 } 381#ifdef ONLY_MUSIC_FILE 382 else if ((strcmp(ext, ".mp3") != 0) 383 && (strcmp(ext, ".wav") != 0) 384 && (strcmp(ext, ".flac") != 0) 385 && (strcmp(ext, ".asf") != 0) 386 && (strcmp(ext, ".wma") != 0) 387 && (strcmp(ext, ".wmv") != 0) 388 && (strcmp(ext, ".m4a") != 0) 389 && (strcmp(ext, ".f4v") != 0) 390 && (strcmp(ext, ".aac") != 0) 391 && (strcmp(ext, ".amr") != 0) 392 && (strcmp(ext, ".awb") != 0) 393 && (strcmp(ext, ".au4") != 0) 394 && (strcmp(ext, ".mov") != 0) 395 && (strcmp(ext, ".m4v") != 0) 396 && (strcmp(ext, ".mp4") != 0)) 397 { 398 /* Artwork - don't scan */ 399 goto out; 400 } 401#endif 402 } 403 404 /* General case */ 405 if (ret < 0) 406 { 407 ret = scan_metadata_ffmpeg(file, &mfi); 408 mfi.data_kind = 0; /* real file */ 409 } 410 411 if (ret < 0) 412 { 413 DPRINTF(E_INFO, L_SCAN, "Could not extract metadata for %s\n", file); 414 415 goto out; 416 } 417 418 mfi.compilation = compilation; 419 420 if (!mfi.item_kind) 421 mfi.item_kind = 2; /* music */ 422 if (!mfi.media_kind) 423 mfi.media_kind = 1; /* music */ 424 425 unicode_fixup_mfi(&mfi); 426 427 fixup_tags(&mfi); 428 429 file_number++; 430 431 if (mfi.id == 0) 432 db_file_add(&mfi); 433 else 434 db_file_update(&mfi); 435 436 out: 437 free_mfi(&mfi, 1); 438} 439 440static void 441process_playlist(char *file) 442{ 443 char *ext; 444 445 ext = strrchr(file, '.'); 446 if (ext) 447 { 448 if (strcmp(ext, ".m3u") == 0) 449 scan_m3u_playlist(file); 450#ifdef ITUNES 451 else if (strcmp(ext, ".xml") == 0) 452 scan_itunes_itml(file); 453#endif 454 } 455} 456 457/* Thread: scan */ 458static void 459defer_playlist(char *path) 460{ 461 struct deferred_pl *pl; 462 463 pl = (struct deferred_pl *)malloc(sizeof(struct deferred_pl)); 464 if (!pl) 465 { 466 DPRINTF(E_WARN, L_SCAN, "Out of memory for deferred playlist\n"); 467 468 return; 469 } 470 471 memset(pl, 0, sizeof(struct deferred_pl)); 472 473 pl->path = strdup(path); 474 if (!pl->path) 475 { 476 DPRINTF(E_WARN, L_SCAN, "Out of memory for deferred playlist\n"); 477 478 free(pl); 479 return; 480 } 481 482 pl->next = playlists; 483 playlists = pl; 484 485 DPRINTF(E_INFO, L_SCAN, "Deferred playlist %s\n", path); 486} 487 488/* Thread: scan (bulk only) */ 489static void 490process_deferred_playlists(void) 491{ 492 struct deferred_pl *pl; 493 494 while ((pl = playlists)) 495 { 496 playlists = pl->next; 497 498 process_playlist(pl->path); 499 500 free(pl->path); 501 free(pl); 502 503 /* Run the event loop */ 504 event_base_loop(evbase_scan, EVLOOP_ONCE | EVLOOP_NONBLOCK); 505 506 if (scan_exit) 507 return; 508 } 509} 510 511/* Thread: scan */ 512static void 513process_file(char *file, time_t mtime, off_t size, int compilation, int flags) 514{ 515 char *ext; 516 517 if(access(REMOTE_NOTIFY_FILE,R_OK)!=-1) 518 { 519 if(access(REMOTE_PAIRING_FILE,R_OK)!=-1) 520 { 521 remote_pairing_read_pin(REMOTE_PAIRING_FILE); 522 } 523 system("rm /tmp/remote_change -r -f"); 524 } 525 526 ext = strrchr(file, '.'); 527 if (ext) 528 { 529 if ((strcmp(ext, ".m3u") == 0) 530#ifdef ITUNES 531 || (strcmp(ext, ".xml") == 0) 532#endif 533 ) 534 { 535 if (flags & F_SCAN_BULK) 536 defer_playlist(file); 537 else 538 process_playlist(file); 539 540 return; 541 } 542 else if (strcmp(ext, ".remote") == 0) 543 { 544 remote_pairing_read_pin(file); 545 546 return; 547 } 548 } 549 550 /* Not any kind of special file, so let's see if it's a media file */ 551 process_media_file(file, mtime, size, compilation); 552} 553 554 555/* Thread: scan */ 556static int 557check_compilation(char *path) 558{ 559 cfg_t *lib; 560 int ndirs; 561 int i; 562 563 lib = cfg_getsec(cfg, "library"); 564 ndirs = cfg_size(lib, "compilations"); 565 566 for (i = 0; i < ndirs; i++) 567 { 568 if (strstr(path, cfg_getnstr(lib, "compilations", i))) 569 return 1; 570 } 571 572 return 0; 573} 574 575/* Thread: scan */ 576static void 577process_directory(char *path, int flags) 578{ 579 struct stacked_dir *bulkstack; 580 DIR *dirp; 581 struct dirent buf; 582 struct dirent *de; 583 char entry[PATH_MAX]; 584 char *deref; 585 struct stat sb; 586 struct watch_info wi; 587#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 588 struct kevent kev; 589#endif 590 int compilation; 591 int ret; 592 593 if (flags & F_SCAN_BULK) 594 { 595 /* Save our directory stack so it won't get handled inside 596 * the event loop - not its business, we're in bulk mode here. 597 */ 598 bulkstack = dirstack; 599 dirstack = NULL; 600 601 /* Run the event loop */ 602 event_base_loop(evbase_scan, EVLOOP_ONCE | EVLOOP_NONBLOCK); 603 604 /* Restore our directory stack */ 605 dirstack = bulkstack; 606 607 if (scan_exit) 608 return; 609 } 610 611 DPRINTF(E_DBG, L_SCAN, "Processing directory %s (flags = 0x%x)\n", path, flags); 612 613 dirp = opendir(path); 614 if (!dirp) 615 { 616 DPRINTF(E_LOG, L_SCAN, "Could not open directory %s: %s\n", path, strerror(errno)); 617 618 return; 619 } 620 621 /* Check for a compilation directory */ 622 compilation = check_compilation(path); 623 624 for (;;) 625 { 626 ret = readdir_r(dirp, &buf, &de); 627 if (ret != 0) 628 { 629 DPRINTF(E_LOG, L_SCAN, "readdir_r error in %s: %s\n", path, strerror(errno)); 630 631 break; 632 } 633 634 if (de == NULL) 635 break; 636 637 if (buf.d_name[0] == '.') 638 continue; 639 640 ret = snprintf(entry, sizeof(entry), "%s/%s", path, buf.d_name); 641 if ((ret < 0) || (ret >= sizeof(entry))) 642 { 643 DPRINTF(E_LOG, L_SCAN, "Skipping %s/%s, PATH_MAX exceeded\n", path, buf.d_name); 644 645 continue; 646 } 647 648 ret = lstat(entry, &sb); 649 if (ret < 0) 650 { 651 DPRINTF(E_LOG, L_SCAN, "Skipping %s, lstat() failed: %s\n", entry, strerror(errno)); 652 653 continue; 654 } 655 656 if (S_ISLNK(sb.st_mode)) 657 { 658 deref = m_realpath(entry); 659 if (!deref) 660 { 661 DPRINTF(E_LOG, L_SCAN, "Skipping %s, could not dereference symlink: %s\n", entry, strerror(errno)); 662 663 continue; 664 } 665 666 ret = stat(deref, &sb); 667 if (ret < 0) 668 { 669 DPRINTF(E_LOG, L_SCAN, "Skipping %s, stat() failed: %s\n", deref, strerror(errno)); 670 671 free(deref); 672 continue; 673 } 674 675 ret = snprintf(entry, sizeof(entry), "%s", deref); 676 free(deref); 677 if ((ret < 0) || (ret >= sizeof(entry))) 678 { 679 DPRINTF(E_LOG, L_SCAN, "Skipping %s, PATH_MAX exceeded\n", deref); 680 681 continue; 682 } 683 } 684 685 if (S_ISREG(sb.st_mode)) 686 { 687if(file_number<MAX_MEDIA_FILE) 688 process_file(entry, sb.st_mtime, sb.st_size, compilation, flags); 689 } 690 else if (S_ISDIR(sb.st_mode)) 691 { 692if(file_number<MAX_MEDIA_FILE) 693 push_dir(&dirstack, entry); 694 } 695 else 696 DPRINTF(E_LOG, L_SCAN, "Skipping %s, not a directory, symlink nor regular file\n", entry); 697 } 698 699 closedir(dirp); 700 701 memset(&wi, 0, sizeof(struct watch_info)); 702 703#if defined(__linux__) 704 /* Add inotify watch */ 705 wi.wd = inotify_add_watch(inofd, path, IN_CREATE | IN_DELETE | IN_MODIFY | IN_CLOSE_WRITE | IN_MOVE | IN_DELETE | IN_MOVE_SELF); 706 if (wi.wd < 0) 707 { 708 DPRINTF(E_WARN, L_SCAN, "Could not create inotify watch for %s: %s\n", path, strerror(errno)); 709 710 return; 711 } 712 713 if (!(flags & F_SCAN_RESCAN)) 714 { 715 wi.cookie = 0; 716 wi.path = path; 717 718 db_watch_add(&wi); 719 } 720 721#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 722 memset(&kev, 0, sizeof(struct kevent)); 723 724 wi.wd = open(path, O_RDONLY | O_NONBLOCK); 725 if (wi.wd < 0) 726 { 727 DPRINTF(E_WARN, L_SCAN, "Could not open directory %s for watching: %s\n", path, strerror(errno)); 728 729 return; 730 } 731 732 /* Add kevent */ 733 EV_SET(&kev, wi.wd, EVFILT_VNODE, EV_ADD | EV_CLEAR, NOTE_DELETE | NOTE_WRITE | NOTE_RENAME, 0, NULL); 734 735 ret = kevent(inofd, &kev, 1, NULL, 0, NULL); 736 if (ret < 0) 737 { 738 DPRINTF(E_WARN, L_SCAN, "Could not add kevent for %s: %s\n", path, strerror(errno)); 739 740 close(wi.wd); 741 return; 742 } 743 744 wi.cookie = 0; 745 wi.path = path; 746 747 db_watch_add(&wi); 748#endif 749} 750 751/* Thread: scan */ 752static void 753process_directories(char *root, int flags) 754{ 755 char *path; 756 757 process_directory(root, flags); 758 759 if (scan_exit) 760 return; 761 762 while ((path = pop_dir(&dirstack))) 763 { 764 if(file_number<MAX_MEDIA_FILE) 765 process_directory(path, flags); 766 767 free(path); 768 769 if (scan_exit) 770 return; 771 } 772} 773 774 775/* Thread: scan */ 776static void 777bulk_scan(void) 778{ 779 cfg_t *lib; 780 int ndirs; 781 char *path; 782 char *deref; 783 time_t start; 784 int i; 785 786 start = time(NULL); 787 788 playlists = NULL; 789 dirstack = NULL; 790 791 lib = cfg_getsec(cfg, "library"); 792 793 ndirs = cfg_size(lib, "directories"); 794 for (i = 0; i < ndirs; i++) 795 { 796 path = cfg_getnstr(lib, "directories", i); 797 798 deref = m_realpath(path); 799 if (!deref) 800 { 801 DPRINTF(E_LOG, L_SCAN, "Skipping library directory %s, could not dereference: %s\n", path, strerror(errno)); 802 803 continue; 804 } 805 806if(access(REMOTE_PAIRING_FILE,F_OK)==0) 807 remote_pairing_read_pin(REMOTE_PAIRING_FILE); 808 809 process_directories(deref, F_SCAN_BULK); 810 811 free(deref); 812 813 if (scan_exit) 814 return; 815 } 816 817 if (playlists) 818 process_deferred_playlists(); 819 820 if (scan_exit) 821 return; 822 823 if (dirstack) 824 DPRINTF(E_LOG, L_SCAN, "WARNING: unhandled leftover directories\n"); 825 826 DPRINTF(E_DBG, L_SCAN, "Purging old database content\n"); 827 db_purge_cruft(start); 828} 829 830 831/* Thread: scan */ 832static void * 833filescanner(void *arg) 834{ 835 int ret; 836 837 ret = db_perthread_init(); 838 if (ret < 0) 839 { 840 DPRINTF(E_LOG, L_SCAN, "Error: DB init failed\n"); 841 842 pthread_exit(NULL); 843 } 844 845 ret = db_watch_clear(); 846 if (ret < 0) 847 { 848 DPRINTF(E_LOG, L_SCAN, "Error: could not clear old watches from DB\n"); 849 850 pthread_exit(NULL); 851 } 852 853 ret = db_groups_clear(); 854 if (ret < 0) 855 { 856 DPRINTF(E_LOG, L_SCAN, "Error: could not clear old groups from DB\n"); 857 858 pthread_exit(NULL); 859 } 860 861 /* Recompute all songalbumids, in case the SQLite DB got transferred 862 * to a different host; the hash is not portable. 863 * It will also rebuild the groups we just cleared. 864 */ 865 db_files_update_songalbumid(); 866 867 bulk_scan(); 868 869 db_hook_post_scan(); 870 871 if (!scan_exit) 872 { 873 /* Enable inotify */ 874 event_add(&inoev, NULL); 875 876 event_base_dispatch(evbase_scan); 877 } 878 879 if (!scan_exit) 880 DPRINTF(E_FATAL, L_SCAN, "Scan event loop terminated ahead of time!\n"); 881 882 db_perthread_deinit(); 883 884 pthread_exit(NULL); 885} 886 887 888#if defined(__linux__) 889/* Thread: scan */ 890static void 891process_inotify_dir(struct watch_info *wi, char *path, struct inotify_event *ie) 892{ 893 struct watch_enum we; 894 uint32_t rm_wd; 895 int flags = 0; 896 int ret; 897 898 DPRINTF(E_DBG, L_SCAN, "Directory event: 0x%x, cookie 0x%x, wd %d\n", ie->mask, ie->cookie, wi->wd); 899 900 if (ie->mask & IN_UNMOUNT) 901 { 902 db_file_disable_bymatch(path, "", 0); 903 db_pl_disable_bymatch(path, "", 0); 904 } 905 906 if (ie->mask & IN_MOVE_SELF) 907 { 908 /* A directory we know about, that got moved from a place 909 * we know about to a place we know nothing about 910 */ 911 if (wi->cookie) 912 { 913 memset(&we, 0, sizeof(struct watch_enum)); 914 915 we.cookie = wi->cookie; 916 917 ret = db_watch_enum_start(&we); 918 if (ret < 0) 919 return; 920 921 while ((db_watch_enum_fetchwd(&we, &rm_wd) == 0) && (rm_wd)) 922 { 923 inotify_rm_watch(inofd, rm_wd); 924 } 925 926 db_watch_enum_end(&we); 927 928 db_watch_delete_bycookie(wi->cookie); 929 } 930 else 931 { 932 /* If the directory exists, it has been moved and we've 933 * kept track of it successfully, so we're done 934 */ 935 ret = access(path, F_OK); 936 if (ret == 0) 937 return; 938 939 /* Most probably a top-level dir is getting moved, 940 * and we can't tell where it's going 941 */ 942 943 inotify_rm_watch(inofd, ie->wd); 944 db_watch_delete_bywd(ie->wd); 945 946 memset(&we, 0, sizeof(struct watch_enum)); 947 948 we.match = path; 949 950 ret = db_watch_enum_start(&we); 951 if (ret < 0) 952 return; 953 954 while ((db_watch_enum_fetchwd(&we, &rm_wd) == 0) && (rm_wd)) 955 { 956 inotify_rm_watch(inofd, rm_wd); 957 } 958 959 db_watch_enum_end(&we); 960 961 db_watch_delete_bymatch(path); 962 963 db_file_disable_bymatch(path, "", 0); 964 db_pl_disable_bymatch(path, "", 0); 965 } 966 } 967 968 if (ie->mask & IN_MOVED_FROM) 969 { 970 db_watch_mark_bypath(path, path, ie->cookie); 971 db_watch_mark_bymatch(path, path, ie->cookie); 972 db_file_disable_bymatch(path, path, ie->cookie); 973 db_pl_disable_bymatch(path, path, ie->cookie); 974 } 975 976 if (ie->mask & IN_MOVED_TO) 977 { 978 if (db_watch_cookie_known(ie->cookie)) 979 { 980 db_watch_move_bycookie(ie->cookie, path); 981 db_file_enable_bycookie(ie->cookie, path); 982 db_pl_enable_bycookie(ie->cookie, path); 983 984 /* We'll rescan the directory tree to update playlists */ 985 flags |= F_SCAN_RESCAN; 986 } 987 988 ie->mask |= IN_CREATE; 989 } 990 991 if (ie->mask & IN_CREATE) 992 { 993 process_directories(path, flags); 994 995 if (dirstack) 996 DPRINTF(E_LOG, L_SCAN, "WARNING: unhandled leftover directories\n"); 997 } 998} 999 1000/* Thread: scan */ 1001static void 1002process_inotify_file(struct watch_info *wi, char *path, struct inotify_event *ie) 1003{ 1004 struct stat sb; 1005 char *deref = NULL; 1006 char *file = path; 1007 int compilation; 1008 int ret; 1009 1010 DPRINTF(E_DBG, L_SCAN, "File event: 0x%x, cookie 0x%x, wd %d\n", ie->mask, ie->cookie, wi->wd); 1011 1012 if ((!strstr(file, ".mp3")) && 1013 (!strstr(file, ".MP3")) && 1014 (!strstr(file, ".Mp3")) && 1015 (!strstr(file, ".mP3")) && 1016 (!strstr(file, ".wav")) && 1017 (!strstr(file, ".flac")) && 1018 (!strstr(file, ".asf")) && 1019 (!strstr(file, ".wma")) && 1020 (!strstr(file, ".wmv")) && 1021 (!strstr(file, ".m4a")) && 1022 (!strstr(file, ".f4v")) && 1023 (!strstr(file, ".aac")) && 1024 (!strstr(file, ".amr")) && 1025 (!strstr(file, ".awb")) && 1026 (!strstr(file, ".au4")) && 1027 (!strstr(file, ".remote"))) 1028 return; 1029 1030 if(strstr(file,"songs.d-journal")) 1031 return; 1032 1033 if(strstr(file,"sparsebundle")) 1034 return; 1035 1036 if(strstr(file,"sparsebundleands")) 1037 return; 1038 1039 if (ie->mask & IN_DELETE) 1040 { 1041 db_file_delete_bypath(path); 1042 db_pl_delete_bypath(path); 1043 } 1044 1045 if (ie->mask & IN_MOVED_FROM) 1046 { 1047 db_file_disable_bypath(path, wi->path, ie->cookie); 1048 db_pl_disable_bypath(path, wi->path, ie->cookie); 1049 } 1050 1051 if (ie->mask & IN_MOVED_TO) 1052 { 1053 ret = db_file_enable_bycookie(ie->cookie, wi->path); 1054 1055 if (ret <= 0) 1056 { 1057 /* It's not a known media file, so it's either a new file 1058 * or a playlist, known or not. 1059 * We want to scan the new file and we want to rescan the 1060 * playlist to update playlist items (relative items). 1061 */ 1062 ie->mask |= IN_CREATE; 1063 db_pl_enable_bycookie(ie->cookie, wi->path); 1064 } 1065 } 1066 1067 if (ie->mask & (IN_MODIFY | IN_CREATE | IN_CLOSE_WRITE)) 1068 { 1069 ret = lstat(path, &sb); 1070 if (ret < 0) 1071 { 1072 DPRINTF(E_LOG, L_SCAN, "Could not lstat() '%s': %s\n", path, strerror(errno)); 1073 1074 return; 1075 } 1076 1077 if (S_ISLNK(sb.st_mode)) 1078 { 1079 deref = m_realpath(path); 1080 if (!deref) 1081 { 1082 DPRINTF(E_LOG, L_SCAN, "Could not dereference symlink '%s': %s\n", path, strerror(errno)); 1083 1084 return; 1085 } 1086 1087 file = deref; 1088 1089 ret = stat(deref, &sb); 1090 if (ret < 0) 1091 { 1092 DPRINTF(E_LOG, L_SCAN, "Could not stat() '%s': %s\n", file, strerror(errno)); 1093 1094 free(deref); 1095 return; 1096 } 1097 1098 if (S_ISDIR(sb.st_mode)) 1099 { 1100 process_inotify_dir(wi, deref, ie); 1101 1102 free(deref); 1103 return; 1104 } 1105 } 1106 1107 compilation = check_compilation(path); 1108 1109 process_file(file, sb.st_mtime, sb.st_size, compilation, 0); 1110 1111 if (deref) 1112 free(deref); 1113 } 1114} 1115 1116/* Thread: scan */ 1117static void 1118inotify_cb(int fd, short event, void *arg) 1119{ 1120 struct inotify_event *buf; 1121 struct inotify_event *ie; 1122 struct watch_info wi; 1123 char path[PATH_MAX]; 1124 int qsize; 1125 int namelen; 1126 int ret; 1127 1128 /* Determine the size of the inotify queue */ 1129 ret = ioctl(fd, FIONREAD, &qsize); 1130 if (ret < 0) 1131 { 1132 DPRINTF(E_LOG, L_SCAN, "Could not determine inotify queue size: %s\n", strerror(errno)); 1133 1134 return; 1135 } 1136 1137 buf = (struct inotify_event *)malloc(qsize); 1138 if (!buf) 1139 { 1140 DPRINTF(E_LOG, L_SCAN, "Could not allocate %d bytes for inotify events\n", qsize); 1141 1142 return; 1143 } 1144 1145 ret = read(fd, buf, qsize); 1146 if (ret < 0) 1147 { 1148 DPRINTF(E_LOG, L_SCAN, "inotify read failed: %s\n", strerror(errno)); 1149 1150 free(buf); 1151 return; 1152 } 1153 1154 /* ioctl(FIONREAD) returns the number of bytes, now we need the number of elements */ 1155 qsize /= sizeof(struct inotify_event); 1156 1157 /* Loop through all the events we got */ 1158 for (ie = buf; (ie - buf) < qsize; ie += (1 + (ie->len / sizeof(struct inotify_event)))) 1159 { 1160 memset(&wi, 0, sizeof(struct watch_info)); 1161 1162 /* ie[0] contains the inotify event information 1163 * the memory space for ie[1+] contains the name of the file 1164 * see the inotify documentation 1165 */ 1166 wi.wd = ie->wd; 1167 ret = db_watch_get_bywd(&wi); 1168 if (ret < 0) 1169 { 1170 if (!(ie->mask & IN_IGNORED)) 1171 DPRINTF(E_LOG, L_SCAN, "No matching watch found, ignoring event (0x%x)\n", ie->mask); 1172 1173 continue; 1174 } 1175 1176 if (ie->mask & IN_IGNORED) 1177 { 1178 DPRINTF(E_DBG, L_SCAN, "%s deleted or backing filesystem unmounted!\n", wi.path); 1179 1180 db_watch_delete_bywd(ie->wd); 1181 free(wi.path); 1182 continue; 1183 } 1184 1185 path[0] = '\0'; 1186 1187 ret = snprintf(path, PATH_MAX, "%s", wi.path); 1188 if ((ret < 0) || (ret >= PATH_MAX)) 1189 { 1190 DPRINTF(E_LOG, L_SCAN, "Skipping event under %s, PATH_MAX exceeded\n", wi.path); 1191 1192 free(wi.path); 1193 continue; 1194 } 1195 1196 if (ie->len > 0) 1197 { 1198 namelen = PATH_MAX - ret; 1199 ret = snprintf(path + ret, namelen, "/%s", ie->name); 1200 if ((ret < 0) || (ret >= namelen)) 1201 { 1202 DPRINTF(E_LOG, L_SCAN, "Skipping %s/%s, PATH_MAX exceeded\n", wi.path, ie->name); 1203 1204 free(wi.path); 1205 continue; 1206 } 1207 } 1208 1209 /* ie->len == 0 catches events on the subject of the watch itself. 1210 * As we only watch directories, this catches directories. 1211 * General watch events like IN_UNMOUNT and IN_IGNORED do not come 1212 * with the IN_ISDIR flag set. 1213 */ 1214 if ((ie->mask & IN_ISDIR) || (ie->len == 0)) 1215 process_inotify_dir(&wi, path, ie); 1216 else 1217 process_inotify_file(&wi, path, ie); 1218 1219 free(wi.path); 1220 } 1221 1222 free(buf); 1223 1224 event_add(&inoev, NULL); 1225} 1226#endif /* __linux__ */ 1227 1228 1229#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 1230/* Thread: scan */ 1231static void 1232kqueue_cb(int fd, short event, void *arg) 1233{ 1234 struct kevent kev; 1235 struct timespec ts; 1236 struct watch_info wi; 1237 struct watch_enum we; 1238 struct stacked_dir *rescan; 1239 struct stacked_dir *d; 1240 struct stacked_dir *dprev; 1241 char *path; 1242 uint32_t wd; 1243 int d_len; 1244 int w_len; 1245 int need_rescan; 1246 int ret; 1247 1248 ts.tv_sec = 0; 1249 ts.tv_nsec = 0; 1250 1251 we.cookie = 0; 1252 1253 rescan = NULL; 1254 1255 DPRINTF(E_DBG, L_SCAN, "Library changed!\n"); 1256 1257 /* We can only monitor directories with kqueue; to monitor files, we'd need 1258 * to have an open fd on every file in the library, which is totally insane. 1259 * Unfortunately, that means we only know when directories get renamed, 1260 * deleted or changed. We don't get directory/file names when directories/files 1261 * are created/deleted/renamed in the directory, so we have to rescan. 1262 */ 1263 while (kevent(fd, NULL, 0, &kev, 1, &ts) > 0) 1264 { 1265 /* This should not happen, and if it does, we'll end up in 1266 * an infinite loop. 1267 */ 1268 if (kev.filter != EVFILT_VNODE) 1269 continue; 1270 1271 wi.wd = kev.ident; 1272 1273 ret = db_watch_get_bywd(&wi); 1274 if (ret < 0) 1275 { 1276 DPRINTF(E_LOG, L_SCAN, "Found no matching watch for kevent, killing this event\n"); 1277 1278 close(kev.ident); 1279 continue; 1280 } 1281 1282 /* Whatever the type of event that happened, disable matching watches and 1283 * files before we trigger an eventual rescan. 1284 */ 1285 we.match = wi.path; 1286 1287 ret = db_watch_enum_start(&we); 1288 if (ret < 0) 1289 { 1290 free(wi.path); 1291 continue; 1292 } 1293 1294 while ((db_watch_enum_fetchwd(&we, &wd) == 0) && (wd)) 1295 { 1296 close(wd); 1297 } 1298 1299 db_watch_enum_end(&we); 1300 1301 db_watch_delete_bymatch(wi.path); 1302 1303 close(wi.wd); 1304 db_watch_delete_bywd(wi.wd); 1305 1306 /* Disable files */ 1307 db_file_disable_bymatch(wi.path, "", 0); 1308 db_pl_disable_bymatch(wi.path, "", 0); 1309 1310 if (kev.flags & EV_ERROR) 1311 { 1312 DPRINTF(E_LOG, L_SCAN, "kevent reports EV_ERROR (%s): %s\n", wi.path, strerror(kev.data)); 1313 1314 ret = access(wi.path, F_OK); 1315 if (ret != 0) 1316 { 1317 free(wi.path); 1318 continue; 1319 } 1320 1321 /* The directory still exists, so try to add it back to the library */ 1322 kev.fflags |= NOTE_WRITE; 1323 } 1324 1325 /* No further action on NOTE_DELETE & NOTE_RENAME; NOTE_WRITE on the 1326 * parent directory will trigger a rescan in both cases and the 1327 * renamed directory will be picked up then. 1328 */ 1329 1330 if (kev.fflags & NOTE_WRITE) 1331 { 1332 DPRINTF(E_DBG, L_SCAN, "Got NOTE_WRITE (%s)\n", wi.path); 1333 1334 need_rescan = 1; 1335 w_len = strlen(wi.path); 1336 1337 /* Abusing stacked_dir a little bit here */ 1338 dprev = NULL; 1339 d = rescan; 1340 while (d) 1341 { 1342 d_len = strlen(d->path); 1343 1344 if (d_len > w_len) 1345 { 1346 /* Stacked dir child of watch dir? */ 1347 if ((d->path[w_len] == '/') && (strncmp(d->path, wi.path, w_len) == 0)) 1348 { 1349 DPRINTF(E_DBG, L_SCAN, "Watched directory is a parent\n"); 1350 1351 if (dprev) 1352 dprev->next = d->next; 1353 else 1354 rescan = d->next; 1355 1356 free(d->path); 1357 free(d); 1358 1359 if (dprev) 1360 d = dprev->next; 1361 else 1362 d = rescan; 1363 1364 continue; 1365 } 1366 } 1367 else if (w_len > d_len) 1368 { 1369 /* Watch dir child of stacked dir? */ 1370 if ((wi.path[d_len] == '/') && (strncmp(wi.path, d->path, d_len) == 0)) 1371 { 1372 DPRINTF(E_DBG, L_SCAN, "Watched directory is a child\n"); 1373 1374 need_rescan = 0; 1375 break; 1376 } 1377 } 1378 else if (strcmp(wi.path, d->path) == 0) 1379 { 1380 DPRINTF(E_DBG, L_SCAN, "Watched directory already listed\n"); 1381 1382 need_rescan = 0; 1383 break; 1384 } 1385 1386 dprev = d; 1387 d = d->next; 1388 } 1389 1390 if (need_rescan) 1391 push_dir(&rescan, wi.path); 1392 } 1393 1394 free(wi.path); 1395 } 1396 1397 while ((path = pop_dir(&rescan))) 1398 { 1399 process_directories(path, 0); 1400 1401 free(path); 1402 1403 if (rescan) 1404 DPRINTF(E_LOG, L_SCAN, "WARNING: unhandled leftover directories\n"); 1405 } 1406 1407 event_add(&inoev, NULL); 1408} 1409#endif /* __FreeBSD__ || __FreeBSD_kernel__ */ 1410 1411 1412/* Thread: scan */ 1413static void 1414exit_cb(int fd, short event, void *arg) 1415{ 1416 event_base_loopbreak(evbase_scan); 1417 1418 scan_exit = 1; 1419} 1420 1421/* Added by Foxconn Antony Start 07/08/2013 */ 1422int filescanner_rescan() 1423{ 1424 int ret; 1425 ret = pthread_create(&tid_scan, NULL, filescanner, NULL); 1426 if (ret != 0) 1427 { 1428 DPRINTF(E_FATAL, L_SCAN, "Could not spawn filescanner thread: %s\n", strerror(errno)); 1429 } 1430} 1431 1432/* Added by Foxconn Antony End */ 1433 1434/* Thread: main */ 1435int 1436filescanner_init(void) 1437{ 1438 int ret; 1439 1440 struct sched_param t_scan_param; 1441 int rs; 1442 int policy; 1443 int sched = SCHED_RR; 1444 1445 scan_exit = 0; 1446 1447 evbase_scan = event_base_new(); 1448 if (!evbase_scan) 1449 { 1450 DPRINTF(E_FATAL, L_SCAN, "Could not create an event base\n"); 1451 1452 return -1; 1453 } 1454 1455#ifdef USE_EVENTFD 1456 exit_efd = eventfd(0, EFD_CLOEXEC); 1457 if (exit_efd < 0) 1458 { 1459 DPRINTF(E_FATAL, L_SCAN, "Could not create eventfd: %s\n", strerror(errno)); 1460 1461 goto pipe_fail; 1462 } 1463#else 1464# if defined(__linux__) 1465 ret = pipe2(exit_pipe, O_CLOEXEC); 1466# else 1467 ret = pipe(exit_pipe); 1468# endif 1469 if (ret < 0) 1470 { 1471 DPRINTF(E_FATAL, L_SCAN, "Could not create pipe: %s\n", strerror(errno)); 1472 1473 goto pipe_fail; 1474 } 1475#endif /* USE_EVENTFD */ 1476 1477#if defined(__linux__) 1478 inofd = inotify_init1(IN_CLOEXEC); 1479 if (inofd < 0) 1480 { 1481 DPRINTF(E_FATAL, L_SCAN, "Could not create inotify fd: %s\n", strerror(errno)); 1482 1483 goto ino_fail; 1484 } 1485 1486 event_set(&inoev, inofd, EV_READ, inotify_cb, NULL); 1487 1488#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 1489 1490 inofd = kqueue(); 1491 if (inofd < 0) 1492 { 1493 DPRINTF(E_FATAL, L_SCAN, "Could not create kqueue: %s\n", strerror(errno)); 1494 1495 goto ino_fail; 1496 } 1497 1498 event_set(&inoev, inofd, EV_READ, kqueue_cb, NULL); 1499#endif 1500 1501 event_base_set(evbase_scan, &inoev); 1502 1503#ifdef USE_EVENTFD 1504 event_set(&exitev, exit_efd, EV_READ, exit_cb, NULL); 1505#else 1506 event_set(&exitev, exit_pipe[0], EV_READ, exit_cb, NULL); 1507#endif 1508 event_base_set(evbase_scan, &exitev); 1509 event_add(&exitev, NULL); 1510 1511 ret = pthread_create(&tid_scan, NULL, filescanner, NULL); 1512 if (ret != 0) 1513 { 1514 DPRINTF(E_FATAL, L_SCAN, "Could not spawn filescanner thread: %s\n", strerror(errno)); 1515 1516 goto thread_fail; 1517 } 1518 1519 t_scan_param.sched_priority = 80; 1520 1521 pthread_setschedparam(tid_scan, sched, &t_scan_param); 1522 1523 return 0; 1524 1525 thread_fail: 1526 close(inofd); 1527 ino_fail: 1528#ifdef USE_EVENTFD 1529 close(exit_efd); 1530#else 1531 close(exit_pipe[0]); 1532 close(exit_pipe[1]); 1533#endif 1534 pipe_fail: 1535 event_base_free(evbase_scan); 1536 1537 return -1; 1538} 1539 1540/* Thread: main */ 1541void 1542filescanner_deinit(void) 1543{ 1544 int ret; 1545 1546#ifdef USE_EVENTFD 1547 ret = eventfd_write(exit_efd, 1); 1548 if (ret < 0) 1549 { 1550 DPRINTF(E_FATAL, L_SCAN, "Could not send exit event: %s\n", strerror(errno)); 1551 1552 return; 1553 } 1554#else 1555 int dummy = 42; 1556 1557 ret = write(exit_pipe[1], &dummy, sizeof(dummy)); 1558 if (ret != sizeof(dummy)) 1559 { 1560 DPRINTF(E_FATAL, L_SCAN, "Could not write to exit fd: %s\n", strerror(errno)); 1561 1562 return; 1563 } 1564#endif 1565 1566 ret = pthread_join(tid_scan, NULL); 1567 if (ret != 0) 1568 { 1569 DPRINTF(E_FATAL, L_SCAN, "Could not join filescanner thread: %s\n", strerror(errno)); 1570 1571 return; 1572 } 1573 1574 event_del(&inoev); 1575 1576#ifdef USE_EVENTFD 1577 close(exit_efd); 1578#else 1579 close(exit_pipe[0]); 1580 close(exit_pipe[1]); 1581#endif 1582 close(inofd); 1583 event_base_free(evbase_scan); 1584} 1585