Ejemplo n.º 1
0
/**
 * @brief Add a directory to monitor
 * @param p_ml This media_library_t object
 * @param psz_dir the directory to add
 * @return VLC_SUCCESS or VLC_EGENERIC
 */
int AddDirToMonitor( media_library_t *p_ml, const char *psz_dir )
{
    assert( p_ml );

    /* Verify if we can open the directory */
    DIR *dir = vlc_opendir( psz_dir );
    if( !dir )
    {
        int err = errno;
        if( err != ENOTDIR )
            msg_Err( p_ml, "%s: %m", psz_dir );
        else
            msg_Dbg( p_ml, "`%s' is not a directory", psz_dir );
        errno = err;
        return VLC_EGENERIC;
    }

    closedir( dir );

    msg_Dbg( p_ml, "Adding directory `%s' to be monitored", psz_dir );
    QuerySimple( p_ml, "INSERT INTO directories ( uri, timestamp, "
                          "recursive ) VALUES( %Q, 0, 0 )", psz_dir );
    vlc_cond_signal( &p_ml->p_sys->p_mon->wait );
    return VLC_SUCCESS;
}
Ejemplo n.º 2
0
/*****************************************************************************
 * DirOpen: Open the directory access
 *****************************************************************************/
int DirOpen (vlc_object_t *obj)
{
    stream_t *access = (stream_t *)obj;

    if (access->psz_filepath == NULL)
        return VLC_EGENERIC;

    DIR *dir = vlc_opendir(access->psz_filepath);
    if (dir == NULL)
        return VLC_EGENERIC;

    return DirInit(access, dir);
}
Ejemplo n.º 3
0
/*****************************************************************************
 * Open: open the directory
 *****************************************************************************/
int DirOpen( vlc_object_t *p_this )
{
    access_t *p_access = (access_t*)p_this;

    if( !p_access->psz_filepath )
        return VLC_EGENERIC;

    DIR *handle = vlc_opendir (p_access->psz_filepath);
    if (handle == NULL)
        return VLC_EGENERIC;

    return DirInit (p_access, handle);
}
Ejemplo n.º 4
0
/**
 * Selects file entries from a directory, as GNU C scandir().
 *
 * @param dirname UTF-8 diretory path
 * @param pointer [OUT] pointer set, on successful completion, to the address
 * of a table of UTF-8 filenames. All filenames must be freed with free().
 * The table itself must be freed with free() as well.
 *
 * @return How many file names were selected (possibly 0),
 * or -1 in case of error.
 */
int vlc_scandir( const char *dirname, char ***namelist,
                  int (*select)( const char * ),
                  int (*compar)( const char **, const char ** ) )
{
    DIR *dir = vlc_opendir (dirname);
    int val = -1;

    if (dir != NULL)
    {
        val = vlc_loaddir (dir, namelist, select, compar);
        closedir (dir);
    }
    return val;
}
void ThemeRepository::parseDirectory( const string &rDir_locale )
{
    DIR *pDir;
    char *pszDirContent;
    // Path separator
    const string &sep = OSFactory::instance( getIntf() )->getDirSeparator();

    // Open the dir
    // FIXME: parseDirectory should be invoked with UTF-8 input instead!!
    string rDir = sFromLocale( rDir_locale );
    pDir = vlc_opendir( rDir.c_str() );

    if( pDir == NULL )
    {
        // An error occurred
        msg_Dbg( getIntf(), "cannot open directory %s", rDir.c_str() );
        return;
    }

    // While we still have entries in the directory
    while( ( pszDirContent = vlc_readdir( pDir ) ) != NULL )
    {
        string name = pszDirContent;
        string extension;
        if( name.size() > 4 )
        {
            extension = name.substr( name.size() - 4, 4 );
        }
        if( extension == ".vlt" || extension == ".wsz" )
        {
            string path = rDir + sep + name;
            string shortname = name.substr( 0, name.size() - 4 );
            for( string::size_type i = 0; i < shortname.size(); i++ )
                shortname[i] = ( i == 0 ) ?
                               toupper( shortname[i] ) :
                               tolower( shortname[i] );
            m_skinsMap[shortname] = path;

            msg_Dbg( getIntf(), "found skin %s", path.c_str() );
        }

        free( pszDirContent );
    }

    closedir( pDir );
}
Ejemplo n.º 6
0
int playlist_FindArtInCache( input_item_t *p_item )
{
    char *psz_path = ArtCachePath( p_item );

    if( !psz_path )
        return VLC_EGENERIC;

    /* Check if file exists */
    DIR *p_dir = vlc_opendir( psz_path );
    if( !p_dir )
    {
        free( psz_path );
        return VLC_EGENERIC;
    }

    bool b_found = false;
    char *psz_filename;
    while( !b_found && (psz_filename = vlc_readdir( p_dir )) )
    {
        if( !strncmp( psz_filename, "art", 3 ) )
        {
            char *psz_file;
            if( asprintf( &psz_file, "%s" DIR_SEP "%s",
                          psz_path, psz_filename ) != -1 )
            {
                char *psz_uri = make_URI( psz_file, "file" );
                if( psz_uri )
                {
                    input_item_SetArtURL( p_item, psz_uri );
                    free( psz_uri );
                }
                free( psz_file );
            }

            b_found = true;
        }
        free( psz_filename );
    }

    /* */
    closedir( p_dir );
    free( psz_path );
    return b_found ? VLC_SUCCESS : VLC_EGENERIC;
}
Ejemplo n.º 7
0
Archivo: net.c Proyecto: 5UN5H1N3/vlc
static int vlclua_opendir( lua_State *L )
{
    const char *psz_dir = luaL_checkstring( L, 1 );
    DIR *p_dir;
    int i = 0;

    if( ( p_dir = vlc_opendir( psz_dir ) ) == NULL )
        return luaL_error( L, "cannot open directory `%s'.", psz_dir );

    lua_newtable( L );
    for( ;; )
    {
        const char *psz_filename = vlc_readdir( p_dir );
        if( !psz_filename ) break;
        i++;
        lua_pushstring( L, psz_filename );
        lua_rawseti( L, -2, i );
    }
    closedir( p_dir );
    return 1;
}
Ejemplo n.º 8
0
bool ThemeLoader::findFile( const string &rootDir, const string &rFileName,
                            string &themeFilePath )
{
    // Path separator
    const string &sep = OSFactory::instance( getIntf() )->getDirSeparator();

    DIR *pCurrDir;
    char *pszDirContent;

    // Open the dir
    pCurrDir = vlc_opendir( rootDir.c_str() );

    if( pCurrDir == NULL )
    {
        // An error occurred
        msg_Dbg( getIntf(), "cannot open directory %s", rootDir.c_str() );
        return false;
    }

    // While we still have entries in the directory
    while( ( pszDirContent = vlc_readdir( pCurrDir ) ) != NULL )
    {
        string newURI = rootDir + sep + pszDirContent;

        // Skip . and ..
        if( string( pszDirContent ) != "." &&
            string( pszDirContent ) != ".." )
        {
#if defined( S_ISDIR )
            struct stat stat_data;

            if( ( vlc_stat( newURI.c_str(), &stat_data ) == 0 )
             && S_ISDIR(stat_data.st_mode) )
#elif defined( DT_DIR )
            if( pDirContent->d_type & DT_DIR )
#else
            if( 0 )
#endif
            {
                // Can we find the file in this subdirectory?
                if( findFile( newURI, rFileName, themeFilePath ) )
                {
                    free( pszDirContent );
                    closedir( pCurrDir );
                    return true;
                }
            }
            else
            {
                // Found the theme file?
                if( rFileName == string( pszDirContent ) )
                {
                    themeFilePath = newURI;
                    free( pszDirContent );
                    closedir( pCurrDir );
                    return true;
                }
            }
        }

        free( pszDirContent );
    }

    closedir( pCurrDir );
    return false;
}
Ejemplo n.º 9
0
Archivo: bank.c Proyecto: etix/vlc
/**
 * Recursively browses a directory to look for plug-ins.
 */
static void AllocatePluginDir (module_bank_t *bank, unsigned maxdepth,
                               const char *absdir, const char *reldir)
{
    if (maxdepth == 0)
        return;
    maxdepth--;

    DIR *dh = vlc_opendir (absdir);
    if (dh == NULL)
        return;

    /* Parse the directory and try to load all files it contains. */
    for (;;)
    {
        char *relpath = NULL, *abspath = NULL;
        const char *file = vlc_readdir (dh);
        if (file == NULL)
            break;

        /* Skip ".", ".." */
        if (!strcmp (file, ".") || !strcmp (file, ".."))
            continue;

        /* Compute path relative to plug-in base directory */
        if (reldir != NULL)
        {
            if (asprintf (&relpath, "%s"DIR_SEP"%s", reldir, file) == -1)
                relpath = NULL;
        }
        else
            relpath = strdup (file);
        if (unlikely(relpath == NULL))
            continue;

        /* Compute absolute path */
        if (asprintf (&abspath, "%s"DIR_SEP"%s", bank->base, relpath) == -1)
        {
            abspath = NULL;
            goto skip;
        }

        struct stat st;
        if (vlc_stat (abspath, &st) == -1)
            goto skip;

        if (S_ISREG (st.st_mode))
        {
            static const char prefix[] = "lib";
            static const char suffix[] = "_plugin"LIBEXT;
            size_t len = strlen (file);

#ifndef __OS2__
            /* Check that file matches the "lib*_plugin"LIBEXT pattern */
            if (len > strlen (suffix)
             && !strncmp (file, prefix, strlen (prefix))
             && !strcmp (file + len - strlen (suffix), suffix))
#else
            /* We load all the files ending with LIBEXT on OS/2,
             * because OS/2 has a 8.3 length limitation for DLL name */
            if (len > strlen (LIBEXT)
             && !strcasecmp (file + len - strlen (LIBEXT), LIBEXT))
#endif
                AllocatePluginFile (bank, abspath, relpath, &st);
        }
        else if (S_ISDIR (st.st_mode))
            /* Recurse into another directory */
            AllocatePluginDir (bank, maxdepth, abspath, relpath);
    skip:
        free (relpath);
        free (abspath);
    }
    closedir (dh);
}
Ejemplo n.º 10
0
int vout_snapshot_SaveImage(char **name, int *sequential,
                             const block_t *image,
                             vout_thread_t *p_vout,
                             const vout_snapshot_save_cfg_t *cfg)
{
    /* */
    char *filename;
    DIR *pathdir = vlc_opendir(cfg->path);
    input_thread_t *input = (input_thread_t*)p_vout->p->input;
    if (pathdir != NULL) {
        /* The use specified a directory path */
        closedir(pathdir);

        /* */
        char *prefix = NULL;
        if (cfg->prefix_fmt)
            prefix = str_format(input, cfg->prefix_fmt);
        if (prefix)
            filename_sanitize(prefix);
        else {
            prefix = strdup("vlcsnap-");
            if (!prefix)
                goto error;
        }

        if (cfg->is_sequential) {
            for (int num = cfg->sequence; ; num++) {
                struct stat st;

                if (asprintf(&filename, "%s" DIR_SEP "%s%05d.%s",
                             cfg->path, prefix, num, cfg->format) < 0) {
                    free(prefix);
                    goto error;
                }
                if (vlc_stat(filename, &st)) {
                    *sequential = num;
                    break;
                }
                free(filename);
            }
        } else {
            struct timespec ts;
            struct tm curtime;
            char buffer[128];

            timespec_get(&ts, TIME_UTC);
            if (localtime_r(&ts.tv_sec, &curtime) == NULL)
                gmtime_r(&ts.tv_sec, &curtime);
            if (strftime(buffer, sizeof(buffer), "%Y-%m-%d-%Hh%Mm%Ss",
                         &curtime) == 0)
                strcpy(buffer, "error");

            if (asprintf(&filename, "%s" DIR_SEP "%s%s%03lu.%s",
                         cfg->path, prefix, buffer, ts.tv_nsec / 1000000,
                         cfg->format) < 0)
                filename = NULL;
        }
        free(prefix);
    } else {
        /* The user specified a full path name (including file name) */
        filename = str_format(input, cfg->path);
        path_sanitize(filename);
    }

    if (!filename)
        goto error;

    /* Save the snapshot */
    FILE *file = vlc_fopen(filename, "wb");
    if (!file) {
        msg_Err(p_vout, "Failed to open '%s'", filename);
        free(filename);
        goto error;
    }
    if (fwrite(image->p_buffer, image->i_buffer, 1, file) != 1) {
        msg_Err(p_vout, "Failed to write to '%s'", filename);
        fclose(file);
        free(filename);
        goto error;
    }
    fclose(file);

    /* */
    if (name)
        *name = filename;
    else
        free(filename);

    return VLC_SUCCESS;

error:
    msg_Err(p_vout, "could not save snapshot");
    return VLC_EGENERIC;
}
Ejemplo n.º 11
0
block_t *DirBlock (access_t *p_access)
{
    access_sys_t *p_sys = p_access->p_sys;
    directory_t *current = p_sys->current;

    if (p_access->info.b_eof)
        return NULL;

    if (current == NULL)
    {   /* Startup: send the XSPF header */
        static const char header[] =
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
            "<playlist version=\"1\" xmlns=\"http://xspf.org/ns/0/\" xmlns:vlc=\"http://www.videolan.org/vlc/playlist/ns/0/\">\n"
            " <trackList>\n";
        block_t *block = block_Alloc (sizeof (header) - 1);
        if (!block)
            goto fatal;
        memcpy (block->p_buffer, header, sizeof (header) - 1);

        /* "Open" the base directory */
        current = malloc (sizeof (*current));
        if (current == NULL)
        {
            block_Release (block);
            goto fatal;
        }
        current->parent = NULL;
        current->handle = p_sys->handle;
#ifndef HAVE_OPENAT
        current->path = strdup (p_access->psz_filepath);
#endif
        current->uri = p_sys->uri;
        if (fstat (dirfd (current->handle), &current->st))
        {
            free (current);
            block_Release (block);
            goto fatal;
        }

        p_sys->handle = NULL;
        p_sys->uri = NULL;
        p_sys->current = current;
        return block;
    }

    char *entry = vlc_readdir (current->handle);
    if (entry == NULL)
    {   /* End of directory, go back to parent */
        closedir (current->handle);
        p_sys->current = current->parent;
        free (current->uri);
#ifndef HAVE_OPENAT
        free (current->path);
#endif
        free (current);

        if (p_sys->current == NULL)
        {   /* End of XSPF playlist */
            char *footer;
            int len = asprintf( &footer, " </trackList>\n" \
                " <extension application=\"http://www.videolan.org/vlc/playlist/0\">\n" \
                "%s" \
                " </extension>\n" \
                "</playlist>\n", p_sys->psz_xspf_extension );
            if (unlikely(len == -1))
                goto fatal;

            block_t *block = block_heap_Alloc (footer, footer, len);
            if (unlikely(block == NULL))
                free (footer);
            p_access->info.b_eof = true;
            return block;
        }
        else
        {
            /* This was the end of a "subnode" */
            /* Write the ID to the extension */
            char *old_xspf_extension = p_sys->psz_xspf_extension;
            if (old_xspf_extension == NULL)
                goto fatal;

            int len2 = asprintf( &p_sys->psz_xspf_extension, "%s  </vlc:node>\n", old_xspf_extension );
            if (len2 == -1)
                goto fatal;
            free( old_xspf_extension );
        }
        return NULL;
    }

    /* Skip current, parent and hidden directories */
    if (entry[0] == '.')
    {
        free (entry);
        return NULL;
    }
    /* Handle recursion */
    if (p_sys->mode != MODE_COLLAPSE)
    {
        directory_t *sub = malloc (sizeof (*sub));
        if (sub == NULL)
        {
            free (entry);
            return NULL;
        }

        DIR *handle;
#ifdef HAVE_OPENAT
        int fd = vlc_openat (dirfd (current->handle), entry, O_RDONLY);
        if (fd != -1)
        {
            handle = fdopendir (fd);
            if (handle == NULL)
                close (fd);
        }
        else
            handle = NULL;
#else
        if (asprintf (&sub->path, "%s/%s", current->path, entry) != -1)
            handle = vlc_opendir (sub->path);
        else
            handle = NULL;
#endif
        if (handle != NULL)
        {
            sub->parent = current;
            sub->handle = handle;

            char *encoded = encode_URI_component (entry);
            if ((encoded == NULL)
             || (asprintf (&sub->uri, "%s/%s", current->uri, encoded) == -1))
                 sub->uri = NULL;
            free (encoded);

            if ((p_sys->mode == MODE_NONE)
             || fstat (dirfd (handle), &sub->st)
             || has_inode_loop (sub)
             || (sub->uri == NULL))
            {
                free (entry);
                closedir (handle);
                free (sub->uri);
                free (sub);
                return NULL;
            }
            p_sys->current = sub;

            /* Add node to xspf extension */
            char *old_xspf_extension = p_sys->psz_xspf_extension;
            if (old_xspf_extension == NULL)
            {
                free (entry);
                goto fatal;
            }

            char *title = convert_xml_special_chars (entry);
            free (entry);
            if (title == NULL
             || asprintf (&p_sys->psz_xspf_extension, "%s"
                          "  <vlc:node title=\"%s\">\n", old_xspf_extension,
                          title) == -1)
            {
                free (title);
                goto fatal;
            }
            free (title);
            free (old_xspf_extension);
            return NULL;
        }
        else
            free (sub);
    }

    /* Skip files with ignored extensions */
    if (p_sys->ignored_exts != NULL)
    {
        const char *ext = strrchr (entry, '.');
        if (ext != NULL)
        {
            size_t extlen = strlen (++ext);
            for (const char *type = p_sys->ignored_exts, *end;
                 type[0]; type = end + 1)
            {
                end = strchr (type, ',');
                if (end == NULL)
                    end = type + strlen (type);

                if (type + extlen == end
                 && !strncasecmp (ext, type, extlen))
                {
                    free (entry);
                    return NULL;
                }

                if (*end == '\0')
                    break;
            }
        }
    }

    char *encoded = encode_URI_component (entry);
    free (entry);
    if (encoded == NULL)
        goto fatal;
    int len = asprintf (&entry,
                        "  <track><location>%s/%s</location>\n" \
                        "   <extension application=\"http://www.videolan.org/vlc/playlist/0\">\n" \
                        "    <vlc:id>%d</vlc:id>\n" \
                        "   </extension>\n" \
                        "  </track>\n",
                        current->uri, encoded, p_sys->i_item_count++);
    free (encoded);
    if (len == -1)
        goto fatal;

    /* Write the ID to the extension */
    char *old_xspf_extension = p_sys->psz_xspf_extension;
    if (old_xspf_extension == NULL)
        goto fatal;

    int len2 = asprintf( &p_sys->psz_xspf_extension, "%s   <vlc:item tid=\"%i\" />\n",
                            old_xspf_extension, p_sys->i_item_count-1 );
    if (len2 == -1)
        goto fatal;
    free( old_xspf_extension );

    block_t *block = block_heap_Alloc (entry, entry, len);
    if (unlikely(block == NULL))
    {
        free (entry);
        goto fatal;
    }
    return block;

fatal:
    p_access->info.b_eof = true;
    return NULL;
}
Ejemplo n.º 12
0
/*****************************************************************************
 * Open: initializes matroska demux structures
 *****************************************************************************/
static int Open( vlc_object_t * p_this )
{
    demux_t            *p_demux = (demux_t*)p_this;
    demux_sys_t        *p_sys;
    matroska_stream_c  *p_stream;
    matroska_segment_c *p_segment;
    const uint8_t      *p_peek;
    std::string         s_path, s_filename;
    vlc_stream_io_callback *p_io_callback;
    EbmlStream         *p_io_stream;
    bool                b_need_preload = false;

    /* peek the begining */
    if( vlc_stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;

    /* is a valid file */
    if( p_peek[0] != 0x1a || p_peek[1] != 0x45 ||
        p_peek[2] != 0xdf || p_peek[3] != 0xa3 ) return VLC_EGENERIC;

    /* Set the demux function */
    p_demux->pf_demux   = Demux;
    p_demux->pf_control = Control;
    p_demux->p_sys      = p_sys = new demux_sys_t( *p_demux );

    p_io_callback = new vlc_stream_io_callback( p_demux->s, false );
    p_io_stream = new (std::nothrow) EbmlStream( *p_io_callback );

    if( p_io_stream == NULL )
    {
        msg_Err( p_demux, "failed to create EbmlStream" );
        delete p_io_callback;
        delete p_sys;
        return VLC_EGENERIC;
    }

    p_stream = p_sys->AnalyseAllSegmentsFound( p_demux, p_io_stream, true );
    if( p_stream == NULL )
    {
        msg_Err( p_demux, "cannot find KaxSegment or missing mandatory KaxInfo" );
        goto error;
    }
    p_sys->streams.push_back( p_stream );

    p_stream->p_io_callback = p_io_callback;
    p_stream->p_estream = p_io_stream;

    for (size_t i=0; i<p_stream->segments.size(); i++)
    {
        p_stream->segments[i]->Preload();
        b_need_preload |= p_stream->segments[i]->b_ref_external_segments;
        if ( p_stream->segments[i]->translations.size() &&
             p_stream->segments[i]->translations[0]->codec_id == MATROSKA_CHAPTER_CODEC_DVD &&
             p_stream->segments[i]->families.size() )
            b_need_preload = true;
    }

    p_segment = p_stream->segments[0];
    if( p_segment->cluster == NULL && p_segment->stored_editions.size() == 0 )
    {
        msg_Err( p_demux, "cannot find any cluster or chapter, damaged file ?" );
        goto error;
    }

    if (b_need_preload && var_InheritBool( p_demux, "mkv-preload-local-dir" ))
    {
        msg_Dbg( p_demux, "Preloading local dir" );
        /* get the files from the same dir from the same family (based on p_demux->psz_path) */
        if ( p_demux->psz_file && !strcmp( p_demux->psz_access, "file" ) )
        {
            // assume it's a regular file
            // get the directory path
            s_path = p_demux->psz_file;
            if (s_path.at(s_path.length() - 1) == DIR_SEP_CHAR)
            {
                s_path = s_path.substr(0,s_path.length()-1);
            }
            else
            {
                if (s_path.find_last_of(DIR_SEP_CHAR) > 0)
                {
                    s_path = s_path.substr(0,s_path.find_last_of(DIR_SEP_CHAR));
                }
            }

            DIR *p_src_dir = vlc_opendir(s_path.c_str());

            if (p_src_dir != NULL)
            {
                const char *psz_file;
                while ((psz_file = vlc_readdir(p_src_dir)) != NULL)
                {
                    if (strlen(psz_file) > 4)
                    {
                        s_filename = s_path + DIR_SEP_CHAR + psz_file;

#if defined(_WIN32) || defined(__OS2__)
                        if (!strcasecmp(s_filename.c_str(), p_demux->psz_file))
#else
                        if (!s_filename.compare(p_demux->psz_file))
#endif
                        {
                            continue; // don't reuse the original opened file
                        }

                        if (!s_filename.compare(s_filename.length() - 3, 3, "mkv") ||
                            !s_filename.compare(s_filename.length() - 3, 3, "mka"))
                        {
                            // test whether this file belongs to our family
                            const uint8_t *p_peek;
                            bool          file_ok = false;
                            char          *psz_url = vlc_path2uri( s_filename.c_str(), "file" );
                            stream_t      *p_file_stream = vlc_stream_NewURL(
                                                            p_demux,
                                                            psz_url );
                            /* peek the begining */
                            if( p_file_stream &&
                                vlc_stream_Peek( p_file_stream, &p_peek, 4 ) >= 4
                                && p_peek[0] == 0x1a && p_peek[1] == 0x45 &&
                                p_peek[2] == 0xdf && p_peek[3] == 0xa3 ) file_ok = true;

                            if ( file_ok )
                            {
                                vlc_stream_io_callback *p_file_io = new vlc_stream_io_callback( p_file_stream, true );
                                EbmlStream *p_estream = new EbmlStream(*p_file_io);

                                p_stream = p_sys->AnalyseAllSegmentsFound( p_demux, p_estream );

                                if ( p_stream == NULL )
                                {
                                    msg_Dbg( p_demux, "the file '%s' will not be used", s_filename.c_str() );
                                    delete p_estream;
                                    delete p_file_io;
                                }
                                else
                                {
                                    p_stream->p_io_callback = p_file_io;
                                    p_stream->p_estream = p_estream;
                                    p_sys->streams.push_back( p_stream );
                                }
                            }
                            else
                            {
                                if( p_file_stream ) {
                                    vlc_stream_Delete( p_file_stream );
                                }
                                msg_Dbg( p_demux, "the file '%s' cannot be opened", s_filename.c_str() );
                            }
                            free( psz_url );
                        }
                    }
                }
                closedir( p_src_dir );
            }
        }

        p_sys->PreloadFamily( *p_segment );
    }
    else if (b_need_preload)
        msg_Warn( p_demux, "This file references other files, you may want to enable the preload of local directory");

    if ( !p_sys->PreloadLinked() ||
         !p_sys->PreparePlayback( *p_sys->p_current_vsegment, 0 ) )
    {
        msg_Err( p_demux, "cannot use the segment" );
        goto error;
    }

    p_sys->FreeUnused();

    p_sys->InitUi();

    return VLC_SUCCESS;

error:
    delete p_sys;
    return VLC_EGENERIC;
}
block_t *DirBlock (access_t *p_access)
{
    access_sys_t *p_sys = p_access->p_sys;
    directory_t *current = p_sys->current;

    if (p_access->info.b_eof)
        return NULL;

    if (p_sys->header)
    {   /* Startup: send the XSPF header */
        static const char header[] =
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
            "<playlist version=\"1\" xmlns=\"http://xspf.org/ns/0/\" xmlns:vlc=\"http://www.videolan.org/vlc/playlist/ns/0/\">\n"
            " <trackList>\n";
        block_t *block = block_Alloc (sizeof (header) - 1);
        if (!block)
            goto fatal;
        memcpy (block->p_buffer, header, sizeof (header) - 1);
        p_sys->header = false;
        return block;
    }

    if (current->i >= current->filec)
    {   /* End of directory, go back to parent */
        closedir (current->handle);
        p_sys->current = current->parent;
        free (current->uri);
        free (current->filev);
#ifndef HAVE_OPENAT
        free (current->path);
#endif
        free (current);

        if (p_sys->current == NULL)
        {   /* End of XSPF playlist */
            char *footer;
            int len = asprintf (&footer, " </trackList>\n"
                " <extension application=\"http://www.videolan.org/"
                                             "vlc/playlist/0\">\n"
                "%s"
                " </extension>\n"
                "</playlist>\n", p_sys->xspf_ext ? p_sys->xspf_ext : "");
            if (unlikely(len == -1))
                goto fatal;

            block_t *block = block_heap_Alloc (footer, len);
            p_access->info.b_eof = true;
            return block;
        }
        else
        {
            /* This was the end of a "subnode" */
            /* Write the ID to the extension */
            char *old_xspf_ext = p_sys->xspf_ext;
            if (old_xspf_ext != NULL
             && asprintf (&p_sys->xspf_ext, "%s  </vlc:node>\n",
                          old_xspf_ext ? old_xspf_ext : "") == -1)
                p_sys->xspf_ext = NULL;
            free (old_xspf_ext);
        }
        return NULL;
    }

    char *entry = current->filev[current->i++];

    /* Handle recursion */
    if (p_sys->mode != MODE_COLLAPSE)
    {
        DIR *handle;
#ifdef HAVE_OPENAT
        int fd = vlc_openat (dirfd (current->handle), entry,
                             O_RDONLY | O_DIRECTORY);
        if (fd == -1)
        {
            if (errno == ENOTDIR)
                goto notdir;
            goto skip; /* File cannot be opened... forget it */
        }

        struct stat st;
        if (fstat (fd, &st)
         || p_sys->mode == MODE_NONE
         || has_inode_loop (current, st.st_dev, st.st_ino)
         || (handle = fdopendir (fd)) == NULL)
        {
            close (fd);
            goto skip;
        }
#else
        char *path;
        if (asprintf (&path, "%s/%s", current->path, entry) == -1)
            goto skip;
        if ((handle = vlc_opendir (path)) == NULL)
            goto notdir;
        if (p_sys->mode == MODE_NONE)
            goto skip;
#endif
        directory_t *sub = malloc (sizeof (*sub));
        if (unlikely(sub == NULL))
        {
            closedir (handle);
#ifndef HAVE_OPENAT
            free (path);
#endif
            goto skip;
        }
        sub->parent = current;
        sub->handle = handle;
        sub->filec = vlc_loaddir (handle, &sub->filev, visible, p_sys->compar);
        if (sub->filec < 0)
            sub->filev = NULL;
        sub->i = 0;
#ifdef HAVE_OPENAT
        sub->device = st.st_dev;
        sub->inode = st.st_ino;
#else
        sub->path = path;
#endif
        p_sys->current = sub;

        char *encoded = encode_URI_component (entry);
        if (encoded == NULL
         || (asprintf (&sub->uri, "%s/%s", current->uri, encoded) == -1))
             sub->uri = NULL;
        free (encoded);
        if (unlikely(sub->uri == NULL))
        {
            free (entry);
            goto fatal;
        }

        /* Add node to XSPF extension */
        char *old_xspf_ext = p_sys->xspf_ext;
        EnsureUTF8 (entry);
        char *title = convert_xml_special_chars (entry);
        if (old_xspf_ext != NULL
         && asprintf (&p_sys->xspf_ext, "%s  <vlc:node title=\"%s\">\n",
                      old_xspf_ext, title ? title : "?") == -1)
            p_sys->xspf_ext = NULL;
        free (old_xspf_ext);
        free (title);
        goto skip;
    }

notdir:
    /* Skip files with ignored extensions */
    if (p_sys->ignored_exts != NULL)
    {
        const char *ext = strrchr (entry, '.');
        if (ext != NULL)
        {
            size_t extlen = strlen (++ext);
            for (const char *type = p_sys->ignored_exts, *end;
                 type[0]; type = end + 1)
            {
                end = strchr (type, ',');
                if (end == NULL)
                    end = type + strlen (type);

                if (type + extlen == end
                 && !strncasecmp (ext, type, extlen))
                {
                    free (entry);
                    return NULL;
                }

                if (*end == '\0')
                    break;
            }
        }
    }

    char *encoded = encode_URI_component (entry);
    free (entry);
    if (encoded == NULL)
        goto fatal;
    int len = asprintf (&entry,
                        "  <track><location>%s/%s</location>\n" \
                        "   <extension application=\"http://www.videolan.org/vlc/playlist/0\">\n" \
                        "    <vlc:id>%d</vlc:id>\n" \
                        "   </extension>\n" \
                        "  </track>\n",
                        current->uri, encoded, p_sys->i_item_count++);
    free (encoded);
    if (len == -1)
        goto fatal;

    /* Write the ID to the extension */
    char *old_xspf_ext = p_sys->xspf_ext;
    if (old_xspf_ext != NULL
     && asprintf (&p_sys->xspf_ext, "%s   <vlc:item tid=\"%i\" />\n",
                  old_xspf_ext, p_sys->i_item_count - 1) == -1)
        p_sys->xspf_ext = NULL;
    free (old_xspf_ext);

    block_t *block = block_heap_Alloc (entry, len);
    if (unlikely(block == NULL))
        goto fatal;
    return block;

fatal:
    p_access->info.b_eof = true;
    return NULL;

skip:
    free (entry);
    return NULL;
}
Ejemplo n.º 14
0
int vout_snapshot_SaveImage(char **name, int *sequential,
                             const block_t *image,
                             vlc_object_t *object,
                             const vout_snapshot_save_cfg_t *cfg)
{
    /* */
    char *filename;
    DIR *pathdir = vlc_opendir(cfg->path);
    if (pathdir != NULL) {
        /* The use specified a directory path */
        closedir(pathdir);

        /* */
        char *prefix = NULL;
        if (cfg->prefix_fmt)
            prefix = str_format(object, cfg->prefix_fmt);
        if (prefix)
            filename_sanitize(prefix);
        else {
            prefix = strdup("vlcsnap-");
            if (!prefix)
                goto error;
        }

        if (cfg->is_sequential) {
            for (int num = cfg->sequence; ; num++) {
                struct stat st;

                if (asprintf(&filename, "%s" DIR_SEP "%s%05d.%s",
                             cfg->path, prefix, num, cfg->format) < 0) {
                    free(prefix);
                    goto error;
                }
                if (vlc_stat(filename, &st)) {
                    *sequential = num;
                    break;
                }
                free(filename);
            }
        } else {
            struct tm    curtime;
            time_t       lcurtime = time(NULL) ;

            if (!localtime_r(&lcurtime, &curtime)) {
                const unsigned int id = (image->i_pts / 100000) & 0xFFFFFF;

                msg_Warn(object, "failed to get current time. Falling back to legacy snapshot naming");

                if (asprintf(&filename, "%s" DIR_SEP "%s%u.%s",
                             cfg->path, prefix, id, cfg->format) < 0)
                    filename = NULL;
            } else {
                /* suffix with the last decimal digit in 10s of seconds resolution
                 * FIXME gni ? */
                const int id = (image->i_pts / (100*1000)) & 0xFF;
                char buffer[128];

                if (!strftime(buffer, sizeof(buffer), "%Y-%m-%d-%Hh%Mm%Ss", &curtime))
                    strcpy(buffer, "error");

                if (asprintf(&filename, "%s" DIR_SEP "%s%s%1u.%s",
                             cfg->path, prefix, buffer, id, cfg->format) < 0)
                    filename = NULL;
            }
        }
        free(prefix);
    } else {
        /* The user specified a full path name (including file name) */
        filename = str_format(object, cfg->path);
        path_sanitize(filename);
    }

    if (!filename)
        goto error;

    /* Save the snapshot */
    FILE *file = vlc_fopen(filename, "wb");
    if (!file) {
        msg_Err(object, "Failed to open '%s'", filename);
        free(filename);
        goto error;
    }
    if (fwrite(image->p_buffer, image->i_buffer, 1, file) != 1) {
        msg_Err(object, "Failed to write to '%s'", filename);
        fclose(file);
        free(filename);
        goto error;
    }
    fclose(file);

    /* */
    if (name)
        *name = filename;
    else
        free(filename);

    return VLC_SUCCESS;

error:
    msg_Err(object, "could not save snapshot");
    return VLC_EGENERIC;
}
Ejemplo n.º 15
0
/**
 * Detect subtitle files.
 *
 * When called this function will split up the psz_name string into a
 * directory, filename and extension. It then opens the directory
 * in which the file resides and tries to find possible matches of
 * subtitles files.
 *
 * \ingroup Demux
 * \param p_this the calling \ref input_thread_t
 * \param psz_path a list of subdirectories (separated by a ',') to look in.
 * \param psz_name_org the complete filename to base the search on.
 * \param pp_slaves an initialized input item slave list to append detected subtitles to
 * \param p_slaves pointer to the size of the slave list
 * \return VLC_SUCCESS if ok
 */
int subtitles_Detect( input_thread_t *p_this, char *psz_path, const char *psz_name_org,
                      input_item_slave_t ***ppp_slaves, int *p_slaves )
{
    int i_fuzzy = var_GetInteger( p_this, "sub-autodetect-fuzzy" );
    if ( i_fuzzy == 0 )
        return VLC_EGENERIC;
    int j, i_fname_len;
    input_item_slave_t **pp_slaves = *ppp_slaves;
    int i_slaves = *p_slaves;
    char *f_fname_noext = NULL, *f_fname_trim = NULL;
    char **subdirs; /* list of subdirectories to look in */

    if( !psz_name_org )
        return VLC_EGENERIC;

    char *psz_fname = vlc_uri2path( psz_name_org );
    if( !psz_fname )
        return VLC_EGENERIC;

    /* extract filename & dirname from psz_fname */
    char *f_dir = strdup( psz_fname );
    if( f_dir == 0 )
    {
        free( psz_fname );
        return VLC_ENOMEM;
    }

    const char *f_fname = strrchr( psz_fname, DIR_SEP_CHAR );
    if( !f_fname )
    {
        free( f_dir );
        free( psz_fname );
        return VLC_EGENERIC;
    }
    f_fname++; /* Skip the '/' */
    f_dir[f_fname - psz_fname] = 0; /* keep dir separator in f_dir */

    i_fname_len = strlen( f_fname );

    f_fname_noext = malloc(i_fname_len + 1);
    f_fname_trim = malloc(i_fname_len + 1 );
    if( !f_fname_noext || !f_fname_trim )
    {
        free( f_dir );
        free( f_fname_noext );
        free( f_fname_trim );
        free( psz_fname );
        return VLC_ENOMEM;
    }

    strcpy_strip_ext( f_fname_noext, f_fname );
    strcpy_trim( f_fname_trim, f_fname_noext );

    subdirs = paths_to_list( f_dir, psz_path );
    for( j = -1; (j == -1) || ( j >= 0 && subdirs != NULL && subdirs[j] != NULL ); j++ )
    {
        const char *psz_dir = (j < 0) ? f_dir : subdirs[j];
        if( psz_dir == NULL || ( j >= 0 && !strcmp( psz_dir, f_dir ) ) )
            continue;

        /* parse psz_src dir */
        DIR *dir = vlc_opendir( psz_dir );
        if( dir == NULL )
            continue;

        msg_Dbg( p_this, "looking for a subtitle file in %s", psz_dir );

        const char *psz_name;
        while( (psz_name = vlc_readdir( dir )) )
        {
            if( psz_name[0] == '.' || !subtitles_Filter( psz_name ) )
                continue;

            char tmp_fname_noext[strlen( psz_name ) + 1];
            char tmp_fname_trim[strlen( psz_name ) + 1];
            char tmp_fname_ext[strlen( psz_name ) + 1];
            const char *tmp;
            int i_prio = 0;

            /* retrieve various parts of the filename */
            strcpy_strip_ext( tmp_fname_noext, psz_name );
            strcpy_get_ext( tmp_fname_ext, psz_name );
            strcpy_trim( tmp_fname_trim, tmp_fname_noext );

            if( !strcmp( tmp_fname_trim, f_fname_trim ) )
            {
                /* matches the movie name exactly */
                i_prio = SLAVE_PRIORITY_MATCH_ALL;
            }
            else if( (tmp = strstr( tmp_fname_trim, f_fname_trim )) )
            {
                /* contains the movie name */
                tmp += strlen( f_fname_trim );
                if( whiteonly( tmp ) )
                {
                    /* chars in front of the movie name */
                    i_prio = SLAVE_PRIORITY_MATCH_RIGHT;
                }
                else
                {
                    /* chars after (and possibly in front of)
                     * the movie name */
                    i_prio = SLAVE_PRIORITY_MATCH_LEFT;
                }
            }
            else if( j == -1 )
            {
                /* doesn't contain the movie name, prefer files in f_dir over subdirs */
                i_prio = SLAVE_PRIORITY_MATCH_NONE;
            }
            if( i_prio >= i_fuzzy )
            {
                struct stat st;
                char *path;

                size_t i_len = strlen( psz_dir );
                const char *psz_format;
                if ( i_len == 0 )
                    continue;
                if( psz_dir[i_len - 1] == DIR_SEP_CHAR )
                    psz_format = "%s%s";
                else
                    psz_format = "%s"DIR_SEP"%s";

                if( asprintf( &path, psz_format, psz_dir, psz_name ) < 0 )
                    continue;

                if( strcmp( path, psz_fname )
                 && vlc_stat( path, &st ) == 0
                 && S_ISREG( st.st_mode ) )
                {
                    msg_Dbg( p_this,
                            "autodetected subtitle: %s with priority %d",
                            path, i_prio );
                    char *psz_uri = vlc_path2uri( path, NULL );
                    input_item_slave_t *p_sub = psz_uri != NULL ?
                        input_item_slave_New( psz_uri, SLAVE_TYPE_SPU, i_prio )
                        : NULL;
                    if( p_sub )
                    {
                        p_sub->b_forced = true;
                        INSERT_ELEM( pp_slaves, i_slaves, i_slaves, p_sub );
                    }
                    free( psz_uri );
                }
                free( path );
            }
        }
        closedir( dir );
    }
    if( subdirs )
    {
        for( j = 0; subdirs[j]; j++ )
            free( subdirs[j] );
        free( subdirs );
    }
    free( f_dir );
    free( f_fname_trim );
    free( f_fname_noext );
    free( psz_fname );

    for( int i = 0; i < i_slaves; i++ )
    {
        input_item_slave_t *p_sub = pp_slaves[i];

        bool b_reject = false;
        char *psz_ext = strrchr( p_sub->psz_uri, '.' );
        if( !psz_ext )
            continue;
        psz_ext++;

        if( !strcasecmp( psz_ext, "sub" ) )
        {
            for( int j = 0; j < i_slaves; j++ )
            {
                input_item_slave_t *p_sub_inner = pp_slaves[j];

                /* A slave can be null if it's already rejected */
                if( p_sub_inner == NULL )
                    continue;

                /* check that the filenames without extension match */
                if( strncasecmp( p_sub->psz_uri, p_sub_inner->psz_uri,
                    strlen( p_sub->psz_uri ) - 3 ) )
                    continue;

                char *psz_ext_inner = strrchr( p_sub_inner->psz_uri, '.' );
                if( !psz_ext_inner )
                    continue;
                psz_ext_inner++;

                /* check that we have an idx file */
                if( !strcasecmp( psz_ext_inner, "idx" ) )
                {
                    b_reject = true;
                    break;
                }
            }
        }
        else if( !strcasecmp( psz_ext, "cdg" ) )
        {
            if( p_sub->i_priority < SLAVE_PRIORITY_MATCH_ALL )
                b_reject = true;
        }
        if( b_reject )
        {
            pp_slaves[i] = NULL;
            input_item_slave_Delete( p_sub );
        }
    }

    /* Sort alphabetically */
    if( i_slaves > 0 )
        qsort( pp_slaves, i_slaves, sizeof (input_item_slave_t*), slave_strcmp );

    *ppp_slaves = pp_slaves; /* in case of realloc */
    *p_slaves = i_slaves;
    return VLC_SUCCESS;
}