static int clearTn(const char *pathMedia, const char *pathDb, const FILE_LIST_T *pFileList) { DIR *pdir; struct dirent *direntry; char buf[VSX_MAX_PATH_LEN]; char buf2[VSX_MAX_PATH_LEN]; size_t sz,sz2; if(!(pdir = fileops_OpenDir(pathDb))) { return -1; } buf[sizeof(buf) - 1] = '\0'; while((direntry = fileops_ReadDir(pdir))) { if(!(direntry->d_type & DT_DIR)) { // "_tn[idx].jpg" if((sz = strlen(direntry->d_name)) > 9 && (!strncasecmp(&direntry->d_name[sz - 4], ".jpg", 4) || !strncasecmp(&direntry->d_name[sz - VSXTMP_EXT_LEN], VSXTMP_EXT, VSXTMP_EXT_LEN) || !strncasecmp(&direntry->d_name[sz - NOTN_EXT_LEN], NOTN_EXT, NOTN_EXT_LEN))) { strncpy(buf, direntry->d_name, sizeof(buf) - 1); for(sz2 = sz - 4; sz2 > sz - 12; sz2--) { if(buf[sz2] == '_') { break; } } buf[sz2] = '\0'; //fprintf(stdout, "check '%s' '%s'\n", buf, direntry->d_name); if(file_list_find(pFileList, buf) == NULL) { mediadb_prepend_dir(pathDb, direntry->d_name, buf2, sizeof(buf)); LOG(X_DEBUG("Removing thumbnail '%s'\n"), buf2); if(fileops_DeleteFile(buf2) != 0) { LOG(X_ERROR("Failed to delete thumbnail %s"), buf2); } } } } } fileops_CloseDir(pdir); return 0; }
static int iterate_subdirs(const MEDIADB_DESCR_T *pMediaDb, const char *pathDb, const char *pathMedia, int level, unsigned int iterIdx) { DIR *pdir; FILE_LIST_T fileList; FILE_LIST_ENTRY_T *pFileListEntry; struct dirent *direntry; char bufMedia[VSX_MAX_PATH_LEN]; char bufDb[VSX_MAX_PATH_LEN]; char tmpfile[VSX_MAX_PATH_LEN]; int rc = 0; int rcsub = 0; int fileListChanged = 0; int numTnCreated = 0; int highestTn; struct stat st; //fprintf(stdout, "%d dir:'%s' '%s'\n", level, pathDb, pathMedia); // // TODO: escape invalid chars in pathnames ' , & # $ ' // if(level >= SRVMEDIA_MAX_LEVELS) { LOG(X_WARNING("Path '%s' exceeded max number of subdirs under %s"), pathMedia, pMediaDb->mediaDir); return -1; } if(!(pdir = fileops_OpenDir(pathMedia))) { return -1; } memset(&fileList, 0, sizeof(fileList)); file_list_read(pathDb, &fileList); strncpy(fileList.pathmedia, pathMedia, sizeof(fileList.pathmedia) - 1); while((direntry = fileops_ReadDir(pdir)) && g_proc_exit == 0) { //fprintf(stdout, "- %d %s\n", level, direntry->d_name); if(direntry->d_type & DT_DIR) { if(mediadb_isvalidDirName(pMediaDb, direntry->d_name)) { if(mediadb_prepend_dir(pathDb, direntry->d_name, bufDb, sizeof(bufDb)) < 0) { LOG(X_WARNING("Unable to concatenate subdir %s %s"), bufDb, direntry->d_name); } else if(mediadb_prepend_dir(pathMedia, direntry->d_name, bufMedia, sizeof(bufMedia)) < 0) { LOG(X_WARNING("Unable to concatenate subdir %s %s"), bufMedia, direntry->d_name); } else { if(numTnCreated > 1) { file_list_write(pathDb, &fileList); } if((rcsub = iterate_subdirs(pMediaDb, bufDb, bufMedia, level+1, iterIdx)) < 0) { rc = rcsub; } if(g_proc_exit != 0) { break; } } } else if(direntry->d_name[0] != '.') { //fprintf(stderr, "skipping directory '%s'\n", direntry->d_name); } } else if(mediadb_isvalidFileName(pMediaDb, direntry->d_name, 1, 0)) { //fprintf(stdout, "%d media file %s '%s'\n", level, pathMedia, direntry->d_name); if(fileops_stat(pathDb, &st) != 0 && mediadb_mkdirfull(pMediaDb->dbDir, pathDb) < 0) { continue; } if(mediadb_prepend_dir(pathDb, direntry->d_name, bufDb, sizeof(bufDb)) < 0) { LOG(X_ERROR("Unable to concatenate subdir %s %s"), bufDb, direntry->d_name); continue; } else if(mediadb_prepend_dir(pathMedia, direntry->d_name, bufMedia, sizeof(bufMedia)) < 0) { LOG(X_ERROR("Unable to concatenate subdir %s %s"), bufMedia, direntry->d_name); continue; } if(update_fileentry(&fileList, direntry->d_name, bufMedia, &pFileListEntry) > 0) { LOG(X_DEBUG("'%s' changed ('%s')"), direntry->d_name, pFileListEntry->name); fileListChanged = 1; if(pFileListEntry->numTn < 0) { pFileListEntry->numTn = 0; } } if(pMediaDb->avcthumb && pFileListEntry && pFileListEntry->vstr[0] != '\0' && pFileListEntry->numTn != -1) { // // On very first iteration, check all thumbnails // snprintf(tmpfile, sizeof(tmpfile), "%s%s."NOTN_EXT, bufDb, pMediaDb->tn_suffix); if(fileops_stat(tmpfile, &st) == 0 && iterIdx > 0) { // // Ignore thumbnail creation if the .notn file has been // previously created on an error condition // } else // // Update thumbnail info // if((highestTn = createTn(pMediaDb, pFileListEntry, bufMedia, bufDb, pFileListEntry->numTn, 1)) > pFileListEntry->numTn || highestTn == -1) { pFileListEntry->numTn = highestTn; fileListChanged = 1; // Periodically update the db file if(numTnCreated > 10) { file_list_write(pathDb, &fileList); numTnCreated = 0; } } } } else { //fprintf(stdout, "skipping %s '%s'\n", pathMedia, direntry->d_name); } } fileops_CloseDir(pdir); if(g_proc_exit == 0) { if(file_list_removeunmarked(&fileList) || fileListChanged) { LOG(X_DEBUG("Writing file index in %s"), pathDb); //fprintf(stdout, "level:%u\n", level); file_list_write(pathDb, &fileList); } // //Remove thumbnails which are not included in the fileList // clearTn(pathMedia, pathDb, &fileList); } file_list_close(&fileList); return rc; }
DIR_ENTRY_LIST_T *direntry_getentries(const MEDIADB_DESCR_T *pMediaDb, const char *dir, const char *fidxdir, const char *searchstr, int includedirs, unsigned int startidx, unsigned int max, enum DIR_SORT sort) { DIR *pdir; int rc = 0; struct dirent *direntry; char path[VSX_MAX_PATH_LEN]; struct stat st; int addEntry; FILE_LIST_T fileList; FILE_LIST_ENTRY_T *pFileEntry = NULL; META_FILE_T metaFile; DIR_ENTRY_LIST_T *pEntryList = NULL; DIR_ENTRY_T entry; DIR_ENTRY_T *pEntry; const char *pdispname; unsigned int idx = 0; unsigned int cnt = 0; unsigned int cntInDir = 0; COMPARE_DIR_ENTRY compareFunc = direntry_getcompfunc(sort); VSX_DEBUG_MGR( LOG(X_DEBUG("MGR - direntry_getentries dir: '%s', fidxdir: '%s', searchstr: '%s', " "includedirs: %d, startidx: %d, max: %d"), dir, fidxdir, searchstr, includedirs, startidx, max)); if(!(pdir = fileops_OpenDir(dir))) { return NULL; } memset(&fileList, 0, sizeof(fileList)); if(fidxdir) { file_list_read(fidxdir, &fileList); } // // Read the directory wide metafile to get a list of 'ignore' entries // memset(&metaFile, 0, sizeof(metaFile)); mediadb_prepend_dir(dir, METAFILE_DEFAULT, path, sizeof(path)); if(fileops_stat(path, &st) == 0) { metafile_open(path, &metaFile, 1, 1); } while((direntry = fileops_ReadDir(pdir))) { VSX_DEBUG_MGR( LOG(X_DEBUGV("MGR - direntry_getentries d_name: '%s', isdir: %d"), direntry->d_name, (direntry->d_type & DT_DIR)) ); if(is_entry_ignored(metaFile.pignoreList, direntry->d_name)) { continue; } if(!(pdispname = find_entry_description(metaFile.pDescriptionList, direntry->d_name))) { pdispname = direntry->d_name; } if(searchstr && !is_match_search(pdispname, NULL, searchstr)) { continue; } memset(&entry, 0, sizeof(entry)); strncpy(entry.d_name, direntry->d_name, sizeof(entry.d_name) - 1); if(pdispname != direntry->d_name) { strncpy(entry.displayname, pdispname, sizeof(entry.displayname) - 1); } entry.d_type = direntry->d_type; addEntry = 0; if(direntry->d_type & DT_DIR) { if(includedirs && mediadb_isvalidDirName(pMediaDb, direntry->d_name)) { addEntry = 1; } } else if(mediadb_isvalidFileName(pMediaDb, direntry->d_name, 1, 1)) { mediadb_prepend_dir(dir, direntry->d_name, path, sizeof(path)); if(fileops_stat(path, &st) == 0) { entry.size = st.st_size; //entry.tm = st.st_mtime; entry.tm = st.st_ctime; if(fidxdir && (pFileEntry = file_list_find(&fileList, direntry->d_name))) { entry.numTn = pFileEntry->numTn; entry.duration = pFileEntry->duration; } addEntry = 1; } } if(addEntry) { VSX_DEBUG_MGR( LOG(X_DEBUGV("MGR - direntry_getentries add d_name: '%s', isdir: %d"), direntry->d_name, (direntry->d_type & DT_DIR)) ); if(compareFunc || (idx >= startidx && (max == 0 || cnt < max))) { if(cnt >= DIR_ENTRY_LIST_BUFNUM) { LOG(X_WARNING("Not showing more than %d entries in %s"), cnt, dir); break; } else if(!(pEntry = direntry_addsorted(&pEntryList, &entry, compareFunc))) { LOG(X_ERROR("Failed to add directory entry '%s' to list"), direntry->d_name); rc = -1; break; } cnt++; } idx++; cntInDir++; } } // // Since when a sort is requested we have to sort every entry in the directory. Now we can move the head pointer // to the first desired entry // if(pEntryList && compareFunc && startidx > 0) { pEntry = pEntryList->pHead; for(idx = 0; idx < startidx; idx++) { pEntry = pEntry->pnext; cnt--; } pEntryList->pHead = pEntry; if(cnt > max) { cnt = max; } //fprintf(stderr, "moved phead to %s, cnt:%d, cntInDir:%d\n", pEntryList->pHead ? pEntryList->pHead->d_name : NULL, cnt, cntInDir); } fileops_CloseDir(pdir); if(fidxdir) { file_list_close(&fileList); } metafile_close(&metaFile); if(rc == 0 && !pEntryList) { // If the user requested an index out of bounds, return an empty list with // a valid cntTotalInDir pEntryList = (DIR_ENTRY_LIST_T *) avc_calloc(1, sizeof(DIR_ENTRY_LIST_T)); } if(pEntryList) { pEntryList->cntTotal = cnt; pEntryList->cntTotalInDir = cntInDir; } //if(pEntryList) fprintf(stderr, "DIR '%s' num:%d numAlloc:%d pnext:0x%x TOTAL:%d/%d\n", dir, pEntryList->num, pEntryList->numAlloc, pEntryList->pnext, pEntryList->cntTotal, pEntryList->cntTotalInDir); return pEntryList; }
int http_purge_segments(const char *dirpath, const char *fileprefix, const char *ext, unsigned int idxmin, int purgeNonIdx) { DIR *pdir; struct dirent *direntry; //struct stat st; char path[VSX_MAX_PATH_LEN]; int rc = 0; char stridx[32]; unsigned int idx; size_t sz; size_t szext; unsigned int szprfx; int isNumeric; if(!dirpath || !fileprefix || !ext) { return -1; } //fprintf(stderr, "http_purge_segments '%s', '%s', '%s', idxmin:%d\n", dirpath, fileprefix, ext, idxmin); if(!(pdir = fileops_OpenDir(dirpath))) { return -1; } szprfx = strlen(fileprefix); szext = strlen(ext); while((direntry = fileops_ReadDir(pdir))) { if(!(direntry->d_type & DT_DIR) && (sz = strlen(direntry->d_name)) >= 7 && !strncasecmp(&direntry->d_name[sz - szext], ext, szext) && !strncasecmp(direntry->d_name, fileprefix, szprfx)) { if((sz = (sz - szprfx - szext)) >= sizeof(stridx)) { sz = sizeof(stridx) - 1; } memcpy(stridx, &direntry->d_name[szprfx], sz); stridx[sz] = '\0'; isNumeric = 1; for(idx = 0; idx < sz; idx++) { if(!CHAR_NUMERIC(stridx[idx])) { isNumeric = 0; break; } } if(isNumeric) { idx = atoi(stridx); } else if(purgeNonIdx) { idx = 0; } else { idx = idxmin; } //fprintf(stderr, "purge_segment '%s' idx:%d ('%s') < %d\n", direntry->d_name, idx, stridx, idxmin); if(idx < idxmin) { mediadb_prepend_dir(dirpath, direntry->d_name, path, sizeof(path)); LOG(X_DEBUG("Deleting '%s'"), path); if(fileops_DeleteFile(path) != 0) { LOG(X_ERROR("Failed to delete '%s'"), path); } } } } fileops_CloseDir(pdir); return rc; }