예제 #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
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;
}
예제 #3
0
static int update_fileentry(FILE_LIST_T *pFileList, const char *mediaName, 
                            const char *mediaPath, FILE_LIST_ENTRY_T **ppEntry) {
  MEDIA_DESCRIPTION_T mediaDescr;
  FILE_STREAM_T fileStream;
  FILE_LIST_ENTRY_T *pFileEntryCur = NULL;
  FILE_LIST_ENTRY_T *pFileEntryNew = NULL;
  FILE_LIST_ENTRY_T fileEntry;
  char buf[VSX_MAX_PATH_LEN];
  struct stat st;
  struct stat st2;
  int havestat = 0;
  size_t szt;
  int fileChanged = 1;

  memset(&fileEntry, 0, sizeof(fileEntry));
      
//fprintf(stdout, "looking for '%s'\n", mediaName);
  if((pFileEntryCur = file_list_find(pFileList, mediaName))) {

    //fprintf(stdout, "found entry '%s' numTn:%d\n", pFileEntryCur->name, pFileEntryCur->numTn);

    // mark the entry as current to avoid deletion
    pFileEntryCur->flag = 1;
        
    if((havestat = !fileops_stat(mediaPath, &st)) == 0) {
      LOG(X_ERROR("Unable to stat '%s'"), mediaPath);
    } else if(st.st_size == pFileEntryCur->size &&
              st.st_ctime == pFileEntryCur->tm) {

      fileChanged = 0;

      //
      // Special case to probe for recent creation .seek file
      // since the last time this entry was written
      //
      if(pFileEntryCur->duration == 0) {
        buf[sizeof(buf) - 1] = '\0';
        strncpy(buf, mediaPath, sizeof(buf) - 1);
        if((szt = strlen(buf))) {
          strncpy(&buf[szt], MP2TS_FILE_SEEKIDX_NAME, sizeof(buf) - szt - 1);
        }
        if(fileops_stat(buf, &st2) == 0) {
          fileChanged = 1;        
        }
      }

    }
    pFileEntryNew = pFileEntryCur;

  } else {

    // Check for invalid chars - ',' is used as a delimeter in .avcfidx
    if(strchr(mediaName, ',') || mediaName[0] == '#' || mediaName[0] == ' ' ||
              mediaName[0] == '=') {
      LOG(X_WARNING("Illegal filename '%s' not added to database"), mediaPath);
      pFileEntryNew = NULL;
      fileChanged = 0;
    } else {
      LOG(X_DEBUG("Could not find database entry '%s'"), mediaPath);
      pFileEntryNew = &fileEntry;
    }
  }

  if(fileChanged) {

    if(OpenMediaReadOnly(&fileStream, mediaPath) == 0) {

      memset(&mediaDescr, 0, sizeof(mediaDescr));

      if(filetype_getdescr(&fileStream, &mediaDescr, 1) == 0) {

         pFileEntryNew->flag = 1;
         pFileEntryNew->duration = mediaDescr.durationSec; 
         pFileEntryNew->size = mediaDescr.totSz;

         if(!havestat && (havestat = !fileops_stat(mediaPath, &st)) == 0) {
           LOG(X_ERROR("Unable to stat new entry '%s'"), mediaPath);
         }
         if(havestat) {
           pFileEntryNew->tm = st.st_ctime;
//fprintf(stderr, "-----------set tm:%ld %s\n", pFileEntryNew->tm, mediaPath);
         }

         if(mediaDescr.haveVid) {
           create_viddescrstr(&mediaDescr, pFileEntryNew->vstr, sizeof(pFileEntryNew->vstr));
         }
         if(mediaDescr.haveAud) {
           create_auddescrstr(&mediaDescr, pFileEntryNew->astr, sizeof(pFileEntryNew->astr));
           //fprintf(stdout, "aud descr:'%s'\n", pFileEntryNew->astr);
         }

       } else {
         pFileEntryNew->flag = 1;
         pFileEntryNew->size = fileStream.size;
       }

       CloseMediaFile(&fileStream);
    } // end of OpenMediaReadOnly

    if(pFileEntryCur == NULL) {
      pFileEntryNew->name[sizeof(pFileEntryNew->name) - 1] = '\0';
      strncpy(pFileEntryNew->name, mediaName, sizeof(pFileEntryNew->name) - 1);
      pFileEntryCur = file_list_addcopy(pFileList, pFileEntryNew);
    }
  } // end of if(fileChanged)

  if(ppEntry) {
    *ppEntry = pFileEntryCur;
  }

  return fileChanged; 
}
예제 #4
0
파일: tuifs.c 프로젝트: AreaScout/vice
/* FIXME: documentation.  */
char *tui_file_selector(const char *title, const char *directory,
                        const char *pattern, const char *default_item,
                        read_contents_func_type contents_func,
                        char **browse_file_return,
                        unsigned int *browse_file_number_return)
{
    static char *return_path = NULL;
    struct file_list *fl;
    int curr_item, first_item, need_update;
    int x, y, width, height, num_cols, num_lines, field_width;
    int num_files;
    char str[0x100];
    int str_len = 0;
    tui_area_t backing_store = NULL;

    if (contents_func != NULL) {
        *browse_file_return = NULL;
    }

    if (browse_file_number_return != NULL) {
        *browse_file_number_return = 0;
    }

    if (directory != NULL) {
        return_path = lib_stralloc(directory);
    } else {
        return_path = ioutil_current_dir();
    }

    slashize_path(&return_path);

    fl = file_list_read(return_path, pattern);
    if (fl == NULL) {
        return NULL;
    }

    first_item = curr_item = 0;
    num_cols = 4;
    field_width = 18;
    num_lines = 17;
    height = num_lines + 2;
    width = field_width * num_cols + 4;
    num_files = num_cols * num_lines;

    if (default_item != NULL && *default_item) {
        int i;

        for (i = 0; i < fl->num_items; i++) {
            if (!strcasecmp(default_item, fl->items[i].name)) {
                curr_item = i;
                while (curr_item - first_item >= num_files) {
                    first_item += num_lines;
                }
                break;
            }
        }
    }

    x = CENTER_X(width);
    y = CENTER_Y(height);

    need_update = 1;

    tui_area_get(&backing_store, x, y, width + 2, height + 1);

    tui_display_window(x, y, width, height, MENU_BORDER, MENU_BACK, title, NULL);

    while (1) {
        int key;

        tui_set_attr(MENU_FORE, MENU_BACK, 0);
        if (need_update) {
            file_selector_display_path(return_path, x + 1, y + height - 1, width - 2);
            file_selector_update(fl, first_item, x + 2, y + 1, field_width, num_lines, num_cols);
            tui_set_attr(FIRST_LINE_FORE, FIRST_LINE_BACK, 0);
            tui_display(0, tui_num_lines() - 1, tui_num_cols(), "\030\031\033\032: Move  <Enter>: Select  %s<Alt>-<letter>: Change drive", contents_func != NULL ? "<Space>: Preview  " : "");
            need_update = 0;
        }
        tui_set_attr(MENU_FORE, MENU_HIGHLIGHT, 0);
        file_selector_display_item(fl, curr_item, first_item, x + 2, y + 1, field_width, num_lines, num_cols);
        key = getkey();
        tui_set_attr(MENU_FORE, MENU_BACK, 0);
        file_selector_display_item(fl, curr_item, first_item, x + 2, y + 1, field_width, num_lines, num_cols);

        switch (key) {
            case K_Escape:
                tui_area_put(backing_store, x, y);
                tui_area_free(backing_store);
                return NULL;
            case K_Left:
                str_len = 0;
                if (curr_item - num_lines >= 0) {
                    curr_item -= num_lines;
                    if (curr_item < first_item) {
                        if (first_item >= num_lines) {
                            first_item -= num_lines;
                            need_update = 1;
                        } else {
                            curr_item += num_lines;
                        }
                    }
                }
                break;
            case K_Up:
                str_len = 0;
                if (curr_item > 0) {
                    curr_item--;
                    if (curr_item < first_item) {
                        first_item = curr_item;
                        need_update = 1;
                    }
                }
                break;
            case K_Right:
                str_len = 0;
                if (curr_item + num_lines < fl->num_used_items) {
                    curr_item += num_lines;
                    if (curr_item - first_item >= num_files) {
                        first_item += num_lines;
                        need_update = 1;
                    }
                }
                break;
            case K_Down:
                str_len = 0;
                if (curr_item < fl->num_used_items - 1) {
                    curr_item++;
                    if (curr_item == first_item + num_files) {
                        first_item++;
                        need_update = 1;
                    }
                }
                break;
            case K_PageDown:
                str_len = 0;
                if (curr_item + num_files < fl->num_used_items) {
                    curr_item += num_files;
                    first_item += num_files;
                }
                need_update = 1;
                break;
            case K_PageUp:
                str_len = 0;
                if (curr_item - num_files >= 0) {
                    curr_item -= num_files;
                    first_item -= num_files;
                    if (first_item < 0) {
                        first_item = 0;
                    }
                    need_update = 1;
                }
                break;
            case K_Home:
                str_len = 0;
                curr_item = 0;
                if (first_item != 0) {
                    first_item = 0;
                    need_update = 1;
                }
                break;
            case K_End:
                str_len = 0;
                curr_item = fl->num_used_items - 1;
                first_item = curr_item - num_files + 1;
                if (first_item < 0) {
                    first_item = 0;
                }
                need_update = 1;
                break;
            case K_Return:
                str_len = 0;
                if (fl->items[curr_item].type == FT_DIR) {
                    struct file_list *new_fl;
                    char *new_path;

                    new_path = change_path(fl, return_path, curr_item);

                    new_fl = file_list_read(new_path, pattern);

                    if (new_fl != NULL) {
                        file_list_free(fl);
                        fl = new_fl;
                        first_item = curr_item = 0;
                        lib_free(return_path);
                        return_path = new_path;
                        need_update = 1;
                        ioutil_chdir(return_path);
                    } else {
                        lib_free(new_path);
                    }
                } else {
                    char *p = util_concat(return_path, fl->items[curr_item].name, NULL);

                    lib_free(return_path);
                    return_path = p;
                    tui_area_put(backing_store, x, y);
                    tui_area_free(backing_store);
                    return return_path;
                }
                break;
            case K_BackSpace:
                if (str_len > 1) {
                    int n;
                    str_len--;
                    n = file_list_find(fl, str, str_len);
                    if (n >= 0) {
                        curr_item = n;
                        if (curr_item < first_item) {
                            first_item = curr_item;
                            need_update = 1;
                        } else if (first_item + num_files <= curr_item) {
                            first_item = curr_item - num_files + 1;
                            need_update = 1;
                        }
                    }
                } else {
                    str_len = 0;
                    curr_item = 0;
                    if (first_item != 0) {
                        first_item = 0;
                        need_update = 1;
                    }
                }
                break;
            case ' ':
                if (contents_func != NULL && fl->items[curr_item].type != FT_DIR && browse_file_return != NULL) {
                    tui_display(0, tui_num_lines() - 1, tui_num_cols(), "");
                    *browse_file_return = tui_image_browser(fl->items[curr_item].name, contents_func, browse_file_number_return);
                    if (*browse_file_return != NULL) {
                        char *p = util_concat(return_path, fl->items[curr_item].name, NULL);

                        lib_free(return_path);
                        return_path = p;
                        tui_area_put(backing_store, x, y);
                        tui_area_free(backing_store);
                        return return_path;
                    }
                    need_update = 1;
                    break;
                } else {
                    tui_beep();
                }
            default:
                {
                    int drive_num;

                    drive_num = alt_key_to_drive_num(key);

                    if (drive_num > 0) {
                        /* `A-a' ... `A-z' change the current drive.  */
                        int num_available_drives;
                        int current_drive;

                        _dos_getdrive(&current_drive);
                        _dos_setdrive(current_drive, &num_available_drives);
                        if (drive_num <= num_available_drives) {
                            char *new_path;

                            /* FIXME: This is a hack...  Maybe there is a cleaner
                               way to do it, but for now I just don't know.  */
                            _dos_setdrive(drive_num, &num_available_drives);
                            new_path = ioutil_current_dir();
                            if (new_path != NULL) {
                                slashize_path(&new_path);
                                _dos_setdrive(current_drive, &num_available_drives);
                                if (new_path != NULL) {
                                    struct file_list *new_fl;

                                    new_fl = file_list_read(new_path, pattern);
                                    if (new_fl != NULL) {
                                        file_list_free(fl);
                                        fl = new_fl;
                                        first_item = curr_item = 0;
                                        lib_free(return_path);
                                        return_path = new_path;
                                        need_update = 1;
                                        ioutil_chdir(return_path);
                                    } else {
                                        lib_free(new_path);
                                    }
                                }
                            } else {
                                _dos_setdrive(current_drive, &num_available_drives);
                                tui_beep();
                            }
                        } else {
                            tui_beep();
                        }
                    } else if (isprint(key) && str_len < 0x100) {
                        int n;

                        str[str_len] = key;
                        n = file_list_find(fl, str, str_len + 1);
                        if (n < 0) {
                            tui_beep();
                        } else {
                            str_len++;
                            curr_item = n;
                            if (curr_item < first_item) {
                                first_item = curr_item;
                                need_update = 1;
                            } else if (first_item + num_files <= curr_item) {
                                first_item = curr_item - num_files + 1;
                                need_update = 1;
                            }
                        }
                    }
                }
                break;
        }
    }
}