diff options
Diffstat (limited to 'libmenu/menu_filesel.c')
-rw-r--r-- | libmenu/menu_filesel.c | 506 |
1 files changed, 0 insertions, 506 deletions
diff --git a/libmenu/menu_filesel.c b/libmenu/menu_filesel.c deleted file mode 100644 index 7c63954d1d..0000000000 --- a/libmenu/menu_filesel.c +++ /dev/null @@ -1,506 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * MPlayer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <dirent.h> -#include <errno.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <ctype.h> -#include <unistd.h> -#include <limits.h> - - -#include "config.h" -#include "mp_msg.h" - -#include "m_struct.h" -#include "m_option.h" - -#include "libmpcodecs/img_format.h" -#include "libmpcodecs/mp_image.h" - -#include "menu.h" -#include "menu_list.h" -#include "input/input.h" -#include "input/keycodes.h" - -#define MENU_KEEP_PATH "/tmp/mp_current_path" - -int menu_keepdir = 0; -char *menu_chroot = NULL; - -struct list_entry_s { - struct list_entry p; - int d; -}; - -struct menu_priv_s { - menu_list_priv_t p; - char* dir; // current dir - /// Cfg fields - char* path; - char* title; - char* file_action; - char* dir_action; - char** actions; - char* filter; -}; - -static struct menu_priv_s cfg_dflt = { - MENU_LIST_PRIV_DFLT, - NULL, - - NULL, - "Select a file: %p", - "loadfile '%p'", - NULL, - NULL, - NULL -}; - -#define ST_OFF(m) M_ST_OFF(struct menu_priv_s,m) - -static const m_option_t cfg_fields[] = { - MENU_LIST_PRIV_FIELDS, - { "path", ST_OFF(path), CONF_TYPE_STRING, 0, 0, 0, NULL }, - { "title", ST_OFF(title), CONF_TYPE_STRING, 0, 0, 0, NULL }, - { "file-action", ST_OFF(file_action), CONF_TYPE_STRING, 0, 0, 0, NULL }, - { "dir-action", ST_OFF(dir_action), CONF_TYPE_STRING, 0, 0, 0, NULL }, - { "actions", ST_OFF(actions), CONF_TYPE_STRING_LIST, 0, 0, 0, NULL}, - { "filter", ST_OFF(filter), CONF_TYPE_STRING, 0, 0, 0, NULL}, - { NULL, NULL, NULL, 0,0,0,NULL } -}; - -#define mpriv (menu->priv) - -static void free_entry(list_entry_t* entry) { - free(entry->p.txt); - free(entry); -} - -static char* replace_path(char* title , char* dir , int escape) { - char *p = strstr(title,"%p"); - if(p) { - int tl = strlen(title); - int dl = strlen(dir); - int t1l = p-title; - int l = tl - 2 + dl; - char *r, *n, *d = dir; - - if (escape) { - do { - if (*d == '\\') - l++; - else if (*d == '\'') /* ' -> \'\\\'\' */ - l+=7; - } while (*d++); - } - r = malloc(l + 1); - n = r + t1l; - memcpy(r,title,t1l); - do { - if (escape) { - if (*dir == '\\') - *n++ = '\\'; - else if (*dir == '\'') { /* ' -> \'\\\'\' */ - *n++ = '\\'; *n++ = '\''; - *n++ = '\\'; *n++ = '\\'; - *n++ = '\\'; *n++ = '\''; - *n++ = '\\'; - } - } - } while ((*n++ = *dir++)); - if(tl - t1l - 2 > 0) - strcpy(n-1,p+2); - return r; - } else - return title; -} - -typedef int (*kill_warn)(const void*, const void*); - -static int mylstat(char *dir, char *file,struct stat* st) { - int l = strlen(dir) + strlen(file); - char s[l+2]; - if (!strcmp("..", file)) { - char *slash; - l -= 3; - strcpy(s, dir); -#if HAVE_DOS_PATHS - if (s[l] == '/' || s[l] == '\\') -#else - if (s[l] == '/') -#endif - s[l] = '\0'; - slash = strrchr(s, '/'); -#if HAVE_DOS_PATHS - if (!slash) - slash = strrchr(s,'\\'); -#endif - if (!slash) - return stat(dir,st); - slash[1] = '\0'; - return stat(s,st); - } - sprintf(s,"%s/%s",dir,file); - return stat(s,st); -} - -static int compare(char **a, char **b){ - if((*a)[strlen(*a) - 1] == '/') { - if((*b)[strlen(*b) - 1] == '/') - return strcmp(*b, *a) ; - else - return 1; - } else { - if((*b)[strlen(*b) - 1] == '/') - return -1; - else - return strcmp(*b, *a); - } -} - -static char **get_extensions(menu_t *menu){ - char **extensions, ext[32]; - FILE *fp; - int n = 1; - - if (!mpriv->filter) - return NULL; - - fp = fopen(mpriv->filter, "r"); - if(!fp) - return NULL; - - extensions = malloc(sizeof(*extensions)); - *extensions = NULL; - - while(fgets(ext,sizeof(ext),fp)) { - char **l, *e; - int s = strlen (ext); - - if(ext[s-1] == '\n') { - ext[s-1] = '\0'; - s--; - } - e = malloc(s+1); - extensions = realloc(extensions, ++n * sizeof(*extensions)); - extensions = realloc(extensions, ++n * sizeof(*extensions)); - strcpy (e, ext); - for (l=extensions; *l; l++); - *l++ = e; - *l = NULL; - } - - fclose (fp); - return extensions; -} - -static void free_extensions(char **extensions){ - if (extensions) { - char **l = extensions; - while (*l) - free (*l++); - free (extensions); - } -} - -static int open_dir(menu_t* menu,char* args) { - char **namelist, **tp; - struct dirent *dp; - struct stat st; - int n; - int path_fp; - list_entry_t* e; - DIR* dirp; - extern int file_filter; - char **extensions, **elem, *ext; - - menu_list_init(menu); - - free(mpriv->dir); - mpriv->dir = strdup(args); - if(mpriv->p.title && mpriv->p.title != mpriv->title && mpriv->p.title != cfg_dflt.p.title) - free(mpriv->p.title); - - mpriv->p.title = replace_path(mpriv->title,mpriv->dir,0); - - if ((dirp = opendir (mpriv->dir)) == NULL){ - mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] opendir error: %s\n", strerror(errno)); - return 0; - } - - if (menu_keepdir) { - path_fp = open (MENU_KEEP_PATH, O_CREAT | O_WRONLY | O_TRUNC, 0666); - if (path_fp >= 0) { - write (path_fp, mpriv->dir, strlen (mpriv->dir)); - close (path_fp); - } - } - - namelist = malloc(sizeof(char *)); - extensions = get_extensions(menu); - - n=0; - while ((dp = readdir(dirp)) != NULL) { - if(dp->d_name[0] == '.' && strcmp(dp->d_name,"..") != 0) - continue; - if (menu_chroot && !strcmp (dp->d_name,"..")) { - size_t len = strlen (menu_chroot); - if ((strlen (mpriv->dir) == len || strlen (mpriv->dir) == len + 1) - && !strncmp (mpriv->dir, menu_chroot, len)) - continue; - } - if (mylstat(args,dp->d_name,&st)) - continue; - if (file_filter && extensions && !S_ISDIR(st.st_mode)) { - if((ext = strrchr(dp->d_name,'.')) == NULL) - continue; - ext++; - elem = extensions; - do { - if (!strcasecmp(ext, *elem)) - break; - } while (*++elem); - if (*elem == NULL) - continue; - } - if(n%20 == 0){ // Get some more mem - if((tp = realloc(namelist, (n+20) * sizeof (char *))) - == NULL) { - mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] realloc error: %s\n", strerror(errno)); - n--; - goto bailout; - } - namelist=tp; - } - - namelist[n] = malloc(strlen(dp->d_name) + 2); - if(namelist[n] == NULL){ - mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] memory allocation error: %s\n", strerror(errno)); - n--; - goto bailout; - } - - strcpy(namelist[n], dp->d_name); - if(S_ISDIR(st.st_mode)) - strcat(namelist[n], "/"); - n++; - } - -bailout: - free_extensions (extensions); - closedir(dirp); - - qsort(namelist, n, sizeof(char *), (kill_warn)compare); - - if (n < 0) { - mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] readdir error: %s\n",strerror(errno)); - return 0; - } - while(n--) { - if((e = calloc(1,sizeof(list_entry_t))) != NULL){ - e->p.next = NULL; - e->p.txt = strdup(namelist[n]); - if(strchr(namelist[n], '/') != NULL) - e->d = 1; - menu_list_add_entry(menu,e); - }else{ - mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] memory allocation error: %s\n", strerror(errno)); - } - free(namelist[n]); - } - free(namelist); - - return 1; -} - -static char *action; - -static void read_cmd(menu_t* menu,int cmd) { - switch(cmd) { - case MENU_CMD_LEFT: - mpriv->p.current = mpriv->p.menu; // Hack : we consider that the first entry is ../ - case MENU_CMD_RIGHT: - case MENU_CMD_OK: { - // Directory - if(mpriv->p.current->d && !mpriv->dir_action) { - // Default action : open this dirctory ourself - int l = strlen(mpriv->dir); - char *slash = NULL, *p = NULL; - if(strcmp(mpriv->p.current->p.txt,"../") == 0) { - if(l <= 1) break; - mpriv->dir[l-1] = '\0'; - slash = strrchr(mpriv->dir,'/'); -#if HAVE_DOS_PATHS - if (!slash) - slash = strrchr(mpriv->dir,'\\'); -#endif - if(!slash) break; - slash[1] = '\0'; - p = strdup(mpriv->dir); - } else { - p = malloc(l + strlen(mpriv->p.current->p.txt) + 1); - sprintf(p,"%s%s",mpriv->dir,mpriv->p.current->p.txt); - } - menu_list_uninit(menu,free_entry); - if(!open_dir(menu,p)) { - mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] Can't open directory %s.\n",p); - menu->cl = 1; - } - free(p); - } else { // File and directory dealt with action string. - int fname_len = strlen(mpriv->dir) + strlen(mpriv->p.current->p.txt) + 1; - char filename[fname_len]; - char *str; - char *action = mpriv->p.current->d ? mpriv->dir_action:mpriv->file_action; - sprintf(filename,"%s%s",mpriv->dir,mpriv->p.current->p.txt); - str = replace_path(action, filename,1); - mp_input_parse_and_queue_cmds(menu->input_ctx, str); - if (str != action) - free(str); - } - } break; - case MENU_CMD_ACTION: { - int fname_len = strlen(mpriv->dir) + strlen(mpriv->p.current->p.txt) + 1; - char filename[fname_len]; - char *str; - sprintf(filename,"%s%s",mpriv->dir,mpriv->p.current->p.txt); - str = replace_path(action, filename,1); - mp_input_parse_and_queue_cmds(menu->input_ctx, str); - if(str != action) - free(str); - } break; - default: - menu_list_read_cmd(menu,cmd); - } -} - -static int read_key(menu_t* menu,int c){ - char **str; - for (str=mpriv->actions; str && *str; str++) - if (c == (*str)[0]) { - action = &(*str)[2]; - read_cmd(menu,MENU_CMD_ACTION); - return 1; - } - if (menu_dflt_read_key(menu, c)) - return 1; - return menu_list_jump_to_key(menu, c); -} - -static void clos(menu_t* menu) { - menu_list_uninit(menu,free_entry); - free(mpriv->dir); -} - -static int open_fs(menu_t* menu, char* args) { - char *path = mpriv->path; - int r = 0; - char wd[PATH_MAX+1], b[PATH_MAX+1]; - args = NULL; // Warning kill - - menu->draw = menu_list_draw; - menu->read_cmd = read_cmd; - menu->read_key = read_key; - menu->close = clos; - - if (menu_keepdir) { - if (!path || path[0] == '\0') { - struct stat st; - int path_fp; - - path_fp = open (MENU_KEEP_PATH, O_RDONLY); - if (path_fp >= 0) { - if (!fstat (path_fp, &st) && (st.st_size > 0)) { - path = malloc(st.st_size+1); - path[st.st_size] = '\0'; - if (!((read(path_fp, path, st.st_size) == st.st_size) && path[0] == '/' - && !stat(path, &st) && S_ISDIR(st.st_mode))) { - free(path); - path = NULL; - } - } - close (path_fp); - } - } - } - - getcwd(wd,PATH_MAX); - if (!path || path[0] == '\0') { -#if 0 - char *slash = NULL; - if (filename && !strstr(filename, "://") && (path=realpath(filename, b))) { - slash = strrchr(path, '/'); -#if HAVE_DOS_PATHS - // FIXME: Do we need and can convert all '\\' in path to '/' on win32? - if (!slash) - slash = strrchr(path, '\\'); -#endif - } - if (slash) - slash[1] = '\0'; - else -#endif - path = wd; - } - if (path[0] != '/') { - if(path[strlen(path)-1] != '/') - snprintf(b,sizeof(b),"%s/%s/",wd,path); - else - snprintf(b,sizeof(b),"%s/%s",wd,path); - path = b; - } else if (path[strlen(path)-1]!='/') { - sprintf(b,"%s/",path); - path = b; - } - if (menu_chroot && menu_chroot[0] == '/') { - int l = strlen(menu_chroot); - if (l > 0 && menu_chroot[l-1] == '/') - --l; - if (strncmp(menu_chroot, path, l) || (path[l] != '\0' && path[l] != '/')) { - if (menu_chroot[l] == '/') - path = menu_chroot; - else { - sprintf(b,"%s/",menu_chroot); - path = b; - } - } - } - r = open_dir(menu,path); - - return r; -} - -const menu_info_t menu_info_filesel = { - "File seletor menu", - "filesel", - "Albeu", - "", - { - "fs_cfg", - sizeof(struct menu_priv_s), - &cfg_dflt, - cfg_fields - }, - open_fs -}; |