Skip to content

Commit

Permalink
super basic 'ls' and 'cat' for reading sqlfs files without mounting them
Browse files Browse the repository at this point in the history
* both only take a single file arg
* 'ls' only shows the file names
* both currently only work with unencrypted sqlfs.db files
  • Loading branch information
eighthave committed Jul 18, 2013
1 parent ab34812 commit 671f428
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Expand Up @@ -19,6 +19,8 @@ m4/
#
# build products
fuse_sqlfs
sqlfscat
sqlfsls
libsqlfs-1.0.la
libsqlfs.pc
*.o
Expand All @@ -34,3 +36,6 @@ tests/c_thread_api_key
tests/c_api_key
tests/c_api_key.db
tests/fuse_test
#
# emacs!
*~
8 changes: 7 additions & 1 deletion Makefile.am
Expand Up @@ -11,8 +11,14 @@ libsqlfs_1_0_la_SOURCES = sqlfs.c
libsqlfs_1_0_la_LIBADD = @SQLITE@ @LIBFUSE@
libsqlfs_1_0_la_LDFLAGS = -version-info 1:0:0

bin_PROGRAMS = sqlfscat sqlfsls
sqlfscat_SOURCES = sqlfscat.c
sqlfscat_LDADD = -lpthread @SQLITE@ ./.libs/libsqlfs-1.0.la
sqlfsls_SOURCES = sqlfsls.cpp
sqlfsls_LDADD = -lpthread @SQLITE@ ./.libs/libsqlfs-1.0.la

if WITH_LIBFUSE
bin_PROGRAMS = fuse_sqlfs
bin_PROGRAMS += fuse_sqlfs
fuse_sqlfs_SOURCES = fuse_sqlfs.c
fuse_sqlfs_LDADD = -lpthread @SQLITE@ @LIBFUSE@ ./.libs/libsqlfs-1.0.la
endif
Expand Down
3 changes: 2 additions & 1 deletion configure.in
Expand Up @@ -9,6 +9,7 @@ AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([dist-bzip2 -Wall])

AC_PROG_CC
AC_PROG_CXX
AC_PROG_LIBTOOL
# needed for "per-product" flags, i.e. fsx_CFLAGS
AM_PROG_CC_C_O
Expand Down Expand Up @@ -81,7 +82,7 @@ AS_IF([test "x$with_fuse" != xno],
AC_DEFINE([HAVE_LIBFUSE], [1],
[Define if you have fuse])
with_fuse=yes
CFLAGS="$CFLAGS -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DFUSE_USE_VERSION=25"
CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DFUSE_USE_VERSION=25"
LIBS="$LIBS -lpthread"
],
[if test "x$with_fuse" != xcheck; then
Expand Down
68 changes: 68 additions & 0 deletions sqlfscat.c
@@ -0,0 +1,68 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

#include "sqlfs.h"

#define BUF_SIZE 8192

int main(int argc, char *argv[])
{
int n;
char buf[BUF_SIZE];
struct stat s;
sqlfs_t *sqlfs = 0;
if (argc != 3)
{
fprintf(stderr, "Usage: %s sqlfs.db /path/to/file/to/cat\n", argv[0]);
exit(1);
}
const char *db = argv[1];
const char *file = argv[2];

/* first setup the database file */
if(access(db, R_OK))
{
fprintf(stderr, "sqlfs file is not readable! (%s)\n", db);
exit(1);
}
if(stat(db, &s) < 0)
{
fprintf(stderr, "stat on %s failed!\n", db);
exit(1);
}
if(S_ISREG(s.st_mode)<0)
{
fprintf(stderr, "Not a regular file: %s\n", db);
exit(1);
}
if (!sqlfs_open(db, &sqlfs)) {
fprintf(stderr, "Failed to open: %s\n", db);
return 1;
}
sqlfs_init(db);

// TODO memset(0) the key after its passed to sqlfs

if (!sqlfs_proc_access(sqlfs, file, R_OK)) {
fprintf(stderr, "Cannot access %s in %s\n", file, db);
//return 1;
}


/* now read the file from sqlfs */
struct fuse_file_info ffi;
int wrote = 0; // this is used to track were we are in the read
sqlfs_proc_open(sqlfs, file, &ffi);
while((n = sqlfs_proc_read(sqlfs, file, buf, BUF_SIZE, wrote, &ffi)) > 0)
{
wrote += write(1, buf, n); // write to stdout
}

sqlfs_close(sqlfs);
// TODO return proper exit value
return 0;
}
83 changes: 83 additions & 0 deletions sqlfsls.cpp
@@ -0,0 +1,83 @@
#include <stdio.h>
#include <stdlib.h>

#include <string>
#include <vector>
#include <iostream>

#include "sqlfs.h"

typedef std::vector<std::string> DirEntries;

/* FUSE filler() function for use with the FUSE style readdir() that
* libsqlfs provides. Note: this function only ever expects statp to
* be NULL and off to be 0. buf is DirEntries */
static int fill_dir(void *buf, const char *name, const struct stat *statp, off_t off) {
DirEntries *entries = (DirEntries*) buf;
if(statp != NULL)
fprintf(stderr, "File.listImpl() fill_dir always expects statp to be NULL");
if(off != 0)
fprintf(stderr, "File.listImpl() fill_dir always expects off to be 0");
entries->push_back(name);
// TODO implement returning an error (1) if something bad happened
return 0;
}

int main(int argc, char *argv[])
{
int n;
struct stat s;
sqlfs_t *sqlfs = 0;
const char *db;
const char *file;
if (argc == 2)
{
db = argv[1];
file = "/";
}
else if (argc != 3)
{
fprintf(stderr, "Usage: %s sqlfs.db [ /path ]\n", argv[0]);
exit(1);
}
else
{
db = argv[1];
file = argv[2];
}

/* first setup the database file */
if(access(db, R_OK))
{
fprintf(stderr, "sqlfs file is not readable! (%s)\n", db);
exit(1);
}
if(stat(db, &s) < 0)
{
fprintf(stderr, "stat on %s failed!\n", db);
exit(1);
}
if(S_ISREG(s.st_mode)<0)
{
fprintf(stderr, "Not a regular file: %s\n", db);
exit(1);
}
if (!sqlfs_open(db, &sqlfs)) {
fprintf(stderr, "Failed to open: %s\n", db);
return 1;
}
sqlfs_init(db);
// TODO memset(0) the key after its passed to sqlfs

/* now read the dir entries */
DirEntries entries;
// using FUSE readdir in old getdir() style which gives us the whole thing at once
int ret = sqlfs_proc_readdir(0, file, (void *)&entries, (fuse_fill_dir_t)fill_dir, 0, NULL);
for(DirEntries::const_iterator i = entries.begin() + 2; i != entries.end(); ++i) {
std::cout << *i << "\n"; // this will print all the contents of *features*
}

sqlfs_close(sqlfs);

return abs(ret); // FUSE returns negative error values
}

0 comments on commit 671f428

Please sign in to comment.