Пример #1
0
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;
}
Пример #2
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}