2 #define _FILE_OFFSET_BITS 64
7 #include <ext2fs/ext2fs.h>
10 #if defined(HAVE_SQLITE3) && defined(HAVE_SQLITE3_H)
15 extern ext2_filsys fs;
25 /* number of files newer than specified time */
27 /* number of files reported */
28 ext2_ino_t nr_reported;
35 int block_iterate_cb(ext2_filsys fs, blk_t *block_nr,
37 blk_t ref_block EXT2FS_ATTR((unused)),
38 int ref_offset EXT2FS_ATTR((unused)),
42 static long count = 10000;
44 static void exec_one_sql_noreturn(sqlite3 *db, char *sqls)
48 if (sqlite3_exec(db, sqls, NULL, NULL, &errmsg) != SQLITE_OK) {
49 fprintf(stderr, "SQL error: %s;\nrequest: %s", errmsg, sqls);
55 static void create_sql_table(sqlite3 *db, const char *table_name,
60 if (asprintf(&sqls, "create table %s (%s)", table_name, columns) < 0) {
61 perror("asprintf failed");
65 exec_one_sql_noreturn(db, sqls);
69 static void begin_one_transaction(sqlite3 *db)
71 exec_one_sql_noreturn(db, "BEGIN;");
74 static void commit_one_transaction(sqlite3 *db)
76 exec_one_sql_noreturn(db, "COMMIT;");
79 static void batch_one_transaction(sqlite3 *db)
84 if (num % count == 0) {
85 commit_one_transaction(db);
86 begin_one_transaction(db);
91 #define COLUMNS "ino, generation, parent, name, size, mtime, ctime, dtime"
93 static void create_full_db(const char *name, int fd)
100 if (sqlite3_open(name, &db) != SQLITE_OK) {
101 fprintf(stderr, "failed to sqlite3_open: %s\n", name);
105 create_sql_table(db, "dirs", COLUMNS);
106 create_sql_table(db, "files", COLUMNS);
108 begin_one_transaction(db);
112 rd = read(fd, sqls, 512);
114 perror("read failed\n");
120 exec_one_sql_noreturn(db, sqls);
121 batch_one_transaction(db);
123 commit_one_transaction(db);
124 printf("database is created, %d records are inserted\n", nr);
128 /* write sql command to pipe */
129 #define PIPECMDLEN 512
130 static void write_sql_command(int fd, const char *sqls)
132 char buf[PIPECMDLEN];
134 if (strlen(sqls) + 1 > PIPECMDLEN) {
135 fprintf(stderr, "too long command");
139 if (write(fd, buf, PIPECMDLEN) != PIPECMDLEN) {
140 perror("failed to write to pipe");
143 scan_data.db.nr_commands ++;
146 pid_t fork_db_creation(const char *database)
152 if (stat(database, &st) == 0) {
153 fprintf(stderr, "%s exists. remove it first\n", database);
157 fprintf(stderr, "failed to pipe");
162 if (pid == (pid_t)-1) {
163 fprintf(stderr, "failed to fork");
166 if (pid == (pid_t)0) {
167 /* child, read data written by parent and write to
170 create_full_db(database, p[0]);
175 /* parent, read inodes and write them to pipe */
177 scan_data.db.fd = p[1];
181 void database_iscan_action(ext2_ino_t ino, struct ext2_inode *inode,
186 if (LINUX_S_ISDIR(inode->i_mode)) {
187 if (ino == EXT2_ROOT_INO) {
188 sqls = sqlite3_mprintf("%s (%u,%u,%u,'%q',%u,%u,%u,%u)",
189 "insert into dirs values",
190 ino, inode->i_generation, ino, "/",
191 inode->i_size, inode->i_mtime,
192 inode->i_ctime, inode->i_dtime);
193 write_sql_command(fd, sqls);
197 if (ext2fs_block_iterate2(fs, ino, 0, buf,
198 block_iterate_cb, &ino)) {
199 fprintf(stderr, "ext2fs_block_iterate2 failed\n");
206 * callback for ext2fs_dblist_dir_iterate to be called for each
209 int database_dblist_iterate_cb(ext2_ino_t dir, struct ext2_dir_entry *dirent,
212 struct ext2_inode inode;
218 if (!ext2fs_fast_test_inode_bitmap2(fs->inode_map, dirent->inode))
219 /* entry of deleted file? can that ever happen */
222 retval = ext2fs_read_inode(fs, dirent->inode, &inode);
224 com_err("ext2fs_read_inode", retval, "while reading inode");
228 if (LINUX_S_ISDIR(inode.i_mode))
233 sprintf(str, "%.*s", namelen, dirent->name);
234 sqls = sqlite3_mprintf("%s %s %s (%u,%u,%u,'%q',%u,%u,%u,%u)",
235 "insert into", table, "values",
236 dirent->inode, inode.i_generation, dir,
238 inode.i_size, inode.i_mtime,
239 inode.i_ctime, inode.i_dtime);
240 write_sql_command(fd, sqls);
248 pid_t fork_db_creation(const char *database)
253 void database_iscan_action(ext2_ino_t ino, struct ext2_inode *inode,
259 int database_dblist_iterate_cb(ext2_ino_t dir, struct ext2_dir_entry *dirent,