SQLite Archiver (Windows)
Check-in [2a85fc2898]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
SHA1:2a85fc289863ddaa86f304966ba31bf752cd67d4
Date: 2014-06-13 18:22:16
User: drh
Comment:Get the sqlarfs.c FuseFS adaptor working for read-only operation.
Tags And Properties
Context
2014-06-13 18:32
[aab6f9cff9] Add a short mention of the FuseFS adaptor to the documentation and homepage. (user: drh, tags: trunk)
2014-06-13 18:22
[2a85fc2898] Get the sqlarfs.c FuseFS adaptor working for read-only operation. (user: drh, tags: trunk)
2014-06-13 17:59
[5766e8f04e] Add a "clean" target to the Makefile. (user: drh, tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to sqlarfs.c.

11
12
13
14
15
16
17


18
19
20
21
22
23
24
25
26
27
28
29
30


31
32
33
34
35
36
37
..
47
48
49
50
51
52
53
54
55
56

57


58
59
60
61
62
63
64
..
71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90








91

92
93
94
95
96
97
98
99
100
101
102
103
104
105
...
215
216
217
218
219
220
221


222
223
224
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <zlib.h>
#include "sqlite3.h"
#include <stdlib.h>



/*
** Global state information about the archive
*/
struct sGlobal {
  sqlite3 *db;           /* Open database connection */
  sqlite3_stmt *pStat;   /* Prepared statement to read stat info */
  sqlite3_stmt *pFList;  /* Prepared statement to list all files */
  sqlite3_stmt *pExists; /* Prepared statement to check if a file exists */
  sqlite3_stmt *pRead;   /* Prepared statement to get file content */
  char *zCacheName;      /* Cached file */
  unsigned long int szCache; /* Size of the cached file */
  char *zCacheData;      /* Content of the cached files */


} g;

/*
** Implementation of stat()
*/
static int sqlarfs_getattr(const char *path, struct stat *stbuf){
  int rc = 0;
................................................................................
               -1, &g.pStat, 0);
    if( rc!=SQLITE_OK ){
      return -ENOENT;
    }
  }
  sqlite3_bind_text(g.pStat, 1, &path[1], -1, SQLITE_STATIC);
  if( sqlite3_step(g.pStat)==SQLITE_ROW ){
    stbuf->st_mode = sqlite3_column_int(g.pStat, 0);
    stbuf->st_nlink = 1;
    stbuf->st_mtime = sqlite3_column_int(g.pStat, 1);

    stbuf->st_size = sqlite3_column_int64(g.pStat, 2);


    rc = 0;
  }else{
    rc = -ENOENT;
  }
  sqlite3_reset(g.pStat);
  return rc;
}
................................................................................
  const char *path,
  void *buf,
  fuse_fill_dir_t filler,
  off_t offset,
  struct fuse_file_info *fi
){
  int rc;
  if( strcmp(path, "/")!=0 ) return -ENOENT;

  if( g.pFList==0 ){
    rc = sqlite3_prepare_v2(g.db,
               "SELECT name FROM sqlar"
               " WHERE name BETWEEN ?1 AND ?1 || char(1114111)"
               "   AND substr(name,length(?1)) NOT GLOB '*/*'",
               -1, &g.pFList, 0);
    if( rc!=SQLITE_OK ){
      return -ENOENT;
    }
  }
  filler(buf, ".", NULL, 0);
  filler(buf, "..", NULL, 0);








  sqlite3_bind_text(g.pFList, 1, &path[1], -1, SQLITE_STATIC);

  while( sqlite3_step(g.pFList)==SQLITE_ROW ){
    filler(buf, (const char*)sqlite3_column_text(g.pFList, 0), NULL, 0);
  }
  sqlite3_reset(g.pFList);
  return 0;

	return 0;
}

/*
** Implementation of open()
*/
static int sqlarfs_open(const char *path, struct fuse_file_info *fi){
  int rc;
................................................................................
    exit(1);
  }
  rc = sqlite3_exec(g.db, "SELECT 1 FROM sqlar LIMIT 1", 0, 0, 0);
  if( rc!=SQLITE_OK ){
    fprintf(stderr, "File [%s] is not an SQLite archive\n", argv[1]);
    exit(1);
  }


  rc = fuse_main(argc-1, argv+1, &sqlarfs_methods, NULL);
  return rc;
}







>
>













>
>







 







|


>

>
>







 







|
>


|
|
|







>
>
>
>
>
>
>
>
|
>





<
<







 







>
>



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
..
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
..
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113


114
115
116
117
118
119
120
...
230
231
232
233
234
235
236
237
238
239
240
241
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <zlib.h>
#include "sqlite3.h"
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

/*
** Global state information about the archive
*/
struct sGlobal {
  sqlite3 *db;           /* Open database connection */
  sqlite3_stmt *pStat;   /* Prepared statement to read stat info */
  sqlite3_stmt *pFList;  /* Prepared statement to list all files */
  sqlite3_stmt *pExists; /* Prepared statement to check if a file exists */
  sqlite3_stmt *pRead;   /* Prepared statement to get file content */
  char *zCacheName;      /* Cached file */
  unsigned long int szCache; /* Size of the cached file */
  char *zCacheData;      /* Content of the cached files */
  pid_t uid;             /* User ID for all content files */
  gid_t gid;             /* Group ID for all content files */
} g;

/*
** Implementation of stat()
*/
static int sqlarfs_getattr(const char *path, struct stat *stbuf){
  int rc = 0;
................................................................................
               -1, &g.pStat, 0);
    if( rc!=SQLITE_OK ){
      return -ENOENT;
    }
  }
  sqlite3_bind_text(g.pStat, 1, &path[1], -1, SQLITE_STATIC);
  if( sqlite3_step(g.pStat)==SQLITE_ROW ){
    stbuf->st_mode = sqlite3_column_int(g.pStat, 0) & ~0222;
    stbuf->st_nlink = 1;
    stbuf->st_mtime = sqlite3_column_int(g.pStat, 1);
    stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime;
    stbuf->st_size = sqlite3_column_int64(g.pStat, 2);
    stbuf->st_uid = g.uid;
    stbuf->st_gid = g.gid;
    rc = 0;
  }else{
    rc = -ENOENT;
  }
  sqlite3_reset(g.pStat);
  return rc;
}
................................................................................
  const char *path,
  void *buf,
  fuse_fill_dir_t filler,
  off_t offset,
  struct fuse_file_info *fi
){
  int rc;
  char *zGlob;
  int nGlob;
  if( g.pFList==0 ){
    rc = sqlite3_prepare_v2(g.db,
               "SELECT substr(name,?2) FROM sqlar"
               " WHERE name GLOB ?1"
               "   AND substr(name,?2) NOT GLOB '*/*'",
               -1, &g.pFList, 0);
    if( rc!=SQLITE_OK ){
      return -ENOENT;
    }
  }
  filler(buf, ".", NULL, 0);
  filler(buf, "..", NULL, 0);
  if( strcmp(path, "/")==0 ){
    zGlob = sqlite3_mprintf("*");
    nGlob = 1;
  }else{
    zGlob = sqlite3_mprintf("%s/*", &path[1]);
    nGlob = (int)strlen(zGlob);
  }
  if( zGlob==0 ) return -EIO;
  sqlite3_bind_text(g.pFList, 1, zGlob, -1, sqlite3_free);
  sqlite3_bind_int(g.pFList, 2, nGlob);
  while( sqlite3_step(g.pFList)==SQLITE_ROW ){
    filler(buf, (const char*)sqlite3_column_text(g.pFList, 0), NULL, 0);
  }
  sqlite3_reset(g.pFList);
  return 0;


}

/*
** Implementation of open()
*/
static int sqlarfs_open(const char *path, struct fuse_file_info *fi){
  int rc;
................................................................................
    exit(1);
  }
  rc = sqlite3_exec(g.db, "SELECT 1 FROM sqlar LIMIT 1", 0, 0, 0);
  if( rc!=SQLITE_OK ){
    fprintf(stderr, "File [%s] is not an SQLite archive\n", argv[1]);
    exit(1);
  }
  g.uid = getuid();
  g.gid = getgid();
  rc = fuse_main(argc-1, argv+1, &sqlarfs_methods, NULL);
  return rc;
}