Exemple #1
0
static int vt_filter( sqlite3_vtab_cursor *p_vtc, 
                      int idxNum, const char *idxStr,
                      int argc, sqlite3_value **argv )
{
    /* Initialize the cursor structure. */
    vtab_cursor *p_cur = (vtab_cursor*)p_vtc;
    vtab *p_vt         = (vtab*)p_vtc->pVtab;

    if (argc > 0)
    {
        p_cur->search_paths = strdup(sqlite3_value_text(argv[0]));
    }
    else
    {
        /* Start search at root file system. */
        p_cur->search_paths = strdup("/");
    }

    /* p_cur->search_paths is a comma-delimited list of directories to
    ** search. p_cur->root_path keeps track of the current directory we are
    ** searching. We move to the next in the list using next_directory(), which
    ** searces the root_path string for the next directory. 
    */

    /* Place root_path to beginning of search path string. */
    p_cur->root_path = p_cur->search_paths;

    /* Zero rows returned thus far. */
    p_cur->count = 0;

    /* Have not reached end of set. */
    p_cur->eof = 0;

    /* Load first directory to search. */
    return next_directory(p_cur);


    return SQLITE_OK;
}
Exemple #2
0
int
file_completion(char *path, int index)
{
    static int      dir_in_use = 0;
    static char    *head, *tail = NULL;
    static int      tail_offset;

    char            nbuf[FILENAME], buffer[FILENAME];
    char           *dir, *base;

    if (path) {
	if (dir_in_use) {
	    close_directory();
	    dir_in_use = 0;
	}
	if (index < 0)
	    return 0;

	head = path;
	tail = path + index;
    }
    if (!dir_in_use) {
	path = head;
	*tail = NUL;

	if (*path == '|')
	    return -1;		/* no completion for pipes */

	if (*path == '+' || *path == '~') {
	    if (!expand_file_name(nbuf, path, 0x11))
		return 0;	/* no completions */
	} else
	    strcpy(nbuf, path);

	if ((base = strrchr(nbuf, '/'))) {
	    if (base == nbuf) {
		dir = "/";
		base++;
	    } else {
		*base++ = NUL;
		dir = nbuf;
	    }
	} else {
	    base = nbuf;
	    dir = ".";
	}

	tail_offset = strlen(base);

	dir_in_use = list_directory(dir, base);

	return dir_in_use;
    }
    if (index)
	return compl_help_directory();

    if (!next_directory(buffer, 1))
	return 0;

    strcpy(tail, buffer + tail_offset);

    return 1;
}
Exemple #3
0
static int vt_next(sqlite3_vtab_cursor *cur)
{
    vtab_cursor *p_cur = (vtab_cursor*)cur;
    vtab* p_vt         = (vtab*)cur->pVtab;

    /** This is a rather involved function. It is the core of this virtual
     *  table. This function recursively reads down into a directory. It
     *  automatically decends into a directory when it finds one, and
     *  automatically ascends out of it when it has read all of its entries.

     *  The logic is as follows:

     *  The p_cur->current_node (a filenode struct) points to the current file
     *  entry (given by the APR handle p_cur->current_node->dirent) and its
     *  associated directory (given by the APR handle
     *  p_cur->current_node->dirent)

     *  We attempt to read the next entry in p_cur->current_node->dir, filling
     *  the p_cur->current_node->dirent. If we succeed, then we have either a
     *  file or a directory. If we have a directory, then we descend into it. If
     *  we have a file, we proceed as usual. In either case, the dirent entry
     *  will consitute a row in the result set, as we have done as much as we
     *  have to and can exit the function. Our only job is to get to the next
     *  valid file or directory entry to return as the current row in the
     *  rowset.

     *  If there are no more entries in the current directory, then we
     *  deallocate p_cur->current_node and proceed up one directory (given by
     *  p_cur->current_node->parent). We thus set p_cur->current_node to
     *  p_cur->current_node->parent, and start over again.
     */

read_next_entry:

    /** First, check for a special case where the top level directory is
     *  actually a top-level file. In this case, we rely that
     *  p_cur->current_node->dir == NULL (set by next_directory()). If this is
     *  true, resort to next_directory().
     */

    if (p_cur->current_node->dir == NULL)
    {
        return next_directory(p_cur);
    }

    /* Read the next directory entry. */

    /* Increment the current row count. */
    p_cur->count += 1;

    struct filenode* d = p_cur->current_node;
    struct filenode* prev_d = d;

reread_next_entry:

    /* Read the next entry in the directory (d->dir). Fills the d->dirent member. */
    if ( apr_dir_read( &d->dirent, 
                      APR_FINFO_DIRENT|APR_FINFO_PROT|APR_FINFO_TYPE|
                      APR_FINFO_NAME|APR_FINFO_SIZE, 
                      d->dir) != APR_SUCCESS )
    {
        /** If we get here, the call failed. There are no more entries in
         *  directory. 
         */

        /** If we are at the top level directory */
        if (d->parent == NULL)
        {
            /** We are done with this directory. See if there is another
             *  top-level directory to search.
             *
             *  If there is not another directory, next_directory() will have set
             *  eof=1. We are at the end of the result set. If there is another
             *  directory to search, then it will load the next dirent for
             *  us. Either way, we have nothing left to do here.
             */
            return next_directory(p_cur);
        }
        else
        {
            /** There is a parent directory that we still have to search
             *  through. Free this filenode and resume iterating through the
             *  parent.
             */ 
            d = move_up_directory(p_cur);

            /* Start over, reading the next entry from parent. */
            goto read_next_entry;
        }        
    }

    /* If the current dirent is a directory, then descend into it. */
    if (d->dirent.filetype == APR_DIR)
    {     
        /* Skip . and .. entries */
        if (d->dirent.name != NULL)
        {
            if (strcmp(d->dirent.name, ".") == 0 || strcmp(d->dirent.name, "..") == 0)
            {
                goto read_next_entry;
            }
        }

        /* Create a new child directory node */

        /* Combine the path and file names to get full path */

        char path[1024];
        sprintf(&path[0], "%s/%s", d->path, d->dirent.name);

        /* Allocate space for new filenode and initlialize members. */
        d              = malloc(sizeof(struct filenode));
        d->path        = strdup(path);
        d->parent      = p_cur->current_node;

        /* See note ZERO-FILL DIRENT below. */
        memset(&d->dirent, 0, sizeof(apr_finfo_t));

        /* Set current pointer to it. */
        p_cur->current_node = d;

        /* Clear the pool memory associated with the path string allocated above. */
        apr_pool_clear(p_cur->tmp_pool);
        
        /* Open the directory */
        if ((p_cur->status = apr_dir_open(&d->dir, d->path, p_cur->pool)) != APR_SUCCESS)
        {
            /* Problem. Couldn't open directory. */

            fprintf( stderr, "Failed to open directory: %s\n", 
                     p_cur->current_node->path );

            /* Set this to null to move_up_directory() doesn't try to
             * apr_close() it (->core dump) */
            p_cur->current_node->dir = NULL;

            /* Skip to next entry */
            deallocate_filenode(d);
            p_cur->current_node = d = prev_d;
            goto reread_next_entry;
        }

        /* Else we were able to open directory. Update the currnet dirent info
        ** to that of the opened directory. This is our next row in the result
        ** set.
        */
        apr_stat( &d->dirent, d->path, 
                  APR_FINFO_DIRENT|APR_FINFO_TYPE|APR_FINFO_NAME, 
                  p_cur->pool );
    }

    return SQLITE_OK;
}